From 191799ab976bd7dad7162d62bf86f2d3cc5d0dbd Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sat, 30 Jan 2021 14:04:37 +0100 Subject: Better Terraform resources. --- .../trygvis/rules/terraform/TerraformResource.java | 117 ++++++++++++++++++++- .../src/main/resources/META-INF/kmodule.xml | 1 + .../io/trygvis/rules/scaleway/terraform.drl | 81 ++++++++++++++ .../rules/terraform/terraform-resources.drl | 14 +++ .../io/trygvis/rules/terraform/terraform.drl | 81 -------------- .../main/resources/templates/terraform/resource.j2 | 1 + .../io/trygvis/rules/engine/TemplateEngine.java | 1 - 7 files changed, 210 insertions(+), 86 deletions(-) create mode 100644 module/ri-base/src/main/resources/io/trygvis/rules/scaleway/terraform.drl create mode 100644 module/ri-base/src/main/resources/io/trygvis/rules/terraform/terraform-resources.drl delete mode 100644 module/ri-base/src/main/resources/io/trygvis/rules/terraform/terraform.drl create mode 100644 module/ri-base/src/main/resources/templates/terraform/resource.j2 diff --git a/module/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformResource.java b/module/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformResource.java index 41bd6ae..8ca6ae2 100644 --- a/module/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformResource.java +++ b/module/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformResource.java @@ -1,14 +1,16 @@ package io.trygvis.rules.terraform; -import java.util.HashMap; -import java.util.Map; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.*; + +@SuppressWarnings("unused") public class TerraformResource { private static final String EOL = System.getProperty("line.separator"); private final String output; private final String kind; private final String instance; - private final Map values = new HashMap<>(); + private final Map values = new LinkedHashMap<>(); public TerraformResource(String output, String kind, String instance) { this.output = output; @@ -20,10 +22,40 @@ public class TerraformResource { return output; } - public void putString(String key, String value) { + public String getKind() { + return kind; + } + + public String getInstance() { + return instance; + } + + public Map getValues() { + return values; + } + + public void set(String key, String value) { values.put(key, new StringTerraformValue(value)); } + public void set(String key, boolean value) { + values.put(key, new BooleanTerraformValue(value)); + } + + public void set(String key, int value) { + values.put(key, new IntegerTerraformValue(value)); + } + + public void setExpression(String key, String value) { + values.put(key, new ExpressionTerraformValue(value)); + } + + public ArrayTerraformValue array(String key) { + var array = new ArrayTerraformValue(); + values.put(key, array); + return array; + } + public String asString() { var buf = new StringBuilder(); @@ -58,6 +90,11 @@ public class TerraformResource { this.value = value; } + @JsonValue + public String getValue() { + return value; + } + @Override public String asString() { return quote(value); @@ -71,6 +108,29 @@ public class TerraformResource { this.value = value; } + @JsonValue + public boolean getValue() { + return value; + } + + @Override + public String asString() { + return String.valueOf(value); + } + } + + public static class IntegerTerraformValue implements TerraformValue { + private final int value; + + public IntegerTerraformValue(int value) { + this.value = value; + } + + @JsonValue + public int getValue() { + return value; + } + @Override public String asString() { return String.valueOf(value); @@ -84,12 +144,61 @@ public class TerraformResource { this.value = value; } + @JsonValue + public String getValue() { + return value; + } + @Override public String asString() { return value; } } + public static class ArrayTerraformValue implements TerraformValue { + private final List values = new ArrayList<>(); + + @JsonValue + public List getValues() { + return values; + } + + public ArrayTerraformValue add(String value) { + values.add(new StringTerraformValue(value)); + return this; + } + + public ArrayTerraformValue add(int value) { + values.add(new IntegerTerraformValue(value)); + return this; + } + + public ArrayTerraformValue add(boolean value) { + values.add(new BooleanTerraformValue(value)); + return this; + } + + public ArrayTerraformValue addExpression(String value) { + values.add(new ExpressionTerraformValue(value)); + return this; + } + + @Override + public String asString() { + if (values.isEmpty()) { + return "[]"; + } + + if (values.size() == 1) { + return "[" + values.get(0).asString() + "]"; + } + + var j = new StringJoiner(",\n ", "[\n", "\n ]"); + values.forEach(value -> j.add(value.asString())); + return j.toString(); + } + } + private static String quote(String value) { return "\"%s\"".formatted(value); } diff --git a/module/ri-base/src/main/resources/META-INF/kmodule.xml b/module/ri-base/src/main/resources/META-INF/kmodule.xml index 79c5e79..4650977 100644 --- a/module/ri-base/src/main/resources/META-INF/kmodule.xml +++ b/module/ri-base/src/main/resources/META-INF/kmodule.xml @@ -8,4 +8,5 @@ + diff --git a/module/ri-base/src/main/resources/io/trygvis/rules/scaleway/terraform.drl b/module/ri-base/src/main/resources/io/trygvis/rules/scaleway/terraform.drl new file mode 100644 index 0000000..06bfc68 --- /dev/null +++ b/module/ri-base/src/main/resources/io/trygvis/rules/scaleway/terraform.drl @@ -0,0 +1,81 @@ +package io.trygvis.rules.terraform.scaleway + +import io.trygvis.rules.dba.Cluster +import io.trygvis.rules.dba.Container +import io.trygvis.rules.machine.Machine +import io.trygvis.rules.dns.DnsEntry +import io.trygvis.rules.dns.DnsEntryTerraformExpression +import java.util.ArrayList; +import java.util.Map; + +global io.trygvis.rules.engine.TemplateEngine te; + +dialect "mvel" + +declare ScalewayMachine + machine : Machine + key : String +end + +declare GoogleManagedZoneTerraformExpression + name : String +end + +rule "Terraform for Machine" +when + $machine: Machine() +then + ScalewayMachine scw = new ScalewayMachine(); + scw.setKey($machine.name); + scw.setMachine($machine); + + insert(scw); +end + +rule "Create DNS entry for Terraform Machine" +when + $machine : Machine(fqdn != null) + not(DnsEntry(fqdn == $machine.fqdn)) +then + DnsEntry a = DnsEntry.a($machine.fqdn); + insert(a); + + String ipv4 = "scaleway_instance_ip.%s.address".formatted($machine.name); + insert(new DnsEntryTerraformExpression(a, $machine.name, ipv4)); +end + +rule "main-scaleway-machine.tf" + agenda-group "generate" +when + $managedZones : ArrayList() from collect(GoogleManagedZoneTerraformExpression()) +then + String path = "terraform/main-scaleway-machine.tf"; + te.template("terraform/main-scaleway-machine", path, Map.of( + "managedZones", $managedZones + )); +end + +rule "TF for TerraformMachine" + agenda-group "generate" +when + $m: Machine() + $scw: ScalewayMachine(machine == $m) +then + String path = "terraform/scaleway-machine-%s.tf".formatted($scw.getKey()); + te.template("terraform/machine", path, Map.of("m", $m, "scw", $scw)); +end + +rule "Terraform for DNS" + agenda-group "generate" +when + $entry: DnsEntry() + $tf : DnsEntryTerraformExpression(entry == $entry) + $managedZone : GoogleManagedZoneTerraformExpression() +then + String path = "terraform/dns-%s.tf".formatted($tf.key); + te.template("terraform/record-set", path, Map.of( + "entry", $entry, + "managedZone", $managedZone, + "tf", $tf) + ); +end diff --git a/module/ri-base/src/main/resources/io/trygvis/rules/terraform/terraform-resources.drl b/module/ri-base/src/main/resources/io/trygvis/rules/terraform/terraform-resources.drl new file mode 100644 index 0000000..34af8fe --- /dev/null +++ b/module/ri-base/src/main/resources/io/trygvis/rules/terraform/terraform-resources.drl @@ -0,0 +1,14 @@ +package io.trygvis.rules.terraform; +import java.util.Map + +global io.trygvis.rules.engine.TemplateEngine te; + +dialect "mvel" + +rule "terraform-resources" + agenda-group "generate" +when + $r : TerraformResource() +then + te.template("terraform/resource", $r.output, Map.of("resource", $r)); +end diff --git a/module/ri-base/src/main/resources/io/trygvis/rules/terraform/terraform.drl b/module/ri-base/src/main/resources/io/trygvis/rules/terraform/terraform.drl deleted file mode 100644 index 7313998..0000000 --- a/module/ri-base/src/main/resources/io/trygvis/rules/terraform/terraform.drl +++ /dev/null @@ -1,81 +0,0 @@ -package io.trygvis.rules.terraform - -import io.trygvis.rules.dba.Cluster -import io.trygvis.rules.dba.Container -import io.trygvis.rules.machine.Machine -import io.trygvis.rules.dns.DnsEntry -import io.trygvis.rules.dns.DnsEntryTerraformExpression -import java.util.ArrayList; -import java.util.Map; - -global io.trygvis.rules.engine.TemplateEngine te; - -dialect "mvel" - -declare ScalewayMachine - machine : Machine - key : String -end - -declare GoogleManagedZoneTerraformExpression - name : String -end - -rule "Terraform for Machine" -when - $machine: Machine() -then - ScalewayMachine scw = new ScalewayMachine(); - scw.setKey($machine.name); - scw.setMachine($machine); - - insert(scw); -end - -rule "Create DNS entry for Terraform Machine" -when - $machine : Machine(fqdn != null) - not(DnsEntry(fqdn == $machine.fqdn)) -then - DnsEntry a = DnsEntry.a($machine.fqdn); - insert(a); - - String ipv4 = "scaleway_instance_ip.%s.address".formatted($machine.name); - insert(new DnsEntryTerraformExpression(a, $machine.name, ipv4)); -end - -rule "main-scaleway-machine.tf" - agenda-group "generate" -when - $managedZones : ArrayList() from collect(GoogleManagedZoneTerraformExpression()) -then - String path = "terraform/main-scaleway-machine.tf"; - te.template("terraform/main-scaleway-machine", path, Map.of( - "managedZones", $managedZones - )); -end - -rule "TF for TerraformMachine" - agenda-group "generate" -when - $m: Machine() - $scw: ScalewayMachine(machine == $m) -then - String path = "terraform/scaleway-machine-%s.tf".formatted($scw.getKey()); - te.template("terraform/machine", path, Map.of("m", $m, "scw", $scw)); -end - -rule "Terraform for DNS" - agenda-group "generate" -when - $entry: DnsEntry() - $tf : DnsEntryTerraformExpression(entry == $entry) - $managedZone : GoogleManagedZoneTerraformExpression() -then - String path = "terraform/dns-%s.tf".formatted($tf.key); - te.template("terraform/record-set", path, Map.of( - "entry", $entry, - "managedZone", $managedZone, - "tf", $tf) - ); -end diff --git a/module/ri-base/src/main/resources/templates/terraform/resource.j2 b/module/ri-base/src/main/resources/templates/terraform/resource.j2 new file mode 100644 index 0000000..91af481 --- /dev/null +++ b/module/ri-base/src/main/resources/templates/terraform/resource.j2 @@ -0,0 +1 @@ +{{ resource.asString() -}} diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/engine/TemplateEngine.java b/module/ri-engine/src/main/java/io/trygvis/rules/engine/TemplateEngine.java index a2ae0c2..e3199d9 100644 --- a/module/ri-engine/src/main/java/io/trygvis/rules/engine/TemplateEngine.java +++ b/module/ri-engine/src/main/java/io/trygvis/rules/engine/TemplateEngine.java @@ -1,6 +1,5 @@ package io.trygvis.rules.engine; -import java.io.FileNotFoundException; import java.io.IOException; import java.util.Map; -- cgit v1.2.3