Skip to content

Add retry for deployment failures and check result for every operation #262

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Tools/PowershellModule/src/Library/Connect-ToAzure.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -70,28 +70,28 @@ Function Connect-ToAzure
if($SubscriptionName -and $SubscriptionId) {
## Attempts a connection to Azure using both the Subscription Name and Subscription Id
Write-Information "Initiating a connection to your Azure Subscription Name $SubscriptionName and Subscription Id $SubscriptionId"
Connect-AzAccount -SubscriptionName $SubscriptionName -SubscriptionId $SubscriptionId
$ConnectResult = Connect-AzAccount -SubscriptionName $SubscriptionName -SubscriptionId $SubscriptionId

$TestAzureConnection = Test-ConnectionToAzure -SubscriptionName $SubscriptionName -SubscriptionId $SubscriptionId
}
elseif($SubscriptionName) {
## Attempts a connection to Azure using Subscription Name
Write-Information "Initiating a connection to your Azure Subscription Name $SubscriptionName"
Connect-AzAccount -SubscriptionName $SubscriptionName
$ConnectResult = Connect-AzAccount -SubscriptionName $SubscriptionName

$TestAzureConnection = Test-ConnectionToAzure -SubscriptionName $SubscriptionName
}
elseif($SubscriptionId) {
## Attempts a connection to Azure using Subscription Id
Write-Information "Initiating a connection to your Azure Subscription Id $SubscriptionId"
Connect-AzAccount -SubscriptionId $SubscriptionId
$ConnectResult = Connect-AzAccount -SubscriptionId $SubscriptionId

$TestAzureConnection = Test-ConnectionToAzure -SubscriptionId $SubscriptionId
}
else{
## Attempts a connection to Azure with the users default Subscription
Write-Information "Initiating a connection to your Azure environment."
Connect-AzAccount
$ConnectResult = Connect-AzAccount

$TestAzureConnection = Test-ConnectionToAzure
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Function Find-WinGetManifest

###############################
## Connects to Azure, if not already connected.
Write-Verbose "Testing connection to Azure."
Write-Verbose "Validating connection to azure, will attempt to connect if not already connected."
$Result = Connect-ToAzure -SubscriptionName $SubscriptionName
if(!($Result)) {
Write-Error "Failed to connect to Azure. Please run Connect-AzAccount to connect to Azure, or re-run the cmdlet and enter your credentials." -ErrorAction Stop
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Function Get-WinGetManifest
"Azure" {
###############################
## Connects to Azure, if not already connected.
Write-Verbose "Testing connection to Azure."
Write-Verbose "Validating connection to azure, will attempt to connect if not already connected."
$Result = Connect-ToAzure -SubscriptionName $SubscriptionName
if(!($Result)) {
Write-Error "Failed to connect to Azure. Please run Connect-AzAccount to connect to Azure, or re-run the cmdlet and enter your credentials." -ErrorAction Stop
Expand Down
134 changes: 72 additions & 62 deletions Tools/PowershellModule/src/Library/New-ARMObjects.ps1

Large diffs are not rendered by default.

17 changes: 7 additions & 10 deletions Tools/PowershellModule/src/Library/New-ARMParameterObjects.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -138,31 +138,28 @@ Function New-ARMParameterObjects
$AzContext = Get-AzContext
$AzTenantID = $AzContext.Tenant.Id
$AzTenantDomain = $AzContext.Tenant.Domains[0]
$DeployAppConfigValues = $false

if ($AzContext.Account.Type -eq "User")
{
$LocalDeployment = $true
$AzObjectID = $(Get-AzADUser -SignedIn).Id
if (!$PublisherEmail) {
$PublisherEmail = $AzContext.Account.Id
}
if (!$PublisherName) {
$PublisherName = $AzContext.Account.Id
}

$DeployAppConfigValues = $false
}
else
{
$LocalDeployment = $false
$AzObjectID = $(Get-AzADServicePrincipal -ApplicationId $AzContext.Account.ID).Id
if (!$PublisherEmail) {
$PublisherEmail = "WinGetRestSource@$AzTenantDomain"
}
if (!$PublisherName) {
$PublisherName = "WinGetRestSource@$AzTenantDomain"
}

$DeployAppConfigValues = $true
}
Write-Verbose -Message "Retrieved the Azure Object Id: $AzObjectID"

Expand Down Expand Up @@ -206,17 +203,17 @@ Function New-ARMParameterObjects
isZoneRedundant = $false
}
)
$ApiManagementSku = "Basicv2"
$ApiManagementSku = "Basic"
}
"Enhanced" {
$AppConfigSku = "Standard"
$KeyVaultSKU = "Standard"
$StorageAccountPerformance = "Standard_GZRS"
$StorageAccountPerformance = "Standard_GRS"
$AspSku = "P1V2"
$CosmosDBAEnableFreeTier = $false
## To enable Serverless then set CosmosDBACapatilities to "[{"name": ""EnableServerless""}]"
$CosmosDBACapabilities = "[]"
$CosmosDBAConsistency = "Strong"
$CosmosDBAConsistency = "Session"
$CosmosDBALocations = @(
@{
locationName = $PrimaryRegionName
Expand All @@ -229,7 +226,7 @@ Function New-ARMParameterObjects
isZoneRedundant = $false
}
)
$ApiManagementSku = "Standardv2"
$ApiManagementSku = "Standard"
}
}

Expand Down Expand Up @@ -293,7 +290,7 @@ Function New-ARMParameterObjects
appConfigName = @{ value = $appConfigName } # Name used to contain the Storage Account connection string in the Key Value
location = @{ value = $Region } # Azure hosting location
sku = @{ value = $AppConfigSku }
deployAppConfigValues = @{ value = $DeployAppConfigValues }
localDeployment = @{ value = $LocalDeployment }
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Function New-MicrosoftEntraIdApp

## Add App Id Uri
$AppId = $App.AppId
Update-AzADApplication -ApplicationId $AppId -IdentifierUri "api://$AppId" -ErrorVariable ErrorUpdate
$App = Update-AzADApplication -ApplicationId $AppId -IdentifierUri "api://$AppId" -ErrorVariable ErrorUpdate
if ($ErrorUpdate)
{
Write-Error "Failed to add App Id Uri. Error: $ErrorUpdate"
Expand All @@ -72,7 +72,7 @@ Function New-MicrosoftEntraIdApp
}
)
}
Update-AzADApplication -ApplicationId $AppId -Api $Api -ErrorVariable ErrorUpdate
$App = Update-AzADApplication -ApplicationId $AppId -Api $Api -ErrorVariable ErrorUpdate
if ($ErrorUpdate)
{
Write-Error "Failed to add Api scope. Error: $ErrorUpdate"
Expand All @@ -96,7 +96,7 @@ Function New-MicrosoftEntraIdApp
}
)
}
Update-AzADApplication -ApplicationId $AppId -Api $Api -ErrorVariable ErrorUpdate
$App = Update-AzADApplication -ApplicationId $AppId -Api $Api -ErrorVariable ErrorUpdate
if ($ErrorUpdate)
{
Write-Error "Failed to add authorized clients"
Expand Down
51 changes: 35 additions & 16 deletions Tools/PowershellModule/src/Library/New-WinGetSource.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,25 @@ Function New-WinGetSource
.PARAMETER ShowConnectionInstructions
[Optional] If specified, the instructions for connecting to the Windows Package Manager REST source. (Default: False)

.PARAMETER MaxRetryCount
[Optional] Max ARM template deployment retry count upon failure. (Default: 5)

.EXAMPLE
New-WinGetSource -Name "contosorestsource"
New-WinGetSource -Name "contosorestsource" -InformationAction Continue -Verbose

Creates the Windows Package Manager REST source in Azure with resources named "contosorestsource" in the westus region of
Azure with the basic level performance.

.EXAMPLE
New-WinGetSource -Name "contosorestsource" -ResourceGroup "WinGet" -SubscriptionName "Visual Studio Subscription" -Region "westus" -ParameterOutput "C:\WinGet" -ImplementationPerformance "Basic" -ShowConnectionInformation
New-WinGetSource -Name "contosorestsource" -ResourceGroup "WinGet" -SubscriptionName "Visual Studio Subscription" -Region "westus" -ParameterOutput "C:\WinGet" -ImplementationPerformance "Basic" -ShowConnectionInformation -InformationAction Continue -Verbose

Creates the Windows Package Manager REST source in Azure with resources named "contosorestsource" in the westus region of
Azure with the basic level performance in the "Visual Studio Subscription" Subscription. Displays the required command
to connect the WinGet client to the new REST source after the REST source has been created.

#>
PARAM(
[Parameter(Position=0, Mandatory=$true)] [string]$Name,
[Parameter(Position=0, Mandatory=$true)] [string]$Name,
[Parameter(Mandatory=$false)] [string]$ResourceGroup = "WinGetRestSource",
[Parameter(Mandatory=$false)] [string]$SubscriptionName = "",
[Parameter(Mandatory=$false)] [string]$Region = "westus",
Expand All @@ -93,7 +96,8 @@ Function New-WinGetSource
[Parameter()] [switch]$CreateNewMicrosoftEntraIdAppRegistration,
[Parameter(Mandatory=$false)] [string]$MicrosoftEntraIdResource = "",
[Parameter(Mandatory=$false)] [string]$MicrosoftEntraIdResourceScope = "",
[Parameter()] [switch]$ShowConnectionInstructions
[Parameter()] [switch]$ShowConnectionInstructions,
[Parameter(Mandatory=$false)] [int]$MaxRetryCount = 5
)

if($ImplementationPerformance -eq "Developer") {
Expand All @@ -106,11 +110,11 @@ Function New-WinGetSource

###############################
## Check input paths
if(!$(Test-Path -Path $TemplateFolderPath)) {
if (!$(Test-Path -Path $TemplateFolderPath)) {
Write-Error "REST Source Function Code is missing in specified path ($TemplateFolderPath)"
return $false
}
if(!$(Test-Path -Path $RestSourcePath)) {
if (!$(Test-Path -Path $RestSourcePath)) {
Write-Error "REST Source Function Code is missing in specified path ($RestSourcePath)"
return $false
}
Expand All @@ -125,7 +129,7 @@ Function New-WinGetSource
###############################
## Create folder for the Parameter output path
$Result = New-Item -ItemType Directory -Path $ParameterOutputPath -Force
if($Result) {
if ($Result) {
Write-Verbose -Message "Created Directory to contain the ARM Parameter files ($($Result.FullName))."
}
else {
Expand All @@ -135,9 +139,9 @@ Function New-WinGetSource

###############################
## Connects to Azure, if not already connected.
Write-Information "Testing connection to Azure."
Write-Information "Validating connection to azure, will attempt to connect if not already connected."
$Result = Connect-ToAzure -SubscriptionName $SubscriptionName
if(!($Result)) {
if (!($Result)) {
Write-Error "Failed to connect to Azure. Please run Connect-AzAccount to connect to Azure, or re-run the cmdlet and enter your credentials."
return $false
}
Expand Down Expand Up @@ -173,7 +177,8 @@ Function New-WinGetSource
return $false
}

#### Verifies ARM Parameters are correct
###############################
## Verifies ARM Parameters are correct. If any failed, the return results will contain failed objects. Otherwise, success.
$Result = Test-ARMTemplates -ARMObjects $ARMObjects -ResourceGroup $ResourceGroup
if($Result){
$ErrReturnObject = @{
Expand All @@ -188,11 +193,25 @@ Function New-WinGetSource

###############################
## Creates Azure Objects with ARM Templates and Parameters
$Result = New-ARMObjects -ARMObjects $ARMObjects -RestSourcePath $RestSourcePath -ResourceGroup $ResourceGroup
if (!$Result) {
Write-Error "Failed to create Azure resources for WinGet rest source"
return $false
}
$Attempt = 0
$Retry = $false
do {
$Attempt++
$Retry = $false

$Result = New-ARMObjects -ARMObjects ([ref]$ARMObjects) -RestSourcePath $RestSourcePath -ResourceGroup $ResourceGroup
if (!$Result) {
if ($Attempt -lt $MaxRetryCount) {
$Retry = $true
Write-Verbose "Retrying deployment after 15 seconds."
Start-Sleep -Seconds 15
}
else {
Write-Error "Failed to create Azure resources for WinGet rest source."
return $false
}
}
} while ($Retry)

###############################
## Shows how to connect local Windows Package Manager Client to newly created REST source
Expand All @@ -203,7 +222,7 @@ Function New-WinGetSource
## Post script Run Informational:
#### Instructions on how to add the REST source to your Windows Package Manager Client
Write-Information -MessageData "Use the following command to register the new REST source with your Windows Package Manager Client:" -InformationAction Continue
Write-Information -MessageData " winget source add -n ""restsource"" -a ""$ApiManagementURL/winget/"" -t ""Microsoft.Rest""" -InformationAction Continue
Write-Information -MessageData " winget source add -n ""$Name"" -a ""$ApiManagementURL/winget/"" -t ""Microsoft.Rest""" -InformationAction Continue

#### For more information about how to use the solution, visit the aka.ms link.
Write-Information -MessageData "`nFor more information on the Windows Package Manager Client, go to: https://aka.ms/winget-command-help`n" -InformationAction Continue
Expand Down
Loading