Modules/Private/30-Credentials.ps1
|
function Test-RangerKeyVaultUri { param( [AllowNull()] $Value ) $Value -is [string] -and $Value.StartsWith('keyvault://') } function ConvertFrom-RangerKeyVaultUri { param( [Parameter(Mandatory = $true)] [string]$Uri ) if (-not (Test-RangerKeyVaultUri -Value $Uri)) { throw "Invalid Key Vault URI: $Uri" } $parts = $Uri.Substring(11).Split('/') if ($parts.Count -lt 2) { throw "Invalid Key Vault URI format: $Uri" } [ordered]@{ VaultName = $parts[0] SecretName = $parts[1] Version = if ($parts.Count -gt 2) { $parts[2] } else { $null } } } function Get-RangerSecretFromUri { param( [Parameter(Mandatory = $true)] [string]$Uri, [switch]$AsPlainText ) $parsed = ConvertFrom-RangerKeyVaultUri -Uri $Uri if (Test-RangerCommandAvailable -Name 'Get-AzKeyVaultSecret') { $secretParams = @{ VaultName = $parsed.VaultName Name = $parsed.SecretName ErrorAction = 'Stop' } if ($parsed.Version) { $secretParams.Version = $parsed.Version } $secret = Get-AzKeyVaultSecret @secretParams if ($AsPlainText) { return ConvertTo-RangerPlainText -Value $secret.SecretValue } return $secret.SecretValue } if (Test-RangerCommandAvailable -Name 'az') { $arguments = @('keyvault', 'secret', 'show', '--vault-name', $parsed.VaultName, '--name', $parsed.SecretName, '--query', 'value', '-o', 'tsv') if ($parsed.Version) { $arguments += @('--version', $parsed.Version) } $value = & az @arguments if ($LASTEXITCODE -ne 0) { throw "Azure CLI failed to resolve Key Vault secret '$Uri'." } if ($AsPlainText) { return $value } return (ConvertTo-SecureString -String $value -AsPlainText -Force) } throw 'Neither Az.KeyVault nor the Azure CLI is available for Key Vault secret resolution.' } function Resolve-RangerPasswordValue { param( $CredentialBlock ) if (-not $CredentialBlock) { return $null } if ($CredentialBlock.passwordSecureString -is [securestring]) { return $CredentialBlock.passwordSecureString } if ($CredentialBlock.password) { return (ConvertTo-SecureString -String ([string]$CredentialBlock.password) -AsPlainText -Force) } if ($CredentialBlock.passwordRef) { return Get-RangerSecretFromUri -Uri $CredentialBlock.passwordRef } return $null } function Resolve-RangerCredentialDefinition { param( [string]$Name, $CredentialBlock, [PSCredential]$OverrideCredential, [bool]$AllowPrompt = $true ) if ($OverrideCredential) { return $OverrideCredential } if ($CredentialBlock -is [PSCredential]) { return $CredentialBlock } if ($CredentialBlock -and $CredentialBlock.username) { $password = Resolve-RangerPasswordValue -CredentialBlock $CredentialBlock if ($password) { return [PSCredential]::new([string]$CredentialBlock.username, $password) } } if ($AllowPrompt -and $Name -ne 'azure') { try { return Get-Credential -Message "Enter the $Name credential for Azure Local Ranger" } catch { return $null } } return $null } function Resolve-RangerAzureCredentialSettings { param( [Parameter(Mandatory = $true)] [System.Collections.IDictionary]$Config, [switch]$SkipSecretResolution ) $settings = if ($Config.credentials.azure) { ConvertTo-RangerHashtable -InputObject $Config.credentials.azure } else { [ordered]@{} } if (-not $settings.method) { $settings.method = 'existing-context' } if (-not $settings.Contains('tenantId') -and -not [string]::IsNullOrWhiteSpace($Config.targets.azure.tenantId)) { $settings.tenantId = $Config.targets.azure.tenantId } if (-not $settings.Contains('subscriptionId') -and -not [string]::IsNullOrWhiteSpace($Config.targets.azure.subscriptionId)) { $settings.subscriptionId = $Config.targets.azure.subscriptionId } if (-not $settings.Contains('useAzureCliFallback')) { $settings.useAzureCliFallback = $true } if (-not $SkipSecretResolution) { if ($settings.clientSecretRef) { $settings.clientSecretSecureString = Get-RangerSecretFromUri -Uri $settings.clientSecretRef } elseif ($settings.clientSecret) { $settings.clientSecretSecureString = ConvertTo-SecureString -String ([string]$settings.clientSecret) -AsPlainText -Force } } return $settings } function Resolve-RangerCredentialMap { param( [Parameter(Mandatory = $true)] [System.Collections.IDictionary]$Config, [hashtable]$Overrides ) $allowPrompt = [bool]$Config.behavior.promptForMissingCredentials $overrides = if ($Overrides) { $Overrides } else { @{} } [ordered]@{ azure = Resolve-RangerAzureCredentialSettings -Config $Config cluster = Resolve-RangerCredentialDefinition -Name 'cluster' -CredentialBlock $Config.credentials.cluster -OverrideCredential $overrides.cluster -AllowPrompt $allowPrompt domain = Resolve-RangerCredentialDefinition -Name 'domain' -CredentialBlock $Config.credentials.domain -OverrideCredential $overrides.domain -AllowPrompt $allowPrompt bmc = Resolve-RangerCredentialDefinition -Name 'bmc' -CredentialBlock $Config.credentials.bmc -OverrideCredential $overrides.bmc -AllowPrompt $allowPrompt firewall = Resolve-RangerCredentialDefinition -Name 'firewall' -CredentialBlock $Config.credentials.firewall -OverrideCredential $overrides.firewall -AllowPrompt $allowPrompt switch = Resolve-RangerCredentialDefinition -Name 'switch' -CredentialBlock $Config.credentials.switch -OverrideCredential $overrides.switch -AllowPrompt $allowPrompt } } |