diff --git a/src/main/java/io/codeka/gaia/runner/StackCommandBuilder.java b/src/main/java/io/codeka/gaia/runner/StackCommandBuilder.java new file mode 100644 index 000000000..331f3ae68 --- /dev/null +++ b/src/main/java/io/codeka/gaia/runner/StackCommandBuilder.java @@ -0,0 +1,73 @@ +package io.codeka.gaia.runner; + +import io.codeka.gaia.bo.Settings; +import io.codeka.gaia.bo.Stack; +import io.codeka.gaia.bo.TerraformModule; +import io.codeka.gaia.bo.backend.Backend; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * A builder class to create stack commands + */ +@Component +public class StackCommandBuilder { + + private Settings settings; + + @Autowired + StackCommandBuilder(Settings settings) { + this.settings = settings; + } + + /** + * + * @return + */ + String buildApplyScript(Stack stack, TerraformModule module){ + var backendGenCommand = String.format("echo \"terraform {\n" + + " backend \\\"http\\\" {\n" + + "\t\taddress=\\\""+settings.getExternalUrl()+"/api/state/%s\\\"\n" + + "\t}\n" + + "}\n\" > backend.tf", stack.getId()); + + String applyCommand = buildApplyCommand(stack, module); + + System.out.println(applyCommand); + + var commands = new String[]{ + "set -ex", + String.format("git clone %s module", module.getGitRepositoryUrl()), + "cd module", + "echo 'generating backend configuration'", + backendGenCommand, + "cat backend.tf", + "terraform version", + "terraform init", + applyCommand + }; + + // generate a backend.tf config ! + + return String.join("\n", commands); + } + + String buildApplyCommand(Stack stack, TerraformModule module) { + var varFormatString = "-var \"%s=%s\" "; + var variablesBuilder = new StringBuilder(); + + module.getVariables().forEach(terraformVariable -> { + + var name = terraformVariable.getName(); + String value = terraformVariable.getDefaultValue(); + // try getting the value from the stack + if(stack.getVariableValues().containsKey(name)){ + value = stack.getVariableValues().get(name); + } + variablesBuilder.append(String.format(varFormatString, name, value)); + }); + + return String.format("terraform apply --auto-approve %s", variablesBuilder.toString()); + } + +} diff --git a/src/main/java/io/codeka/gaia/runner/StackRunner.java b/src/main/java/io/codeka/gaia/runner/StackRunner.java index 003a6c06d..0f2d41a43 100644 --- a/src/main/java/io/codeka/gaia/runner/StackRunner.java +++ b/src/main/java/io/codeka/gaia/runner/StackRunner.java @@ -33,13 +33,16 @@ public class StackRunner { private Settings settings; + private StackCommandBuilder stackCommandBuilder; + private Map jobs = new HashMap<>(); @Autowired - public StackRunner(DockerClient dockerClient, ContainerConfig containerConfig, Settings settings) { + public StackRunner(DockerClient dockerClient, ContainerConfig containerConfig, Settings settings, StackCommandBuilder stackCommandBuilder) { this.dockerClient = dockerClient; this.containerConfig = containerConfig; this.settings = settings; + this.stackCommandBuilder = stackCommandBuilder; } @Async @@ -98,49 +101,7 @@ public void run(Job job, TerraformModule module, Stack stack) { } }); - var backendGenCommand = String.format("echo \"terraform {\n" + - " backend \\\"http\\\" {\n" + - "\t\taddress=\\\""+settings.getExternalUrl()+"/api/state/%s\\\"\n" + - "\t}\n" + - "}\n\" > backend.tf", stack.getId()); - - var varFormatString = " -var \"%s=%s\" "; - var variablesBuilder = new StringBuilder(); - - module.getVariables().forEach(terraformVariable -> { - - var name = terraformVariable.getName(); - String value = terraformVariable.getDefaultValue(); - // try getting the value from the stack - if(stack.getVariableValues().containsKey(name)){ - value = stack.getVariableValues().get(name); - } - variablesBuilder.append(String.format(varFormatString, name, value)); - }); - - stack.getVariableValues().forEach((s, s2) -> { - variablesBuilder.append(String.format(varFormatString, s, s2)); - }); - - var applyCommand = String.format("terraform apply --auto-approve %s", variablesBuilder.toString()); - - System.out.println(applyCommand); - - var commands = new String[]{ - "set -ex", - String.format("git clone %s module", module.getGitRepositoryUrl()), - "cd module", - "echo 'generating backend configuration'", - backendGenCommand, - "cat backend.tf", - "terraform version", - "terraform init", - applyCommand - }; - - // generate a backend.tf config ! - - var commandScript = String.join("\n", commands); + var commandScript = stackCommandBuilder.buildApplyScript(stack, module); System.err.println("Writing buffer"); writable.write(ByteBuffer.wrap(commandScript.getBytes())); diff --git a/src/test/java/io/codeka/gaia/runner/StackCommandBuilderTest.java b/src/test/java/io/codeka/gaia/runner/StackCommandBuilderTest.java new file mode 100644 index 000000000..8f328e370 --- /dev/null +++ b/src/test/java/io/codeka/gaia/runner/StackCommandBuilderTest.java @@ -0,0 +1,85 @@ +package io.codeka.gaia.runner; + +import io.codeka.gaia.bo.Settings; +import io.codeka.gaia.bo.Stack; +import io.codeka.gaia.bo.TerraformModule; +import io.codeka.gaia.bo.TerraformVariable; +import org.junit.jupiter.api.Test; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +class StackCommandBuilderTest { + + @Test + void buildApplyCommand_shouldGenerateASimpleApplyCommand(){ + var stackCommandBuilder = new StackCommandBuilder(new Settings()); + + var module = new TerraformModule(); + module.setVariables(Collections.emptyList()); + + var stack = new Stack(); + + var applyCommand = stackCommandBuilder.buildApplyCommand(stack, module); + + assertEquals("terraform apply --auto-approve ", applyCommand); + } + + @Test + void buildApplyCommand_shouldGenerateASingleVariableApplyCommand(){ + var stackCommandBuilder = new StackCommandBuilder(new Settings()); + + var module = new TerraformModule(); + var variable = new TerraformVariable(); + variable.setName("test"); + module.setVariables(List.of(variable)); + + var stack = new Stack(); + stack.setVariableValues(Map.of("test", "value")); + + var applyCommand = stackCommandBuilder.buildApplyCommand(stack, module); + + assertEquals("terraform apply --auto-approve -var \"test=value\" ", applyCommand); + } + + @Test + void buildApplyCommand_shouldGenerateAMultipleVariableApplyCommand(){ + var stackCommandBuilder = new StackCommandBuilder(new Settings()); + + var module = new TerraformModule(); + var variable = new TerraformVariable(); + variable.setName("test"); + var variable2 = new TerraformVariable(); + variable2.setName("test2"); + module.setVariables(List.of(variable, variable2)); + + var stack = new Stack(); + stack.setVariableValues(Map.of("test", "value", "test2", "value2")); + + var applyCommand = stackCommandBuilder.buildApplyCommand(stack, module); + + assertEquals("terraform apply --auto-approve -var \"test=value\" -var \"test2=value2\" ", applyCommand); + } + + @Test + void buildApplyCommand_shouldUseDefaultVariableValues(){ + var stackCommandBuilder = new StackCommandBuilder(new Settings()); + + var module = new TerraformModule(); + var variable = new TerraformVariable(); + variable.setName("test"); + variable.setDefaultValue("defaultValue"); + module.setVariables(List.of(variable)); + + var stack = new Stack(); + stack.setVariableValues(Collections.emptyMap()); + + var applyCommand = stackCommandBuilder.buildApplyCommand(stack, module); + + assertEquals("terraform apply --auto-approve -var \"test=defaultValue\" ", applyCommand); + } + +} \ No newline at end of file