private bool DoesPolicyReferenceNamedValue(Extractor exc, IEnumerable <TemplateResource> policyResources, string propertyName, PropertyTemplateResource propertyTemplateResource)
        {
            // check if named value is referenced in a policy file
            foreach (PolicyTemplateResource policyTemplateResource in policyResources)
            {
                string policyContent = ExtractorUtils.GetPolicyContent(exc, policyTemplateResource);

                if (policyContent.Contains(string.Concat("{{", propertyTemplateResource.properties.displayName, "}}")) || policyContent.Contains(string.Concat("{{", propertyName, "}}")))
                {
                    // dont need to go through all policies if the named value has already been found
                    return(true);
                }
            }
            return(false);
        }
Exemple #2
0
        /// <summary>
        /// Generate the ARM assets for the backend resources
        /// </summary>
        /// <param name="apimname"></param>
        /// <param name="resourceGroup"></param>
        /// <param name="singleApiName"></param>
        /// <param name="apiTemplateResources"></param>
        /// <param name="propertyResources"></param>
        /// <param name="policyXMLBaseUrl"></param>
        /// <param name="policyXMLSasToken"></param>
        /// <param name="extractBackendParameters"></param>
        /// <returns>a combination of a Template and the value for the BackendSettings parameter</returns>
        public async Task <Tuple <Template, Dictionary <string, BackendApiParameters> > > GenerateBackendsARMTemplateAsync(string apimname, string resourceGroup, string singleApiName, List <TemplateResource> apiTemplateResources, List <TemplateResource> propertyResources, Extractor exc)
        {
            Console.WriteLine("------------------------------------------");
            Console.WriteLine("Extracting backends from service");
            Template armTemplate = GenerateEmptyPropertyTemplateWithParameters();

            if (exc.paramBackend)
            {
                TemplateParameterProperties extractBackendParametersProperties = new TemplateParameterProperties()
                {
                    type = "object"
                };
                armTemplate.parameters.Add(ParameterNames.BackendSettings, extractBackendParametersProperties);
            }

            List <TemplateResource> templateResources = new List <TemplateResource>();

            // isolate api and operation policy resources in the case of a single api extraction, as they may reference backends
            var policyResources     = apiTemplateResources.Where(resource => (resource.type == ResourceTypeConstants.APIPolicy || resource.type == ResourceTypeConstants.APIOperationPolicy || resource.type == ResourceTypeConstants.ProductPolicy));
            var namedValueResources = propertyResources.Where(resource => (resource.type == ResourceTypeConstants.Property));

            // pull all backends for service
            JObject oBackends            = new JObject();
            var     oBackendParameters   = new Dictionary <string, BackendApiParameters>();
            int     skipNumberOfBackends = 0;

            do
            {
                string backends = await GetBackendsAsync(apimname, resourceGroup, skipNumberOfBackends);

                oBackends = JObject.Parse(backends);

                foreach (var item in oBackends["value"])
                {
                    string backendName = ((JValue)item["name"]).Value.ToString();
                    string backend     = await GetBackendDetailsAsync(apimname, resourceGroup, backendName);

                    // convert returned backend to template resource class
                    BackendTemplateResource backendTemplateResource = JsonConvert.DeserializeObject <BackendTemplateResource>(backend);
                    backendTemplateResource.name       = $"[concat(parameters('{ParameterNames.ApimServiceName}'), '/{backendName}')]";
                    backendTemplateResource.apiVersion = GlobalConstants.APIVersion;

                    bool includeBackend = false;
                    ////only extract the backend if this is a full extraction, or in the case of a single api, if it is referenced by one of the policies
                    if (singleApiName == null)
                    {
                        // if the user is extracting all apis, extract all the backends
                        includeBackend = true;
                    }
                    else
                    {
                        // check extracted policies to see if the backend is referenced.
                        foreach (PolicyTemplateResource policyTemplateResource in policyResources)
                        {
                            string policyContent = ExtractorUtils.GetPolicyContent(exc, policyTemplateResource);

                            if (DoesPolicyReferenceBackend(policyContent, namedValueResources, backendName, backendTemplateResource))
                            {
                                // backend was used in policy, extract it
                                includeBackend = true;

                                // dont need to go through all policies if the back end has already been found
                                break;
                            }
                        }
                    }

                    if (includeBackend)
                    {
                        if (exc.paramBackend)
                        {
                            var    apiToken          = new BackendApiParameters();
                            string validApiParamName = ExtractorUtils.GenValidParamName(backendName, ParameterPrefix.Diagnostic).ToLower();

                            if (!string.IsNullOrEmpty(backendTemplateResource.properties.resourceId))
                            {
                                apiToken.resourceId = backendTemplateResource.properties.resourceId;
                                backendTemplateResource.properties.resourceId = $"[parameters('{ParameterNames.BackendSettings}').{validApiParamName}.resourceId]";
                            }

                            if (!string.IsNullOrEmpty(backendTemplateResource.properties.url))
                            {
                                apiToken.url = backendTemplateResource.properties.url;
                                backendTemplateResource.properties.url = $"[parameters('{ParameterNames.BackendSettings}').{validApiParamName}.url]";
                            }

                            if (!string.IsNullOrEmpty(backendTemplateResource.properties.protocol))
                            {
                                apiToken.protocol = backendTemplateResource.properties.protocol;
                                backendTemplateResource.properties.protocol = $"[parameters('{ParameterNames.BackendSettings}').{validApiParamName}.protocol]";
                            }
                            oBackendParameters.Add(validApiParamName, apiToken);
                        }

                        Console.WriteLine("'{0}' Backend found", backendName);
                        templateResources.Add(backendTemplateResource);
                    }
                }

                skipNumberOfBackends += GlobalConstants.NumOfRecords;
            }while (oBackends["nextLink"] != null);

            armTemplate.resources = templateResources.ToArray();
            return(new Tuple <Template, Dictionary <string, BackendApiParameters> >(armTemplate, oBackendParameters));
        }
Exemple #3
0
        public async Task <bool> IsNamedValueUsedInBackends(string apimname, string resourceGroup, string singleApiName, List <TemplateResource> apiTemplateResources, Extractor exc, string propertyName, string propertyDisplayName)
        {
            // isolate api and operation policy resources in the case of a single api extraction, as they may reference backends
            var policyResources          = apiTemplateResources.Where(resource => (resource.type == ResourceTypeConstants.APIPolicy || resource.type == ResourceTypeConstants.APIOperationPolicy || resource.type == ResourceTypeConstants.ProductPolicy));
            var emptyNamedValueResources = new List <TemplateResource>();

            // pull all backends for service
            JObject oBackends            = new JObject();
            int     skipNumberOfBackends = 0;

            do
            {
                string backends = await GetBackendsAsync(apimname, resourceGroup, skipNumberOfBackends);

                oBackends = JObject.Parse(backends);

                foreach (var item in oBackends["value"])
                {
                    var content = item.ToString();

                    // check if backend references the named value, credentials for example
                    if (content.Contains(string.Concat("{{", propertyName, "}}")) || content.Contains(string.Concat("{{", propertyDisplayName, "}}")))
                    {
                        //only true if this is a full extraction, or in the case of a single api, if it is referenced by one of the API policies
                        if (singleApiName == null)
                        {
                            return(true);
                        }
                        else
                        {
                            // is this backend related to the single api?
                            // is backend used in the extracted policies for this API
                            // if backend id is referenced in policy
                            // or a named value is referenced in policy to a backend, we have already checked the policy for named value.

                            // check if this backend is used by any of the policies extracted
                            string backendName = ((JValue)item["name"]).Value.ToString();
                            string backend     = await GetBackendDetailsAsync(apimname, resourceGroup, backendName);

                            // convert returned backend to template resource class
                            BackendTemplateResource backendTemplateResource = JsonConvert.DeserializeObject <BackendTemplateResource>(backend);

                            // we have already checked if the named value is used in a policy, we just need to confirm if the backend is referenced by this single api within the policy file
                            // this is why an empty named values must be passed to this method for validation
                            foreach (PolicyTemplateResource policyTemplateResource in policyResources)
                            {
                                string policyContent = ExtractorUtils.GetPolicyContent(exc, policyTemplateResource);

                                if (DoesPolicyReferenceBackend(policyContent, emptyNamedValueResources, backendName, backendTemplateResource))
                                {
                                    // dont need to go through all policies and backends if the named values has already been found
                                    return(true);
                                }
                            }
                        }
                    }
                }

                skipNumberOfBackends += GlobalConstants.NumOfRecords;
            }while (oBackends["nextLink"] != null);

            return(false);
        }