Merge pull request 'feat!(certificates): expose full /certificates/search filter surface on Get/Search-InfisicalCertificate' (#6) from dev into main
Reviewed-on: #6
This commit was merged in pull request #6.
This commit is contained in:
@@ -6,6 +6,18 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) loos
|
||||
|
||||
## Unreleased
|
||||
|
||||
## 2026.06.05.0215
|
||||
|
||||
- Build produced from commit 82f99ea7d4a4.
|
||||
|
||||
## Unreleased (carried forward)
|
||||
|
||||
## 2026.06.05.0205
|
||||
|
||||
- Build produced from commit 86968c18cb15.
|
||||
|
||||
## Unreleased (carried forward)
|
||||
|
||||
## 2026.06.05.0117
|
||||
|
||||
- Build produced from commit cffda99591c9.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@{
|
||||
RootModule = 'PSInfisicalAPI.psm1'
|
||||
ModuleVersion = '2026.06.05.0117'
|
||||
ModuleVersion = '2026.06.05.0215'
|
||||
GUID = 'b8a2f3d4-7c51-4d2f-9e6a-1f0c8b3d4e51'
|
||||
Author = 'Grace Solutions'
|
||||
CompanyName = 'Grace Solutions'
|
||||
@@ -40,7 +40,6 @@
|
||||
'Get-InfisicalCertificateProfile',
|
||||
'Get-InfisicalCertificatePolicy',
|
||||
'Get-InfisicalCertificate',
|
||||
'Search-InfisicalCertificate',
|
||||
'Request-InfisicalCertificate',
|
||||
'ConvertTo-InfisicalCertificate',
|
||||
'Install-InfisicalCertificate',
|
||||
@@ -63,7 +62,7 @@
|
||||
LicenseUri = 'https://www.gnu.org/licenses/agpl-3.0.html'
|
||||
ProjectUri = 'https://prod.git.gracesolution.info/gsadmin/PSInfisicalAPI'
|
||||
ReleaseNotes = 'See CHANGELOG.md in the project repository for release history.'
|
||||
CommitHash = 'cffda99591c9'
|
||||
CommitHash = '82f99ea7d4a4'
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -1060,7 +1060,7 @@ $GetInfisicalCertificateAuthorityResult = Get-InfisicalCertificateAuthority @Get
|
||||
<maml:alertSet>
|
||||
<maml:title>Notes</maml:title>
|
||||
<maml:alert>
|
||||
<maml:para>For advanced filtering (validity window, key algorithm, extended key usage, etc.) use Search-InfisicalCertificate instead. Single mode returns metadata only; to obtain certificate and chain PEM material use ConvertTo-InfisicalCertificate or Export-InfisicalCertificate. Accepts pipeline input by property name on -SerialNumber.</maml:para>
|
||||
<maml:para>Single mode returns metadata only; to obtain certificate and chain PEM material use ConvertTo-InfisicalCertificate or Export-InfisicalCertificate. Accepts pipeline input by property name on -SerialNumber.</maml:para>
|
||||
</maml:alert>
|
||||
</maml:alertSet>
|
||||
<command:examples>
|
||||
@@ -1219,50 +1219,6 @@ $GetInfisicalCertificatePolicyResult = Get-InfisicalCertificatePolicy @GetInfisi
|
||||
</command:examples>
|
||||
</command:command>
|
||||
|
||||
<command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
|
||||
<command:details>
|
||||
<command:name>Search-InfisicalCertificate</command:name>
|
||||
<maml:description><maml:para>Searches Infisical certificates with advanced filters and automatic paging.</maml:para></maml:description>
|
||||
<command:verb>Search</command:verb>
|
||||
<command:noun>InfisicalCertificate</command:noun>
|
||||
</command:details>
|
||||
<maml:description>
|
||||
<maml:para>Performs a server-side search across certificates with filters for friendly name, common name, free-text search, status, CA/profile/application/enrollment scope, key/signature algorithm, source, and validity window (-NotBeforeFrom/-NotBeforeTo/-NotAfterFrom/-NotAfterTo). Results are paged automatically unless -NoAutoPage is supplied. -ProjectId is required.</maml:para>
|
||||
</maml:description>
|
||||
<maml:alertSet>
|
||||
<maml:title>Notes</maml:title>
|
||||
<maml:alert>
|
||||
<maml:para>Use -SortBy together with -SortOrder ('asc'/'desc') to control result ordering. Pair with Get-InfisicalCertificate or Export-InfisicalCertificate to drill into specific hits.</maml:para>
|
||||
</maml:alert>
|
||||
</maml:alertSet>
|
||||
<command:examples>
|
||||
<command:example>
|
||||
<maml:title>EXAMPLE 1</maml:title>
|
||||
<dev:code>Search-InfisicalCertificate -Search $env:COMPUTERNAME -Status 'active'</dev:code>
|
||||
<dev:remarks><maml:para>Finds active certificates whose searchable fields contain the local hostname.</maml:para></dev:remarks>
|
||||
</command:example>
|
||||
<command:example>
|
||||
<maml:title>EXAMPLE 2</maml:title>
|
||||
<dev:code>$GetInfisicalCertificateAuthorityListResult = Get-InfisicalCertificateAuthority | Where-Object { $_.FriendlyName -eq 'Issuing CA - Platform' }
|
||||
|
||||
$SearchInfisicalCertificateParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase)
|
||||
$SearchInfisicalCertificateParameters.ProjectId = $ProjectId
|
||||
$SearchInfisicalCertificateParameters.CommonName = $env:COMPUTERNAME
|
||||
$SearchInfisicalCertificateParameters.Status = 'active'
|
||||
$SearchInfisicalCertificateParameters.CaId = @($GetInfisicalCertificateAuthorityListResult.Id)
|
||||
$SearchInfisicalCertificateParameters.KeyAlgorithm = @('RSA')
|
||||
$SearchInfisicalCertificateParameters.NotAfterTo = (Get-Date).AddDays(30)
|
||||
$SearchInfisicalCertificateParameters.SortBy = 'notAfter'
|
||||
$SearchInfisicalCertificateParameters.SortOrder = 'asc'
|
||||
$SearchInfisicalCertificateParameters.Limit = 100
|
||||
$SearchInfisicalCertificateParameters.Verbose = $True
|
||||
|
||||
$SearchInfisicalCertificateResult = Search-InfisicalCertificate @SearchInfisicalCertificateParameters</dev:code>
|
||||
<dev:remarks><maml:para>Searches for RSA certificates from a specific CA, scoped to the local hostname, that expire within the next 30 days, sorted soonest-first.</maml:para></dev:remarks>
|
||||
</command:example>
|
||||
</command:examples>
|
||||
</command:command>
|
||||
|
||||
<command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
|
||||
<command:details>
|
||||
<command:name>Request-InfisicalCertificate</command:name>
|
||||
|
||||
@@ -1060,7 +1060,7 @@ $GetInfisicalCertificateAuthorityResult = Get-InfisicalCertificateAuthority @Get
|
||||
<maml:alertSet>
|
||||
<maml:title>Notes</maml:title>
|
||||
<maml:alert>
|
||||
<maml:para>For advanced filtering (validity window, key algorithm, extended key usage, etc.) use Search-InfisicalCertificate instead. Single mode returns metadata only; to obtain certificate and chain PEM material use ConvertTo-InfisicalCertificate or Export-InfisicalCertificate. Accepts pipeline input by property name on -SerialNumber.</maml:para>
|
||||
<maml:para>Single mode returns metadata only; to obtain certificate and chain PEM material use ConvertTo-InfisicalCertificate or Export-InfisicalCertificate. Accepts pipeline input by property name on -SerialNumber.</maml:para>
|
||||
</maml:alert>
|
||||
</maml:alertSet>
|
||||
<command:examples>
|
||||
@@ -1219,50 +1219,6 @@ $GetInfisicalCertificatePolicyResult = Get-InfisicalCertificatePolicy @GetInfisi
|
||||
</command:examples>
|
||||
</command:command>
|
||||
|
||||
<command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
|
||||
<command:details>
|
||||
<command:name>Search-InfisicalCertificate</command:name>
|
||||
<maml:description><maml:para>Searches Infisical certificates with advanced filters and automatic paging.</maml:para></maml:description>
|
||||
<command:verb>Search</command:verb>
|
||||
<command:noun>InfisicalCertificate</command:noun>
|
||||
</command:details>
|
||||
<maml:description>
|
||||
<maml:para>Performs a server-side search across certificates with filters for friendly name, common name, free-text search, status, CA/profile/application/enrollment scope, key/signature algorithm, source, and validity window (-NotBeforeFrom/-NotBeforeTo/-NotAfterFrom/-NotAfterTo). Results are paged automatically unless -NoAutoPage is supplied. -ProjectId is required.</maml:para>
|
||||
</maml:description>
|
||||
<maml:alertSet>
|
||||
<maml:title>Notes</maml:title>
|
||||
<maml:alert>
|
||||
<maml:para>Use -SortBy together with -SortOrder ('asc'/'desc') to control result ordering. Pair with Get-InfisicalCertificate or Export-InfisicalCertificate to drill into specific hits.</maml:para>
|
||||
</maml:alert>
|
||||
</maml:alertSet>
|
||||
<command:examples>
|
||||
<command:example>
|
||||
<maml:title>EXAMPLE 1</maml:title>
|
||||
<dev:code>Search-InfisicalCertificate -Search $env:COMPUTERNAME -Status 'active'</dev:code>
|
||||
<dev:remarks><maml:para>Finds active certificates whose searchable fields contain the local hostname.</maml:para></dev:remarks>
|
||||
</command:example>
|
||||
<command:example>
|
||||
<maml:title>EXAMPLE 2</maml:title>
|
||||
<dev:code>$GetInfisicalCertificateAuthorityListResult = Get-InfisicalCertificateAuthority | Where-Object { $_.FriendlyName -eq 'Issuing CA - Platform' }
|
||||
|
||||
$SearchInfisicalCertificateParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase)
|
||||
$SearchInfisicalCertificateParameters.ProjectId = $ProjectId
|
||||
$SearchInfisicalCertificateParameters.CommonName = $env:COMPUTERNAME
|
||||
$SearchInfisicalCertificateParameters.Status = 'active'
|
||||
$SearchInfisicalCertificateParameters.CaId = @($GetInfisicalCertificateAuthorityListResult.Id)
|
||||
$SearchInfisicalCertificateParameters.KeyAlgorithm = @('RSA')
|
||||
$SearchInfisicalCertificateParameters.NotAfterTo = (Get-Date).AddDays(30)
|
||||
$SearchInfisicalCertificateParameters.SortBy = 'notAfter'
|
||||
$SearchInfisicalCertificateParameters.SortOrder = 'asc'
|
||||
$SearchInfisicalCertificateParameters.Limit = 100
|
||||
$SearchInfisicalCertificateParameters.Verbose = $True
|
||||
|
||||
$SearchInfisicalCertificateResult = Search-InfisicalCertificate @SearchInfisicalCertificateParameters</dev:code>
|
||||
<dev:remarks><maml:para>Searches for RSA certificates from a specific CA, scoped to the local hostname, that expire within the next 30 days, sorted soonest-first.</maml:para></dev:remarks>
|
||||
</command:example>
|
||||
</command:examples>
|
||||
</command:command>
|
||||
|
||||
<command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10">
|
||||
<command:details>
|
||||
<command:name>Request-InfisicalCertificate</command:name>
|
||||
|
||||
@@ -90,7 +90,6 @@ The module exports 37 cmdlets. Discovery cmdlets (`Get-Infisical*`) use a `List`
|
||||
| `Get-InfisicalCertificateAuthority` | Lists or retrieves Infisical internal Certificate Authorities. |
|
||||
| `Get-InfisicalPkiSubscriber` | Lists or retrieves Infisical PKI subscribers in a project. |
|
||||
| `Get-InfisicalCertificate` | Lists or retrieves Infisical certificates in a project, with optional filters and automatic paging. |
|
||||
| `Search-InfisicalCertificate` | Searches Infisical certificates with advanced filters and automatic paging. |
|
||||
| `Request-InfisicalCertificate` | Requests a new Infisical certificate (local CSR + sign) or reuses a still-valid existing one. |
|
||||
| `ConvertTo-InfisicalCertificate` | Materializes an X509Certificate2 from an Infisical certificate record, bundle, or serial number. |
|
||||
| `Install-InfisicalCertificate` | Installs an Infisical certificate (and optional chain) into a Windows certificate store. |
|
||||
|
||||
@@ -134,7 +134,6 @@ function Write-Manifest {
|
||||
'Get-InfisicalCertificateProfile',
|
||||
'Get-InfisicalCertificatePolicy',
|
||||
'Get-InfisicalCertificate',
|
||||
'Search-InfisicalCertificate',
|
||||
'Request-InfisicalCertificate',
|
||||
'ConvertTo-InfisicalCertificate',
|
||||
'Install-InfisicalCertificate',
|
||||
@@ -210,7 +209,7 @@ if (`$cmds.Count -eq 0) {
|
||||
throw "No cmdlets were exported by the PSInfisicalAPI module."
|
||||
}
|
||||
|
||||
`$expectedCmds = @('Connect-Infisical','Disconnect-Infisical','Get-InfisicalSecret','New-InfisicalSecret','Update-InfisicalSecret','Remove-InfisicalSecret','Copy-InfisicalSecret','ConvertTo-InfisicalSecretDictionary','Export-InfisicalSecrets','Get-InfisicalProject','New-InfisicalProject','Update-InfisicalProject','Remove-InfisicalProject','Get-InfisicalEnvironment','New-InfisicalEnvironment','Update-InfisicalEnvironment','Remove-InfisicalEnvironment','Get-InfisicalFolder','New-InfisicalFolder','Update-InfisicalFolder','Remove-InfisicalFolder','Get-InfisicalTag','New-InfisicalTag','Update-InfisicalTag','Remove-InfisicalTag','Get-InfisicalCertificateAuthority','Get-InfisicalPkiSubscriber','Get-InfisicalCertificateProfile','Get-InfisicalCertificatePolicy','Get-InfisicalCertificate','Search-InfisicalCertificate','Request-InfisicalCertificate','ConvertTo-InfisicalCertificate','Install-InfisicalCertificate','Uninstall-InfisicalCertificate','Export-InfisicalCertificate','Get-InfisicalCertificateApplication','Get-InfisicalCertificateApplicationEnrollment','New-InfisicalScepDynamicChallenge','Get-InfisicalScepMdmProfile','Export-InfisicalScepMdmProfile','Write-InfisicalScepMdmProfileToWmi')
|
||||
`$expectedCmds = @('Connect-Infisical','Disconnect-Infisical','Get-InfisicalSecret','New-InfisicalSecret','Update-InfisicalSecret','Remove-InfisicalSecret','Copy-InfisicalSecret','ConvertTo-InfisicalSecretDictionary','Export-InfisicalSecrets','Get-InfisicalProject','New-InfisicalProject','Update-InfisicalProject','Remove-InfisicalProject','Get-InfisicalEnvironment','New-InfisicalEnvironment','Update-InfisicalEnvironment','Remove-InfisicalEnvironment','Get-InfisicalFolder','New-InfisicalFolder','Update-InfisicalFolder','Remove-InfisicalFolder','Get-InfisicalTag','New-InfisicalTag','Update-InfisicalTag','Remove-InfisicalTag','Get-InfisicalCertificateAuthority','Get-InfisicalPkiSubscriber','Get-InfisicalCertificateProfile','Get-InfisicalCertificatePolicy','Get-InfisicalCertificate','Request-InfisicalCertificate','ConvertTo-InfisicalCertificate','Install-InfisicalCertificate','Uninstall-InfisicalCertificate','Export-InfisicalCertificate','Get-InfisicalCertificateApplication','Get-InfisicalCertificateApplicationEnrollment','New-InfisicalScepDynamicChallenge','Get-InfisicalScepMdmProfile','Export-InfisicalScepMdmProfile','Write-InfisicalScepMdmProfileToWmi')
|
||||
foreach (`$expected in `$expectedCmds) {
|
||||
if (-not (Get-Command -Name `$expected -Module PSInfisicalAPI -ErrorAction SilentlyContinue)) {
|
||||
throw "Cmdlet not found: `$expected"
|
||||
|
||||
@@ -61,11 +61,31 @@ namespace PSInfisicalAPI.Tests
|
||||
Type cmdletType = ModuleAssembly.GetType("PSInfisicalAPI.Cmdlets.GetInfisicalCertificateCmdlet", true);
|
||||
Assert.NotNull(cmdletType.GetProperty("CommonName"));
|
||||
Assert.NotNull(cmdletType.GetProperty("FriendlyName"));
|
||||
Assert.NotNull(cmdletType.GetProperty("Search"));
|
||||
Assert.NotNull(cmdletType.GetProperty("Status"));
|
||||
Assert.NotNull(cmdletType.GetProperty("CaId"));
|
||||
Assert.NotNull(cmdletType.GetProperty("ProfileId"));
|
||||
Assert.NotNull(cmdletType.GetProperty("ApplicationId"));
|
||||
Assert.NotNull(cmdletType.GetProperty("ApplicationIds"));
|
||||
Assert.NotNull(cmdletType.GetProperty("EnrollmentType"));
|
||||
Assert.NotNull(cmdletType.GetProperty("ExtendedKeyUsage"));
|
||||
Assert.NotNull(cmdletType.GetProperty("KeyAlgorithm"));
|
||||
Assert.NotNull(cmdletType.GetProperty("SignatureAlgorithm"));
|
||||
Assert.NotNull(cmdletType.GetProperty("KeySize"));
|
||||
Assert.NotNull(cmdletType.GetProperty("Source"));
|
||||
Assert.NotNull(cmdletType.GetProperty("FromDate"));
|
||||
Assert.NotNull(cmdletType.GetProperty("ToDate"));
|
||||
Assert.NotNull(cmdletType.GetProperty("NotAfterFrom"));
|
||||
Assert.NotNull(cmdletType.GetProperty("NotAfterTo"));
|
||||
Assert.NotNull(cmdletType.GetProperty("NotBeforeFrom"));
|
||||
Assert.NotNull(cmdletType.GetProperty("NotBeforeTo"));
|
||||
Assert.NotNull(cmdletType.GetProperty("Metadata"));
|
||||
Assert.NotNull(cmdletType.GetProperty("ForPkiSync"));
|
||||
Assert.NotNull(cmdletType.GetProperty("SortBy"));
|
||||
Assert.NotNull(cmdletType.GetProperty("SortOrder"));
|
||||
Assert.NotNull(cmdletType.GetProperty("Limit"));
|
||||
Assert.NotNull(cmdletType.GetProperty("Offset"));
|
||||
Assert.NotNull(cmdletType.GetProperty("NoAutoPage"));
|
||||
Assert.NotNull(cmdletType.GetProperty("List"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Management.Automation;
|
||||
using PSInfisicalAPI.Connections;
|
||||
using PSInfisicalAPI.Models;
|
||||
@@ -14,12 +16,38 @@ namespace PSInfisicalAPI.Cmdlets
|
||||
[Alias("Id", "Identifier")]
|
||||
public string SerialNumber { get; set; }
|
||||
|
||||
[Parameter(ParameterSetName = "List")] public SwitchParameter List { get; set; }
|
||||
[Parameter(ParameterSetName = "List", Mandatory = true)] public string ProjectId { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public string CommonName { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public string FriendlyName { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public string Search { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public string Status { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public string[] CaId { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public string[] ProfileId { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public string ApplicationId { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public string[] ApplicationIds { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public string[] EnrollmentType { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public string ExtendedKeyUsage { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public string[] KeyAlgorithm { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public string SignatureAlgorithm { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public int[] KeySize { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public string[] Source { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public DateTimeOffset? FromDate { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public DateTimeOffset? ToDate { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public DateTimeOffset? NotAfterFrom { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public DateTimeOffset? NotAfterTo { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public DateTimeOffset? NotBeforeFrom { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public DateTimeOffset? NotBeforeTo { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public Hashtable Metadata { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public SwitchParameter ForPkiSync { get; set; }
|
||||
|
||||
[Parameter(ParameterSetName = "List")]
|
||||
[ValidateSet("notAfter", "notBefore", "createdAt", "commonName", "keyAlgorithm", "status")]
|
||||
public string SortBy { get; set; }
|
||||
|
||||
[Parameter(ParameterSetName = "List")]
|
||||
[ValidateSet("asc", "desc")]
|
||||
public string SortOrder { get; set; }
|
||||
|
||||
[Parameter(ParameterSetName = "List")] public int? Limit { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public int? Offset { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public SwitchParameter NoAutoPage { get; set; }
|
||||
@@ -47,8 +75,28 @@ namespace PSInfisicalAPI.Cmdlets
|
||||
ProjectId = ProjectId,
|
||||
CommonName = CommonName,
|
||||
FriendlyName = FriendlyName,
|
||||
Search = Search,
|
||||
Status = Status,
|
||||
CaIds = CaId,
|
||||
ProfileIds = ProfileId,
|
||||
ApplicationId = ApplicationId,
|
||||
ApplicationIds = ApplicationIds,
|
||||
EnrollmentTypes = EnrollmentType,
|
||||
ExtendedKeyUsage = ExtendedKeyUsage,
|
||||
KeyAlgorithm = KeyAlgorithm,
|
||||
SignatureAlgorithm = SignatureAlgorithm,
|
||||
KeySizes = KeySize,
|
||||
Source = Source,
|
||||
FromDate = FromDate,
|
||||
ToDate = ToDate,
|
||||
NotAfterFrom = NotAfterFrom,
|
||||
NotAfterTo = NotAfterTo,
|
||||
NotBeforeFrom = NotBeforeFrom,
|
||||
NotBeforeTo = NotBeforeTo,
|
||||
Metadata = ToStringDictionary(Metadata),
|
||||
SortBy = SortBy,
|
||||
SortOrder = SortOrder,
|
||||
ForPkiSync = ForPkiSync.IsPresent ? (bool?)true : null,
|
||||
Limit = Limit ?? 100,
|
||||
Offset = Offset ?? 0
|
||||
};
|
||||
@@ -87,5 +135,17 @@ namespace PSInfisicalAPI.Cmdlets
|
||||
ThrowTerminatingForException("GetInfisicalCertificateCmdlet", "GetCertificate", exception);
|
||||
}
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> ToStringDictionary(Hashtable hashtable)
|
||||
{
|
||||
if (hashtable == null) { return null; }
|
||||
Dictionary<string, string> result = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (DictionaryEntry entry in hashtable)
|
||||
{
|
||||
if (entry.Key == null) { continue; }
|
||||
result[entry.Key.ToString()] = entry.Value != null ? entry.Value.ToString() : null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@ namespace PSInfisicalAPI.Cmdlets
|
||||
|
||||
[Parameter(Mandatory = true)] public string ProjectId { get; set; }
|
||||
|
||||
[Parameter(ParameterSetName = "List")] public SwitchParameter List { get; set; }
|
||||
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
|
||||
@@ -18,8 +18,6 @@ namespace PSInfisicalAPI.Cmdlets
|
||||
[Parameter(Mandatory = true)] public string Environment { get; set; }
|
||||
[Parameter] public string Path { get; set; }
|
||||
|
||||
[Parameter(ParameterSetName = "List")] public SwitchParameter List { get; set; }
|
||||
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
|
||||
@@ -14,8 +14,6 @@ namespace PSInfisicalAPI.Cmdlets
|
||||
[Alias("Id")]
|
||||
public string ProjectId { get; set; }
|
||||
|
||||
[Parameter(ParameterSetName = "List")] public SwitchParameter List { get; set; }
|
||||
|
||||
[Parameter(ParameterSetName = "List")]
|
||||
[ValidateSet("secret-manager", "cert-manager", "kms", "ssh", "secret-scanning", "pam", "ai")]
|
||||
public string Type { get; set; }
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace PSInfisicalAPI.Cmdlets
|
||||
[Parameter(ParameterSetName = "Single")] public int? Version { get; set; }
|
||||
[Parameter(ParameterSetName = "Single")] public InfisicalSecretType Type { get; set; } = InfisicalSecretType.Shared;
|
||||
|
||||
[Parameter(ParameterSetName = "List")] public SwitchParameter List { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public SwitchParameter Recursive { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public SwitchParameter IncludePersonalOverrides { get; set; }
|
||||
[Parameter(ParameterSetName = "List")] public Hashtable MetadataFilter { get; set; }
|
||||
|
||||
@@ -16,8 +16,6 @@ namespace PSInfisicalAPI.Cmdlets
|
||||
|
||||
[Parameter(Mandatory = true)] public string ProjectId { get; set; }
|
||||
|
||||
[Parameter(ParameterSetName = "List")] public SwitchParameter List { get; set; }
|
||||
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Management.Automation;
|
||||
using PSInfisicalAPI.Connections;
|
||||
using PSInfisicalAPI.Models;
|
||||
using PSInfisicalAPI.Pki;
|
||||
|
||||
namespace PSInfisicalAPI.Cmdlets
|
||||
{
|
||||
[Cmdlet(VerbsCommon.Search, "InfisicalCertificate")]
|
||||
[OutputType(typeof(InfisicalCertificate))]
|
||||
public sealed class SearchInfisicalCertificateCmdlet : InfisicalCmdletBase
|
||||
{
|
||||
[Parameter(Mandatory = true)] public string ProjectId { get; set; }
|
||||
[Parameter] public string FriendlyName { get; set; }
|
||||
[Parameter] public string CommonName { get; set; }
|
||||
[Parameter] public string Search { get; set; }
|
||||
[Parameter] public string Status { get; set; }
|
||||
[Parameter] public string[] CaId { get; set; }
|
||||
[Parameter] public string[] ProfileId { get; set; }
|
||||
[Parameter] public string[] ApplicationId { get; set; }
|
||||
[Parameter] public string[] EnrollmentType { get; set; }
|
||||
[Parameter] public string ExtendedKeyUsage { get; set; }
|
||||
[Parameter] public string[] KeyAlgorithm { get; set; }
|
||||
[Parameter] public string SignatureAlgorithm { get; set; }
|
||||
[Parameter] public string[] Source { get; set; }
|
||||
[Parameter] public DateTimeOffset? NotAfterFrom { get; set; }
|
||||
[Parameter] public DateTimeOffset? NotAfterTo { get; set; }
|
||||
[Parameter] public DateTimeOffset? NotBeforeFrom { get; set; }
|
||||
[Parameter] public DateTimeOffset? NotBeforeTo { get; set; }
|
||||
[Parameter] public string SortBy { get; set; }
|
||||
[Parameter] [ValidateSet("asc", "desc")] public string SortOrder { get; set; }
|
||||
[Parameter] public int? Limit { get; set; }
|
||||
[Parameter] public int? Offset { get; set; }
|
||||
[Parameter] public SwitchParameter NoAutoPage { get; set; }
|
||||
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
InfisicalConnection connection = InfisicalSessionManager.RequireCurrent();
|
||||
InfisicalPkiClient client = new InfisicalPkiClient(HttpClient, Logger);
|
||||
|
||||
InfisicalCertificateSearchQuery query = BuildQuery(ProjectId);
|
||||
int requestedLimit = query.Limit ?? 100;
|
||||
query.Limit = requestedLimit;
|
||||
query.Offset = query.Offset ?? 0;
|
||||
|
||||
int emitted = 0;
|
||||
while (true)
|
||||
{
|
||||
InfisicalCertificateSearchResult page = client.SearchCertificates(connection, query);
|
||||
if (page == null || page.Certificates == null || page.Certificates.Length == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (InfisicalCertificate cert in page.Certificates)
|
||||
{
|
||||
WriteObject(cert);
|
||||
emitted++;
|
||||
}
|
||||
|
||||
if (NoAutoPage.IsPresent || page.Certificates.Length < requestedLimit)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (page.TotalCount > 0 && emitted >= page.TotalCount)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
query.Offset = (query.Offset ?? 0) + page.Certificates.Length;
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
ThrowTerminatingForException("SearchInfisicalCertificateCmdlet", "SearchCertificates", exception);
|
||||
}
|
||||
}
|
||||
|
||||
private InfisicalCertificateSearchQuery BuildQuery(string projectId)
|
||||
{
|
||||
return new InfisicalCertificateSearchQuery
|
||||
{
|
||||
ProjectId = projectId,
|
||||
FriendlyName = FriendlyName,
|
||||
CommonName = CommonName,
|
||||
Search = Search,
|
||||
Status = Status,
|
||||
CaIds = CaId,
|
||||
ProfileIds = ProfileId,
|
||||
ApplicationIds = ApplicationId,
|
||||
EnrollmentTypes = EnrollmentType,
|
||||
ExtendedKeyUsage = ExtendedKeyUsage,
|
||||
KeyAlgorithm = KeyAlgorithm,
|
||||
SignatureAlgorithm = SignatureAlgorithm,
|
||||
Source = Source,
|
||||
NotAfterFrom = NotAfterFrom,
|
||||
NotAfterTo = NotAfterTo,
|
||||
NotBeforeFrom = NotBeforeFrom,
|
||||
NotBeforeTo = NotBeforeTo,
|
||||
SortBy = SortBy,
|
||||
SortOrder = SortOrder,
|
||||
Limit = Limit,
|
||||
Offset = Offset
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace PSInfisicalAPI.Models
|
||||
public string ProjectId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
public InfisicalCertificatePolicySubject Subject { get; set; }
|
||||
public InfisicalCertificatePolicySubject[] Subject { get; set; }
|
||||
public InfisicalCertificatePolicySan[] Sans { get; set; }
|
||||
public InfisicalCertificatePolicyUsages KeyUsages { get; set; }
|
||||
public InfisicalCertificatePolicyUsages ExtendedKeyUsages { get; set; }
|
||||
|
||||
@@ -70,11 +70,13 @@ namespace PSInfisicalAPI.Pki
|
||||
[JsonProperty("limit", NullValueHandling = NullValueHandling.Ignore)] public int? Limit { get; set; }
|
||||
[JsonProperty("caIds", NullValueHandling = NullValueHandling.Ignore)] public string[] CaIds { get; set; }
|
||||
[JsonProperty("profileIds", NullValueHandling = NullValueHandling.Ignore)] public string[] ProfileIds { get; set; }
|
||||
[JsonProperty("applicationId", NullValueHandling = NullValueHandling.Ignore)] public string ApplicationId { get; set; }
|
||||
[JsonProperty("applicationIds", NullValueHandling = NullValueHandling.Ignore)] public string[] ApplicationIds { get; set; }
|
||||
[JsonProperty("enrollmentTypes", NullValueHandling = NullValueHandling.Ignore)] public string[] EnrollmentTypes { get; set; }
|
||||
[JsonProperty("extendedKeyUsage", NullValueHandling = NullValueHandling.Ignore)] public string ExtendedKeyUsage { get; set; }
|
||||
[JsonProperty("keyAlgorithm", NullValueHandling = NullValueHandling.Ignore)] public string[] KeyAlgorithm { get; set; }
|
||||
[JsonProperty("signatureAlgorithm", NullValueHandling = NullValueHandling.Ignore)] public string SignatureAlgorithm { get; set; }
|
||||
[JsonProperty("keySizes", NullValueHandling = NullValueHandling.Ignore)] public int[] KeySizes { get; set; }
|
||||
[JsonProperty("source", NullValueHandling = NullValueHandling.Ignore)] public string[] Source { get; set; }
|
||||
[JsonProperty("fromDate", NullValueHandling = NullValueHandling.Ignore)] public string FromDate { get; set; }
|
||||
[JsonProperty("toDate", NullValueHandling = NullValueHandling.Ignore)] public string ToDate { get; set; }
|
||||
@@ -82,11 +84,18 @@ namespace PSInfisicalAPI.Pki
|
||||
[JsonProperty("notAfterTo", NullValueHandling = NullValueHandling.Ignore)] public string NotAfterTo { get; set; }
|
||||
[JsonProperty("notBeforeFrom", NullValueHandling = NullValueHandling.Ignore)] public string NotBeforeFrom { get; set; }
|
||||
[JsonProperty("notBeforeTo", NullValueHandling = NullValueHandling.Ignore)] public string NotBeforeTo { get; set; }
|
||||
[JsonProperty("metadata", NullValueHandling = NullValueHandling.Ignore)] public InfisicalCertificateSearchMetadataEntryDto[] Metadata { get; set; }
|
||||
[JsonProperty("sortBy", NullValueHandling = NullValueHandling.Ignore)] public string SortBy { get; set; }
|
||||
[JsonProperty("sortOrder", NullValueHandling = NullValueHandling.Ignore)] public string SortOrder { get; set; }
|
||||
[JsonProperty("forPkiSync", NullValueHandling = NullValueHandling.Ignore)] public bool? ForPkiSync { get; set; }
|
||||
}
|
||||
|
||||
internal sealed class InfisicalCertificateSearchMetadataEntryDto
|
||||
{
|
||||
[JsonProperty("key")] public string Key { get; set; }
|
||||
[JsonProperty("value", NullValueHandling = NullValueHandling.Ignore)] public string Value { get; set; }
|
||||
}
|
||||
|
||||
internal sealed class InfisicalCertificateBundleResponseDto
|
||||
{
|
||||
[JsonProperty("serialNumber")] public string SerialNumber { get; set; }
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace PSInfisicalAPI.Pki
|
||||
[JsonProperty("projectId")] public string ProjectId { get; set; }
|
||||
[JsonProperty("name")] public string Name { get; set; }
|
||||
[JsonProperty("description")] public string Description { get; set; }
|
||||
[JsonProperty("subject")] public InfisicalCertificatePolicySubjectDto Subject { get; set; }
|
||||
[JsonProperty("subject")] public JToken SubjectRaw { get; set; }
|
||||
[JsonProperty("sans")] public JToken SansRaw { get; set; }
|
||||
[JsonProperty("keyUsages")] public InfisicalCertificatePolicyUsagesDto KeyUsages { get; set; }
|
||||
[JsonProperty("extendedKeyUsages")] public InfisicalCertificatePolicyUsagesDto ExtendedKeyUsages { get; set; }
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace PSInfisicalAPI.Pki
|
||||
ProjectId = !string.IsNullOrEmpty(dto.ProjectId) ? dto.ProjectId : fallbackProjectId,
|
||||
Name = dto.Name,
|
||||
Description = dto.Description,
|
||||
Subject = MapSubject(dto.Subject),
|
||||
Subject = MapSubjects(dto.SubjectRaw),
|
||||
Sans = MapSans(dto.SansRaw),
|
||||
KeyUsages = MapUsages(dto.KeyUsages),
|
||||
ExtendedKeyUsages = MapUsages(dto.ExtendedKeyUsages),
|
||||
@@ -52,8 +52,32 @@ namespace PSInfisicalAPI.Pki
|
||||
return results.ToArray();
|
||||
}
|
||||
|
||||
private static InfisicalCertificatePolicySubject MapSubject(InfisicalCertificatePolicySubjectDto dto)
|
||||
private static InfisicalCertificatePolicySubject[] MapSubjects(JToken token)
|
||||
{
|
||||
if (token == null || token.Type == JTokenType.Null) { return null; }
|
||||
|
||||
List<InfisicalCertificatePolicySubject> results = new List<InfisicalCertificatePolicySubject>();
|
||||
if (token.Type == JTokenType.Array)
|
||||
{
|
||||
foreach (JToken child in (JArray)token)
|
||||
{
|
||||
InfisicalCertificatePolicySubject mapped = MapSubjectObject(child);
|
||||
if (mapped != null) { results.Add(mapped); }
|
||||
}
|
||||
}
|
||||
else if (token.Type == JTokenType.Object)
|
||||
{
|
||||
InfisicalCertificatePolicySubject mapped = MapSubjectObject(token);
|
||||
if (mapped != null) { results.Add(mapped); }
|
||||
}
|
||||
|
||||
return results.Count > 0 ? results.ToArray() : null;
|
||||
}
|
||||
|
||||
private static InfisicalCertificatePolicySubject MapSubjectObject(JToken token)
|
||||
{
|
||||
if (token == null || token.Type != JTokenType.Object) { return null; }
|
||||
InfisicalCertificatePolicySubjectDto dto = token.ToObject<InfisicalCertificatePolicySubjectDto>();
|
||||
if (dto == null) { return null; }
|
||||
return new InfisicalCertificatePolicySubject
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PSInfisicalAPI.Pki
|
||||
{
|
||||
@@ -13,11 +14,13 @@ namespace PSInfisicalAPI.Pki
|
||||
public int? Limit { get; set; }
|
||||
public string[] CaIds { get; set; }
|
||||
public string[] ProfileIds { get; set; }
|
||||
public string ApplicationId { get; set; }
|
||||
public string[] ApplicationIds { get; set; }
|
||||
public string[] EnrollmentTypes { get; set; }
|
||||
public string ExtendedKeyUsage { get; set; }
|
||||
public string[] KeyAlgorithm { get; set; }
|
||||
public string SignatureAlgorithm { get; set; }
|
||||
public int[] KeySizes { get; set; }
|
||||
public string[] Source { get; set; }
|
||||
public DateTimeOffset? FromDate { get; set; }
|
||||
public DateTimeOffset? ToDate { get; set; }
|
||||
@@ -25,6 +28,7 @@ namespace PSInfisicalAPI.Pki
|
||||
public DateTimeOffset? NotAfterTo { get; set; }
|
||||
public DateTimeOffset? NotBeforeFrom { get; set; }
|
||||
public DateTimeOffset? NotBeforeTo { get; set; }
|
||||
public IDictionary<string, string> Metadata { get; set; }
|
||||
public string SortBy { get; set; }
|
||||
public string SortOrder { get; set; }
|
||||
public bool? ForPkiSync { get; set; }
|
||||
|
||||
@@ -863,11 +863,13 @@ namespace PSInfisicalAPI.Pki
|
||||
Limit = query.Limit,
|
||||
CaIds = query.CaIds,
|
||||
ProfileIds = query.ProfileIds,
|
||||
ApplicationId = query.ApplicationId,
|
||||
ApplicationIds = query.ApplicationIds,
|
||||
EnrollmentTypes = query.EnrollmentTypes,
|
||||
ExtendedKeyUsage = query.ExtendedKeyUsage,
|
||||
KeyAlgorithm = query.KeyAlgorithm,
|
||||
SignatureAlgorithm = query.SignatureAlgorithm,
|
||||
KeySizes = query.KeySizes,
|
||||
Source = query.Source,
|
||||
FromDate = FormatTimestamp(query.FromDate),
|
||||
ToDate = FormatTimestamp(query.ToDate),
|
||||
@@ -875,12 +877,25 @@ namespace PSInfisicalAPI.Pki
|
||||
NotAfterTo = FormatTimestamp(query.NotAfterTo),
|
||||
NotBeforeFrom = FormatTimestamp(query.NotBeforeFrom),
|
||||
NotBeforeTo = FormatTimestamp(query.NotBeforeTo),
|
||||
Metadata = BuildMetadataEntries(query.Metadata),
|
||||
SortBy = query.SortBy,
|
||||
SortOrder = query.SortOrder,
|
||||
ForPkiSync = query.ForPkiSync
|
||||
};
|
||||
}
|
||||
|
||||
private static InfisicalCertificateSearchMetadataEntryDto[] BuildMetadataEntries(IDictionary<string, string> source)
|
||||
{
|
||||
if (source == null || source.Count == 0) { return null; }
|
||||
List<InfisicalCertificateSearchMetadataEntryDto> entries = new List<InfisicalCertificateSearchMetadataEntryDto>(source.Count);
|
||||
foreach (KeyValuePair<string, string> pair in source)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pair.Key)) { continue; }
|
||||
entries.Add(new InfisicalCertificateSearchMetadataEntryDto { Key = pair.Key, Value = pair.Value });
|
||||
}
|
||||
return entries.Count == 0 ? null : entries.ToArray();
|
||||
}
|
||||
|
||||
private static string FormatTimestamp(DateTimeOffset? value)
|
||||
{
|
||||
if (!value.HasValue) { return null; }
|
||||
|
||||
Reference in New Issue
Block a user