ps/Modules/Alkami.DevOps.Common/Public/Get-AwsCredentialConfiguration.ps1
2023-05-30 22:51:22 -07:00

144 lines
5.0 KiB
PowerShell

function Get-AwsCredentialConfiguration {
<#
.SYNOPSIS
Used to read/parse the AWS credentials file entries to a queryable object array
.DESCRIPTION
Used to read/parse the AWS credentials file entries to a queryable object array. Runs parsed values through ConvertTo-AwsCredentialEntry
.EXAMPLE
Get-AwsCredentialConfiguration
Name : GrandPooBah
role_arn : arn:aws:iam::123430414321:role/CLI-God-Mode-On
mfa_serial : arn:aws:iam::123410044321:mfa/poobah-cli
region : canada-west-99
source_profile : default
Name : Gibberish
role_arn : arn:aws:iam::123495924321:role/CLI-NoGood-DoNothing
mfa_serial : arn:aws:iam::123410044321:mfa/gwhiting-cli
region : mexico-north-1
source_profile : default
.LINK
ConvertTo-AwsCredentialEntry
#>
[CmdletBinding()]
[OutputType([object[]])]
param()
$logLead = Get-LogLeadName
$userProfileDirectory = Get-EnvironmentVariable -StoreName Process -Name USERPROFILE
$configurationSources = @()
$configurationSources += Join-Path -Path $userProfileDirectory -ChildPath ".aws/config"
$configurationSources += Join-Path -Path $userProfileDirectory -ChildPath ".aws/credentials"
# ToDo - Add the AWS SDK Credentials Source
[System.Collections.ArrayList]$objects = @()
$awsProfile = @{}
$lines = @()
$propertiesToIgnore = @("aws_secret_access_key", "aws_session_token")
foreach ($source in $configurationSources) {
if (-NOT (Test-Path -Path $source)) {
Write-Verbose "$logLead : Credential file does not exist at [$source]"
continue
}
$fileContent = Get-Content -Path $source
if (Test-IsCollectionNullOrEmpty -Collection $fileContent) {
Write-Verbose "$logLead : Credential file at [$source] exists but is empty. Skipping."
continue
}
$lines += $fileContent
$lines += "EOF"
}
if (Test-IsCollectionNullOrEmpty -Collection $lines) {
Write-Warning "$logLead : Unable to locate any configured AWS credentials sources. Have you set up your local profiles?"
return
}
foreach ($line in $lines) {
if ($line.StartsWith('#') -or (Test-StringIsNullOrWhitespace -Value $line)) {
# This is a comment or empty line, ignore it
continue
} elseif ($line -eq "EOF" -and (-NOT (Test-StringIsNullOrWhitespace -Value $awsProfile.Name))) {
# Save the final profile or in between file swaps
$objects += $awsProfile
} elseif ($line.StartsWith('[')) {
# This is a new profile, push any old profile into the objects array and start fresh
if ($null -ne $awsProfile.Name -and ($null -eq ($objects | Where-Object { $_.Name -eq $awsProfile.Name }))) {
# $awsProfile object is populated, save it
$objects += $awsProfile
}
$sanitizedProfileName = $line -replace "\[|\]|(profile\s+)", ""
Write-Verbose "$logLead : Looking for existing parsed profiles named [$sanitizedProfileName]"
$existingProfile = $objects | Where-Object { $_.Name -eq $sanitizedProfileName }
if ($null -ne $existingProfile) {
# Load the existing profile to attach properties, where unique
Write-Verbose "$logLead : Duplicate profile name [$sanitizedProfileName] found. First-in properties win in this scenario."
$awsProfile = $existingProfile
$objects.Remove($existingProfile)
} else {
# This is a new profile
$awsProfile = New-Object PSObject -Property @{ Name = $sanitizedProfileName }
}
} else {
if ($null -eq $awsProfile.Name) {
# We skip this step unless we're anchored to a profile
# to avoid picking up trash or duplicate properties
continue
}
# The only things left are valid properties to attach to an object
# Unless we're specifically ignoring them
$splits = $line -split '='
$propertyName = $splits[0].Trim()
if ($propertiesToIgnore -contains $propertyName) {
# This is a sensitive property that will never be recorded
Write-Verbose "$logLead : Skipping excluded property [$propertyName] for profile [$($awsProfile.Name)]"
continue
} elseif ($null -ne $awsProfile.$propertyName) {
# This property has been recorded already. It is a duplicate, and first read wins
Write-Verbose ("$logLead : Skipping duplicate property [$propertyName] for profile [$($awsProfile.Name)] - existing value: [$($awsProfile.$propertyName)]")
continue
}
$propertyValue = $splits[1].Trim()
Add-Member -InputObject $awsProfile -NotePropertyName $propertyName -NotePropertyValue $propertyValue -Force
}
}
return ($objects | ConvertTo-AwsCredentialEntry | Sort-Object -Property Name)
}