public Template CreateBackendTemplate(CreatorConfig creatorConfig)
        {
            // create empty template
            Template backendTemplate = CreateEmptyTemplate();

            // add parameters
            backendTemplate.parameters = new Dictionary <string, TemplateParameterProperties>
            {
                { ParameterNames.ApimServiceName, new TemplateParameterProperties()
                  {
                      type = "string"
                  } }
            };

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

            foreach (BackendTemplateProperties backendTemplatePropeties in creatorConfig.backends)
            {
                // create backend resource with properties
                BackendTemplateResource backendTemplateResource = new BackendTemplateResource()
                {
                    name       = $"[concat(parameters('{ParameterNames.ApimServiceName}'), '/{backendTemplatePropeties.title}')]",
                    type       = ResourceTypeConstants.Backend,
                    apiVersion = GlobalConstants.APIVersion,
                    properties = backendTemplatePropeties,
                    dependsOn  = new string[] { }
                };
                resources.Add(backendTemplateResource);
            }

            backendTemplate.resources = resources.ToArray();
            return(backendTemplate);
        }
Exemple #2
0
        public async Task <Template> GenerateBackendsARMTemplateAsync(string apimname, string resourceGroup, string singleApiName, List <TemplateResource> apiTemplateResources, List <TemplateResource> propertyResources, string policyXMLBaseUrl, string policyXMLSasToken)
        {
            Console.WriteLine("------------------------------------------");
            Console.WriteLine("Extracting backends from service");
            Template armTemplate = GenerateEmptyTemplateWithParameters(policyXMLBaseUrl, policyXMLSasToken);

            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
            string backends = await GetBackendsAsync(apimname, resourceGroup);

            JObject 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;

                ////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
                //    Console.WriteLine("'{0}' Backend found", backendName);
                //    templateResources.Add(backendTemplateResource);
                //}
                //else
                //{
                //    bool isReferencedInPolicy = false;
                //    foreach (PolicyTemplateResource policyTemplateResource in policyResources)
                //    {
                //        // the backend is used in a policy if the xml contains a set-backend-service policy, which will reference the backend's url or id
                //        string policyContent = policyTemplateResource.properties.policyContent;
                //        isReferencedInPolicy = DoesPolicyReferenceBackend(policyContent, namedValueResources,  backendName, backendTemplateResource);
                //    }
                //    if (isReferencedInPolicy == true)
                //    {
                //        // backend was used in policy, extract it
                //        Console.WriteLine("'{0}' Backend found", backendName);
                //        templateResources.Add(backendTemplateResource);
                //    }
                //}

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

            armTemplate.resources = templateResources.ToArray();
            return(armTemplate);
        }
        public Template CreateBackendTemplate(CreatorConfig creatorConfig)
        {
            // create empty template
            Template backendTemplate = CreateEmptyTemplate();

            // add parameters
            backendTemplate.parameters = new Dictionary <string, TemplateParameterProperties>
            {
                { ParameterNames.ApimServiceName, new TemplateParameterProperties()
                  {
                      type = "string"
                  } }
            };

            List <TemplateResource> resources        = new List <TemplateResource>();
            StringBuilder           serviceParameter = new StringBuilder();

            foreach (BackendTemplateProperties backendTemplatePropeties in creatorConfig.backends)
            {
                if (serviceParameter.Length == 0)
                {
                    serviceParameter.Append("{");
                }
                else
                {
                    serviceParameter.Append(",");
                }
                serviceParameter.Append(string.Concat("\"", GetSanitisedName(backendTemplatePropeties.title), "\": \"", backendTemplatePropeties.url, "\""));

                // create backend resource with properties
                BackendTemplateResource backendTemplateResource = new BackendTemplateResource()
                {
                    name       = $"[concat(parameters('{ParameterNames.ApimServiceName}'), '/{backendTemplatePropeties.title}')]",
                    type       = ResourceTypeConstants.Backend,
                    apiVersion = GlobalConstants.APIVersion,
                    properties = backendTemplatePropeties,
                    dependsOn  = new string[] { }
                };
                backendTemplateResource.properties.url = $"[parameters('{ParameterNames.ServiceUrl}').{GetSanitisedName(backendTemplatePropeties.title)}]";
                resources.Add(backendTemplateResource);
            }

            serviceParameter.Append("}");
            backendTemplate.parameters.Add(ParameterNames.ServiceUrl, new TemplateParameterProperties()
            {
                type = "object", defaultValue = serviceParameter.ToString()
            });

            backendTemplate.resources = resources.ToArray();
            return(backendTemplate);
        }
Exemple #4
0
        bool DoesPolicyReferenceBackend(
            string policyContent,
            IEnumerable <NamedValueTemplateResource> namedValueResources,
            string backendName,
            BackendTemplateResource backendTemplateResource)
        {
            // a policy is referenced by a backend with the set-backend-service policy, which will reference use the backends name or url, or through referencing a named value that applies to the backend
            var namedValueResourcesUsedByBackend = namedValueResources.Where(resource => this.DoesBackendReferenceNamedValue(resource, backendTemplateResource));

            if (backendName != null && policyContent.Contains(backendName) ||
                backendTemplateResource.Properties.Url != null && policyContent.Contains(backendTemplateResource.Properties.Url) ||
                backendTemplateResource.Properties.Title != null && policyContent.Contains(backendTemplateResource.Properties.Title) ||
                backendTemplateResource.Properties.ResourceId != null && policyContent.Contains(backendTemplateResource.Properties.ResourceId))
            {
                return(true);
            }

            return(namedValueResourcesUsedByBackend.Any(x =>
                                                        (x.Properties.DisplayName is not null && policyContent.Contains(x.Properties.DisplayName)) ||
                                                        (x.Properties.Value is not null && policyContent.Contains(x.Properties.Value))));
        }
Exemple #5
0
        public async Task <Template> Create(DeploymentDefinition creatorConfig)
        {
            var template = EmptyTemplate;

            template.Parameters.Add(ApiServiceNameParameter.Key, ApiServiceNameParameter.Value);

            var resources = new List <TemplateResource>();

            foreach (var backendTemplatePropeties in creatorConfig.Backends)
            {
                var backendTemplateResource = new BackendTemplateResource()
                {
                    Name       = $"[concat(parameters('ApimServiceName'), '/{backendTemplatePropeties.Title}')]",
                    Properties = backendTemplatePropeties,
                    DependsOn  = new string[] { }
                };
                resources.Add(backendTemplateResource);
            }

            template.Resources = resources.ToArray();
            return(await Task.FromResult(template));
        }
Exemple #6
0
        public bool DoesPolicyReferenceBackend(string policyContent, IEnumerable <TemplateResource> namedValueResources, string backendName, BackendTemplateResource backendTemplateResource)
        {
            // a policy is referenced by a backend with the set-backend-service policy, which will reference use the backends name or url, or through referencing a named value that applies to the backend
            var namedValueResourcesUsedByBackend = namedValueResources.Where(resource => DoesBackendReferenceNamedValue(resource, backendTemplateResource));

            if ((backendName != null && policyContent.Contains(backendName)) ||
                (backendTemplateResource.properties.url != null && policyContent.Contains(backendTemplateResource.properties.url)) ||
                (backendTemplateResource.properties.title != null && policyContent.Contains(backendTemplateResource.properties.title)) ||
                (backendTemplateResource.properties.resourceId != null && policyContent.Contains(backendTemplateResource.properties.resourceId)))
            {
                return(true);
            }
            foreach (PropertyTemplateResource namedValueResource in namedValueResourcesUsedByBackend)
            {
                if (policyContent.Contains(namedValueResource.properties.displayName) || policyContent.Contains(namedValueResource.properties.value))
                {
                    return(true);
                }
            }
            return(false);
        }
Exemple #7
0
        public bool DoesBackendReferenceNamedValue(TemplateResource namedValueResource, BackendTemplateResource backendTemplateResource)
        {
            string namedValue = (namedValueResource as PropertyTemplateResource).properties.value;

            return(namedValue == backendTemplateResource.properties.url ||
                   namedValue == backendTemplateResource.properties.description ||
                   namedValue == backendTemplateResource.properties.title);
        }
Exemple #8
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, ExtractorParameters extractorParameters)
        {
            Console.WriteLine("------------------------------------------");
            Console.WriteLine("Extracting backends from service");
            Template armTemplate = this.templateBuilder.GenerateTemplateWithApimServiceNameProperty().Build();

            if (extractorParameters.ParameterizeBackend)
            {
                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 this.GetBackendsAsync(apimname, resourceGroup, skipNumberOfBackends);

                oBackends = JObject.Parse(backends);

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

                    // convert returned backend to template resource class
                    BackendTemplateResource backendTemplateResource = backend.Deserialize <BackendTemplateResource>();
                    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 = PolicyTemplateUtils.GetPolicyContent(extractorParameters, policyTemplateResource);

                            if (this.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 (extractorParameters.ParameterizeBackend)
                        {
                            var    apiToken          = new BackendApiParameters();
                            string validApiParamName = ParameterNamingHelper.GenerateValidParameterName(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 #9
0
        public async Task <bool> IsNamedValueUsedInBackends(string apimname, string resourceGroup, string singleApiName, List <TemplateResource> apiTemplateResources, ExtractorParameters extractorParameters, 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 this.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 this.GetBackendDetailsAsync(apimname, resourceGroup, backendName);

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

                            // 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 = PolicyTemplateUtils.GetPolicyContent(extractorParameters, policyTemplateResource);

                                if (this.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);
        }
Exemple #10
0
        public void ShouldCreateBackendTemplateFromCreatorConfig()
        {
            // arrange
            BackendTemplateCreator backendTemplateCreator = new BackendTemplateCreator(new TemplateBuilder());
            CreatorConfig          creatorConfig          = new CreatorConfig()
            {
                backends = new List <BackendTemplateProperties>()
            };
            BackendTemplateProperties backend = new BackendTemplateProperties()
            {
                title       = "title",
                description = "description",
                resourceId  = "resourceId",
                url         = "url",
                protocol    = "protocol",
                proxy       = new BackendProxy()
                {
                    url      = "url",
                    username = "******",
                    password = "******"
                },
                tls = new BackendTLS()
                {
                    validateCertificateChain = true,
                    validateCertificateName  = true
                },
                credentials = new BackendCredentials()
                {
                    certificate   = new string[] { "cert1" },
                    query         = new object(),
                    header        = new object(),
                    authorization = new BackendCredentialsAuthorization()
                    {
                        scheme    = "scheme",
                        parameter = "parameter"
                    }
                },
                properties = new BackendSubProperties()
                {
                    serviceFabricCluster = new BackendServiceFabricCluster()
                    {
                        clientCertificatethumbprint   = "",
                        managementEndpoints           = new string[] { "endpoint" },
                        maxPartitionResolutionRetries = 1,
                        serverCertificateThumbprints  = new string[] { "thumbprint" },
                        serverX509Names = new ServerX509Names[] {
                            new ServerX509Names()
                            {
                                name = "name",
                                issuerCertificateThumbprint = "thumbprint"
                            }
                        }
                    }
                }
            };

            creatorConfig.backends.Add(backend);

            // act
            Template backendTemplate = backendTemplateCreator.CreateBackendTemplate(creatorConfig);
            BackendTemplateResource backendTemplateResource = (BackendTemplateResource)backendTemplate.Resources[0];

            // assert
            Assert.Equal($"[concat(parameters('{ParameterNames.ApimServiceName}'), '/{backend.title}')]", backendTemplateResource.Name);
            Assert.Equal(backend.title, backendTemplateResource.Properties.title);
            Assert.Equal(backend.description, backendTemplateResource.Properties.description);
            Assert.Equal(backend.resourceId, backendTemplateResource.Properties.resourceId);
            Assert.Equal(backend.url, backendTemplateResource.Properties.url);
            Assert.Equal(backend.protocol, backendTemplateResource.Properties.protocol);
            Assert.Equal(backend.proxy.url, backendTemplateResource.Properties.proxy.url);
            Assert.Equal(backend.proxy.username, backendTemplateResource.Properties.proxy.username);
            Assert.Equal(backend.proxy.password, backendTemplateResource.Properties.proxy.password);
            Assert.Equal(backend.tls.validateCertificateChain, backendTemplateResource.Properties.tls.validateCertificateChain);
            Assert.Equal(backend.tls.validateCertificateName, backendTemplateResource.Properties.tls.validateCertificateName);
            Assert.Equal(backend.credentials.certificate, backendTemplateResource.Properties.credentials.certificate);
            Assert.Equal(backend.credentials.query, backendTemplateResource.Properties.credentials.query);
            Assert.Equal(backend.credentials.header, backendTemplateResource.Properties.credentials.header);
            Assert.Equal(backend.credentials.authorization.scheme, backendTemplateResource.Properties.credentials.authorization.scheme);
            Assert.Equal(backend.credentials.authorization.parameter, backendTemplateResource.Properties.credentials.authorization.parameter);
            Assert.Equal(backend.properties.serviceFabricCluster.clientCertificatethumbprint, backendTemplateResource.Properties.properties.serviceFabricCluster.clientCertificatethumbprint);
            Assert.Equal(backend.properties.serviceFabricCluster.managementEndpoints, backendTemplateResource.Properties.properties.serviceFabricCluster.managementEndpoints);
            Assert.Equal(backend.properties.serviceFabricCluster.maxPartitionResolutionRetries, backendTemplateResource.Properties.properties.serviceFabricCluster.maxPartitionResolutionRetries);
            Assert.Equal(backend.properties.serviceFabricCluster.serverCertificateThumbprints, backendTemplateResource.Properties.properties.serviceFabricCluster.serverCertificateThumbprints);
            Assert.Equal(backend.properties.serviceFabricCluster.serverX509Names[0].issuerCertificateThumbprint, backendTemplateResource.Properties.properties.serviceFabricCluster.serverX509Names[0].issuerCertificateThumbprint);
            Assert.Equal(backend.properties.serviceFabricCluster.serverX509Names[0].name, backendTemplateResource.Properties.properties.serviceFabricCluster.serverX509Names[0].name);
        }
Exemple #11
0
        public bool DoesBackendReferenceNamedValue(NamedValueTemplateResource namedValueResource, BackendTemplateResource backendTemplateResource)
        {
            var namedValue = namedValueResource.Properties.Value;

            return(namedValue == backendTemplateResource.Properties.Url ||
                   namedValue == backendTemplateResource.Properties.Description ||
                   namedValue == backendTemplateResource.Properties.Title);
        }
        public void ShouldCreateBackendTemplateFromCreatorConfig()
        {
            // arrange
            BackendTemplateCreator backendTemplateCreator = new BackendTemplateCreator(new TemplateBuilder());
            CreatorConfig          creatorConfig          = new CreatorConfig()
            {
                backends = new List <BackendTemplateProperties>()
            };
            BackendTemplateProperties backend = new BackendTemplateProperties()
            {
                Title       = "title",
                Description = "description",
                ResourceId  = "resourceId",
                Url         = "url",
                Protocol    = "protocol",
                Proxy       = new BackendProxy()
                {
                    Url      = "url",
                    Username = "******",
                    Password = "******"
                },
                Tls = new BackendTls()
                {
                    ValidateCertificateChain = true,
                    ValidateCertificateName  = true
                },
                Credentials = new BackendCredentials()
                {
                    Certificate   = new string[] { "cert1" },
                    Query         = new object(),
                    Header        = new object(),
                    Authorization = new BackendCredentialsAuthorization()
                    {
                        Scheme    = "scheme",
                        Parameter = "parameter"
                    }
                },
                Properties = new BackendServiceFabricProperties()
                {
                    ServiceFabricCluster = new BackendServiceFabricCluster()
                    {
                        ClientCertificatethumbprint   = "",
                        ManagementEndpoints           = new string[] { "endpoint" },
                        MaxPartitionResolutionRetries = 1,
                        ServerCertificateThumbprints  = new string[] { "thumbprint" },
                        ServerX509Names = new ServerX509Names[] {
                            new ServerX509Names()
                            {
                                Name = "name",
                                IssuerCertificateThumbprint = "thumbprint"
                            }
                        }
                    }
                }
            };

            creatorConfig.backends.Add(backend);

            // act
            Template backendTemplate = backendTemplateCreator.CreateBackendTemplate(creatorConfig);
            BackendTemplateResource backendTemplateResource = (BackendTemplateResource)backendTemplate.Resources[0];

            // assert
            Assert.Equal($"[concat(parameters('{ParameterNames.ApimServiceName}'), '/{backend.Title}')]", backendTemplateResource.Name);
            Assert.Equal(backend.Title, backendTemplateResource.Properties.Title);
            Assert.Equal(backend.Description, backendTemplateResource.Properties.Description);
            Assert.Equal(backend.ResourceId, backendTemplateResource.Properties.ResourceId);
            Assert.Equal(backend.Url, backendTemplateResource.Properties.Url);
            Assert.Equal(backend.Protocol, backendTemplateResource.Properties.Protocol);
            Assert.Equal(backend.Proxy.Url, backendTemplateResource.Properties.Proxy.Url);
            Assert.Equal(backend.Proxy.Username, backendTemplateResource.Properties.Proxy.Username);
            Assert.Equal(backend.Proxy.Password, backendTemplateResource.Properties.Proxy.Password);
            Assert.Equal(backend.Tls.ValidateCertificateChain, backendTemplateResource.Properties.Tls.ValidateCertificateChain);
            Assert.Equal(backend.Tls.ValidateCertificateName, backendTemplateResource.Properties.Tls.ValidateCertificateName);
            Assert.Equal(backend.Credentials.Certificate, backendTemplateResource.Properties.Credentials.Certificate);
            Assert.Equal(backend.Credentials.Query, backendTemplateResource.Properties.Credentials.Query);
            Assert.Equal(backend.Credentials.Header, backendTemplateResource.Properties.Credentials.Header);
            Assert.Equal(backend.Credentials.Authorization.Scheme, backendTemplateResource.Properties.Credentials.Authorization.Scheme);
            Assert.Equal(backend.Credentials.Authorization.Parameter, backendTemplateResource.Properties.Credentials.Authorization.Parameter);
            Assert.Equal(backend.Properties.ServiceFabricCluster.ClientCertificatethumbprint, backendTemplateResource.Properties.Properties.ServiceFabricCluster.ClientCertificatethumbprint);
            Assert.Equal(backend.Properties.ServiceFabricCluster.ManagementEndpoints, backendTemplateResource.Properties.Properties.ServiceFabricCluster.ManagementEndpoints);
            Assert.Equal(backend.Properties.ServiceFabricCluster.MaxPartitionResolutionRetries, backendTemplateResource.Properties.Properties.ServiceFabricCluster.MaxPartitionResolutionRetries);
            Assert.Equal(backend.Properties.ServiceFabricCluster.ServerCertificateThumbprints, backendTemplateResource.Properties.Properties.ServiceFabricCluster.ServerCertificateThumbprints);
            Assert.Equal(backend.Properties.ServiceFabricCluster.ServerX509Names[0].IssuerCertificateThumbprint, backendTemplateResource.Properties.Properties.ServiceFabricCluster.ServerX509Names[0].IssuerCertificateThumbprint);
            Assert.Equal(backend.Properties.ServiceFabricCluster.ServerX509Names[0].Name, backendTemplateResource.Properties.Properties.ServiceFabricCluster.ServerX509Names[0].Name);
        }