Пример #1
0
        /// <summary>
        /// Upon notification of activation of a subscription from AMP, deploy the ARM template.
        /// </summary>
        /// <param name="provisionModel"></param>
        /// <param name="azureLocation"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task ProcessStartProvisioningAsync(
            Subscription subscription,
            string azureLocation,
            CancellationToken cancellationToken = default)
        {
            Offer offer = await _context.Offers.FindAsync(subscription.OfferId);

            Plan plan = await _context.Plans.FindAsync(subscription.OfferId, subscription.PlanId);

            string deploymentName    = $"{plan.PlanName}{offer.OfferName}{new Random().Next(0, 9999).ToString("D4")}"; // deployment name cannot exceed 64 characters, otherwise returns 400
            string isvSubscriptionId = offer.HostSubscription.ToString();

            // get the subscribe template for this plan
            string templatePath = await GetTemplatePath(
                offer,
                plan,
                FulfillmentAction.Activate
                );

            object parameters = await GetTemplateParameters(
                offer,
                plan,
                FulfillmentAction.Activate
                );

            // create a resource group for the subscription
            var resourceGroup = (await _provisioningClient.CreateOrUpdateResourceGroupAsync(
                                     Guid.NewGuid(),
                                     Guid.NewGuid(),
                                     isvSubscriptionId,
                                     $"luna-{subscription.SubscriptionId}",
                                     azureLocation,
                                     cancellationToken
                                     )).Name;

            // deploy the ARM template
            // note that the rollback property is set to false here because this is a fresh resource group with nothing to fallback on if this deployment fails
            await _provisioningClient.PutDeploymentAsync(
                requestId : Guid.NewGuid(),
                correlationId : Guid.NewGuid(),
                subscriptionId : isvSubscriptionId,
                resourceGroup : resourceGroup,
                deploymentName : deploymentName,
                templatePath : templatePath,
                parameters : parameters,
                cancellationToken : cancellationToken);
        }
        public async Task <Subscription> DeployArmTemplateAsync(Guid subscriptionId)
        {
            Subscription subscription = await _context.Subscriptions.FindAsync(subscriptionId);

            ValidateSubscriptionAndInputState(subscription);

            try
            {
                if (subscription.ResourceGroup == null)
                {
                    // If resource group is not created, transit to ProvisioningPending state to create resource group
                    return(await TransitToNextState(subscription, ProvisioningState.ProvisioningPending));
                }

                Offer offer = await FindOfferById(subscription.OfferId);

                Plan plan = await FindPlanById(subscription.PlanId);

                string deploymentName    = $"{plan.PlanName}{offer.OfferName}{new Random().Next(0, 9999).ToString("D4")}"; // deployment name cannot exceed 64 characters, otherwise returns 400
                string isvSubscriptionId = offer.HostSubscription.ToString();

                string templatePath = await GetTemplatePath(plan, subscription.ProvisioningType);

                if (templatePath == null)
                {
                    // If template is not specified, do nothing and transit to WebhookPending state
                    return(await TransitToNextState(subscription, ProvisioningState.WebhookPending));
                }

                // Reevaluate parameters if not subscribe. If it is subscribe, the parameters are evaluated when creating resource group
                if (!subscription.ProvisioningType.Equals(nameof(ProvisioningType.Subscribe)))
                {
                    await EvaluateParameters(offer, plan, subscription);
                }

                templatePath = await _storageUtility.GetFileReferenceWithSasKeyAsync(templatePath);

                JObject parameters = new JObject();
                using (WebClient client = new WebClient())
                {
                    string  content = client.DownloadString(templatePath);
                    Context context = await SetContext(offer.OfferName, subscription.Owner, subscriptionId, plan.PlanName, subscription.ProvisioningType);

                    var paramList = ARMTemplateHelper.GetArmTemplateParameters(content);
                    foreach (var param in paramList)
                    {
                        JProperty value = new JProperty("value", context.Parameters[param.Key]);
                        parameters.Add(param.Key, new JObject(value));
                    }
                }

                _logger.LogInformation(
                    LoggingUtils.ComposeHttpClientLogMessage(
                        _provisioningClient.GetType().Name,
                        nameof(_provisioningClient.PutDeploymentAsync),
                        subscriptionId));

                var result = await _provisioningClient.PutDeploymentAsync(
                    Guid.NewGuid(),
                    Guid.NewGuid(),
                    isvSubscriptionId,
                    subscription.ResourceGroup,
                    deploymentName,
                    parameters : parameters,
                    templatePath : templatePath);

                subscription.DeploymentName = result.Name;

                _logger.LogInformation($"Running ARM deployment {deploymentName} for subscription {isvSubscriptionId} in resource group {subscription.ResourceGroup}.");

                return(await TransitToNextState(subscription, ProvisioningState.ArmTemplateRunning));
            }
            catch (Exception e)
            {
                return(await HandleExceptions(subscription, e));
            }
        }