ps/Modules/Alkami.DevOps.Certificates/Public/Publish-PodToSecretServer.ps1

148 lines
6.0 KiB
PowerShell
Raw Permalink Normal View History

2023-05-30 22:51:22 -07:00
function Publish-PodToSecretServer {
<#
.SYNOPSIS
Publish Pod's Certificates to Secret Server.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string[]]$ADGroups,
[Parameter(Mandatory = $false)]
[PSObject]$Pod,
[Parameter (Mandatory = $false)]
[string]$PodName,
[Parameter(Mandatory = $false)]
[string]$SecretServerUserName,
[Parameter(Mandatory = $false)]
[string]$SecretServerPassword,
[Parameter(Mandatory = $false)]
[string]$SecretServerUrl ="https://alkami.secretservercloud.com",
[Parameter(Mandatory = $false)]
[string]$TempFolder = "C:\Temp",
[Parameter(Mandatory = $false)]
[ValidateSet("Production", "Staging")]
[string]$EnvironmentType,
[Parameter(Mandatory = $false)]
[string]$SubFolder
)
begin {
Import-AWSModule # SSM
switch ($EnvironmentType) {
"Production" {$RootFolderName = "Production-CertApi"}
"Staging" {$RootFolderName = "Staging-CertApi"}
}
# Get all parmeters which weren't supplied.
if(!$EnvironmentType)
{
$EnvironmentType = Get-AppSetting Environment.Type
}
if(!$PodName)
{
$PodName = Get-AppSetting Environment.Name
}
if(!$SubFolder)
{
$SubFolder = Get-AppSetting Environment.Server
}
if((!$SecretServerUserName -or !$SecretServerPassword))
{
if(Test-IsAws)
{
if(!$SecretServerUserName) {
$SecretServerUserName = (Get-SSMParameter -Name "secret_server_api_username" -WithDecryption $true).Value
}
if(!$SecretServerPassword) {
$SecretServerPassword = (Get-SSMParameter -Name "secret_server_api_password" -WithDecryption $true).Value
}
}
else {
Write-Error "Secret credentials must be manually provided if this is run on a non-AWS machine. They cannot be retrieved from SSM."
}
}
if (!$Pod) {
$PodName = "$PodName-CertApi" # Tack on something to make the folder name distinct from manually created folders.
$Pod = Export-CertificatesToFileSystem -PodName $PodName -ADGroups $ADGroups
}
$secretServer = [SecretServerConnection]::new($SecretServerUrl, $SecretServerUserName, $SecretServerPassword)
$UseTwoFactor = $false
$secretServer.Authenticate($UseTwoFactor)
Add-Type -Assembly System.IO.Compression.FileSystem
}
process {
#Zip certficates and their chain
$certificatesFromAllStores = $Pod.Stores.Values.Certificates.Values
Compress-Certificates $certificatesFromAllStores $TempFolder
#Create folder for this pod
$rootFolderId = $SecretServer.GetFolderIdByName($RootFolderName)
$podFolderId = $secretServer.GetFolderIdByName($Pod.PodName, $rootFolderId)
if (!$podFolderId) {
$podFolderId = $secretServer.AddFolder($rootFolderId, $Pod.PodName)
}
$subFolderId = $secretServer.GetFolderIdByName($Subfolder, $podFolderId)
if (!$subFolderId) {
$subFolderId = $secretServer.AddFolder($podFolderId, $Subfolder)
}
foreach ($store in $Pod.Stores.Keys) {
$storeFolderId = $secretServer.GetFolderIdByName($store, $subFolderId)
if (!$storeFolderId) {
$storeFolderId = $secretServer.AddFolder($subFolderId, $store)
}
$certificates = $Pod.Stores.$store.Certificates.Values
foreach ($certificate in $certificates) {
try {
#Process
#Get a new secret template
$templateId = $secretServer.GetSecretTemplateIdByName("CertificateStore")
$secret = $SecretServer.GetSecretTemplateById($templateId, $storeFolderId)
# Configure the secret
# Each of these two line blocks creates a *reference* to a specific item in the secret.items list. That reference is then set to the correct
# certificate field value, which updates the $secret.items[x].itemValue value. Clear as mud?
$certName = $secret.items | Where-Object {$_.fieldName -eq "Certificate Name"}
$certName.itemValue = $certificate.Name
$certPassword = $secret.items | Where-Object {$_.fieldName -eq "Import Password"}
$certPassword.itemValue = $certificate.Password
$certNotes = $secret.items | Where-Object {$_.fieldName -eq "Notes"}
$certNotes.itemValue = "ADGroups with access to this certificate: $($certificate.ADGroups)"
$certThumbprint = $secret.items | Where-Object {$_.fieldName -eq "Thumbprint"}
$certThumbprint.itemValue = $certificate.Thumbprint
$certExpirationDate = $secret.items | Where-Object {$_.fieldName -eq "ExperationDate"} # Yes, Expiration is mispelled, because Thycotic.
$certExpirationDate.itemValue = $certificate.ExpirationDate.ToShortDateString()
$secretName = $certificate.Name, $certificate.thumbprint, $store.ToString()[0] -join "-"
$secretId = $secretServer.CreateSecret($secret, $storeFolderId, $secretName)
#Upload certificate zip folder
Write-Output "Publishing certificate $($certificate.Name)"
$zipFilePath = $certificate.Folder, ($certificate.Name.Trim() + ".zip") -join "\"
$secretServer.UploadFile($secretId, "pfx-File", $zipFilePath)
}
catch [InvalidOperationException] {
Write-Warning "There was a problem publishing a certificate."
Write-Warning $_
}
}
}
}
}