From 1a39e9df3a9d064fc5875e67aa92a566d90b7201 Mon Sep 17 00:00:00 2001 From: djpbessems Date: Wed, 10 Mar 2021 11:32:53 +0100 Subject: [PATCH] Merge key/value pairs in vault secret --- README.md | 5 ++ .../ADDS/payload/Provision-VaultPassword.ps1 | 72 ++++++++++++++++--- scripts/ADDS/payload/scripts/03.Users.yml | 2 +- 3 files changed, 67 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 86ba128..57f6772 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,11 @@ When **provisioning** the appliance through the vCenter 'Deploy OVF template...' "addsconfig.safemodepw" = var.adds_safemodepassword # "addsconfig.ntpserver" = "0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org" + "vault.api" = "https://vault.example.org/v1" + "vault.token" = "s.R2E1anlOcTZrTmZSTVZRazJM" + "vault.pwpolicy" = "complex" + "vault.secret" = "contoso-project42" + # "dhcpconfig.startip" = "10.0.0.50" # "dhcpconfig.endip" = "10.0.0.250" # "dhcpconfig.subnetmask" = "255.255.255.0" diff --git a/scripts/ADDS/payload/Provision-VaultPassword.ps1 b/scripts/ADDS/payload/Provision-VaultPassword.ps1 index 5f4f4c0..046f56d 100644 --- a/scripts/ADDS/payload/Provision-VaultPassword.ps1 +++ b/scripts/ADDS/payload/Provision-VaultPassword.ps1 @@ -7,27 +7,77 @@ Param( [Parameter()] [string]$VaultPwPolicy, [Parameter(Mandatory)] - [string]$Container, + [string]$VaulSecret, [Parameter(Mandatory)] [string]$Username ) +# Generate new password $InvokeWebRequestSplat = @{ Uri = "$($VaultAPIAddress)/sys/policies/password/$($VaultPasswordPolicy)/generate" Headers = @{'X-Vault-Token'="$VaultToken"} } $NewPassword = (Invoke-WebRequest @InvokeWebRequestSplat | ConvertFrom-Json).data.password -$InvokeWebRequestSplat = @{ - Uri = "$($VaultAPIAddress)/secret/data/$($Container)" - Method = 'POST' - Headers = @{'X-Vault-Token'="$VaultToken"} - Body = @{ - data = @{ - "password.$($Username)" = $NewPassword - } - } | ConvertTo-Json +# Check for existense of secret +$Response, $ErrResponse = $Null, $Null +Try { + $InvokeWebRequestSplat = @{ + Uri = "$(VaultAPIAddress)/secret/metadata/$($VaultSecret)" + Headers = @{'X-Vault-Token' = "$VaultToken"} + UseBasicParsing = $True + } + $Response = Invoke-WebRequest @InvokeWebRequestSplat +} +Catch { + $StreamReader = [System.IO.StreamReader]::new($_.Exception.Response.GetResponseStream()) + $StreamReader.BaseStream.Position = 0 + $ErrResponse = $StreamReader.ReadToEnd() + $StreamReader.Close() +} + +If ([boolean]$Response) { + # Secret already exists; retrieve existing key/value pairs + $InvokeWebRequestSplat = @{ + Uri = "$(VaultAPIAddress)/secret/data/$($VaultSecret)" + Headers = @{'X-Vault-Token' = "$VaultToken"} + UseBasicParsing = $True + } + $Secret = (Invoke-WebRequest @InvokeWebRequestSplat | ConvertFrom-Json).data + + # Merge new password into dictionary + $AddMemberSplat = @{ + MemberType = 'NoteProperty' + Name = "password.$($Username)" + Value = $NewPassword + Force = $True + } + $Secret.data | Add-Member @AddMemberSplat + + # Store as new version + $InvokeWebRequestSplat = @{ + Uri = "$($VaultAPIAddress)/secret/data/$($VaulSecret)" + Method = 'POST' + Headers = @{'X-Vault-Token'="$VaultToken"} + Body = @{ + data = $Secret.data + } | ConvertTo-Json + } + Invoke-WebRequest @InvokeWebRequestSplat +} +ElseIf ([boolean]$ErrResponse) { + # Secret did not exist yet, store as new secret + $InvokeWebRequestSplat = @{ + Uri = "$($VaultAPIAddress)/secret/data/$($VaulSecret)" + Method = 'POST' + Headers = @{'X-Vault-Token'="$VaultToken"} + Body = @{ + data = @{ + "password.$($Username)" = $NewPassword + } + } | ConvertTo-Json + } + Invoke-WebRequest @InvokeWebRequestSplat } -Invoke-WebRequest @InvokeWebRequestSplat Return $NewPassword \ No newline at end of file diff --git a/scripts/ADDS/payload/scripts/03.Users.yml b/scripts/ADDS/payload/scripts/03.Users.yml index d276bbb..0082ebf 100644 --- a/scripts/ADDS/payload/scripts/03.Users.yml +++ b/scripts/ADDS/payload/scripts/03.Users.yml @@ -17,4 +17,4 @@ Users: Variables: - Name: password.janedoe Expression: | - & "$($PSScriptRoot)\..\Provision-VaultPassword.ps1" -Container $Parameter['vault.secret'] -Username 'janedoe' -VaultAPIAddress $Parameter['vault.api'] -VaultToken $Parameter['vault.token'] -VaultPwPolicy $Parameter['vault.pwpolicy'] + & "$($PSScriptRoot)\..\Provision-VaultPassword.ps1" -VaulSecret $Parameter['vault.secret'] -Username 'janedoe' -VaultAPIAddress $Parameter['vault.api'] -VaultToken $Parameter['vault.token'] -VaultPwPolicy $Parameter['vault.pwpolicy']