feat: gate -Prefix to skip already-prefixed names; add -ForcePrefix override on ConvertTo/Import/Export/Start cmdlets

This commit is contained in:
GraceSolutions
2026-06-07 10:35:18 -04:00
parent b5575222eb
commit 97193d46f2
8 changed files with 44 additions and 13 deletions
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Security;
using PSInfisicalAPI.Common;
using PSInfisicalAPI.Errors;
using PSInfisicalAPI.Models;
@@ -24,6 +25,9 @@ namespace PSInfisicalAPI.Cmdlets
[Parameter]
public string Prefix { get; set; }
[Parameter]
public SwitchParameter ForcePrefix { get; set; }
private readonly List<InfisicalSecret> _buffer = new List<InfisicalSecret>();
protected override void ProcessRecord()
@@ -63,11 +67,10 @@ namespace PSInfisicalAPI.Cmdlets
private Dictionary<string, TValue> BuildDictionary<TValue>(Func<InfisicalSecret, TValue> valueSelector)
{
Dictionary<string, TValue> dictionary = new Dictionary<string, TValue>(StringComparer.OrdinalIgnoreCase);
string prefix = Prefix ?? string.Empty;
foreach (InfisicalSecret secret in _buffer)
{
string key = string.Concat(prefix, secret.SecretName ?? string.Empty);
string key = InfisicalPrefix.Apply(secret.SecretName ?? string.Empty, Prefix, ForcePrefix.IsPresent);
if (dictionary.ContainsKey(key))
{
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Management.Automation;
using System.Text;
using PSInfisicalAPI.Common;
using PSInfisicalAPI.Errors;
using PSInfisicalAPI.Exports;
using PSInfisicalAPI.Models;
@@ -40,6 +41,9 @@ namespace PSInfisicalAPI.Cmdlets
[Parameter]
public string Prefix { get; set; }
[Parameter]
public SwitchParameter ForcePrefix { get; set; }
private readonly List<InfisicalSecret> _buffer = new List<InfisicalSecret>();
protected override void ProcessRecord()
@@ -71,7 +75,7 @@ namespace PSInfisicalAPI.Cmdlets
InfisicalExportRequest request = new InfisicalExportRequest
{
Secrets = ApplyPrefix(_buffer, Prefix),
Secrets = ApplyPrefix(_buffer, Prefix, ForcePrefix.IsPresent),
Format = Format,
Path = Path,
Scope = Scope,
@@ -88,7 +92,7 @@ namespace PSInfisicalAPI.Cmdlets
}
}
private static InfisicalSecret[] ApplyPrefix(List<InfisicalSecret> source, string prefix)
private static InfisicalSecret[] ApplyPrefix(List<InfisicalSecret> source, string prefix, bool force)
{
if (string.IsNullOrEmpty(prefix)) { return source.ToArray(); }
@@ -104,7 +108,7 @@ namespace PSInfisicalAPI.Cmdlets
Environment = original.Environment,
Version = original.Version,
Type = original.Type,
SecretName = string.Concat(prefix, original.SecretName),
SecretName = InfisicalPrefix.Apply(original.SecretName, prefix, force),
SecretValue = original.SecretValue,
SecretValueHidden = original.SecretValueHidden,
SecretPath = original.SecretPath,
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Management.Automation;
using System.Security;
using PSInfisicalAPI.Common;
using PSInfisicalAPI.Errors;
using PSInfisicalAPI.Imports;
using PSInfisicalAPI.Models;
@@ -31,6 +32,9 @@ namespace PSInfisicalAPI.Cmdlets
[Parameter]
public string Prefix { get; set; }
[Parameter]
public SwitchParameter ForcePrefix { get; set; }
protected override void EndProcessing()
{
try
@@ -66,12 +70,11 @@ namespace PSInfisicalAPI.Cmdlets
Func<string, TValue> valueSelector)
{
Dictionary<string, TValue> dictionary = new Dictionary<string, TValue>(StringComparer.OrdinalIgnoreCase);
string prefix = Prefix ?? string.Empty;
foreach (KeyValuePair<string, string> pair in pairs)
{
if (pair.Key == null) { continue; }
string key = string.Concat(prefix, pair.Key);
string key = InfisicalPrefix.Apply(pair.Key, Prefix, ForcePrefix.IsPresent);
if (dictionary.ContainsKey(key))
{
@@ -95,6 +95,9 @@ namespace PSInfisicalAPI.Cmdlets
[Parameter]
public string Prefix { get; set; }
[Parameter]
public SwitchParameter ForcePrefix { get; set; }
private readonly List<InfisicalSecret> _secretBuffer = new List<InfisicalSecret>();
protected override void ProcessRecord()
@@ -135,7 +138,8 @@ namespace PSInfisicalAPI.Cmdlets
LogOutput = LogOutput.IsPresent,
ContinueOnError = ContinueOnError.IsPresent,
Secrets = _secretBuffer.ToArray(),
Prefix = Prefix
Prefix = Prefix,
ForcePrefix = ForcePrefix.IsPresent
};
InfisicalProcessResult result = InfisicalProcessRunner.Run(options, Logger);
@@ -0,0 +1,15 @@
using System;
namespace PSInfisicalAPI.Common
{
public static class InfisicalPrefix
{
public static string Apply(string original, string prefix, bool force)
{
if (string.IsNullOrEmpty(prefix)) { return original ?? string.Empty; }
if (original == null) { return prefix; }
if (!force && original.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) { return original; }
return string.Concat(prefix, original);
}
}
}
@@ -26,5 +26,6 @@ namespace PSInfisicalAPI.Process
public bool ContinueOnError { get; set; }
public InfisicalSecret[] Secrets { get; set; }
public string Prefix { get; set; }
public bool ForcePrefix { get; set; }
}
}
@@ -6,6 +6,7 @@ using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using PSInfisicalAPI.Common;
using PSInfisicalAPI.Logging;
using PSInfisicalAPI.Models;
using PSInfisicalAPI.Security;
@@ -39,7 +40,7 @@ namespace PSInfisicalAPI.Process
foreach (InfisicalSecret secret in options.Secrets)
{
if (secret == null || string.IsNullOrEmpty(secret.SecretName) || secret.SecretValue == null) { continue; }
string name = string.IsNullOrEmpty(options.Prefix) ? secret.SecretName : string.Concat(options.Prefix, secret.SecretName);
string name = InfisicalPrefix.Apply(secret.SecretName, options.Prefix, options.ForcePrefix);
SecureStringUtility.UsePlainText(secret.SecretValue, plain =>
{
processEnv[name] = plain;