public static WebDeployPublishSettings GetPublishProperties(AzureServicePrincipalAccount account, string resourceGroupName, AzureTargetSite azureTargetSite) { if (account.ResourceManagementEndpointBaseUri != DefaultVariables.ResourceManagementEndpoint) { Log.Info("Using override for resource management endpoint - {0}", account.ResourceManagementEndpointBaseUri); } if (account.ActiveDirectoryEndpointBaseUri != DefaultVariables.ActiveDirectoryEndpoint) { Log.Info("Using override for Azure Active Directory endpoint - {0}", account.ActiveDirectoryEndpointBaseUri); } var token = ServicePrincipal.GetAuthorizationToken(account.TenantId, account.ClientId, account.Password, account.ResourceManagementEndpointBaseUri, account.ActiveDirectoryEndpointBaseUri); var baseUri = new Uri(account.ResourceManagementEndpointBaseUri); using (var resourcesClient = new ResourceManagementClient(new TokenCredentials(token)) { SubscriptionId = account.SubscriptionNumber, BaseUri = baseUri, }) using (var webSiteClient = new WebSiteManagementClient(new Uri(account.ResourceManagementEndpointBaseUri), new TokenCredentials(token)) { SubscriptionId = account.SubscriptionNumber }) { webSiteClient.SetRetryPolicy(new RetryPolicy(new HttpStatusCodeErrorDetectionStrategy(), 3)); resourcesClient.HttpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); resourcesClient.HttpClient.BaseAddress = baseUri; Log.Verbose($"Looking up site {azureTargetSite.Site} {(string.IsNullOrWhiteSpace(resourceGroupName) ? string.Empty : $"in resourceGroup {resourceGroupName}")}"); Site matchingSite; if (string.IsNullOrWhiteSpace(resourceGroupName)) { matchingSite = FindSiteByNameWithRetry(account, azureTargetSite, webSiteClient) ?? throw new CommandException(GetSiteNotFoundExceptionMessage(account, azureTargetSite)); resourceGroupName = matchingSite.ResourceGroup; } else { var site = webSiteClient.WebApps.Get(resourceGroupName, azureTargetSite.Site); Log.Verbose("Found site:"); LogSite(site); matchingSite = site ?? throw new CommandException(GetSiteNotFoundExceptionMessage(account, azureTargetSite, resourceGroupName)); } // ARM resource ID of the source app. App resource ID is of the form: // - /subscriptions/{subId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{siteName} for production slots and // - /subscriptions/{subId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{siteName}/slots/{slotName} for other slots. // We allow the slot to be defined on both the target directly (which will come through on the matchingSite.Name) or on the // step for backwards compatibility with older Azure steps. if (azureTargetSite.HasSlot) { Log.Verbose($"Using the deployment slot {azureTargetSite.Slot}"); } return(GetWebdeployPublishProfile(webSiteClient, resourceGroupName, matchingSite.Name, azureTargetSite.HasSlot ? azureTargetSite.Slot : null).GetAwaiter().GetResult()); }
public int ExecuteHealthCheck() { var account = new AzureServicePrincipalAccount(variables); var resourceGroupName = variables.Get(SpecialVariables.Action.Azure.ResourceGroupName); var webAppName = variables.Get(SpecialVariables.Action.Azure.WebAppName); ConfirmWebAppExists(account, resourceGroupName, webAppName); return(0); }
public static WebSiteManagementClient CreateWebSiteManagementClient(this AzureServicePrincipalAccount account) { return(string.IsNullOrWhiteSpace(account.ResourceManagementEndpointBaseUri) ? new WebSiteManagementClient(account.Credentials()) { SubscriptionId = account.SubscriptionNumber } : new WebSiteManagementClient(new Uri(account.ResourceManagementEndpointBaseUri), account.Credentials()) { SubscriptionId = account.SubscriptionNumber }); }
void ConfirmWebAppExists(AzureServicePrincipalAccount servicePrincipalAccount, string resourceGroupName, string siteAndSlotName) { using (var webSiteClient = servicePrincipalAccount.CreateWebSiteManagementClient()) { var matchingSite = webSiteClient.WebApps .ListByResourceGroup(resourceGroupName, true) .ToList() .FirstOrDefault(x => string.Equals(x.Name, siteAndSlotName, StringComparison.OrdinalIgnoreCase)); if (matchingSite == null) { throw new Exception($"Could not find site {siteAndSlotName} in resource group {resourceGroupName}, using Service Principal with subscription {servicePrincipalAccount.SubscriptionNumber}"); } } }
private static WebDeployPublishSettings GetPublishProfile(IVariables variables) { var account = new AzureServicePrincipalAccount(variables); var siteAndSlotName = variables.Get(SpecialVariables.Action.Azure.WebAppName); var slotName = variables.Get(SpecialVariables.Action.Azure.WebAppSlot); var targetSite = AzureWebAppHelper.GetAzureTargetSite(siteAndSlotName, slotName); if (account is AzureServicePrincipalAccount servicePrincipalAccount) { return(ResourceManagerPublishProfileProvider.GetPublishProperties(servicePrincipalAccount, variables.Get(SpecialVariables.Action.Azure.ResourceGroupName, string.Empty), targetSite)); } throw new CommandException("Account type must be Azure Service Principal"); }
public void Install(RunningDeployment deployment) { try { var variables = deployment.Variables; var resourceGroupName = variables.Get(SpecialVariables.Action.Azure.ResourceGroupName, string.Empty); var siteAndSlotName = variables.Get(SpecialVariables.Action.Azure.WebAppName); var azureEnvironment = variables.Get(SpecialVariables.Action.Azure.Environment); var account = new AzureServicePrincipalAccount(variables); var client = account.CreateWebSiteManagementClient(); var site = client?.WebApps.Get(resourceGroupName, siteAndSlotName); if (site != null) { var portalUrl = GetAzurePortalUrl(azureEnvironment); log.Info($"Default Host Name: {site.DefaultHostName}"); log.Info($"Application state: {site.State}"); log.Info("Links:"); log.Info(log.FormatLink($"https://{site.DefaultHostName}")); if (!site.HttpsOnly.HasValue || site.HttpsOnly == false) { log.Info(log.FormatLink($"http://{site.DefaultHostName}")); } string portalUri = $"https://{portalUrl}/#@/resource{site.Id}"; log.Info(log.FormatLink(portalUri, "View in Azure Portal")); } } catch { // do nothing } }
public static SitePublishProfile GetPublishProperties(AzureServicePrincipalAccount account, string resourceGroupName, AzureTargetSite azureTargetSite) { if (account.ResourceManagementEndpointBaseUri != DefaultVariables.ResourceManagementEndpoint) { Log.Info("Using override for resource management endpoint - {0}", account.ResourceManagementEndpointBaseUri); } if (account.ActiveDirectoryEndpointBaseUri != DefaultVariables.ActiveDirectoryEndpoint) { Log.Info("Using override for Azure Active Directory endpoint - {0}", account.ActiveDirectoryEndpointBaseUri); } var token = ServicePrincipal.GetAuthorizationToken(account.TenantId, account.ClientId, account.Password, account.ResourceManagementEndpointBaseUri, account.ActiveDirectoryEndpointBaseUri); var baseUri = new Uri(account.ResourceManagementEndpointBaseUri); using (var resourcesClient = new ResourceManagementClient(new TokenCredentials(token)) { SubscriptionId = account.SubscriptionNumber, BaseUri = baseUri, }) using (var webSiteClient = new WebSiteManagementClient(new Uri(account.ResourceManagementEndpointBaseUri), new TokenCredentials(token)) { SubscriptionId = account.SubscriptionNumber }) { webSiteClient.SetRetryPolicy(new Microsoft.Rest.TransientFaultHandling.RetryPolicy(new HttpStatusCodeErrorDetectionStrategy(), 3)); resourcesClient.HttpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); resourcesClient.HttpClient.BaseAddress = baseUri; Log.Verbose($"Looking up site {azureTargetSite.Site} {(string.IsNullOrWhiteSpace(resourceGroupName) ? string.Empty : $"in resourceGroup {resourceGroupName}")}"); Site matchingSite; if (string.IsNullOrWhiteSpace(resourceGroupName)) { matchingSite = FindSiteByNameWithRetry(account, azureTargetSite, webSiteClient) ?? throw new CommandException(GetSiteNotFoundExceptionMessage(account, azureTargetSite)); resourceGroupName = matchingSite.ResourceGroup; } else { var site = webSiteClient.WebApps.Get(resourceGroupName, azureTargetSite.Site); Log.Verbose("Found site:"); LogSite(site); matchingSite = site ?? throw new CommandException(GetSiteNotFoundExceptionMessage(account, azureTargetSite, resourceGroupName)); } // ARM resource ID of the source app. App resource ID is of the form: // - /subscriptions/{subId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{siteName} for production slots and // - /subscriptions/{subId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{siteName}/slots/{slotName} for other slots. // We allow the slot to be defined on both the target directly (which will come through on the matchingSite.Name) or on the // step for backwards compatibility with older Azure steps. var siteAndSlotPath = matchingSite.Name; if (azureTargetSite.HasSlot) { Log.Verbose($"Using the deployment slot {azureTargetSite.Slot}"); siteAndSlotPath = $"{matchingSite.Name}/slots/{azureTargetSite.Slot}"; } // Once we know the Resource Group, we have to POST a request to the URI below to retrieve the publishing credentials var publishSettingsUri = new Uri(resourcesClient.BaseUri, $"/subscriptions/{account.SubscriptionNumber}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{siteAndSlotPath}/config/publishingCredentials/list?api-version=2016-08-01"); Log.Verbose($"Retrieving publishing profile from {publishSettingsUri}"); SitePublishProfile publishProperties = null; var request = new HttpRequestMessage { Method = HttpMethod.Post, RequestUri = publishSettingsUri }; // Add the authentication headers var requestTask = resourcesClient.Credentials.ProcessHttpRequestAsync(request, new CancellationToken()) .ContinueWith(authResult => resourcesClient.HttpClient.SendAsync(request), TaskContinuationOptions.NotOnFaulted) .ContinueWith(publishSettingsResponse => { var result = publishSettingsResponse.Result.Result; if (!result.IsSuccessStatusCode) { Log.Error($"Retrieving publishing credentials failed. Publish-settings URI: {publishSettingsUri}"); throw new Exception($"Retrieving publishing credentials failed with HTTP status {(int)result.StatusCode} - {result.ReasonPhrase}"); } dynamic response = JObject.Parse(result.Content.AsString()); string publishUserName = response.properties.publishingUserName; string publishPassword = response.properties.publishingPassword; string scmUri = response.properties.scmUri; Log.Verbose($"Retrieved publishing profile. URI: {scmUri} UserName: {publishUserName}"); publishProperties = new SitePublishProfile(publishUserName, publishPassword, new Uri(scmUri)); }, TaskContinuationOptions.NotOnFaulted); requestTask.Wait(); return(publishProperties); }
static string GetAuthorizationToken(AzureServicePrincipalAccount account) { return(ServicePrincipal.GetAuthorizationToken(account.TenantId, account.ClientId, account.Password, account.ResourceManagementEndpointBaseUri, account.ActiveDirectoryEndpointBaseUri)); }
public static ServiceClientCredentials Credentials(this AzureServicePrincipalAccount account) { return(new TokenCredentials(GetAuthorizationToken(account))); }