Skip to content

Instantly share code, notes, and snippets.

@gregory-seidman
Last active November 5, 2021 20:49
Show Gist options
  • Save gregory-seidman/2500694414781b37ebe21f41e3835287 to your computer and use it in GitHub Desktop.
Save gregory-seidman/2500694414781b37ebe21f41e3835287 to your computer and use it in GitHub Desktop.
Turn AWS ServiceManager configuration into nested JSON
#!/usr/bin/env powershell
param (
[ValidateScript({
if ($_ -eq $null) {
return $true
}
if (-Not ($_ | Test-Path -PathType Leaf) ) {
throw "Input file is a directory or does not exist"
}
return $true
})]
[Parameter(Position=0,Mandatory,ParameterSetName="FileInput")]
[string]$InputFile = $null,
[Parameter(ValueFromPipeline,ParameterSetName="PipeInput")]
[string[]]$InputJson,
[Parameter(Mandatory,ParameterSetName="AwsInput")]
[string]$AwsPath = $null,
[ValidateScript({
if ($_ -eq $null) {
return $true
}
if ($_ | Test-Path -PathType Container) {
throw "Cannot write to a directory"
}
if (-Not ($_.Directory | Test-Path -PathType Container) ) {
throw "The output file's directory must exist"
}
return $true
})]
[string]$OutputFile = $null,
[Parameter(ParameterSetName="FileInput")]
[Parameter(ParameterSetName="PipeInput")]
[string]$KeyPrefix = "/"
)
Switch ($PSCmdlet.ParameterSetName) {
"FileInput" {
$InputJson = (Get-Content $InputFile)
}
"PipeInput" {
if ($null -eq $InputJson -Or 0 -eq $InputJson.Length) {
throw "No JSON input provided"
}
}
"AwsInput" {
$KeyPrefix = $AwsPath
$InputJson = (aws "--no-cli-auto-prompt" "ssm" "get-parameters-by-path" "--recursive" "--no-cli-pager" "--path" $AwsPath)
}
}
$json = [string]::Join([System.Environment]::NewLine, $InputJson) |`
ConvertFrom-Json
if ($null -eq $json -Or `
$null -eq $json.Parameters -Or `
-Not [System.Array] -eq $json.Parameters.GetType().BaseType) {
throw "Missing or invalid JSON input"
}
if (-Not $KeyPrefix.StartsWith("/")) {
$KeyPrefix = "/$KeyPrefix"
}
if (-Not $KeyPrefix.EndsWith("/")) {
$KeyPrefix = "$KeyPrefix/"
}
$output = @{}
$longest = 0
foreach ($kv in $json.Parameters) {
$key = $kv.Name
$value = $kv.Value
if ($key.StartsWith($KeyPrefix)) {
$key = $key.Substring($KeyPrefix.Length)
}
Write-Debug "$key = $value"
[System.Collections.Generic.Queue[string]]$keyPath = `
$key.Split("/", [System.StringSplitOptions]::RemoveEmptyEntries)
if ($keyPath.Count -gt $longest) {
$longest = $keyPath.Count
}
$parentDict = $output
while ($keyPath.Count -gt 1) {
$segment = $keyPath.Dequeue()
if (-Not $parentDict.ContainsKey($segment)) {
$parentDict[$segment] = @{}
}
$parentDict = $parentDict[$segment]
}
$parentDict[$keyPath.Dequeue()] = $value
}
if (-Not $null -eq $OutputFile) {
ConvertTo-Json $output -Depth $longest | Set-Content $OutputFile
} else {
ConvertTo-Json $output -Depth $longest
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment