diff --git a/MicroserviceTemplate/tools/EnvironmentInitializer/Helper.cs b/MicroserviceTemplate/tools/EnvironmentInitializer/Helper.cs index b3f0879..6670e38 100644 --- a/MicroserviceTemplate/tools/EnvironmentInitializer/Helper.cs +++ b/MicroserviceTemplate/tools/EnvironmentInitializer/Helper.cs @@ -7,54 +7,82 @@ namespace EnvironmentInitializer { public static class Helper { - public static string RunCmdCommand(string command, string? directory = null, bool waitForExit = true) + public static void UpdateTargetPropertyJson(string targetJson, string newKmsKeyId, string newKmsPublicKey) { - try + var targetConfiguration = File.ReadAllText(targetJson); + JsonNode? jsonNode = JsonSerializer.Deserialize(targetConfiguration); + jsonNode!["ModuleConfiguration"]!["Infrastructure"]!["Kms"]!["SigningKeyId"] = newKmsKeyId; + jsonNode!["ModuleConfiguration"]!["Infrastructure"]!["Kms"]!["PublicKey"] = newKmsPublicKey; + File.WriteAllText(targetJson, JsonSerializer.Serialize(jsonNode, new JsonSerializerOptions() { WriteIndented = true })); + } + + public static void UpdateTargetPropertyXml(string targetXml, string newKmsKeyId, string newKmsPublicKey) + { + var xmlDocument = new XmlDocument { - var p = new Process(); - if (!string.IsNullOrEmpty(directory)) - { - p.StartInfo.WorkingDirectory = directory; - } - p.StartInfo.UseShellExecute = false; - p.StartInfo.RedirectStandardOutput = true; - p.StartInfo.FileName = "cmd.exe"; - p.StartInfo.Arguments = $"/C {command}"; - p.Start(); - if (waitForExit) - { - var output = p.StandardOutput.ReadToEnd(); - p.WaitForExit(); - return output; - } + PreserveWhitespace = true //to preserve formatting this must be done before loading so that the whitespace doesn't get thrown away at load time + }; - return string.Empty; + xmlDocument.Load(targetXml); + + XmlNode? node = xmlDocument.SelectSingleNode("//add[@key='amazonKmsSigningKeyId']"); + if (node != null && node.Attributes != null) + { + node.Attributes["value"]!.Value = newKmsKeyId; } - catch + + node = xmlDocument.SelectSingleNode("//add[@key='amazonKmsPublicKey']"); + if (node != null && node.Attributes != null) { - return string.Empty; + node.Attributes["value"]!.Value = newKmsPublicKey; } + + xmlDocument.Save(targetXml); } - public static string RunPowerShellCommand(string command, string? directory = null, bool waitForExit = true) + public static string? RunCommand(ConsoleMode consoleMode, string command, string? directory = null, bool waitForExit = true) { + var fileName = string.Empty; + var arguments = string.Empty; + try { - var p = new Process(); + switch (consoleMode) + { + case ConsoleMode.CommandPrompt: + fileName = "cmd.exe"; + arguments = $"/C {command}"; + break; + case ConsoleMode.Powershell: + fileName = "powershell.exe"; + arguments = $" -c {command}"; + break; + default: + break; + } + + + var process = new Process(); if (!string.IsNullOrEmpty(directory)) { - p.StartInfo.WorkingDirectory = directory; + process.StartInfo.WorkingDirectory = directory; } - p.StartInfo.UseShellExecute = false; - p.StartInfo.RedirectStandardOutput = true; - p.StartInfo.FileName = "powershell.exe"; - p.StartInfo.Arguments = $" -c {command}"; - p.Start(); + process.StartInfo.FileName = fileName; + process.StartInfo.Arguments = arguments; + process.StartInfo.UseShellExecute = false; + process.StartInfo.RedirectStandardOutput = true; + process.StartInfo.CreateNoWindow = true; + process.Start(); if (waitForExit) { - var output = p.StandardOutput.ReadToEnd(); - p.WaitForExit(); + var output = string.Empty; + while (!process.StandardOutput.EndOfStream) + { + output = process.StandardOutput.ReadLine(); + Console.WriteLine(output); + } + return output; } @@ -96,4 +124,10 @@ public static void KillProcess(string name) } } } + + public enum ConsoleMode + { + CommandPrompt, + Powershell + } } \ No newline at end of file diff --git a/MicroserviceTemplate/tools/EnvironmentInitializer/Program.cs b/MicroserviceTemplate/tools/EnvironmentInitializer/Program.cs index a35b463..a77b873 100644 --- a/MicroserviceTemplate/tools/EnvironmentInitializer/Program.cs +++ b/MicroserviceTemplate/tools/EnvironmentInitializer/Program.cs @@ -1,6 +1,8 @@ using EnvironmentInitializer; using Microsoft.Extensions.Configuration; +Console.ForegroundColor = ConsoleColor.White; + var debugEnabled = args.Length > 0 && !string.IsNullOrEmpty(args[0]) && args[0].ToLower().Equals("--debug"); var exitEnabled = args.Length > 0 && !string.IsNullOrEmpty(args[0]) && args[0].ToLower().Equals("--exit"); @@ -22,11 +24,11 @@ Helper.KillProcess("ServiceName.API"); Helper.KillProcess("Authentication.API"); Helper.KillProcess("FeatureManagement.API"); -Helper.KillProcess("Analytics.API"); +Helper.KillProcess("Analytics.API"); Helper.KillProcess("Mock.API"); -Helper.RunPowerShellCommand(@"docker kill $(docker ps -q)"); -Helper.RunPowerShellCommand(@"docker rm --force $(docker ps -a -q)"); -Helper.RunPowerShellCommand(@"docker network prune --force"); +Helper.RunCommand(ConsoleMode.Powershell, @"docker kill $(docker ps -q)"); +Helper.RunCommand(ConsoleMode.Powershell, @"docker rm --force $(docker ps -a -q)"); +Helper.RunCommand(ConsoleMode.Powershell, @"docker network prune --force"); if (exitEnabled) { @@ -34,44 +36,53 @@ return; } +//TODO: Make this a parameter var tyeYmlFolder = @"C:\Dev\GitHub\Workbench\MicroserviceTemplate"; if (debugEnabled) { Console.WriteLine("Running Tye in debug mode... do not forget to attach the debugger!"); - Helper.RunPowerShellCommand(@"tye run --port 10000 --dashboard --debug *", tyeYmlFolder, false); + Helper.RunCommand(ConsoleMode.Powershell, @"tye run --port 10000 --dashboard --debug *", tyeYmlFolder, false); } else { - Console.WriteLine("Running Tye..."); - Helper.RunPowerShellCommand(@"tye run --port 10000 --dashboard", tyeYmlFolder, false); + Console.WriteLine("Spining up new docker containers..."); + Helper.RunCommand(ConsoleMode.Powershell, @"tye run --port 10000 --dashboard", tyeYmlFolder, false); } -Console.WriteLine("Spining up new docker containers..."); + var sourceJson = string.Empty; -var cognitoDockerState = string.Empty; -var dynamoDbDockerState = string.Empty; -while (!cognitoDockerState.Equals("running") && - !dynamoDbDockerState.Equals("running")) + +//Cognito +Console.WriteLine("Waiting for Cognito container to be in RUNNING state"); +var containerState = string.Empty; +while (!containerState.Equals("running")) +{ + sourceJson = Helper.RunCommand(ConsoleMode.CommandPrompt, @"docker container ls --filter ""name = cognito*"" --format=""{{json .}}"""); + containerState = Helper.GetJsonPropertyValue("State", sourceJson!); + cognitoContainerId = Helper.GetJsonPropertyValue("ID", sourceJson!); +} + +//DynamoDB +Console.WriteLine("Waiting for DynamoDB container to be in RUNNING state"); +containerState = string.Empty; +while (!containerState.Equals("running")) { - Thread.Sleep(60000); - sourceJson = Helper.RunCmdCommand(@"docker container ls --filter ""name = cognito*"" --format=""{{json .}}"""); - cognitoDockerState = Helper.GetJsonPropertyValue("State", sourceJson); - cognitoContainerId = Helper.GetJsonPropertyValue("ID", sourceJson); - sourceJson = Helper.RunCmdCommand(@"docker container ls --filter ""name = dynamodb*"" --format=""{{json .}}"""); - dynamoDbDockerState = Helper.GetJsonPropertyValue("State", sourceJson); + sourceJson = Helper.RunCommand(ConsoleMode.CommandPrompt, @"docker container ls --filter ""name = dynamodb*"" --format=""{{json .}}"""); + containerState = Helper.GetJsonPropertyValue("State", sourceJson!); } -Console.WriteLine("Starting local environment configuration..."); +//Once the container is running, we wait 40 seconds for DynamoDB to warm up +Console.WriteLine("DynamoDB is warming up..."); +Thread.Sleep(40000); //DynamoDB -Console.WriteLine("Configuring DynamoDB..."); foreach (var dynamoDbTable in dynamoDbTables) { if (!string.IsNullOrEmpty(dynamoDbTable.TableName)) { Console.WriteLine($"Creating DynamoDB table ({dynamoDbTable.TableName})"); - Helper.RunCmdCommand($"aws --endpoint-url={dynamoDbLocalUrl} dynamodb create-table --table-name {dynamoDbTable.TableName} --attribute-definitions {dynamoDbTable.AttributeDefinitions} --key-schema {dynamoDbTable.KeySchema} --billing-mode PAY_PER_REQUEST"); + Helper.RunCommand(ConsoleMode.CommandPrompt, $"aws --endpoint-url={dynamoDbLocalUrl} dynamodb create-table --table-name {dynamoDbTable.TableName} --attribute-definitions {dynamoDbTable.AttributeDefinitions} --key-schema {dynamoDbTable.KeySchema} --billing-mode PAY_PER_REQUEST --region ap-southeast-2"); Console.WriteLine($"DynamoDB table ({dynamoDbTable.TableName}) has been created."); } } @@ -81,6 +92,8 @@ Directory.CreateDirectory(cognitoLocalDbFolder); File.Copy($@"{Directory.GetCurrentDirectory()}\CognitoLocalDb\clients.json", $@"{cognitoLocalDbFolder}\clients.json", true); File.Copy($@"{Directory.GetCurrentDirectory()}\CognitoLocalDb\user-pool-test.json", $@"{cognitoLocalDbFolder}\user-pool-test.json", true); -Helper.RunCmdCommand($@"docker container restart {cognitoContainerId}"); +Helper.RunCommand(ConsoleMode.CommandPrompt, $@"docker container restart {cognitoContainerId} -t 0"); -Console.WriteLine("Environment configuration is done."); \ No newline at end of file +Console.ForegroundColor = ConsoleColor.Green; +Console.WriteLine("Environment configuration is done."); +Console.ForegroundColor = ConsoleColor.White; \ No newline at end of file