Skip to content

Commit

Permalink
move to al-go-helper
Browse files Browse the repository at this point in the history
  • Loading branch information
freddydk committed Jun 4, 2024
1 parent a5cd65e commit 877688b
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 124 deletions.
75 changes: 74 additions & 1 deletion Actions/AL-Go-Helper.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2360,4 +2360,77 @@ function Get-PackageVersion($PackageName) {
else {
throw "Package $PackageName is not in the list of packages"
}
}
}

function InstallAzModuleIfNeeded {
Param(
[string] $moduleName
)

if (Get-Module -Name $moduleName) {
# Already installed
return
}
if ($isWindows) {
# GitHub hosted Windows Runners have AZ PowerShell module saved in C:\Modules\az_*
# Remove AzureRm modules from PSModulePath and add AZ modules
if (Test-Path 'C:\Modules\az_*') {
$azModulesPath = Get-ChildItem 'C:\Modules\az_*' | Where-Object { $_.PSIsContainer }
if ($azModulesPath) {
Write-Host "Adding AZ module path: $($azModulesPath.FullName)"
$ENV:PSModulePath = "$($azModulesPath.FullName);$(("$ENV:PSModulePath".Split(';') | Where-Object { $_ -notlike 'C:\\Modules\Azure*' }) -join ';')"
}
}
}
else {
# Linux runners have AZ PowerShell module saved in /usr/share/powershell/Modules/Az.*
}
$azModule = Get-Module -name $moduleName -ListAvailable | Select-Object -First 1
if ($azModule) {
Write-Host "$moduleName Module is available in version $($azModule.Version)"
Write-Host "Using $moduleName version $($azModule.Version)"
}
else {
$AzModule = Get-InstalledModule -Name $moduleName -ErrorAction SilentlyContinue
if ($AzModule) {
Write-Host "$moduleName version $($AzModule.Version) is installed"
}
else {
Write-Host "Installing and importing $moduleName"
Install-Module $moduleName -Force
}
}
Import-Module $moduleName -DisableNameChecking -WarningAction SilentlyContinue | Out-Null
}

function ConnectAz {
param(
[PsCustomObject] $azureCredentials
)
try {
Clear-AzContext -Scope Process
Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue
if ($azureCredentials.PSObject.Properties.Name -eq 'ClientSecret') {
$credential = New-Object PSCredential -argumentList $azureCredentials.ClientId, $azureCredentials.ClientSecret
Connect-AzAccount -ServicePrincipal -Tenant $azureCredentials.TenantId -Credential $credential -WarningAction SilentlyContinue | Out-Null
}
else {
try {
Write-Host "Query ID_TOKEN from $ENV:ACTIONS_ID_TOKEN_REQUEST_URL"
$result = Invoke-RestMethod -Method GET -UseBasicParsing -Headers @{ "Authorization" = "bearer $ENV:ACTIONS_ID_TOKEN_REQUEST_TOKEN"; "Accept" = "application/vnd.github+json" } -Uri "$ENV:ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange"
}
catch {
throw "Unable to get ID_TOKEN, maybe id_token: write permissions are missing. Error was $($_.Exception.Message)"
}
Connect-AzAccount -ApplicationId $azureCredentials.ClientId -Tenant $azureCredentials.TenantId -FederatedToken $result.value -WarningAction SilentlyContinue | Out-Null
}
if ($azureCredentials.PSObject.Properties.Name -eq 'SubScriptionId') {
Set-AzContext -SubscriptionId $azureCredentials.SubscriptionId -Tenant $azureCredentials.TenantId -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Out-Null
}
$script:keyvaultConnectionExists = $true
Write-Host "Successfully connected to Azure Key Vault."
}
catch {
throw "Error trying to authenticate to Azure using Az. Error was $($_.Exception.Message)"
}
}
108 changes: 62 additions & 46 deletions Actions/Deliver/Deliver.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,62 @@
[bool] $goLive
)

$telemetryScope = $null

function EnsureAzStorageModule() {
if (get-command New-AzStorageContext -ErrorAction SilentlyContinue) {
Write-Host "Using Az.Storage PowerShell module"
function ConnectAzStorageAccount {
Param(
[PSCustomObject] $storageAccountCredentials
)

$azStorageContext = $null
$message = ''
if ($storageAccountCredentials.PSObject.Properties.Name -eq 'sastoken') {
try {
$azStorageContext = New-AzStorageContext -StorageAccountName $storageAccountCredentials.StorageAccountName -SasToken $storageAccountCredentials.sastoken
}
catch {
$message = "Unable to create AzStorageContext based on StorageAccountName and sastoken.`nError was: $($_.Exception.Message)"
}
}
else {
$azureStorageModule = Get-Module -name 'Azure.Storage' -ListAvailable | Select-Object -First 1
if ($azureStorageModule) {
Write-Host "Azure.Storage Module is available in version $($azureStorageModule.Version)"
Write-Host "Using Azure.Storage version $($azureStorageModule.Version)"
Import-Module 'Azure.Storage' -DisableNameChecking -WarningAction SilentlyContinue | Out-Null
Set-Alias -Name New-AzStorageContext -Value New-AzureStorageContext -Scope Script
Set-Alias -Name Get-AzStorageContainer -Value Get-AzureStorageContainer -Scope Script
Set-Alias -Name New-AzStorageContainer -Value New-AzureStorageContainer -Scope Script
Set-Alias -Name Set-AzStorageBlobContent -Value Set-AzureStorageBlobContent -Scope Script
elseif ($storageAccountCredentials.PSObject.Properties.Name -eq 'StorageAccountKey') {
try {
$azStorageContext = New-AzStorageContext -StorageAccountName $storageAccountCredentials.StorageAccountName -StorageAccountKey $storageAccountCredentials.StorageAccountKey
}
else {
Write-Host "Installing and importing Az.Storage."
Install-Module 'Az.Storage' -Force
Import-Module 'Az.Storage' -DisableNameChecking -WarningAction SilentlyContinue | Out-Null
catch {
$message = "Unable to create AzStorageContext based on StorageAccountName and StorageAccountKey.`nError was: $($_.Exception.Message)"
}
}
elseif ($storageAccountCredentials.Keys -contains 'ClientID' -and $storageAccountCredentials.Keys -contains 'TenantID' -and $storageAccountCredentials.Keys -contains 'SubscriptionId') {
try {
InstallAzModuleIfNeeded -moduleName 'Az.Accounts'
ConnectAz -azureCredentials $storageAccountCredentials
$azStorageContext = New-AzStorageContext -StorageAccountName $storageAccount.StorageAccountName -UseConnectedAccount
}
catch {
$message = "Unable to create AzStorageContext based on StorageAccountName and federated credentials.`nError was: $($_.Exception.Message)"
}
}
else {
$message = "Insufficient information in StorageContext secret. See https://aka.ms/algosettings#storagecontext for details"
}
if ($message) {
switch($storageAccountCredentials.ErrorAction) {
'Error' {
throw $message
}
'None' {
Write-Host $message
$azStorageContext = $null
}
default {
Write-Host "::WARNING::$message"
$azStorageContext = $null
}
}
}
return $azStorageContext
}

$telemetryScope = $null

try {
. (Join-Path -Path $PSScriptRoot -ChildPath "../AL-Go-Helper.ps1" -Resolve)
DownloadAndImportBcContainerHelper
Expand Down Expand Up @@ -315,38 +346,22 @@ try {
Push-BcNuGetPackage -nuGetServerUrl $nuGetServerUrl -nuGetToken $nuGetToken -bcNuGetPackage $package
}
elseif ($deliveryTarget -eq "Storage") {
EnsureAzStorageModule
InstallAzModuleIfNeeded -moduleName 'Az.Storage'
try {
$storageAccount = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets.storageContext)) | ConvertFrom-Json | ConvertTo-HashTable
# Check that containerName and blobName are present
$storageAccount.containerName | Out-Null
$storageAccount.blobName | Out-Null
}
catch {
throw "StorageContext secret is malformed. Needs to be formatted as Json, containing StorageAccountName, containerName, blobName and sastoken or storageAccountKey.`nError was: $($_.Exception.Message)"
}
if ($storageAccount.Keys -contains 'sastoken') {
try {
$azStorageContext = New-AzStorageContext -StorageAccountName $storageAccount.StorageAccountName -SasToken $storageAccount.sastoken
}
catch {
throw "Unable to create AzStorageContext based on StorageAccountName and sastoken.`nError was: $($_.Exception.Message)"
$storageAccountCredentials = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets.storageContext)) | ConvertFrom-Json
$storageAccountCredentials.StorageAccountName | Out-Null
if (!($storageAccountCredentials.PSObject.Properties.Name -eq 'ErrorAction')) {
$storageAccountCredentials | Add-Member -MemberType NoteProperty -Name 'ErrorAction' -Value 'Warning'
}
$storageContainerName = $storageAccountCredentials.containerName
$storageBlobName = $storageAccountCredentials.blobName
}
else {
try {
$azStorageContext = New-AzStorageContext -StorageAccountName $storageAccount.StorageAccountName -StorageAccountKey $storageAccount.StorageAccountKey
}
catch {
throw "Unable to create AzStorageContext based on StorageAccountName and StorageAccountKey.`nError was: $($_.Exception.Message)"
}
catch {
throw "StorageContext secret is malformed. Needs to be formatted as Json, containing StorageAccountName, containerName, blobName.`nError was: $($_.Exception.Message)"
}

$storageContainerName = $storageAccount.ContainerName.ToLowerInvariant().replace('{project}',$projectName).replace('{branch}',$refname).ToLowerInvariant()
$storageBlobName = $storageAccount.BlobName.ToLowerInvariant()
$azStorageContext = ConnectAzStorageAccount -storageAccountCredentials $storageAccountCredentials
Write-Host "Storage Container Name is $storageContainerName"
Write-Host "Storage Blob Name is $storageBlobName"

$containerExists = $true
try {
Get-AzStorageContainer -Context $azStorageContext -name $storageContainerName | Out-Null
Expand Down Expand Up @@ -415,7 +430,8 @@ try {
# if type is Release, we only get here with the projects that needs to be delivered to AppSource
# if type is CD, we get here for all projects, but should only deliver to AppSource if AppSourceContinuousDelivery is set to true
if ($type -eq 'Release' -or $projectSettings.deliverToAppSource.continuousDelivery) {
EnsureAzStorageModule
# AppSource submission requires the Az.Storage module
InstallAzModuleIfNeeded -moduleName 'Az.Storage'
$appSourceContext = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($secrets.appSourceContext)) | ConvertFrom-Json | ConvertTo-HashTable
if (!$appSourceContext) {
throw "appSourceContext secret is missing"
Expand Down
80 changes: 3 additions & 77 deletions Actions/ReadSecrets/ReadSecretsHelper.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ $script:keyvaultConnectionExists = $false
$script:isKeyvaultSet = $script:gitHubSecrets.PSObject.Properties.Name -eq "AZURE_CREDENTIALS"
$script:escchars = @(' ','!','\"','#','$','%','\u0026','\u0027','(',')','*','+',',','-','.','/','0','1','2','3','4','5','6','7','8','9',':',';','\u003c','=','\u003e','?','@','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[','\\',']','^','_',[char]96,'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','{','|','}','~')

if ($PSVersionTable.PSVersion -lt [Version]"6.0.0") {
$script:isWindows = $true
}
. (Join-Path -Path $PSScriptRoot -ChildPath "..\AL-Go-Helper.ps1" -Resolve)

function MaskValue {
Param(
Expand Down Expand Up @@ -82,16 +80,6 @@ function GetKeyVaultCredentials {
MaskValue -key 'ClientSecret' -value $creds.ClientSecret
$creds.ClientSecret = ConvertTo-SecureString $creds.ClientSecret -AsPlainText -Force
}
else {
try {
Write-Host "Query ID_TOKEN from $ENV:ACTIONS_ID_TOKEN_REQUEST_URL"
$result = Invoke-RestMethod -Method GET -UseBasicParsing -Headers @{ "Authorization" = "bearer $ENV:ACTIONS_ID_TOKEN_REQUEST_TOKEN"; "Accept" = "application/vnd.github+json" } -Uri "$ENV:ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange"
$creds | Add-Member -MemberType NoteProperty -Name 'ClientAssertion' -Value $result.value
}
catch {
Write-Host "::WARNING::Unable to get ID_TOKEN, maybe id_token: write permissions are missing"
}
}
# Check thet $creds contains the needed properties
$creds.ClientId | Out-Null
$creds.TenantId | Out-Null
Expand Down Expand Up @@ -126,68 +114,6 @@ function GetKeyVaultCredentials {
return $creds
}

function InstallKeyVaultModuleIfNeeded {
if (Get-Module -Name 'Az.KeyVault') {
# Already installed
return
}
if ($isWindows) {
# GitHub hosted Windows Runners have AZ PowerShell module saved in C:\Modules\az_*
# Remove AzureRm modules from PSModulePath and add AZ modules
if (Test-Path 'C:\Modules\az_*') {
$azModulesPath = Get-ChildItem 'C:\Modules\az_*' | Where-Object { $_.PSIsContainer }
if ($azModulesPath) {
Write-Host "Adding AZ module path: $($azModulesPath.FullName)"
$ENV:PSModulePath = "$($azModulesPath.FullName);$(("$ENV:PSModulePath".Split(';') | Where-Object { $_ -notlike 'C:\\Modules\Azure*' }) -join ';')"
}
}
}
else {
# Linux runners have AZ PowerShell module saved in /usr/share/powershell/Modules/Az.*
}
$azKeyVaultModule = Get-Module -name 'Az.KeyVault' -ListAvailable | Select-Object -First 1
if ($azKeyVaultModule) {
Write-Host "Az.KeyVault Module is available in version $($azKeyVaultModule.Version)"
Write-Host "Using Az.KeyVault version $($azKeyVaultModule.Version)"
}
else {
$AzKeyVaultModule = Get-InstalledModule -Name 'Az.KeyVault' -ErrorAction SilentlyContinue
if ($AzKeyVaultModule) {
Write-Host "Az.KeyVault version $($AzKeyVaultModule.Version) is installed"
}
else {
Write-Host "Installing and importing Az.KeyVault"
Install-Module 'Az.KeyVault' -Force
}
}
Import-Module 'Az.KeyVault' -DisableNameChecking -WarningAction SilentlyContinue | Out-Null
}

function ConnectAzureKeyVault {
param(
[PsCustomObject] $keyVaultCredentials
)
try {
Clear-AzContext -Scope Process
Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue
if ($keyVaultCredentials.PSObject.Properties.Name -eq 'ClientAssertion') {
Connect-AzAccount -ApplicationId $keyVaultCredentials.ClientId -Tenant $keyVaultCredentials.TenantId -FederatedToken $keyVaultCredentials.ClientAssertion -WarningAction SilentlyContinue | Out-Null
}
else {
$credential = New-Object PSCredential -argumentList $keyVaultCredentials.ClientId, $keyVaultCredentials.ClientSecret
Connect-AzAccount -ServicePrincipal -Tenant $keyVaultCredentials.TenantId -Credential $credential -WarningAction SilentlyContinue | Out-Null
}
if ($keyVaultCredentials.PSObject.Properties.Name -eq 'SubScriptionId') {
Set-AzContext -SubscriptionId $keyVaultCredentials.SubscriptionId -Tenant $keyVaultCredentials.TenantId -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Out-Null
}
$script:keyvaultConnectionExists = $true
Write-Host "Successfully connected to Azure Key Vault."
}
catch {
throw "Error trying to authenticate to Azure using Az. Error was $($_.Exception.Message)"
}
}

function GetKeyVaultSecret {
param (
[string] $secretName,
Expand All @@ -200,10 +126,10 @@ function GetKeyVaultSecret {
}

if (-not $script:keyvaultConnectionExists) {
InstallKeyVaultModuleIfNeeded
InstallAzModuleIfNeeded -moduleName 'Az.KeyVault'
$message = ''
try {
ConnectAzureKeyVault -keyVaultCredentials $keyVaultCredentials
ConnectAz -azureCredentials $keyVaultCredentials
}
catch {
$message = "Error trying to get secrets from Azure Key Vault. Error was $($_.Exception.Message)"
Expand Down

0 comments on commit 877688b

Please sign in to comment.