Skip to content
This repository has been archived by the owner on May 2, 2023. It is now read-only.

Commit

Permalink
Ensure HealthCheck respects configured proxy settings
Browse files Browse the repository at this point in the history
Fixes OctopusDeploy/Issues#7544

Updates the HealthCheck to use the new version of
the Azure SDKs. It's in beta, so not touching the
actual deployment code at this stage.
  • Loading branch information
mjhilton committed Jun 14, 2022
1 parent 2fa692c commit e1d0e67
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 10 deletions.
22 changes: 22 additions & 0 deletions source/Calamari/Azure/AzureClient.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System.Net;
using System.Net.Http;
using Azure.Core.Pipeline;
using Azure.Identity;
using Azure.ResourceManager;
using Microsoft.Azure.Management.Fluent;
using Microsoft.Azure.Management.ResourceManager.Fluent;

Expand All @@ -23,5 +26,24 @@ public static IAzure CreateAzureClient(this ServicePrincipalAccount servicePrinc
.Authenticate(credentials)
.WithSubscription(servicePrincipal.SubscriptionNumber);
}

/// <summary>
/// Creates an ArmClient for the new Azure SDK, which replaces the older fluent libraries.
/// We should migrate to this SDK once it stabilises.
/// </summary>
/// <param name="servicePrincipal">Service Principal Account to use when connecting to Azure</param>
/// <returns></returns>
public static ArmClient CreateArmClient(this ServicePrincipalAccount servicePrincipal)
{
var environment = new AzureKnownEnvironment(servicePrincipal.AzureEnvironment).AsAzureArmEnvironment();

var httpClientTransport = new HttpClientTransport(new HttpClientHandler { Proxy = WebRequest.DefaultWebProxy });

var tokenCredentialOptions = new TokenCredentialOptions { Transport = httpClientTransport };
var credential = new ClientSecretCredential(servicePrincipal.TenantId, servicePrincipal.ClientId, servicePrincipal.Password, tokenCredentialOptions);

var armClientOptions = new ArmClientOptions() { Transport = httpClientTransport, Environment = environment };
return new ArmClient(credential, defaultSubscriptionId: servicePrincipal.SubscriptionNumber, armClientOptions);
}
}
}
18 changes: 15 additions & 3 deletions source/Calamari/Azure/AzureKnownEnvironment.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Azure.ResourceManager;
using Microsoft.Azure.Management.ResourceManager.Fluent;

namespace Calamari.Azure
Expand All @@ -15,11 +16,11 @@ public AzureKnownEnvironment(string environment)
if (string.IsNullOrEmpty(environment) || environment == "AzureCloud") // This environment name is defined in Sashimi.Azure.Accounts.AzureEnvironmentsListAction
Value = Global.Value; // We interpret it as the normal Azure environment for historical reasons)

azureEnvironment = AzureEnvironment.FromName(Value) ??
azureSdkEnvironment = AzureEnvironment.FromName(Value) ??
throw new InvalidOperationException($"Unknown environment name {Value}");
}

private readonly AzureEnvironment azureEnvironment;
private readonly AzureEnvironment azureSdkEnvironment;
public string Value { get; }

public static readonly AzureKnownEnvironment Global = new AzureKnownEnvironment("AzureGlobalCloud");
Expand All @@ -29,7 +30,18 @@ public AzureKnownEnvironment(string environment)

public AzureEnvironment AsAzureSDKEnvironment()
{
return azureEnvironment;
return azureSdkEnvironment;
}

public ArmEnvironment AsAzureArmEnvironment() => ToArmEnvironment(Value);

private static ArmEnvironment ToArmEnvironment(string name) => name switch
{
"AzureGlobalCloud" => ArmEnvironment.AzurePublicCloud,
"AzureChinaCloud" => ArmEnvironment.AzureChina,
"AzureGermanCloud" => ArmEnvironment.AzureGermany,
"AzureUSGovernment" => ArmEnvironment.AzureGovernment,
_ => throw new InvalidOperationException($"ARM Environment {name} is not a known Azure Environment name.")
};
}
}
2 changes: 2 additions & 0 deletions source/Calamari/Calamari.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.2.3" />
<PackageReference Include="Azure.ResourceManager.AppService" Version="1.0.0-beta.2" />
<PackageReference Include="Calamari.Common" Version="21.1.0" />
<PackageReference Include="Microsoft.Azure.Management.AppService.Fluent" Version="1.37.1" />
<PackageReference Include="Microsoft.Azure.Management.Fluent" Version="1.37.1" />
Expand Down
23 changes: 16 additions & 7 deletions source/Calamari/HealthCheckCommand.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Azure;
using Azure.ResourceManager.AppService;
using Azure.ResourceManager.Resources;
using Calamari.Azure;
using Calamari.Common.Commands;
using Calamari.Common.Plumbing.Pipeline;
using Microsoft.Azure.Management.ResourceManager.Fluent;

namespace Calamari.AzureAppService
{
Expand Down Expand Up @@ -34,14 +36,21 @@ public Task Execute(RunningDeployment context)
return ConfirmWebAppExists(account, resourceGroupName, webAppName);
}

async Task ConfirmWebAppExists(ServicePrincipalAccount servicePrincipal, string resourceGroupName, string siteAndSlotName)
private async Task ConfirmWebAppExists(ServicePrincipalAccount servicePrincipal, string resourceGroupName, string siteAndSlotName)
{
var azureClient = servicePrincipal.CreateAzureClient();
var webApp = await azureClient.WebApps.GetByResourceGroupAsync(resourceGroupName, siteAndSlotName);
if (webApp == null)
var client = servicePrincipal.CreateArmClient();
var subscription = await client.GetDefaultSubscriptionAsync();
var resourceGroups = subscription.GetResourceGroups();

try
{
ResourceGroupResource resourceGroup = await resourceGroups.GetAsync(resourceGroupName);
_ = await resourceGroup.GetWebSiteAsync(siteAndSlotName);
}
catch (RequestFailedException rfe) when (rfe.Status == 404)
{
throw new Exception($"Could not find site {siteAndSlotName} in resource group {resourceGroupName}, using Service Principal with subscription {servicePrincipal.SubscriptionNumber}");
throw new Exception($"Could not find site {siteAndSlotName} in resource group {resourceGroupName}, using Service Principal with subscription {servicePrincipal.SubscriptionNumber}", rfe);
}
}
}
}
}

0 comments on commit e1d0e67

Please sign in to comment.