CI: add dotnet --info / df -h / free -m diagnostics and an explicit 'Restore NuGet packages' step before build to isolate restore failures (build of e15f650 on main exited with code -1 and zero dotnet output). #5

Merged
gsadmin merged 27 commits from dev into main 2026-06-05 01:24:51 +00:00
8 changed files with 666 additions and 5 deletions
Showing only changes of commit a195901a10 - Show all commits
@@ -63,5 +63,13 @@ namespace PSInfisicalAPI.Endpoints
public const string GetCertificatePolicy = "GetCertificatePolicy"; public const string GetCertificatePolicy = "GetCertificatePolicy";
public const string ListCertificateAuthorities = "ListCertificateAuthorities"; public const string ListCertificateAuthorities = "ListCertificateAuthorities";
public const string ListCertificateApplications = "ListCertificateApplications";
public const string GetCertificateApplication = "GetCertificateApplication";
public const string GetCertificateApplicationByName = "GetCertificateApplicationByName";
public const string ListCertificateApplicationProfiles = "ListCertificateApplicationProfiles";
public const string GetCertificateApplicationEnrollment = "GetCertificateApplicationEnrollment";
public const string GenerateScepDynamicChallenge = "GenerateScepDynamicChallenge";
} }
} }
@@ -703,6 +703,67 @@ namespace PSInfisicalAPI.Endpoints
Template = "/api/v1/cert-manager/ca", Template = "/api/v1/cert-manager/ca",
RequiresAuthorization = true RequiresAuthorization = true
}); });
Add(map, new InfisicalEndpointDefinition
{
Name = InfisicalEndpointNames.ListCertificateApplications,
Resource = "Pki",
Version = "v1",
Method = "GET",
Template = "/api/v1/cert-manager/applications",
RequiresAuthorization = true
});
Add(map, new InfisicalEndpointDefinition
{
Name = InfisicalEndpointNames.GetCertificateApplication,
Resource = "Pki",
Version = "v1",
Method = "GET",
Template = "/api/v1/cert-manager/applications/{applicationId}",
RequiresAuthorization = true
});
Add(map, new InfisicalEndpointDefinition
{
Name = InfisicalEndpointNames.GetCertificateApplicationByName,
Resource = "Pki",
Version = "v1",
Method = "GET",
Template = "/api/v1/cert-manager/applications/by-name/{name}",
RequiresAuthorization = true
});
Add(map, new InfisicalEndpointDefinition
{
Name = InfisicalEndpointNames.ListCertificateApplicationProfiles,
Resource = "Pki",
Version = "v1",
Method = "GET",
Template = "/api/v1/cert-manager/applications/{applicationId}/profiles",
RequiresAuthorization = true
});
Add(map, new InfisicalEndpointDefinition
{
Name = InfisicalEndpointNames.GetCertificateApplicationEnrollment,
Resource = "Pki",
Version = "v1",
Method = "GET",
Template = "/api/v1/cert-manager/applications/{applicationId}/profiles/{profileId}/enrollment",
RequiresAuthorization = true
});
Add(map, new InfisicalEndpointDefinition
{
Name = InfisicalEndpointNames.GenerateScepDynamicChallenge,
Resource = "Pki",
Version = "v1",
Method = "POST",
Template = "/scep/applications/{applicationId}/profiles/{profileId}/challenge",
RequiresAuthorization = true,
ContainsSecretMaterialInResponse = true
});
} }
public static InfisicalEndpointDefinition Get(string name) public static InfisicalEndpointDefinition Get(string name)
+17 -5
View File
@@ -23,7 +23,8 @@ namespace PSInfisicalAPI.Http
string operationName, string operationName,
IDictionary<string, string> pathParameters, IDictionary<string, string> pathParameters,
IEnumerable<KeyValuePair<string, string>> queryParameters, IEnumerable<KeyValuePair<string, string>> queryParameters,
string body) string body,
IDictionary<string, string> extraHeaders = null)
{ {
if (connection == null) { throw new ArgumentNullException(nameof(connection)); } if (connection == null) { throw new ArgumentNullException(nameof(connection)); }
if (string.IsNullOrEmpty(endpointName)) { throw new ArgumentNullException(nameof(endpointName)); } if (string.IsNullOrEmpty(endpointName)) { throw new ArgumentNullException(nameof(endpointName)); }
@@ -31,7 +32,7 @@ namespace PSInfisicalAPI.Http
InfisicalEndpointDefinition definition = InfisicalEndpointRegistry.Get(endpointName); InfisicalEndpointDefinition definition = InfisicalEndpointRegistry.Get(endpointName);
Uri uri = InfisicalUriBuilder.Build(connection.BaseUri, definition, pathParameters, queryParameters); Uri uri = InfisicalUriBuilder.Build(connection.BaseUri, definition, pathParameters, queryParameters);
InfisicalHttpResponse response = ExecuteAuthorized(connection, definition, operationName, uri, body); InfisicalHttpResponse response = ExecuteAuthorized(connection, definition, operationName, uri, body, extraHeaders);
if (response.StatusCode >= 200 && response.StatusCode < 300) if (response.StatusCode >= 200 && response.StatusCode < 300)
{ {
@@ -49,7 +50,8 @@ namespace PSInfisicalAPI.Http
string operationName, string operationName,
IDictionary<string, string> pathParameters, IDictionary<string, string> pathParameters,
IEnumerable<KeyValuePair<string, string>> queryParameters, IEnumerable<KeyValuePair<string, string>> queryParameters,
string body) string body,
IDictionary<string, string> extraHeaders = null)
{ {
if (connection == null) { throw new ArgumentNullException(nameof(connection)); } if (connection == null) { throw new ArgumentNullException(nameof(connection)); }
if (string.IsNullOrEmpty(endpointName)) { throw new ArgumentNullException(nameof(endpointName)); } if (string.IsNullOrEmpty(endpointName)) { throw new ArgumentNullException(nameof(endpointName)); }
@@ -61,7 +63,7 @@ namespace PSInfisicalAPI.Http
{ {
InfisicalEndpointDefinition definition = candidates[index]; InfisicalEndpointDefinition definition = candidates[index];
Uri uri = InfisicalUriBuilder.Build(connection.BaseUri, definition, pathParameters, queryParameters); Uri uri = InfisicalUriBuilder.Build(connection.BaseUri, definition, pathParameters, queryParameters);
InfisicalHttpResponse response = ExecuteAuthorized(connection, definition, operationName, uri, body); InfisicalHttpResponse response = ExecuteAuthorized(connection, definition, operationName, uri, body, extraHeaders);
if (response.StatusCode >= 200 && response.StatusCode < 300) if (response.StatusCode >= 200 && response.StatusCode < 300)
{ {
@@ -95,7 +97,8 @@ namespace PSInfisicalAPI.Http
InfisicalEndpointDefinition definition, InfisicalEndpointDefinition definition,
string operationName, string operationName,
Uri uri, Uri uri,
string body) string body,
IDictionary<string, string> extraHeaders = null)
{ {
Dictionary<string, string> headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); Dictionary<string, string> headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
headers["Accept"] = "application/json"; headers["Accept"] = "application/json";
@@ -118,6 +121,15 @@ namespace PSInfisicalAPI.Http
}); });
} }
if (extraHeaders != null)
{
foreach (KeyValuePair<string, string> entry in extraHeaders)
{
if (string.IsNullOrEmpty(entry.Key)) { continue; }
headers[entry.Key] = entry.Value;
}
}
InfisicalHttpRequest request = new InfisicalHttpRequest InfisicalHttpRequest request = new InfisicalHttpRequest
{ {
OperationName = operationName, OperationName = operationName,
@@ -0,0 +1,31 @@
using System;
namespace PSInfisicalAPI.Models
{
public sealed class InfisicalCertificateApplication
{
public string Id { get; set; }
public string ProjectId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int? ProfileCount { get; set; }
public int? MemberCount { get; set; }
public int? CertificateCount { get; set; }
public DateTimeOffset? CreatedAtUtc { get; set; }
public DateTimeOffset? UpdatedAtUtc { get; set; }
}
public sealed class InfisicalCertificateApplicationProfileAttachment
{
public string ApplicationId { get; set; }
public string ProfileId { get; set; }
public string ProfileSlug { get; set; }
public string ProfileDescription { get; set; }
public string ApiConfigId { get; set; }
public string EstConfigId { get; set; }
public string AcmeConfigId { get; set; }
public string ScepConfigId { get; set; }
public DateTimeOffset? CreatedAtUtc { get; set; }
public DateTimeOffset? UpdatedAtUtc { get; set; }
}
}
@@ -0,0 +1,55 @@
using System;
namespace PSInfisicalAPI.Models
{
public sealed class InfisicalCertificateApplicationEnrollment
{
public string ApplicationId { get; set; }
public string ProfileId { get; set; }
public InfisicalCertificateApplicationApiEnrollment Api { get; set; }
public InfisicalCertificateApplicationEstEnrollment Est { get; set; }
public InfisicalCertificateApplicationAcmeEnrollment Acme { get; set; }
public InfisicalCertificateApplicationScepEnrollment Scep { get; set; }
public bool ApiConfigured { get { return Api != null; } }
public bool EstConfigured { get; set; }
public bool AcmeConfigured { get; set; }
public bool ScepConfigured { get; set; }
}
public sealed class InfisicalCertificateApplicationApiEnrollment
{
public string Id { get; set; }
public bool? AutoRenew { get; set; }
public int? RenewBeforeDays { get; set; }
}
public sealed class InfisicalCertificateApplicationEstEnrollment
{
public string Id { get; set; }
public bool? DisableBootstrapCaValidation { get; set; }
public string EstEndpointUrl { get; set; }
}
public sealed class InfisicalCertificateApplicationAcmeEnrollment
{
public string Id { get; set; }
public bool? SkipDnsOwnershipVerification { get; set; }
public bool? SkipEabBinding { get; set; }
public string DirectoryUrl { get; set; }
}
public sealed class InfisicalCertificateApplicationScepEnrollment
{
public string Id { get; set; }
public string ChallengeType { get; set; }
public bool? IncludeCaCertInResponse { get; set; }
public bool? AllowCertBasedRenewal { get; set; }
public int? DynamicChallengeExpiryMinutes { get; set; }
public int? DynamicChallengeMaxPending { get; set; }
public string ScepEndpointUrl { get; set; }
public string ChallengeEndpointUrl { get; set; }
public string RaCertificatePem { get; set; }
public string RaCertificateThumbprint { get; set; }
public DateTimeOffset? RaCertExpiresAtUtc { get; set; }
}
}
@@ -0,0 +1,92 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace PSInfisicalAPI.Pki
{
internal sealed class InfisicalCertificateApplicationResponseDto
{
[JsonProperty("id")] public string Id { get; set; }
[JsonProperty("projectId")] public string ProjectId { get; set; }
[JsonProperty("name")] public string Name { get; set; }
[JsonProperty("description")] public string Description { get; set; }
[JsonProperty("profileCount")] public int? ProfileCount { get; set; }
[JsonProperty("memberCount")] public int? MemberCount { get; set; }
[JsonProperty("certificateCount")] public int? CertificateCount { get; set; }
[JsonProperty("createdAt")] public string CreatedAt { get; set; }
[JsonProperty("updatedAt")] public string UpdatedAt { get; set; }
}
internal sealed class InfisicalCertificateApplicationListResponseDto
{
[JsonProperty("applications")] public List<InfisicalCertificateApplicationResponseDto> Applications { get; set; }
[JsonProperty("total")] public int? Total { get; set; }
}
internal sealed class InfisicalCertificateApplicationProfileAttachmentDto
{
[JsonProperty("applicationId")] public string ApplicationId { get; set; }
[JsonProperty("profileId")] public string ProfileId { get; set; }
[JsonProperty("profileSlug")] public string ProfileSlug { get; set; }
[JsonProperty("profileDescription")] public string ProfileDescription { get; set; }
[JsonProperty("apiConfigId")] public string ApiConfigId { get; set; }
[JsonProperty("estConfigId")] public string EstConfigId { get; set; }
[JsonProperty("acmeConfigId")] public string AcmeConfigId { get; set; }
[JsonProperty("scepConfigId")] public string ScepConfigId { get; set; }
[JsonProperty("createdAt")] public string CreatedAt { get; set; }
[JsonProperty("updatedAt")] public string UpdatedAt { get; set; }
}
internal sealed class InfisicalCertificateApplicationProfilesResponseDto
{
[JsonProperty("profiles")] public List<InfisicalCertificateApplicationProfileAttachmentDto> Profiles { get; set; }
}
internal sealed class InfisicalCertificateApplicationEnrollmentResponseDto
{
[JsonProperty("applicationId")] public string ApplicationId { get; set; }
[JsonProperty("profileId")] public string ProfileId { get; set; }
[JsonProperty("api")] public InfisicalCertificateApplicationApiEnrollmentDto Api { get; set; }
[JsonProperty("est")] public InfisicalCertificateApplicationEstEnrollmentDto Est { get; set; }
[JsonProperty("acme")] public InfisicalCertificateApplicationAcmeEnrollmentDto Acme { get; set; }
[JsonProperty("scep")] public InfisicalCertificateApplicationScepEnrollmentDto Scep { get; set; }
[JsonProperty("estConfigured")] public bool? EstConfigured { get; set; }
[JsonProperty("acmeConfigured")] public bool? AcmeConfigured { get; set; }
[JsonProperty("scepConfigured")] public bool? ScepConfigured { get; set; }
}
internal sealed class InfisicalCertificateApplicationApiEnrollmentDto
{
[JsonProperty("id")] public string Id { get; set; }
[JsonProperty("autoRenew")] public bool? AutoRenew { get; set; }
[JsonProperty("renewBeforeDays")] public int? RenewBeforeDays { get; set; }
}
internal sealed class InfisicalCertificateApplicationEstEnrollmentDto
{
[JsonProperty("id")] public string Id { get; set; }
[JsonProperty("disableBootstrapCaValidation")] public bool? DisableBootstrapCaValidation { get; set; }
[JsonProperty("estEndpointUrl")] public string EstEndpointUrl { get; set; }
}
internal sealed class InfisicalCertificateApplicationAcmeEnrollmentDto
{
[JsonProperty("id")] public string Id { get; set; }
[JsonProperty("skipDnsOwnershipVerification")] public bool? SkipDnsOwnershipVerification { get; set; }
[JsonProperty("skipEabBinding")] public bool? SkipEabBinding { get; set; }
[JsonProperty("directoryUrl")] public string DirectoryUrl { get; set; }
}
internal sealed class InfisicalCertificateApplicationScepEnrollmentDto
{
[JsonProperty("id")] public string Id { get; set; }
[JsonProperty("challengeType")] public string ChallengeType { get; set; }
[JsonProperty("includeCaCertInResponse")] public bool? IncludeCaCertInResponse { get; set; }
[JsonProperty("allowCertBasedRenewal")] public bool? AllowCertBasedRenewal { get; set; }
[JsonProperty("dynamicChallengeExpiryMinutes")] public int? DynamicChallengeExpiryMinutes { get; set; }
[JsonProperty("dynamicChallengeMaxPending")] public int? DynamicChallengeMaxPending { get; set; }
[JsonProperty("scepEndpointUrl")] public string ScepEndpointUrl { get; set; }
[JsonProperty("challengeEndpointUrl")] public string ChallengeEndpointUrl { get; set; }
[JsonProperty("raCertificatePem")] public string RaCertificatePem { get; set; }
[JsonProperty("raCertExpiresAt")] public string RaCertExpiresAt { get; set; }
}
}
@@ -0,0 +1,175 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using PSInfisicalAPI.Models;
namespace PSInfisicalAPI.Pki
{
internal static class InfisicalCertificateApplicationMapper
{
public static InfisicalCertificateApplication Map(InfisicalCertificateApplicationResponseDto dto, string fallbackProjectId)
{
if (dto == null) { return null; }
return new InfisicalCertificateApplication
{
Id = dto.Id,
ProjectId = !string.IsNullOrEmpty(dto.ProjectId) ? dto.ProjectId : fallbackProjectId,
Name = dto.Name,
Description = dto.Description,
ProfileCount = dto.ProfileCount,
MemberCount = dto.MemberCount,
CertificateCount = dto.CertificateCount,
CreatedAtUtc = ParseTimestamp(dto.CreatedAt),
UpdatedAtUtc = ParseTimestamp(dto.UpdatedAt)
};
}
public static InfisicalCertificateApplication[] MapMany(IEnumerable<InfisicalCertificateApplicationResponseDto> items, string fallbackProjectId)
{
if (items == null) { return Array.Empty<InfisicalCertificateApplication>(); }
List<InfisicalCertificateApplication> results = new List<InfisicalCertificateApplication>();
foreach (InfisicalCertificateApplicationResponseDto dto in items)
{
InfisicalCertificateApplication mapped = Map(dto, fallbackProjectId);
if (mapped != null) { results.Add(mapped); }
}
return results.ToArray();
}
public static InfisicalCertificateApplicationProfileAttachment MapAttachment(InfisicalCertificateApplicationProfileAttachmentDto dto)
{
if (dto == null) { return null; }
return new InfisicalCertificateApplicationProfileAttachment
{
ApplicationId = dto.ApplicationId,
ProfileId = dto.ProfileId,
ProfileSlug = dto.ProfileSlug,
ProfileDescription = dto.ProfileDescription,
ApiConfigId = dto.ApiConfigId,
EstConfigId = dto.EstConfigId,
AcmeConfigId = dto.AcmeConfigId,
ScepConfigId = dto.ScepConfigId,
CreatedAtUtc = ParseTimestamp(dto.CreatedAt),
UpdatedAtUtc = ParseTimestamp(dto.UpdatedAt)
};
}
public static InfisicalCertificateApplicationProfileAttachment[] MapAttachments(IEnumerable<InfisicalCertificateApplicationProfileAttachmentDto> items)
{
if (items == null) { return Array.Empty<InfisicalCertificateApplicationProfileAttachment>(); }
List<InfisicalCertificateApplicationProfileAttachment> results = new List<InfisicalCertificateApplicationProfileAttachment>();
foreach (InfisicalCertificateApplicationProfileAttachmentDto dto in items)
{
InfisicalCertificateApplicationProfileAttachment mapped = MapAttachment(dto);
if (mapped != null) { results.Add(mapped); }
}
return results.ToArray();
}
public static InfisicalCertificateApplicationEnrollment MapEnrollment(InfisicalCertificateApplicationEnrollmentResponseDto dto)
{
if (dto == null) { return null; }
return new InfisicalCertificateApplicationEnrollment
{
ApplicationId = dto.ApplicationId,
ProfileId = dto.ProfileId,
Api = MapApi(dto.Api),
Est = MapEst(dto.Est),
Acme = MapAcme(dto.Acme),
Scep = MapScep(dto.Scep),
EstConfigured = dto.EstConfigured.GetValueOrDefault(),
AcmeConfigured = dto.AcmeConfigured.GetValueOrDefault(),
ScepConfigured = dto.ScepConfigured.GetValueOrDefault()
};
}
private static InfisicalCertificateApplicationApiEnrollment MapApi(InfisicalCertificateApplicationApiEnrollmentDto dto)
{
if (dto == null) { return null; }
return new InfisicalCertificateApplicationApiEnrollment { Id = dto.Id, AutoRenew = dto.AutoRenew, RenewBeforeDays = dto.RenewBeforeDays };
}
private static InfisicalCertificateApplicationEstEnrollment MapEst(InfisicalCertificateApplicationEstEnrollmentDto dto)
{
if (dto == null) { return null; }
return new InfisicalCertificateApplicationEstEnrollment { Id = dto.Id, DisableBootstrapCaValidation = dto.DisableBootstrapCaValidation, EstEndpointUrl = dto.EstEndpointUrl };
}
private static InfisicalCertificateApplicationAcmeEnrollment MapAcme(InfisicalCertificateApplicationAcmeEnrollmentDto dto)
{
if (dto == null) { return null; }
return new InfisicalCertificateApplicationAcmeEnrollment { Id = dto.Id, SkipDnsOwnershipVerification = dto.SkipDnsOwnershipVerification, SkipEabBinding = dto.SkipEabBinding, DirectoryUrl = dto.DirectoryUrl };
}
private static InfisicalCertificateApplicationScepEnrollment MapScep(InfisicalCertificateApplicationScepEnrollmentDto dto)
{
if (dto == null) { return null; }
return new InfisicalCertificateApplicationScepEnrollment
{
Id = dto.Id,
ChallengeType = dto.ChallengeType,
IncludeCaCertInResponse = dto.IncludeCaCertInResponse,
AllowCertBasedRenewal = dto.AllowCertBasedRenewal,
DynamicChallengeExpiryMinutes = dto.DynamicChallengeExpiryMinutes,
DynamicChallengeMaxPending = dto.DynamicChallengeMaxPending,
ScepEndpointUrl = dto.ScepEndpointUrl,
ChallengeEndpointUrl = dto.ChallengeEndpointUrl,
RaCertificatePem = dto.RaCertificatePem,
RaCertificateThumbprint = ComputeThumbprint(dto.RaCertificatePem),
RaCertExpiresAtUtc = ParseTimestamp(dto.RaCertExpiresAt)
};
}
internal static string ComputeThumbprint(string pem)
{
if (string.IsNullOrEmpty(pem)) { return null; }
try
{
byte[] der = Convert.FromBase64String(StripPemArmor(pem));
using (X509Certificate2 cert = new X509Certificate2(der))
{
return cert.Thumbprint;
}
}
catch
{
return null;
}
}
private static string StripPemArmor(string pem)
{
StringBuilder sb = new StringBuilder(pem.Length);
using (StringReader reader = new StringReader(pem))
{
string line;
while ((line = reader.ReadLine()) != null)
{
string trimmed = line.Trim();
if (trimmed.Length == 0) { continue; }
if (trimmed.StartsWith("-----", StringComparison.Ordinal)) { continue; }
sb.Append(trimmed);
}
}
return sb.ToString();
}
private static DateTimeOffset? ParseTimestamp(string value)
{
if (string.IsNullOrEmpty(value)) { return null; }
DateTimeOffset parsed;
if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out parsed))
{
return parsed;
}
return null;
}
}
}
@@ -640,6 +640,233 @@ namespace PSInfisicalAPI.Pki
} }
} }
public InfisicalCertificateApplication[] ListCertificateApplications(InfisicalConnection connection, string projectId, int? limit, int? offset)
{
if (connection == null) { throw new ArgumentNullException(nameof(connection)); }
string resolvedProjectId = FirstNonEmpty(projectId, connection.ProjectId);
if (string.IsNullOrEmpty(resolvedProjectId)) { throw new InfisicalConfigurationException("ProjectId is required."); }
List<KeyValuePair<string, string>> query = new List<KeyValuePair<string, string>>();
if (limit.HasValue) { query.Add(new KeyValuePair<string, string>("limit", limit.Value.ToString(CultureInfo.InvariantCulture))); }
if (offset.HasValue) { query.Add(new KeyValuePair<string, string>("offset", offset.Value.ToString(CultureInfo.InvariantCulture))); }
Dictionary<string, string> headers = BuildProjectHeader(resolvedProjectId);
try
{
_logger.Information(Component, "Attempting to list Infisical certificate applications. Please Wait...");
InfisicalHttpResponse response = _invoker.Invoke(connection, InfisicalEndpointNames.ListCertificateApplications, "ListCertificateApplications", null, query, null, headers);
string body = response.Body;
response.Clear();
List<InfisicalCertificateApplicationResponseDto> source = ParseApplicationListBody(body);
InfisicalCertificateApplication[] mapped = InfisicalCertificateApplicationMapper.MapMany(source, resolvedProjectId);
_logger.Information(Component, "Infisical certificate application list retrieval was successful.");
return mapped;
}
catch (Exception)
{
_logger.Error(Component, "Infisical certificate application list retrieval failed.");
throw;
}
}
public InfisicalCertificateApplication GetCertificateApplication(InfisicalConnection connection, string applicationId, string projectId)
{
if (connection == null) { throw new ArgumentNullException(nameof(connection)); }
if (string.IsNullOrEmpty(applicationId)) { throw new InfisicalConfigurationException("ApplicationId is required."); }
Dictionary<string, string> pathParameters = new Dictionary<string, string> { { "applicationId", applicationId } };
string resolvedProjectId = FirstNonEmpty(projectId, connection.ProjectId);
Dictionary<string, string> headers = !string.IsNullOrEmpty(resolvedProjectId) ? BuildProjectHeader(resolvedProjectId) : null;
try
{
_logger.Information(Component, string.Concat("Attempting to retrieve Infisical certificate application '", applicationId, "'. Please Wait..."));
InfisicalHttpResponse response = _invoker.Invoke(connection, InfisicalEndpointNames.GetCertificateApplication, "GetCertificateApplication", pathParameters, null, null, headers);
string body = response.Body;
response.Clear();
InfisicalCertificateApplicationResponseDto inner = ParseApplicationSingleBody(body);
InfisicalCertificateApplication mapped = InfisicalCertificateApplicationMapper.Map(inner, resolvedProjectId);
_logger.Information(Component, "Infisical certificate application retrieval was successful.");
return mapped;
}
catch (Exception)
{
_logger.Error(Component, "Infisical certificate application retrieval failed.");
throw;
}
}
public InfisicalCertificateApplication GetCertificateApplicationByName(InfisicalConnection connection, string name, string projectId)
{
if (connection == null) { throw new ArgumentNullException(nameof(connection)); }
if (string.IsNullOrEmpty(name)) { throw new InfisicalConfigurationException("ApplicationName is required."); }
string resolvedProjectId = FirstNonEmpty(projectId, connection.ProjectId);
if (string.IsNullOrEmpty(resolvedProjectId)) { throw new InfisicalConfigurationException("ProjectId is required."); }
Dictionary<string, string> pathParameters = new Dictionary<string, string> { { "name", name } };
Dictionary<string, string> headers = BuildProjectHeader(resolvedProjectId);
try
{
_logger.Information(Component, string.Concat("Attempting to retrieve Infisical certificate application '", name, "' by name. Please Wait..."));
InfisicalHttpResponse response = _invoker.Invoke(connection, InfisicalEndpointNames.GetCertificateApplicationByName, "GetCertificateApplicationByName", pathParameters, null, null, headers);
string body = response.Body;
response.Clear();
InfisicalCertificateApplicationResponseDto inner = ParseApplicationSingleBody(body);
InfisicalCertificateApplication mapped = InfisicalCertificateApplicationMapper.Map(inner, resolvedProjectId);
_logger.Information(Component, "Infisical certificate application (by name) retrieval was successful.");
return mapped;
}
catch (Exception)
{
_logger.Error(Component, "Infisical certificate application (by name) retrieval failed.");
throw;
}
}
public InfisicalCertificateApplicationProfileAttachment[] ListCertificateApplicationProfiles(InfisicalConnection connection, string applicationId, string projectId)
{
if (connection == null) { throw new ArgumentNullException(nameof(connection)); }
if (string.IsNullOrEmpty(applicationId)) { throw new InfisicalConfigurationException("ApplicationId is required."); }
Dictionary<string, string> pathParameters = new Dictionary<string, string> { { "applicationId", applicationId } };
string resolvedProjectId = FirstNonEmpty(projectId, connection.ProjectId);
Dictionary<string, string> headers = !string.IsNullOrEmpty(resolvedProjectId) ? BuildProjectHeader(resolvedProjectId) : null;
try
{
_logger.Information(Component, string.Concat("Attempting to list profile attachments for Infisical certificate application '", applicationId, "'. Please Wait..."));
InfisicalHttpResponse response = _invoker.Invoke(connection, InfisicalEndpointNames.ListCertificateApplicationProfiles, "ListCertificateApplicationProfiles", pathParameters, null, null, headers);
string body = response.Body;
response.Clear();
List<InfisicalCertificateApplicationProfileAttachmentDto> source = ParseApplicationProfilesBody(body);
InfisicalCertificateApplicationProfileAttachment[] mapped = InfisicalCertificateApplicationMapper.MapAttachments(source);
_logger.Information(Component, "Infisical certificate application profile attachment listing was successful.");
return mapped;
}
catch (Exception)
{
_logger.Error(Component, "Infisical certificate application profile attachment listing failed.");
throw;
}
}
public InfisicalCertificateApplicationEnrollment GetCertificateApplicationEnrollment(InfisicalConnection connection, string applicationId, string profileId, string projectId)
{
if (connection == null) { throw new ArgumentNullException(nameof(connection)); }
if (string.IsNullOrEmpty(applicationId)) { throw new InfisicalConfigurationException("ApplicationId is required."); }
if (string.IsNullOrEmpty(profileId)) { throw new InfisicalConfigurationException("ProfileId is required."); }
Dictionary<string, string> pathParameters = new Dictionary<string, string>
{
{ "applicationId", applicationId },
{ "profileId", profileId }
};
string resolvedProjectId = FirstNonEmpty(projectId, connection.ProjectId);
Dictionary<string, string> headers = !string.IsNullOrEmpty(resolvedProjectId) ? BuildProjectHeader(resolvedProjectId) : null;
try
{
_logger.Information(Component, string.Concat("Attempting to retrieve enrollment for application '", applicationId, "' / profile '", profileId, "'. Please Wait..."));
InfisicalHttpResponse response = _invoker.Invoke(connection, InfisicalEndpointNames.GetCertificateApplicationEnrollment, "GetCertificateApplicationEnrollment", pathParameters, null, null, headers);
InfisicalCertificateApplicationEnrollmentResponseDto dto = _serializer.Deserialize<InfisicalCertificateApplicationEnrollmentResponseDto>(response.Body);
response.Clear();
InfisicalCertificateApplicationEnrollment mapped = InfisicalCertificateApplicationMapper.MapEnrollment(dto);
_logger.Information(Component, "Infisical certificate application enrollment retrieval was successful.");
return mapped;
}
catch (Exception)
{
_logger.Error(Component, "Infisical certificate application enrollment retrieval failed.");
throw;
}
}
public string GenerateScepDynamicChallenge(InfisicalConnection connection, string applicationId, string profileId)
{
if (connection == null) { throw new ArgumentNullException(nameof(connection)); }
if (string.IsNullOrEmpty(applicationId)) { throw new InfisicalConfigurationException("ApplicationId is required."); }
if (string.IsNullOrEmpty(profileId)) { throw new InfisicalConfigurationException("ProfileId is required."); }
Dictionary<string, string> pathParameters = new Dictionary<string, string>
{
{ "applicationId", applicationId },
{ "profileId", profileId }
};
Dictionary<string, string> headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "Accept", "text/plain" }
};
try
{
_logger.Information(Component, string.Concat("Attempting to generate SCEP dynamic challenge for application '", applicationId, "' / profile '", profileId, "'. Please Wait..."));
InfisicalHttpResponse response = _invoker.Invoke(connection, InfisicalEndpointNames.GenerateScepDynamicChallenge, "GenerateScepDynamicChallenge", pathParameters, null, string.Empty, headers);
string body = response.Body != null ? response.Body.Trim() : null;
response.Clear();
if (string.IsNullOrEmpty(body)) { throw new InfisicalApiException("SCEP dynamic challenge response was empty."); }
_logger.Information(Component, "Infisical SCEP dynamic challenge generation was successful.");
return body;
}
catch (Exception)
{
_logger.Error(Component, "Infisical SCEP dynamic challenge generation failed.");
throw;
}
}
private static Dictionary<string, string> BuildProjectHeader(string projectId)
{
return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "x-infisical-project-id", projectId }
};
}
private List<InfisicalCertificateApplicationResponseDto> ParseApplicationListBody(string body)
{
if (string.IsNullOrEmpty(body)) { return null; }
JToken token = JToken.Parse(body);
if (token.Type == JTokenType.Array)
{
return token.ToObject<List<InfisicalCertificateApplicationResponseDto>>();
}
InfisicalCertificateApplicationListResponseDto wrapper = token.ToObject<InfisicalCertificateApplicationListResponseDto>();
return wrapper != null ? wrapper.Applications : null;
}
private InfisicalCertificateApplicationResponseDto ParseApplicationSingleBody(string body)
{
if (string.IsNullOrEmpty(body)) { return null; }
JToken token = JToken.Parse(body);
if (token.Type != JTokenType.Object) { return null; }
JObject obj = (JObject)token;
if (obj["application"] is JObject inner) { return inner.ToObject<InfisicalCertificateApplicationResponseDto>(); }
return obj.ToObject<InfisicalCertificateApplicationResponseDto>();
}
private List<InfisicalCertificateApplicationProfileAttachmentDto> ParseApplicationProfilesBody(string body)
{
if (string.IsNullOrEmpty(body)) { return null; }
JToken token = JToken.Parse(body);
if (token.Type == JTokenType.Array)
{
return token.ToObject<List<InfisicalCertificateApplicationProfileAttachmentDto>>();
}
InfisicalCertificateApplicationProfilesResponseDto wrapper = token.ToObject<InfisicalCertificateApplicationProfilesResponseDto>();
return wrapper != null ? wrapper.Profiles : null;
}
internal static InfisicalCertificateSearchRequestDto BuildSearchRequest(InfisicalCertificateSearchQuery query) internal static InfisicalCertificateSearchRequestDto BuildSearchRequest(InfisicalCertificateSearchQuery query)
{ {
return new InfisicalCertificateSearchRequestDto return new InfisicalCertificateSearchRequestDto