Beispiel #1
0
        /// <summary>
        /// Parses and checks the given JSON object to see if any armTemplateParameters were added or removed.
        /// If parameters were added then they are created in the db along with a join entry in the armTemplateArmTemplateParameters table.
        /// If parameters were removed then the join entry in the armTemplateArmTemplateParameters table is removed.
        /// </summary>
        /// <param name="offer">The name of the offer the parameters belong to</param>
        /// <param name="armTemplateJSON">The JSON object to parse.</param>
        /// <param name="armTemplateId">The ID of the armTemplate.</param>
        /// <returns></returns>
        private async Task UpdateArmTemplateParameters(Offer offer, object armTemplateJSON, long armTemplateId)
        {
            List <KeyValuePair <string, string> >  incompleteParams = ARMTemplateHelper.GetArmTemplateParameters(armTemplateJSON.ToString());
            List <ArmTemplateArmTemplateParameter> joinEntries      = await _armTemplateArmTemplateParameterService.GetAllJoinEntries(armTemplateId);

            Dictionary <string, ArmTemplateParameter> paramsDb = new Dictionary <string, ArmTemplateParameter>();
            HashSet <string> usedParamNames = new HashSet <string>();

            // Populate paramsDb so that it maps the ArmTemplateParameter name to the ArmTemplateParameter object
            foreach (ArmTemplateArmTemplateParameter entry in joinEntries)
            {
                ArmTemplateParameter armTemplateParameter = await _context.ArmTemplateParameters.FindAsync(entry.ArmTemplateParameterId);

                if (!paramsDb.ContainsKey(armTemplateParameter.Name))
                {
                    paramsDb.Add(armTemplateParameter.Name, armTemplateParameter);
                }
            }

            foreach (KeyValuePair <string, string> incompleteParam in incompleteParams)
            {
                // Check if a param with the same name as the incompleteParam already exists
                if (!paramsDb.ContainsKey(incompleteParam.Key))
                {
                    ArmTemplateParameter armParameter = new ArmTemplateParameter
                    {
                        OfferId = offer.Id,
                        Name    = incompleteParam.Key,
                        Type    = incompleteParam.Value,
                        // TODO: do we need to indicate an incomplete parameter?
                        Value = string.Empty
                    };

                    // A param with the same name as the incompleteParam does not exist, so create it
                    await _armTemplateParameterService.CreateAsync(offer.OfferName, armTemplateId, armParameter);
                }

                // Keep track of all the new parameters we are using in usedParamNames
                if (!usedParamNames.Contains(incompleteParam.Key))
                {
                    usedParamNames.Add(incompleteParam.Key);
                }
            }

            foreach (KeyValuePair <string, ArmTemplateParameter> paramDb in paramsDb)
            {
                // Check if there is a param in the db that we are no longer using
                if (!usedParamNames.Contains(paramDb.Key))
                {
                    ArmTemplateArmTemplateParameter armTemplateArmTemplateParameter = await _context.ArmTemplateArmTemplateParameters.FindAsync(armTemplateId, paramDb.Value.Id);

                    // Remove the join entry for any unused params
                    _context.ArmTemplateArmTemplateParameters.Remove(armTemplateArmTemplateParameter);
                    await _context._SaveChangesAsync();
                }
            }
        }
Beispiel #2
0
        public void Constructor_TypeInArmValueTypes_SetPropertiesAsExpected()
        {
            var actual = new ArmTemplateParameter(paramName, paramValue, "bool");
            var expectedReferencePattern = @"parameters\([""']{1}testParam[""']{1}\)";

            Assert.Equal(paramName, actual.Name);
            Assert.Equal(paramValue, actual.Value);
            Assert.Equal("bool", actual.Type);
            Assert.Equal(expectedReferencePattern, actual.ReferencePattern.ToString());
        }
Beispiel #3
0
        /// <summary>
        /// Parse the ARM template to get the parameter names and build an object containing the parameter names and values
        /// </summary>
        /// <param name="offer"></param>
        /// <param name="plan"></param>
        /// <param name="subscriptionAction"></param>
        /// <returns>An object containing the parameter names and values</returns>
        public async Task <Dictionary <string, object> > GetTemplateParameters(
            Offer offer,
            Plan plan,
            FulfillmentAction subscriptionAction
            )
        {
            ArmTemplate template = null;

            switch (subscriptionAction)
            {
            case FulfillmentAction.Activate:
                template = await _lunaClient.GetArmTemplate(offer.OfferName, plan.SubscribeArmTemplateName);

                break;

            case FulfillmentAction.Update:
                template = await _lunaClient.GetArmTemplate(offer.OfferName, plan.SubscribeArmTemplateName);

                break;

            case FulfillmentAction.Unsubscribe:
                template = await _lunaClient.GetArmTemplate(offer.OfferName, plan.UnsubscribeArmTemplateName);

                break;

            default:
                throw new InvalidEnumArgumentException();
            }

            string templateContent = await _storage.DownloadToTextAsync(template.TemplateFilePath);

            var parameters    = ARMTemplateHelper.GetArmTemplateParameters(templateContent);
            var parameterList = new Dictionary <string, object>();

            foreach (var parameter in parameters)
            {
                ArmTemplateParameter atp = await _lunaClient.GetArmTemplateParameter(offer.OfferName, parameter.Key);

                parameterList.Add(
                    atp.Name,
                    new { Value = atp.Value }
                    );
            }
            return(parameterList);
        }
Beispiel #4
0
        /// <summary>
        /// Parses the given JSON object for ArmTemplateParameters then creates them in the db.
        /// The join entry is also created in the armTemplateArmTemplateParameters table.
        /// </summary>
        /// <param name="offer">The name of the offer the parameters belong to.</param>
        /// <param name="armTemplateJSON">The JSON to parse.</param>
        /// <param name="armTemplateId">The ID of the armTemplate.</param>
        /// <returns></returns>
        private async Task CreateArmTemplateParameters(Offer offer, object armTemplateJSON, long armTemplateId)
        {
            var parameters = ARMTemplateHelper.GetArmTemplateParameters(armTemplateJSON.ToString());

            foreach (var param in parameters)
            {
                ArmTemplateParameter armParameter = new ArmTemplateParameter
                {
                    OfferId = offer.Id,
                    Name    = param.Key,
                    Type    = param.Value,
                    // TODO: do we need to indicate an incomplete parameter?
                    Value = string.Empty
                };

                await _armTemplateParameterService.CreateAsync(offer.OfferName, armTemplateId, armParameter);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Creates an armTemplateParameter object within an offer.
        /// </summary>
        /// <param name="offerName">The name of the offer.</param>
        /// <param name="armTemplateId">The id of the armTemplate that the parameter is associated with.</param>
        /// <param name="armTemplateParameter">The armTemplateParameter to create.</param>
        /// <returns>The created armTemplateParameter.</returns>
        public async Task <ArmTemplateParameter> CreateAsync(string offerName, long armTemplateId, ArmTemplateParameter armTemplateParameter)
        {
            if (armTemplateParameter is null)
            {
                throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(ArmTemplateParameter).Name),
                                                      UserErrorCode.PayloadNotProvided);
            }

            if (ExpressionEvaluationUtils.ReservedParameterNames.Contains(armTemplateParameter.Name))
            {
                _logger.LogInformation($"ARM template {armTemplateId} is referencing system parameter {armTemplateParameter.Name}.");
                return(armTemplateParameter);
                //throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage(typeof(ArmTemplateParameter).Name,
                //    armTemplateParameter.Name, offerName: offerName));
            }

            Offer offer = await _offerService.GetAsync(offerName);

            // Check if the ArmTemplateParameter already exists
            if (await ExistsAsync(offerName, armTemplateParameter.Name))
            {
                // Just create a new join entry to keep track of the fact that this ArmTempate is using this parameter
                ArmTemplateParameter armTemplateParameterDb = await GetAsync(offerName, armTemplateParameter.Name);

                await _armTemplateArmTemplateParameterService.CreateJoinEntryAsync(armTemplateId, armTemplateParameterDb.Id);

                return(armTemplateParameterDb);
            }

            armTemplateParameter.OfferId = offer.Id;

            _context.ArmTemplateParameters.Add(armTemplateParameter);
            await _context._SaveChangesAsync();

            await _armTemplateArmTemplateParameterService.CreateJoinEntryAsync(armTemplateId, armTemplateParameter.Id);

            _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(ArmTemplateParameter).Name, armTemplateParameter.Name, offerName: offerName));


            return(armTemplateParameter);
        }
Beispiel #6
0
        /// <summary>
        /// Updates an ArmTemplateParameter within an offer by name.
        /// </summary>
        /// <param name="offerName">The name of the offer.</param>
        /// <param name="parameterName">The name of the ArmTemplateParameter to update.</param>
        /// <param name="armTemplateParameter">The updated ArmTemplateParameter object.</param>
        /// <returns>The updated ArmTemplateParameter object.</returns>
        public async Task <ArmTemplateParameter> UpdateAsync(string offerName, string parameterName, ArmTemplateParameter armTemplateParameter)
        {
            if (armTemplateParameter is null)
            {
                throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(ArmTemplateParameter).Name),
                                                      UserErrorCode.PayloadNotProvided);
            }
            _logger.LogInformation(LoggingUtils.ComposeUpdateResourceMessage(typeof(ArmTemplateParameter).Name, armTemplateParameter.Name, offerName: offerName, payload: JsonSerializer.Serialize(armTemplateParameter)));

            Offer offer = await _offerService.GetAsync(offerName);

            ArmTemplateParameter armTemplateParameterDb = await GetAsync(offerName, parameterName);

            armTemplateParameterDb.Copy(armTemplateParameter);
            armTemplateParameterDb.OfferId = offer.Id;

            _context.ArmTemplateParameters.Update(armTemplateParameterDb);
            await _context._SaveChangesAsync();

            _logger.LogInformation(LoggingUtils.ComposeResourceUpdatedMessage(typeof(ArmTemplateParameter).Name, armTemplateParameter.Name, offerName: offerName));

            return(armTemplateParameterDb);
        }
Beispiel #7
0
        public async Task <ActionResult> UpdateAsync(string offerName, string name, [FromBody] ArmTemplateParameter armTemplateParameter)
        {
            AADAuthHelper.VerifyUserAccess(this.HttpContext, _logger, true);
            if (armTemplateParameter == null)
            {
                throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(ArmTemplateParameter).Name),
                                                      UserErrorCode.PayloadNotProvided);
            }

            if (!name.Equals(armTemplateParameter.Name))
            {
                throw new LunaBadRequestUserException(LoggingUtils.ComposeNameMismatchErrorMessage(typeof(ArmTemplateParameter).Name),
                                                      UserErrorCode.NameMismatch);
            }

            _logger.LogInformation(LoggingUtils.ComposeUpdateResourceMessage(typeof(ArmTemplateParameter).Name,
                                                                             name,
                                                                             JsonSerializer.Serialize(armTemplateParameter)));

            await _armTemplateParameterService.UpdateAsync(offerName, name, armTemplateParameter);

            return(Ok(armTemplateParameter));
        }
Beispiel #8
0
        /// <summary>
        /// Uploads the given armTemplate as a JSON file in blob storage and records the URI to the
        /// created resrouce in the db.
        /// </summary>
        /// <param name="offerName">The name of the offer.</param>
        /// <param name="templateName">The name of the ARM template.</param>
        /// <param name="armTemplateJSON">The ARM Template's raw JSON data.</param>
        /// <returns>The created armTemplate db record.</returns>
        public async Task <ArmTemplate> CreateAsync(string offerName, string templateName, object armTemplateJSON)
        {
            if (armTemplateJSON is null)
            {
                throw new LunaBadRequestUserException(LoggingUtils.ComposePayloadNotProvidedErrorMessage(typeof(ArmTemplate).Name),
                                                      UserErrorCode.PayloadNotProvided);
            }

            // Check that the offer does not already have an armTemplate with the same templateName
            if (await ExistsAsync(offerName, templateName))
            {
                throw new LunaConflictUserException(LoggingUtils.ComposeAlreadyExistsErrorMessage(typeof(ArmTemplate).Name,
                                                                                                  templateName,
                                                                                                  offerName: offerName));
            }

            // Get the offer associated with the offerName provided
            var offer = await _offerService.GetAsync(offerName);

            // Get the container name associated with the offer
            var containerName = offer.ContainerName.ToString();

            // Upload the armTemplateJSON as a file in blob storage and get the URL to the created resource
            var url = await uploadToBlobStorageAsync(containerName, GetArmTemplateFileName(templateName), armTemplateJSON.ToString());

            _logger.LogInformation($"Arm template {templateName} in offer {offerName} is uploaded to {url}.");

            // Create the armTemplate to store in db
            ArmTemplate armTemplate = new ArmTemplate {
                OfferId          = offer.Id,
                TemplateName     = templateName,
                TemplateFilePath = url
            };

            // Add armTemplate to db
            _context.ArmTemplates.Add(armTemplate);
            await _context._SaveChangesAsync();

            _logger.LogInformation(LoggingUtils.ComposeResourceCreatedMessage(typeof(ArmTemplate).Name, templateName, offerName: offerName));

            if (!await _armTemplateParameterService.ExistsAsync(offerName, "resourceGroupLocation"))
            {
                // Add parameter for resourceGroupLocation
                ArmTemplateParameter armParameter = new ArmTemplateParameter
                {
                    OfferId = offer.Id,
                    Name    = "resourceGroupLocation",
                    Type    = "string",
                    // TODO: do we need to indicate an incomplete parameter?
                    Value = string.Empty
                };

                await _armTemplateParameterService.CreateAsync(offerName, armTemplate.Id, armParameter);
            }

            if (!await _armTemplateParameterService.ExistsAsync(offerName, "entryPointUrl"))
            {
                // Add parameter for entryPointLink
                ArmTemplateParameter armParameter = new ArmTemplateParameter
                {
                    OfferId = offer.Id,
                    Name    = "entryPointUrl",
                    Type    = "string",
                    // TODO: do we need to indicate an incomplete parameter?
                    Value = string.Empty
                };

                await _armTemplateParameterService.CreateAsync(offerName, armTemplate.Id, armParameter);
            }

            // Add arm template parameters
            await CreateArmTemplateParameters(offer, armTemplateJSON, armTemplate.Id);

            return(armTemplate);
        }