diff --git a/Amaurot.Processor/Clients/TofuClient.cs b/Amaurot.Processor/Clients/TofuClient.cs index 008e56e..fd99e9c 100644 --- a/Amaurot.Processor/Clients/TofuClient.cs +++ b/Amaurot.Processor/Clients/TofuClient.cs @@ -8,22 +8,30 @@ internal static class TofuClient { private static readonly string TofuPath = Environment.GetEnvironmentVariable("TOFU_PATH")!; - private const string TofuArguments = "-input=false -no-color"; - - public static async Task TofuExecution( - ExecutionType executionType, - string directory - ) + public static async Task TofuExecution(Execution execution) { - var tofu = Process.Start( - new ProcessStartInfo + var processStartInfo = new ProcessStartInfo + { + FileName = TofuPath, + WorkingDirectory = execution.Directory, + RedirectStandardOutput = true, + }; + + processStartInfo.ArgumentList.Add(execution.ExecutionType.ToString().ToLower()); + processStartInfo.ArgumentList.Add("-input=false"); + processStartInfo.ArgumentList.Add("-no-color"); + + var varFiles = execution.Workspace.VarFiles; + + if (varFiles is not null) + { + foreach (var varFile in varFiles) { - FileName = TofuPath, - Arguments = $"{executionType.ToString().ToLower()} {TofuArguments}", - WorkingDirectory = directory, - RedirectStandardOutput = true, + processStartInfo.ArgumentList.Add($"-var-file={varFile}"); } - ); + } + + var tofu = Process.Start(processStartInfo); await tofu!.WaitForExitAsync(); @@ -31,7 +39,7 @@ string directory return new PlanOutput { - ExecutionType = executionType, + ExecutionType = execution.ExecutionType, ExecutionState = tofu.ExitCode is 0 or 2 ? CommitStatusState.Success : CommitStatusState.Failure, diff --git a/Amaurot.Processor/Models/OpenTofu/Execution.cs b/Amaurot.Processor/Models/OpenTofu/Execution.cs new file mode 100644 index 0000000..08f0366 --- /dev/null +++ b/Amaurot.Processor/Models/OpenTofu/Execution.cs @@ -0,0 +1,8 @@ +namespace Amaurot.Processor.Models.OpenTofu; + +internal class Execution +{ + public required ExecutionType ExecutionType { get; init; } + public required string Directory { get; init; } + public required Workspace Workspace { get; init; } +} diff --git a/Amaurot.Processor/Models/OpenTofu/Workspaces.cs b/Amaurot.Processor/Models/OpenTofu/Workspaces.cs new file mode 100644 index 0000000..f6a435e --- /dev/null +++ b/Amaurot.Processor/Models/OpenTofu/Workspaces.cs @@ -0,0 +1,11 @@ +namespace Amaurot.Processor.Models.OpenTofu; + +internal class Workspaces +{ + public required Dictionary Workspace { get; init; } +} + +internal class Workspace +{ + public string[]? VarFiles { get; init; } +} diff --git a/Amaurot.Processor/Program.cs b/Amaurot.Processor/Program.cs index b2fc9bb..a99aa0f 100644 --- a/Amaurot.Processor/Program.cs +++ b/Amaurot.Processor/Program.cs @@ -1,4 +1,5 @@ using System.IO.Compression; +using System.Text.Json; using Amaurot.Common.Models; using Amaurot.Processor.Clients; using Amaurot.Processor.Models.GitHub.Commit; @@ -96,7 +97,7 @@ await gitHubClient.CreateCommitStatus( ZipFile.ExtractToDirectory(zipball, tempDirectory.FullName); - var executionOutputs = new Dictionary>(); + var executionOutputs = new Dictionary>>(); var executionState = CommitStatusState.Success; foreach (var tfDirectory in tfDirectories) @@ -104,42 +105,75 @@ await gitHubClient.CreateCommitStatus( var directory = $"{tempDirectory.FullName}/{taskRequestBody.RepositoryOwner}-{taskRequestBody.RepositoryName}-{taskRequestBody.Sha}/{tfDirectory}"; - var init = await TofuClient.TofuExecution(ExecutionType.Init, directory); + Workspaces workspaces; - executionOutputs.Add(tfDirectory, [init]); - - if (init.ExecutionState != CommitStatusState.Success) + await using (var workspacesFile = File.OpenRead($"{directory}/amaurot.json")) { - executionState = CommitStatusState.Failure; - continue; + workspaces = (await JsonSerializer.DeserializeAsync(workspacesFile))!; } - var plan = await TofuClient.TofuExecution(ExecutionType.Plan, directory); - - executionOutputs[tfDirectory].Add(plan); - - if (plan.ExecutionState != CommitStatusState.Success) + foreach (var workspace in workspaces.Workspace) { - executionState = CommitStatusState.Failure; + var executionOutput = new Dictionary>(); + + var init = await TofuClient.TofuExecution( + new Execution + { + ExecutionType = ExecutionType.Init, + Directory = directory, + Workspace = workspace.Value, + } + ); + + executionOutput.Add(workspace.Key, [init]); + + if (init.ExecutionState != CommitStatusState.Success) + { + executionState = CommitStatusState.Failure; + continue; + } + + var plan = await TofuClient.TofuExecution( + new Execution + { + ExecutionType = ExecutionType.Plan, + Directory = directory, + Workspace = workspace.Value, + } + ); + + executionOutput[workspace.Key].Add(plan); + + if (plan.ExecutionState != CommitStatusState.Success) + { + executionState = CommitStatusState.Failure; + } + + executionOutputs.Add(tfDirectory, executionOutput); } } tempDirectory.Delete(true); - var comment = $"OpenTofu plan output for commit {taskRequestBody.Sha}:\n\n"; + var comment = $"Amaurot plan output for commit {taskRequestBody.Sha}:\n\n" + "---\n"; foreach (var directory in executionOutputs) { - comment += $"`{directory.Key}`:\n"; + comment += $"* `{directory.Key}`\n"; - foreach (var executionOutput in directory.Value) + foreach (var workspace in directory.Value) { - comment += - $"
{executionOutput.ExecutionType.ToString()}:\n\n" - + "```\n" - + $"{executionOutput.ExecutionStdout}\n" - + "```\n" - + "
\n\n"; + comment += $" * {workspace.Key}\n"; + + foreach (var executionOutput in workspace.Value) + { + comment += + $"
{executionOutput.ExecutionType.ToString()}\n\n" + + " ```\n" + + $" {executionOutput.ExecutionStdout}\n" + + " ```\n" + + "
\n"; + } } }