Пример #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> CreateResourceGroupAsync(Guid subscriptionId)
        {
            Subscription subscription = await _context.Subscriptions.FindAsync(subscriptionId);

            ValidateSubscriptionAndInputState(subscription);

            try
            {
                Offer offer = await FindOfferById(subscription.OfferId);

                Plan plan = await FindPlanById(subscription.PlanId);

                string isvSubscriptionId = offer.HostSubscription.ToString();

                var parameters = await EvaluateParameters(offer, plan, subscription);

                subscription.EntryPointUrl = parameters.ContainsKey("entryPointUrl") ? parameters["entryPointUrl"].ToString() : "";

                if (plan.SubscribeArmTemplateId == null)
                {
                    // Don't need to deploy anything, transit to WebhookPending state
                    return(await TransitToNextState(subscription, ProvisioningState.WebhookPending));
                }

                string azureLocation     = null;
                string resourceGroupName = $"{offer.OfferName}-{subscription.SubscriptionId}";

                if (parameters.ContainsKey("resourceGroupLocation"))
                {
                    azureLocation = parameters["resourceGroupLocation"].ToString();
                }
                else
                {
                    throw new LunaBadRequestUserException("The ResourceGroupLocation parameter is not specified.", UserErrorCode.ParameterNotProvided);
                }

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

                bool resourceGroupExists = await _provisioningClient.ResourceGroupExistsAsync(
                    Guid.NewGuid(),
                    Guid.NewGuid(),
                    isvSubscriptionId,
                    resourceGroupName,
                    default);

                if (!resourceGroupExists)
                {
                    _logger.LogInformation(
                        LoggingUtils.ComposeHttpClientLogMessage(
                            _provisioningClient.GetType().Name,
                            nameof(_provisioningClient.CreateOrUpdateResourceGroupAsync),
                            subscriptionId));

                    var result = await _provisioningClient.CreateOrUpdateResourceGroupAsync(
                        Guid.NewGuid(),
                        Guid.NewGuid(),
                        isvSubscriptionId,
                        resourceGroupName,
                        azureLocation,
                        default
                        );

                    _logger.LogInformation($"Deploying resource group {resourceGroupName} in location {azureLocation}.");
                }
                else
                {
                    throw new LunaConflictUserException($"Resource group with name {resourceGroupName} already exist.");
                }

                subscription.ResourceGroup = resourceGroupName;

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