09c577ebd0
- Endpoint registry now stores ordered candidate lists per logical operation; Get/TryGet preserve prior behavior, new GetCandidates(name) exposes the ladder. Added v3 fallbacks (/api/v3/secrets/raw and /api/v3/secrets/raw/{secretName}) after v4. - InfisicalConnection gains PinnedApiVersion and a ResolvedEndpointVersions cache so the chosen version sticks for the session. - InfisicalSecretsClient.SendWithVersionFallback walks candidates in pin -> cached -> registry order, falls back on routing-style failures (404 without an Infisical JSON envelope, 405, or 400 mentioning workspaceId/projectSlug) when no version is pinned, and surfaces real application errors immediately. - Get-InfisicalSecret(s) expose -ApiVersion; Connect-Infisical sets PinnedApiVersion only when -ApiVersion is explicitly bound on the command line (env-var/default values do not pin). - Logger.Error routes via WriteWarning to avoid premature terminating errors that masked InfisicalApiException details; EnsureSuccess no longer redacts non-2xx bodies so server error envelopes are visible. - InfisicalSecretsClient sends both projectId and workspaceId so it works against both new and legacy server-side validators.
147 lines
5.7 KiB
C#
147 lines
5.7 KiB
C#
using System.Collections.Generic;
|
|
using PSInfisicalAPI.Errors;
|
|
|
|
namespace PSInfisicalAPI.Endpoints
|
|
{
|
|
public static class InfisicalEndpointRegistry
|
|
{
|
|
private static readonly Dictionary<string, List<InfisicalEndpointDefinition>> Candidates =
|
|
new Dictionary<string, List<InfisicalEndpointDefinition>>
|
|
{
|
|
{
|
|
InfisicalEndpointNames.UniversalAuthLogin,
|
|
new List<InfisicalEndpointDefinition>
|
|
{
|
|
new InfisicalEndpointDefinition
|
|
{
|
|
Name = InfisicalEndpointNames.UniversalAuthLogin,
|
|
Resource = "Authentication",
|
|
Version = "v1",
|
|
Method = "POST",
|
|
Template = "/api/v1/auth/universal-auth/login",
|
|
RequiresAuthorization = false,
|
|
ContainsSecretMaterialInRequest = true,
|
|
ContainsSecretMaterialInResponse = true
|
|
}
|
|
}
|
|
},
|
|
{
|
|
InfisicalEndpointNames.ListSecrets,
|
|
new List<InfisicalEndpointDefinition>
|
|
{
|
|
new InfisicalEndpointDefinition
|
|
{
|
|
Name = InfisicalEndpointNames.ListSecrets,
|
|
Resource = "Secrets",
|
|
Version = "v4",
|
|
Method = "GET",
|
|
Template = "/api/v4/secrets",
|
|
RequiresAuthorization = true,
|
|
ContainsSecretMaterialInRequest = false,
|
|
ContainsSecretMaterialInResponse = true
|
|
},
|
|
new InfisicalEndpointDefinition
|
|
{
|
|
Name = InfisicalEndpointNames.ListSecrets,
|
|
Resource = "Secrets",
|
|
Version = "v3",
|
|
Method = "GET",
|
|
Template = "/api/v3/secrets/raw",
|
|
RequiresAuthorization = true,
|
|
ContainsSecretMaterialInRequest = false,
|
|
ContainsSecretMaterialInResponse = true
|
|
}
|
|
}
|
|
},
|
|
{
|
|
InfisicalEndpointNames.RetrieveSecret,
|
|
new List<InfisicalEndpointDefinition>
|
|
{
|
|
new InfisicalEndpointDefinition
|
|
{
|
|
Name = InfisicalEndpointNames.RetrieveSecret,
|
|
Resource = "Secrets",
|
|
Version = "v4",
|
|
Method = "GET",
|
|
Template = "/api/v4/secrets/{secretName}",
|
|
RequiresAuthorization = true,
|
|
ContainsSecretMaterialInRequest = false,
|
|
ContainsSecretMaterialInResponse = true
|
|
},
|
|
new InfisicalEndpointDefinition
|
|
{
|
|
Name = InfisicalEndpointNames.RetrieveSecret,
|
|
Resource = "Secrets",
|
|
Version = "v3",
|
|
Method = "GET",
|
|
Template = "/api/v3/secrets/raw/{secretName}",
|
|
RequiresAuthorization = true,
|
|
ContainsSecretMaterialInRequest = false,
|
|
ContainsSecretMaterialInResponse = true
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
public static InfisicalEndpointDefinition Get(string name)
|
|
{
|
|
List<InfisicalEndpointDefinition> list = GetCandidatesInternal(name);
|
|
return list[0];
|
|
}
|
|
|
|
public static bool TryGet(string name, out InfisicalEndpointDefinition definition)
|
|
{
|
|
if (string.IsNullOrEmpty(name))
|
|
{
|
|
definition = null;
|
|
return false;
|
|
}
|
|
|
|
List<InfisicalEndpointDefinition> list;
|
|
if (!Candidates.TryGetValue(name, out list) || list == null || list.Count == 0)
|
|
{
|
|
definition = null;
|
|
return false;
|
|
}
|
|
|
|
definition = list[0];
|
|
return true;
|
|
}
|
|
|
|
public static IReadOnlyList<InfisicalEndpointDefinition> GetCandidates(string name)
|
|
{
|
|
return GetCandidatesInternal(name);
|
|
}
|
|
|
|
public static IEnumerable<InfisicalEndpointDefinition> All()
|
|
{
|
|
List<InfisicalEndpointDefinition> result = new List<InfisicalEndpointDefinition>();
|
|
foreach (List<InfisicalEndpointDefinition> list in Candidates.Values)
|
|
{
|
|
foreach (InfisicalEndpointDefinition definition in list)
|
|
{
|
|
result.Add(definition);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private static List<InfisicalEndpointDefinition> GetCandidatesInternal(string name)
|
|
{
|
|
if (string.IsNullOrEmpty(name))
|
|
{
|
|
throw new InfisicalConfigurationException("Endpoint name must be provided.");
|
|
}
|
|
|
|
List<InfisicalEndpointDefinition> list;
|
|
if (!Candidates.TryGetValue(name, out list) || list == null || list.Count == 0)
|
|
{
|
|
throw new InfisicalConfigurationException(string.Concat("Unknown endpoint name: ", name));
|
|
}
|
|
|
|
return list;
|
|
}
|
|
}
|
|
}
|