From e4821f82249bddb443a1f6a6e403087cab659c6d Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Fri, 1 Jan 2021 20:35:28 +0100 Subject: Migrating to Drools. --- .gitignore | 2 + .idea/.gitignore | 8 + acme.yaml | 11 + classpath.txt | 40 ++++ out/phase-1.yaml | 246 +++++++++++++++++++++ pom.xml | 139 ++++++++++++ src/main/java/io/trygvis/rules/acme/AcmeIo.java | 81 +++++++ src/main/java/io/trygvis/rules/acme/AcmeMyApp.java | 6 + .../java/io/trygvis/rules/acme/AcmeObject.java | 16 ++ src/main/java/io/trygvis/rules/acme/AcmeOps.java | 4 + src/main/java/io/trygvis/rules/dba/Cluster.java | 9 + src/main/java/io/trygvis/rules/dba/Container.java | 17 ++ src/main/java/io/trygvis/rules/dns/DnsEntry.java | 19 ++ src/main/java/io/trygvis/rules/engine/Main.java | 36 +++ .../java/io/trygvis/rules/machine/Machine.java | 9 + .../java/io/trygvis/rules/terraform/Machine.java | 4 + src/main/resources/META-INF/kmodule.xml | 10 + src/main/resources/io/trygvis/rules/acme/acme.drl | 30 +++ src/main/resources/io/trygvis/rules/dba/dba.drl | 1 + .../resources/io/trygvis/rules/machine/machine.drl | 14 ++ 20 files changed, 702 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 acme.yaml create mode 100644 classpath.txt create mode 100644 out/phase-1.yaml create mode 100644 pom.xml create mode 100644 src/main/java/io/trygvis/rules/acme/AcmeIo.java create mode 100644 src/main/java/io/trygvis/rules/acme/AcmeMyApp.java create mode 100644 src/main/java/io/trygvis/rules/acme/AcmeObject.java create mode 100644 src/main/java/io/trygvis/rules/acme/AcmeOps.java create mode 100644 src/main/java/io/trygvis/rules/dba/Cluster.java create mode 100644 src/main/java/io/trygvis/rules/dba/Container.java create mode 100644 src/main/java/io/trygvis/rules/dns/DnsEntry.java create mode 100644 src/main/java/io/trygvis/rules/engine/Main.java create mode 100644 src/main/java/io/trygvis/rules/machine/Machine.java create mode 100644 src/main/java/io/trygvis/rules/terraform/Machine.java create mode 100644 src/main/resources/META-INF/kmodule.xml create mode 100644 src/main/resources/io/trygvis/rules/acme/acme.drl create mode 100644 src/main/resources/io/trygvis/rules/dba/dba.drl create mode 100644 src/main/resources/io/trygvis/rules/machine/machine.drl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..26a9bfe --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.iml +target diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/acme.yaml b/acme.yaml new file mode 100644 index 0000000..26398b2 --- /dev/null +++ b/acme.yaml @@ -0,0 +1,11 @@ +type: io.trygvis.rules.acme.AcmeMyApp +data: + environment: ci + dockerTag: development +--- +type: io.trygvis.rules.acme.AcmeMyApp +data: + environment: production + dockerTag: master +--- +type: io.trygvis.rules.acme.AcmeOps diff --git a/classpath.txt b/classpath.txt new file mode 100644 index 0000000..bfc9a03 --- /dev/null +++ b/classpath.txt @@ -0,0 +1,40 @@ +io.trygvis.rules-sandbox:rules-sandbox:1.0-SNAPSHOT:jar +ch.qos.logback:logback-classic:1.2.3:jar +ch.qos.logback:logback-core:1.2.3:jar +com.fasterxml.jackson.core:jackson-annotations:2.12.0:jar +com.fasterxml.jackson.core:jackson-core:2.12.0:jar +com.fasterxml.jackson.core:jackson-databind:2.12.0:jar +com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.12.0:jar +com.github.virtuald:curvesapi:1.06:jar +com.thoughtworks.xstream:xstream:1.4.14:jar +com.zaxxer:SparseBitSet:1.2:jar +commons-codec:commons-codec:1.11:jar +org.antlr:antlr-runtime:3.5.2:jar +org.apache.commons:commons-collections4:4.4:jar +org.apache.commons:commons-compress:1.19:jar +org.apache.commons:commons-math3:3.4.1:jar +org.apache.poi:poi:4.1.2:jar +org.apache.poi:poi-ooxml:4.1.2:jar +org.apache.poi:poi-ooxml-schemas:4.1.2:jar +org.apache.xmlbeans:xmlbeans:3.1.0:jar +org.drools:drools-compiler:7.47.0.Final:jar +org.drools:drools-core:7.47.0.Final:jar +org.drools:drools-core-dynamic:7.47.0.Final:jar +org.drools:drools-core-reflective:7.47.0.Final:jar +org.drools:drools-decisiontables:7.47.0.Final:jar +org.drools:drools-ecj:7.47.0.Final:jar +org.drools:drools-mvel:7.47.0.Final:jar +org.drools:drools-templates:7.47.0.Final:jar +org.kie:kie-api:7.47.0.Final:jar +org.kie:kie-internal:7.47.0.Final:jar +org.kie:kie-memory-compiler:7.47.0.Final:jar +org.kie.soup:kie-soup-commons:7.47.0.Final:jar +org.kie.soup:kie-soup-maven-support:7.47.0.Final:jar +org.kie.soup:kie-soup-project-datamodel-api:7.47.0.Final:jar +org.kie.soup:kie-soup-project-datamodel-commons:7.47.0.Final:jar +org.kie.soup:kie-soup-xstream:7.47.0.Final:jar +org.mvel:mvel2:2.4.10.Final:jar +org.slf4j:slf4j-api:1.7.26:jar +org.yaml:snakeyaml:1.26:jar +xmlpull:xmlpull:1.2.0:jar +xpp3:xpp3_min:1.2.0:jar diff --git a/out/phase-1.yaml b/out/phase-1.yaml new file mode 100644 index 0000000..0b8d48b --- /dev/null +++ b/out/phase-1.yaml @@ -0,0 +1,246 @@ +--- +type: "io.trygvis.rules.acme.AcmeMyApp" +data: + environment: "ci" + dockerTag: "development" +--- +type: "io.trygvis.rules.acme.AcmeMyApp" +data: + environment: "production" + dockerTag: "master" +--- +type: "io.trygvis.rules.dba.Cluster" +data: + name: "acme-ci" +--- +type: "io.trygvis.rules.dba.Cluster" +data: + name: "acme-production" +--- +type: "io.trygvis.rules.dba.Container" +data: + cluster: + name: "acme-ci" + name: "db" + machineRole: "mdb" + image: "mongodb" + tag: "3.2" +--- +type: "io.trygvis.rules.dba.Container" +data: + cluster: + name: "acme-ci" + name: "app" + machineRole: "4tune-web" + image: "4tune-web" + tag: "development" +--- +type: "io.trygvis.rules.dba.Container" +data: + cluster: + name: "acme-production" + name: "db" + machineRole: "mdb" + image: "mongodb" + tag: "3.2" +--- +type: "io.trygvis.rules.dba.Container" +data: + cluster: + name: "acme-production" + name: "app" + machineRole: "statera" + image: "statera" + tag: "master" +--- +type: "io.trygvis.rules.dba.Container" +data: + cluster: + name: "acme-production" + name: "app" + machineRole: "4tune-web" + image: "4tune-web" + tag: "master" +--- +type: "io.trygvis.rules.dba.Container" +data: + cluster: + name: "acme-ci" + name: "app" + machineRole: "4tune-api" + image: "4tune-api" + tag: "development" +--- +type: "io.trygvis.rules.dba.Container" +data: + cluster: + name: "acme-production" + name: "db" + machineRole: "pdb" + image: "postgresql" + tag: "13" +--- +type: "io.trygvis.rules.dba.Container" +data: + cluster: + name: "acme-ci" + name: "app" + machineRole: "statera" + image: "statera" + tag: "development" +--- +type: "io.trygvis.rules.dba.Container" +data: + cluster: + name: "acme-production" + name: "app" + machineRole: "4tune-api" + image: "4tune-api" + tag: "master" +--- +type: "io.trygvis.rules.dba.Container" +data: + cluster: + name: "acme-production" + name: "app" + machineRole: "statera-console" + image: "statera-console" + tag: "master" +--- +type: "io.trygvis.rules.dba.Container" +data: + cluster: + name: "acme-ci" + name: "db" + machineRole: "pdb" + image: "postgresql" + tag: "13" +--- +type: "io.trygvis.rules.dba.Container" +data: + cluster: + name: "acme-ci" + name: "app" + machineRole: "statera-console" + image: "statera-console" + tag: "development" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "app.machine.acme.org" + type: "AAAA" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "app.machine.acme.org" + type: "A" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "app.machine.acme.org" + type: "A" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "app.machine.acme.org" + type: "A" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "db.machine.acme.org" + type: "A" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "app.machine.acme.org" + type: "A" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "db.machine.acme.org" + type: "A" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "app.machine.acme.org" + type: "A" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "db.machine.acme.org" + type: "AAAA" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "db.machine.acme.org" + type: "A" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "app.machine.acme.org" + type: "AAAA" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "db.machine.acme.org" + type: "AAAA" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "db.machine.acme.org" + type: "AAAA" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "db.machine.acme.org" + type: "A" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "app.machine.acme.org" + type: "AAAA" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "app.machine.acme.org" + type: "AAAA" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "app.machine.acme.org" + type: "AAAA" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "app.machine.acme.org" + type: "AAAA" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "app.machine.acme.org" + type: "A" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "db.machine.acme.org" + type: "AAAA" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "app.machine.acme.org" + type: "A" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "app.machine.acme.org" + type: "AAAA" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "app.machine.acme.org" + type: "A" +--- +type: "io.trygvis.rules.dns.DnsEntry" +data: + fqdn: "app.machine.acme.org" + type: "AAAA" diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..753b284 --- /dev/null +++ b/pom.xml @@ -0,0 +1,139 @@ + + + 4.0.0 + + io.trygvis.rules-sandbox + rules-sandbox + 1.0-SNAPSHOT + + + io.trygvis.rules.sandbox + 7.47.0.Final + 2.12.0 + + 15 + UTF-8 + + + + + + org.drools + drools + ${drools.version} + pom + import + + + org.glassfish.jaxb + jaxb-bom + 2.3.2 + pom + import + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + ${version.jackson} + + + com.fasterxml.jackson.core + jackson-annotations + ${version.jackson} + + + com.fasterxml.jackson.core + jackson-core + ${version.jackson} + + + com.fasterxml.jackson.core + jackson-databind + ${version.jackson} + + + + + + + + org.kie + kie-api + + + org.drools + drools-core + + + org.drools + drools-compiler + + + org.drools + drools-decisiontables + + + org.drools + drools-templates + + + org.kie + kie-internal + + + + org.mvel + mvel2 + + + + ch.qos.logback + logback-classic + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + com.fasterxml.jackson.core + jackson-core + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 15 + ${java.version} + UTF-8 + + --enable-preview + + 15 + + + + eu.nets.oss.maven + classpath-maven-plugin + 1.0 + + + default + + export-classpath + + + + + + + diff --git a/src/main/java/io/trygvis/rules/acme/AcmeIo.java b/src/main/java/io/trygvis/rules/acme/AcmeIo.java new file mode 100644 index 0000000..67dd4cb --- /dev/null +++ b/src/main/java/io/trygvis/rules/acme/AcmeIo.java @@ -0,0 +1,81 @@ +package io.trygvis.rules.acme; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; +import org.drools.core.common.DefaultFactHandle; +import org.kie.api.runtime.rule.FactHandle; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + +public class AcmeIo { + private final ObjectMapper mapper; + + public AcmeIo() { + var factory = new YAMLFactory(); + factory.enable(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID); + factory.enable(YAMLGenerator.Feature.USE_NATIVE_OBJECT_ID); + mapper = new ObjectMapper(factory); + mapper.findAndRegisterModules(); + } + + public List load(String file) throws IOException { + var parser = mapper.getFactory().createParser(new File(file)); + + var objects = mapper.readValues(parser, AcmeObject.class).readAll(new ArrayList<>()); + + List items = new ArrayList<>(objects.size()); + for (AcmeObject object : objects) { + try { + var type = Class.forName(object.type); + var x = mapper.treeToValue(object.data, type); + items.add(x); + } catch (ClassNotFoundException e) { + throw new IOException(e); + } + } + + return items; + } + + public void dump(String s, Collection factHandles) throws IOException { + var out = new File("out"); + + if (!out.isDirectory()) { + if (!out.mkdirs()) { + throw new IOException("Could not create directory: " + out); + } + } + + List> facts = new ArrayList<>(factHandles.size()); + for (var handle : factHandles) { + if (handle instanceof DefaultFactHandle h) { + facts.add(new AbstractMap.SimpleImmutableEntry<>( + h.getObjectClassName(), + h.getObject())); + } + } + + facts.sort(Map.Entry.comparingByKey()); + + var factory = mapper.getFactory(); + try (var writer = new FileWriter(new File(out, s + ".yaml")); + var g = factory.createGenerator(writer)) { + for (Map.Entry fact : facts) { + g.writeObject(new AcmeObject( + fact.getKey(), + mapper.valueToTree(fact.getValue()) + )); + } + } + } +} diff --git a/src/main/java/io/trygvis/rules/acme/AcmeMyApp.java b/src/main/java/io/trygvis/rules/acme/AcmeMyApp.java new file mode 100644 index 0000000..a1340e7 --- /dev/null +++ b/src/main/java/io/trygvis/rules/acme/AcmeMyApp.java @@ -0,0 +1,6 @@ +package io.trygvis.rules.acme; + +public class AcmeMyApp { + public String environment; + public String dockerTag; +} diff --git a/src/main/java/io/trygvis/rules/acme/AcmeObject.java b/src/main/java/io/trygvis/rules/acme/AcmeObject.java new file mode 100644 index 0000000..a75c4ba --- /dev/null +++ b/src/main/java/io/trygvis/rules/acme/AcmeObject.java @@ -0,0 +1,16 @@ +package io.trygvis.rules.acme; + +import com.fasterxml.jackson.databind.node.ObjectNode; + +public final class AcmeObject { + public String type; + public ObjectNode data; + + public AcmeObject() { + } + + public AcmeObject(String type, ObjectNode data) { + this.type = type; + this.data = data; + } +} diff --git a/src/main/java/io/trygvis/rules/acme/AcmeOps.java b/src/main/java/io/trygvis/rules/acme/AcmeOps.java new file mode 100644 index 0000000..147fcfa --- /dev/null +++ b/src/main/java/io/trygvis/rules/acme/AcmeOps.java @@ -0,0 +1,4 @@ +package io.trygvis.rules.acme; + +public class AcmeOps { +} diff --git a/src/main/java/io/trygvis/rules/dba/Cluster.java b/src/main/java/io/trygvis/rules/dba/Cluster.java new file mode 100644 index 0000000..949d9ae --- /dev/null +++ b/src/main/java/io/trygvis/rules/dba/Cluster.java @@ -0,0 +1,9 @@ +package io.trygvis.rules.dba; + +public class Cluster { + public String name; + + public Cluster(String name) { + this.name = name; + } +} diff --git a/src/main/java/io/trygvis/rules/dba/Container.java b/src/main/java/io/trygvis/rules/dba/Container.java new file mode 100644 index 0000000..6df939d --- /dev/null +++ b/src/main/java/io/trygvis/rules/dba/Container.java @@ -0,0 +1,17 @@ +package io.trygvis.rules.dba; + +public class Container { + public Cluster cluster; + public String name; + public String machineRole; + public String image; + public String tag; + + public Container(Cluster cluster, String name, String machineRole, String image, String tag) { + this.cluster = cluster; + this.name = name; + this.machineRole = machineRole; + this.image = image; + this.tag = tag; + } +} diff --git a/src/main/java/io/trygvis/rules/dns/DnsEntry.java b/src/main/java/io/trygvis/rules/dns/DnsEntry.java new file mode 100644 index 0000000..e7d9f4c --- /dev/null +++ b/src/main/java/io/trygvis/rules/dns/DnsEntry.java @@ -0,0 +1,19 @@ +package io.trygvis.rules.dns; + +public class DnsEntry { + public String fqdn; + public String type; + + public DnsEntry(String fqdn, String type) { + this.fqdn = fqdn; + this.type = type; + } + + public static DnsEntry a(String fqdn) { + return new DnsEntry(fqdn, "A"); + } + + public static DnsEntry aaaa(String fqdn) { + return new DnsEntry(fqdn, "AAAA"); + } +} diff --git a/src/main/java/io/trygvis/rules/engine/Main.java b/src/main/java/io/trygvis/rules/engine/Main.java new file mode 100644 index 0000000..3730c28 --- /dev/null +++ b/src/main/java/io/trygvis/rules/engine/Main.java @@ -0,0 +1,36 @@ +package io.trygvis.rules.engine; + +import io.trygvis.rules.acme.AcmeIo; +import org.drools.core.audit.WorkingMemoryConsoleLogger; +import org.drools.core.common.DefaultFactHandle; +import org.kie.api.KieServices; +import org.kie.api.event.rule.AgendaEventListener; +import org.kie.api.event.rule.RuleRuntimeEventListener; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) throws IOException { + var io = new AcmeIo(); + + var objects = io.load("acme.yaml"); + + var services = KieServices.Factory.get(); + var container = services.getKieClasspathContainer(); + var session = container.newKieSession(); + + for (var object : objects) { + System.out.println("object = " + object); + session.insert(object); + } + + var logger = new WorkingMemoryConsoleLogger(session); + session.addEventListener((AgendaEventListener) logger); + session.addEventListener((RuleRuntimeEventListener) logger); + session.fireAllRules(); + + io.dump("phase-1", session.getFactHandles()); + + session.dispose(); + } +} diff --git a/src/main/java/io/trygvis/rules/machine/Machine.java b/src/main/java/io/trygvis/rules/machine/Machine.java new file mode 100644 index 0000000..b58aeb2 --- /dev/null +++ b/src/main/java/io/trygvis/rules/machine/Machine.java @@ -0,0 +1,9 @@ +package io.trygvis.rules.machine; + +public class Machine { + public String name; + + public Machine(String name) { + this.name = name; + } +} diff --git a/src/main/java/io/trygvis/rules/terraform/Machine.java b/src/main/java/io/trygvis/rules/terraform/Machine.java new file mode 100644 index 0000000..01bea77 --- /dev/null +++ b/src/main/java/io/trygvis/rules/terraform/Machine.java @@ -0,0 +1,4 @@ +package io.trygvis.rules.terraform; + +public class Machine { +} diff --git a/src/main/resources/META-INF/kmodule.xml b/src/main/resources/META-INF/kmodule.xml new file mode 100644 index 0000000..911fdc6 --- /dev/null +++ b/src/main/resources/META-INF/kmodule.xml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/src/main/resources/io/trygvis/rules/acme/acme.drl b/src/main/resources/io/trygvis/rules/acme/acme.drl new file mode 100644 index 0000000..2439ddb --- /dev/null +++ b/src/main/resources/io/trygvis/rules/acme/acme.drl @@ -0,0 +1,30 @@ +package io.trygvis.rules.acme; + +import io.trygvis.rules.dba.Cluster; +import io.trygvis.rules.dba.Container; + +rule "Ops" +when + $ops: AcmeOps() +then + var cluster = new Cluster("acme-ops"); + insert(cluster); + insert(new Container(cluster, "app", "pdb", "postgresql", "11")); + insert(new Container(cluster, "app", "n8n", "n8n", "0.84.1")); +end + +rule "MyApp" +when + $app: AcmeMyApp() +then + var cluster = new Cluster("acme-" + $app.environment); + insert(cluster); + + var tag = $app.dockerTag; + insert(new Container(cluster, "app", "statera", "statera", tag)); + insert(new Container(cluster, "app", "statera-console", "statera-console", tag)); + insert(new Container(cluster, "app", "4tune-web", "4tune-web", tag)); + insert(new Container(cluster, "app", "4tune-api", "4tune-api", tag)); + insert(new Container(cluster, "db", "pdb", "postgresql", "13")); + insert(new Container(cluster, "db", "mdb", "mongodb", "3.2")); +end diff --git a/src/main/resources/io/trygvis/rules/dba/dba.drl b/src/main/resources/io/trygvis/rules/dba/dba.drl new file mode 100644 index 0000000..7beceef --- /dev/null +++ b/src/main/resources/io/trygvis/rules/dba/dba.drl @@ -0,0 +1 @@ +package io.trygvis.rules.dba; diff --git a/src/main/resources/io/trygvis/rules/machine/machine.drl b/src/main/resources/io/trygvis/rules/machine/machine.drl new file mode 100644 index 0000000..45df925 --- /dev/null +++ b/src/main/resources/io/trygvis/rules/machine/machine.drl @@ -0,0 +1,14 @@ +package io.trygvis.rules.machine; + +import io.trygvis.rules.dba.Cluster; +import io.trygvis.rules.dba.Container; +import io.trygvis.rules.machine.Machine; +import io.trygvis.rules.dns.DnsEntry; + +rule "New machine" +when + $container: Container() +then + insert(DnsEntry.a($container.name + ".machine.acme.org")); + insert(DnsEntry.aaaa($container.name + ".machine.acme.org")); +end -- cgit v1.2.3