From 49c1f42c2f746c67054bb4fc788b68691ea031b1 Mon Sep 17 00:00:00 2001 From: Pawel Pabich Date: Mon, 11 Jul 2016 11:18:49 +1000 Subject: [PATCH 1/2] Now we are specific re what we are looking for in the RM templates. It should help us stay healthy even if types of node are added to the template. --- .../Calamari.Azure.Tests.csproj | 6 +- .../ResourceGroupTemplateNormalizerFixture.cs | 57 +++++++++++++++++++ .../ResourceGroupTemplateParserFixture.cs | 45 --------------- source/Calamari.Azure.Tests/app.config | 2 +- source/Calamari.Azure.Tests/packages.config | 2 +- source/Calamari.Azure/Calamari.Azure.csproj | 3 +- .../DeployAzureResourceGroupCommand.cs | 2 +- .../DeployAzureResourceGroupConvention.cs | 18 +++--- .../ResourceGroupTemplateNormalizer.cs | 36 ++++++++++++ .../ResourceGroupTemplateParameter.cs | 10 ---- .../ResourceGroupTemplateParameterParser.cs | 44 -------------- 11 files changed, 108 insertions(+), 117 deletions(-) create mode 100644 source/Calamari.Azure.Tests/ResourceGroups/ResourceGroupTemplateNormalizerFixture.cs delete mode 100644 source/Calamari.Azure.Tests/ResourceGroups/ResourceGroupTemplateParserFixture.cs create mode 100644 source/Calamari.Azure/Deployment/Integration/ResourceGroups/ResourceGroupTemplateNormalizer.cs delete mode 100644 source/Calamari.Azure/Deployment/Integration/ResourceGroups/ResourceGroupTemplateParameter.cs delete mode 100644 source/Calamari.Azure/Deployment/Integration/ResourceGroups/ResourceGroupTemplateParameterParser.cs diff --git a/source/Calamari.Azure.Tests/Calamari.Azure.Tests.csproj b/source/Calamari.Azure.Tests/Calamari.Azure.Tests.csproj index 57073277e..ae68a2db2 100644 --- a/source/Calamari.Azure.Tests/Calamari.Azure.Tests.csproj +++ b/source/Calamari.Azure.Tests/Calamari.Azure.Tests.csproj @@ -63,8 +63,8 @@ ..\packages\Microsoft.WindowsAzure.Management.Compute.6.1.2\lib\net40\Microsoft.WindowsAzure.Management.Compute.dll True - - ..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll + + ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll True @@ -122,7 +122,7 @@ - + diff --git a/source/Calamari.Azure.Tests/ResourceGroups/ResourceGroupTemplateNormalizerFixture.cs b/source/Calamari.Azure.Tests/ResourceGroups/ResourceGroupTemplateNormalizerFixture.cs new file mode 100644 index 000000000..61c6741fc --- /dev/null +++ b/source/Calamari.Azure.Tests/ResourceGroups/ResourceGroupTemplateNormalizerFixture.cs @@ -0,0 +1,57 @@ +using System; +using System.IO; +using Calamari.Azure.Deployment.Integration.ResourceGroups; +using NUnit.Framework; + +namespace Calamari.Azure.Tests.ResourceGroups +{ + [TestFixture] + public class ResourceGroupTemplateNormalizerFixture + { + ResourceGroupTemplateNormalizer subject; + + [SetUp] + public void SetUp() + { + subject = new ResourceGroupTemplateNormalizer(); + } + + [Test] + public void ShouldNormallizeParametersWithEnvelope() + { + var result = subject.Normalize(ReadParametersFile("params_with_envelope.json")); + + Assert.AreEqual(StripWhiteSpace(GetParameter()), StripWhiteSpace(result)); + } + + [Test] + public void ShouldNormallizeParametersSansEnvelope() + { + var result = subject.Normalize(ReadParametersFile("params_sans_envelope.json")); + + Assert.AreEqual(StripWhiteSpace(GetParameter()), StripWhiteSpace(result)); + } + + private string ReadParametersFile(string fileName) + { + var path = GetType().Namespace.Replace("Calamari.Azure.Tests.", String.Empty); + path = path.Replace('.', Path.DirectorySeparatorChar); + return File.ReadAllText(Path.Combine(AzureTestEnvironment.TestWorkingDirectory, path, fileName)); + } + + private string StripWhiteSpace(string input) + { + return input.Replace(" ", string.Empty) + .Replace(Environment.NewLine, string.Empty); + } + + private string GetParameter() + { + return @"{ + 'lifeTheUniverseAndEverything': { + 'value': '42' + } + }".Replace("'", "\""); + } + } +} \ No newline at end of file diff --git a/source/Calamari.Azure.Tests/ResourceGroups/ResourceGroupTemplateParserFixture.cs b/source/Calamari.Azure.Tests/ResourceGroups/ResourceGroupTemplateParserFixture.cs deleted file mode 100644 index 9c5640772..000000000 --- a/source/Calamari.Azure.Tests/ResourceGroups/ResourceGroupTemplateParserFixture.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.IO; -using Calamari.Azure.Deployment.Integration.ResourceGroups; -using NUnit.Framework; - -namespace Calamari.Azure.Tests.ResourceGroups -{ - [TestFixture] - public class ResourceGroupTemplateParserFixture - { - ResourceGroupTemplateParameterParser subject; - - [SetUp] - public void SetUp() - { - subject = new ResourceGroupTemplateParameterParser(); - } - - [Test] - public void CanParseParametersWithEnvelope() - { - var result = subject.ParseParameters(ReadParametersFile("params_with_envelope.json")); - - Assert.AreEqual(1, result.Count); - Assert.AreEqual("42", result["lifeTheUniverseAndEverything"].Value); - } - - [Test] - public void CanParseParametersSansEnvelope() - { - var result = subject.ParseParameters(ReadParametersFile("params_sans_envelope.json")); - - Assert.AreEqual(1, result.Count); - Assert.AreEqual("42", result["lifeTheUniverseAndEverything"].Value); - } - - private string ReadParametersFile(string fileName) - { - var path = GetType().Namespace.Replace("Calamari.Azure.Tests.", String.Empty); - path = path.Replace('.', Path.DirectorySeparatorChar); - return File.ReadAllText(Path.Combine(AzureTestEnvironment.TestWorkingDirectory, path, fileName)); - - } - } -} \ No newline at end of file diff --git a/source/Calamari.Azure.Tests/app.config b/source/Calamari.Azure.Tests/app.config index d937870b0..1fcc8dec6 100644 --- a/source/Calamari.Azure.Tests/app.config +++ b/source/Calamari.Azure.Tests/app.config @@ -32,7 +32,7 @@ - + diff --git a/source/Calamari.Azure.Tests/packages.config b/source/Calamari.Azure.Tests/packages.config index b2bacba79..b92bd1586 100644 --- a/source/Calamari.Azure.Tests/packages.config +++ b/source/Calamari.Azure.Tests/packages.config @@ -9,7 +9,7 @@ - + diff --git a/source/Calamari.Azure/Calamari.Azure.csproj b/source/Calamari.Azure/Calamari.Azure.csproj index b9e6d64b4..e124bc821 100644 --- a/source/Calamari.Azure/Calamari.Azure.csproj +++ b/source/Calamari.Azure/Calamari.Azure.csproj @@ -210,8 +210,7 @@ - - + diff --git a/source/Calamari.Azure/Commands/DeployAzureResourceGroupCommand.cs b/source/Calamari.Azure/Commands/DeployAzureResourceGroupCommand.cs index ba1011828..aa5d473a9 100644 --- a/source/Calamari.Azure/Commands/DeployAzureResourceGroupCommand.cs +++ b/source/Calamari.Azure/Commands/DeployAzureResourceGroupCommand.cs @@ -53,7 +53,7 @@ public override int Execute(string[] commandLineArguments) new ContributeEnvironmentVariablesConvention(), new LogVariablesConvention(), new ExtractPackageToStagingDirectoryConvention(new GenericPackageExtractor(), fileSystem), - new DeployAzureResourceGroupConvention(templateFile, templateParameterFile, filesInPackage, fileSystem, new ResourceGroupTemplateParameterParser()) + new DeployAzureResourceGroupConvention(templateFile, templateParameterFile, filesInPackage, fileSystem, new ResourceGroupTemplateNormalizer()) }; var deployment = new RunningDeployment(packageFile, variables); diff --git a/source/Calamari.Azure/Deployment/Conventions/DeployAzureResourceGroupConvention.cs b/source/Calamari.Azure/Deployment/Conventions/DeployAzureResourceGroupConvention.cs index 3e9a12036..2c9385289 100644 --- a/source/Calamari.Azure/Deployment/Conventions/DeployAzureResourceGroupConvention.cs +++ b/source/Calamari.Azure/Deployment/Conventions/DeployAzureResourceGroupConvention.cs @@ -28,16 +28,16 @@ public class DeployAzureResourceGroupConvention : IInstallConvention readonly string templateParametersFile; private readonly bool filesInPackage; readonly ICalamariFileSystem fileSystem; - readonly IResourceGroupTemplateParameterParser parameterParser; + readonly IResourceGroupTemplateNormalizer parameterNormalizer; public DeployAzureResourceGroupConvention(string templateFile, string templateParametersFile, bool filesInPackage, - ICalamariFileSystem fileSystem, IResourceGroupTemplateParameterParser parameterParser) + ICalamariFileSystem fileSystem, IResourceGroupTemplateNormalizer parameterNormalizer) { this.templateFile = templateFile; this.templateParametersFile = templateParametersFile; this.filesInPackage = filesInPackage; this.fileSystem = fileSystem; - this.parameterParser = parameterParser; + this.parameterNormalizer = parameterNormalizer; } public void Install(RunningDeployment deployment) @@ -55,7 +55,7 @@ public void Install(RunningDeployment deployment) variables[SpecialVariables.Action.Azure.ResourceGroupDeploymentMode]); var template = ResolveAndSubstituteFile(templateFile, filesInPackage, variables); var parameters = !string.IsNullOrWhiteSpace(templateParametersFile) - ? parameterParser.ParseParameters(ResolveAndSubstituteFile(templateParametersFile, filesInPackage, variables)) + ? parameterNormalizer.Normalize(ResolveAndSubstituteFile(templateParametersFile, filesInPackage, variables)) : null; Log.Info( @@ -82,14 +82,12 @@ static string GenerateDeploymentNameFromStepName(string stepName) } static void CreateDeployment(Func createArmClient, string resourceGroupName, string deploymentName, - DeploymentMode deploymentMode, string template, IDictionary parameters) + DeploymentMode deploymentMode, string template, string parameters) { - var parameterJson = parameters != null ? JsonConvert.SerializeObject(parameters, Formatting.Indented) : null; - Log.Verbose($"Template:\n{template}\n"); - if (parameterJson != null) + if (parameters != null) { - Log.Verbose($"Parameters:\n{parameterJson}\n"); + Log.Verbose($"Parameters:\n{parameters}\n"); } using (var armClient = createArmClient()) @@ -101,7 +99,7 @@ static void CreateDeployment(Func createArmClient, st { Mode = deploymentMode, Template = template, - Parameters = parameterJson + Parameters = parameters } }); diff --git a/source/Calamari.Azure/Deployment/Integration/ResourceGroups/ResourceGroupTemplateNormalizer.cs b/source/Calamari.Azure/Deployment/Integration/ResourceGroups/ResourceGroupTemplateNormalizer.cs new file mode 100644 index 000000000..f6b4af52e --- /dev/null +++ b/source/Calamari.Azure/Deployment/Integration/ResourceGroups/ResourceGroupTemplateNormalizer.cs @@ -0,0 +1,36 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Calamari.Azure.Deployment.Integration.ResourceGroups +{ + public interface IResourceGroupTemplateNormalizer + { + string Normalize(string json); + } + + /// + /// There are 2 ways the parameters can be passed to Clamari but the Resource Group Client supports only one format so we need to + /// normalize the input. Have a look at ResourceGroupTemplateNormalizerFixture for more details. + /// + public class ResourceGroupTemplateNormalizer : IResourceGroupTemplateNormalizer + { + public string Normalize(string json) + { + try + { + var envelope = JsonConvert.DeserializeObject(json); + return JsonConvert.SerializeObject(envelope.Parameters); + } + catch (JsonSerializationException) + { + return json; + } + } + + class ParameterEnvelope + { + [JsonProperty("parameters", Required = Required.Always)] + public JObject Parameters { get; set; } + } + } +} \ No newline at end of file diff --git a/source/Calamari.Azure/Deployment/Integration/ResourceGroups/ResourceGroupTemplateParameter.cs b/source/Calamari.Azure/Deployment/Integration/ResourceGroups/ResourceGroupTemplateParameter.cs deleted file mode 100644 index f0b4ee1bd..000000000 --- a/source/Calamari.Azure/Deployment/Integration/ResourceGroups/ResourceGroupTemplateParameter.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace Calamari.Azure.Deployment.Integration -{ - public class ResourceGroupTemplateParameter - { - [JsonProperty("value")] - public object Value { get; set; } - } -} \ No newline at end of file diff --git a/source/Calamari.Azure/Deployment/Integration/ResourceGroups/ResourceGroupTemplateParameterParser.cs b/source/Calamari.Azure/Deployment/Integration/ResourceGroups/ResourceGroupTemplateParameterParser.cs deleted file mode 100644 index c2fc996ba..000000000 --- a/source/Calamari.Azure/Deployment/Integration/ResourceGroups/ResourceGroupTemplateParameterParser.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Calamari.Azure.Deployment.Integration.ResourceGroups -{ - public interface IResourceGroupTemplateParameterParser - { - IDictionary ParseParameters(string json); - } - - public class ResourceGroupTemplateParameterParser : IResourceGroupTemplateParameterParser - { - - public IDictionary ParseParameters(string json) - { - Dictionary parameters; - - try - { - parameters = JsonConvert.DeserializeObject>(json); - } - catch (JsonSerializationException) - { - parameters = - new Dictionary(JsonConvert.DeserializeObject(json).Parameters); - } - - return parameters; - } - - - class ParameterEnvelope - { - [JsonProperty("$schema")] - public string Schema { get; set; } - - [JsonProperty("contentVersion")] - public string ContentVersion { get; set; } - - [JsonProperty("parameters")] - public IDictionary Parameters { get; set; } - } - } -} \ No newline at end of file From 1a7221dfe189ffbc63323bb685c2e729b9666e73 Mon Sep 17 00:00:00 2001 From: Pawel Pabich Date: Mon, 18 Jul 2016 09:33:27 +1000 Subject: [PATCH 2/2] Made the tests a bit more comprehensive --- .../ResourceGroupTemplateNormalizerFixture.cs | 14 +++++++++++--- .../ResourceGroups/params_sans_envelope.json | 14 +++++++++++--- .../ResourceGroups/params_with_envelope.json | 8 ++++++++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/source/Calamari.Azure.Tests/ResourceGroups/ResourceGroupTemplateNormalizerFixture.cs b/source/Calamari.Azure.Tests/ResourceGroups/ResourceGroupTemplateNormalizerFixture.cs index 61c6741fc..caa0d80b5 100644 --- a/source/Calamari.Azure.Tests/ResourceGroups/ResourceGroupTemplateNormalizerFixture.cs +++ b/source/Calamari.Azure.Tests/ResourceGroups/ResourceGroupTemplateNormalizerFixture.cs @@ -48,9 +48,17 @@ private string StripWhiteSpace(string input) private string GetParameter() { return @"{ - 'lifeTheUniverseAndEverything': { - 'value': '42' - } + 'lifeTheUniverseAndEverything': { + 'value': '42' + }, + 'password': { + 'reference': { + 'keyVault': { + 'id': 'id/othervalue/test' + }, + 'secretName': 'secretName' + } + } }".Replace("'", "\""); } } diff --git a/source/Calamari.Azure.Tests/ResourceGroups/params_sans_envelope.json b/source/Calamari.Azure.Tests/ResourceGroups/params_sans_envelope.json index 478e30f90..f9f7b9d36 100644 --- a/source/Calamari.Azure.Tests/ResourceGroups/params_sans_envelope.json +++ b/source/Calamari.Azure.Tests/ResourceGroups/params_sans_envelope.json @@ -1,5 +1,13 @@ { - "lifeTheUniverseAndEverything": { - "value": "42" - } + "lifeTheUniverseAndEverything": { + "value": "42" + }, + "password": { + "reference": { + "keyVault": { + "id": "id/othervalue/test" + }, + "secretName": "secretName" + } + } } \ No newline at end of file diff --git a/source/Calamari.Azure.Tests/ResourceGroups/params_with_envelope.json b/source/Calamari.Azure.Tests/ResourceGroups/params_with_envelope.json index 52723c548..f22b0ba83 100644 --- a/source/Calamari.Azure.Tests/ResourceGroups/params_with_envelope.json +++ b/source/Calamari.Azure.Tests/ResourceGroups/params_with_envelope.json @@ -4,6 +4,14 @@ "parameters": { "lifeTheUniverseAndEverything": { "value": "42" + }, + "password": { + "reference": { + "keyVault": { + "id": "id/othervalue/test" + }, + "secretName": "secretName" + } } } } \ No newline at end of file