public void ParseAndValidateTemplate_ValidTemplateWithCopyIndex_ProcessResourceCopies()
        {
            string templateJson = @"{
                ""$schema"": ""https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"",
                ""contentVersion"": ""1.0.0.0"",
                ""parameters"": { },
                ""variables"": { },
                ""resources"": [
                    {
                        ""apiVersion"": ""2016-03-30"",
                        ""copy"": {
                            ""count"": 2,
                            ""name"": ""masterLbLoopNode""
                        },
                        ""location"": ""westus2"",
                        ""name"": ""[concat('name', '/', 'SSH-', 'VMNamePrefix-', copyIndex())]"",
                        ""properties"": {
                            ""backendPort"": 22,
                            ""enableFloatingIP"": false,
                            ""frontendIPConfiguration"": {
                                ""id"": ""Microsoft.Network/loadBalancers/loadBalancer/frontendIPConfigurations/config""
                            },
                            ""frontendPort"": ""[copyIndex(2200)]"",
                            ""protocol"": ""Tcp""
                        },
                        ""type"": ""Microsoft.Network/loadBalancers/inboundNatRules""
                    }
                ],
                ""outputs"": {}
            }";

            ArmTemplateProcessor armTemplateProcessor = new ArmTemplateProcessor(templateJson);

            var parameters = new InsensitiveDictionary <JToken>();

            var metadata = new InsensitiveDictionary <JToken>
            {
                { "subscription", new JObject(
                      new JProperty("id", "/subscriptions/00000000-0000-0000-0000-000000000000"),
                      new JProperty("subscriptionId", "00000000-0000-0000-0000-000000000000"),
                      new JProperty("tenantId", "00000000-0000-0000-0000-000000000000")) },
                { "resourceGroup", new JObject(
                      new JProperty("id", "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourceGroupName"),
                      new JProperty("location", "westus2"),
                      new JProperty("name", "resource-group")) },
                { "tenantId", "00000000-0000-0000-0000-000000000000" }
            };

            Template template = armTemplateProcessor.ParseAndValidateTemplate(parameters, metadata);

            Assert.AreEqual(2, template.Resources.Length);

            Assert.AreEqual("name/SSH-VMNamePrefix-0", template.Resources.First().Name.Value);
            Assert.AreEqual("[concat('name', '/', 'SSH-', 'VMNamePrefix-', copyIndex())]", template.Resources.First().OriginalName);
            Assert.AreEqual(2200, template.Resources.First().Properties.Value.InsensitiveToken("frontendPort").Value <int>());

            Assert.AreEqual("name/SSH-VMNamePrefix-1", template.Resources.Last().Name.Value);
            Assert.AreEqual("[concat('name', '/', 'SSH-', 'VMNamePrefix-', copyIndex())]", template.Resources.Last().OriginalName);
            Assert.AreEqual(2201, template.Resources.Last().Properties.Value.InsensitiveToken("frontendPort").Value <int>());
        }
        /// <summary>
        /// Runs the TemplateAnalyzer logic given the template and parameters passed to it
        /// </summary>
        /// <returns>An enumerable of TemplateAnalyzer results</returns>
        public IEnumerable <IResult> EvaluateRulesAgainstTemplate()
        {
            JToken templatejObject;

            try
            {
                ArmTemplateProcessor armTemplateProcessor = new ArmTemplateProcessor(Template);
                templatejObject = armTemplateProcessor.ProcessTemplate(Parameters);
            }
            catch (Exception e)
            {
                throw new TemplateAnalyzerException("Error while processing template.", e);
            }

            if (templatejObject == null)
            {
                throw new TemplateAnalyzerException("Processed Template cannot be null.");
            }

            try
            {
                var rules          = LoadRules();
                var jsonRuleEngine = new JsonEngine.JsonRuleEngine();

                IEnumerable <IResult> results = jsonRuleEngine.EvaluateRules(new TemplateContext {
                    OriginalTemplate = JObject.Parse(Template), ExpandedTemplate = templatejObject, IsMainTemplate = true
                }, rules);

                return(results);
            }
            catch (Exception e)
            {
                throw new TemplateAnalyzerException("Error while evaluating rules.", e);
            }
        }
 public static void ClassInit(TestContext testContext)
 {
     _armTemplateProcessor = new ArmTemplateProcessor(@"{
         ""$schema"": ""https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"",
         ""contentVersion"": ""1.0.0.0"",
         ""parameters"": { },
         ""variables"": { },
         ""resources"": [
             {
                 ""apiVersion"": ""2020-05-01"",
                 ""type"": ""Microsoft.Network/publicIPAddresses"",
                 ""name"": ""publicIPAddress"",
                 ""location"": ""westus"",
                 ""tags"": {},
                 ""properties"": {
                     ""publicIPAllocationMethod"": ""Dynamic"",
                     ""dnsSettings"": {
                         ""domainNameLabel"": ""[concat('linux-vm-', uniqueString(resourceGroup().id))]""
                     }
                 }
             }
         ],
         ""outputs"": {}
     }");
 }