Ejemplo n.º 1
0
        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());
                }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
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
     });
 }
Ejemplo n.º 4
0
 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}");
         }
     }
 }
Ejemplo n.º 5
0
        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");
        }
Ejemplo n.º 6
0
        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);
                }
Ejemplo n.º 8
0
 static string GetAuthorizationToken(AzureServicePrincipalAccount account)
 {
     return(ServicePrincipal.GetAuthorizationToken(account.TenantId, account.ClientId, account.Password,
                                                   account.ResourceManagementEndpointBaseUri, account.ActiveDirectoryEndpointBaseUri));
 }
Ejemplo n.º 9
0
 public static ServiceClientCredentials Credentials(this AzureServicePrincipalAccount account)
 {
     return(new TokenCredentials(GetAuthorizationToken(account)));
 }