From b8699860653e593271e50c8ba1b73f66fcb6287c Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Wed, 6 Jan 2021 12:05:23 +0100 Subject: Starting on splitting up into different modules. --- .idea/runConfigurations/Main.xml | 15 -- classpath.txt | 56 +---- module/ri-engine/classpath.txt | 56 +++++ module/ri-engine/pom.xml | 93 ++++++++ .../main/java/io/trygvis/rules/acme/AcmeIo.java | 260 +++++++++++++++++++++ .../main/java/io/trygvis/rules/acme/AcmeMyApp.java | 6 + .../java/io/trygvis/rules/acme/AcmeObject.java | 16 ++ .../main/java/io/trygvis/rules/acme/AcmeOps.java | 4 + .../main/java/io/trygvis/rules/acme/IpCalc.java | 67 ++++++ .../main/java/io/trygvis/rules/dba/Cluster.java | 9 + .../main/java/io/trygvis/rules/dba/Container.java | 17 ++ .../main/java/io/trygvis/rules/dns/DnsEntry.java | 27 +++ .../rules/dns/DnsEntryTerraformExpression.java | 21 ++ .../java/io/trygvis/rules/engine/KeyValue.java | 14 ++ .../main/java/io/trygvis/rules/engine/Main.java | 53 +++++ .../io/trygvis/rules/engine/TemplateEngine.java | 30 +++ .../java/io/trygvis/rules/machine/Machine.java | 13 ++ .../java/io/trygvis/rules/network/Ipv4Address.java | 57 +++++ .../java/io/trygvis/rules/network/Ipv4Cidr.java | 54 +++++ .../src/main/resources/META-INF/kmodule.xml | 11 + .../main/resources/io/trygvis/rules/acme/acme.drl | 62 +++++ .../main/resources/io/trygvis/rules/dba/dba.drl | 1 + .../resources/io/trygvis/rules/engine/default.drl | 15 ++ .../resources/io/trygvis/rules/machine/machine.drl | 6 + .../io/trygvis/rules/terraform/terraform.drl | 60 +++++ .../java/io/trygvis/rules/acme/IpCalcTest.java | 27 +++ module/ri-wireguard/classpath.txt | 1 + module/ri-wireguard/pom.xml | 16 ++ .../src/main/java/io/trygvis/rules/acme/Foo.java | 7 + .../src/main/resources/META-INF/kmodule.xml | 9 + .../main/resources/io/trygvis/rules/acme/vpn.drl | 105 +++++++++ pom.xml | 85 ++----- src/main/java/io/trygvis/rules/acme/AcmeIo.java | 260 --------------------- 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/acme/IpCalc.java | 67 ------ 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 | 27 --- .../rules/dns/DnsEntryTerraformExpression.java | 21 -- .../java/io/trygvis/rules/engine/KeyValue.java | 14 -- src/main/java/io/trygvis/rules/engine/Main.java | 53 ----- .../io/trygvis/rules/engine/TemplateEngine.java | 30 --- .../java/io/trygvis/rules/machine/Machine.java | 13 -- .../java/io/trygvis/rules/network/Ipv4Address.java | 57 ----- .../java/io/trygvis/rules/network/Ipv4Cidr.java | 54 ----- src/main/resources/META-INF/kmodule.xml | 11 - src/main/resources/io/trygvis/rules/acme/acme.drl | 62 ----- src/main/resources/io/trygvis/rules/acme/vpn.drl | 110 --------- src/main/resources/io/trygvis/rules/dba/dba.drl | 1 - .../resources/io/trygvis/rules/engine/default.drl | 15 -- .../resources/io/trygvis/rules/machine/machine.drl | 6 - .../io/trygvis/rules/terraform/terraform.drl | 60 ----- .../java/io/trygvis/rules/acme/IpCalcTest.java | 27 --- 55 files changed, 1131 insertions(+), 1082 deletions(-) delete mode 100644 .idea/runConfigurations/Main.xml create mode 100644 module/ri-engine/classpath.txt create mode 100644 module/ri-engine/pom.xml create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/acme/AcmeIo.java create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/acme/AcmeMyApp.java create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/acme/AcmeObject.java create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/acme/AcmeOps.java create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/acme/IpCalc.java create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/dba/Cluster.java create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/dba/Container.java create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/dns/DnsEntry.java create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/dns/DnsEntryTerraformExpression.java create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/engine/KeyValue.java create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/engine/Main.java create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/engine/TemplateEngine.java create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/machine/Machine.java create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/network/Ipv4Address.java create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/network/Ipv4Cidr.java create mode 100644 module/ri-engine/src/main/resources/META-INF/kmodule.xml create mode 100644 module/ri-engine/src/main/resources/io/trygvis/rules/acme/acme.drl create mode 100644 module/ri-engine/src/main/resources/io/trygvis/rules/dba/dba.drl create mode 100644 module/ri-engine/src/main/resources/io/trygvis/rules/engine/default.drl create mode 100644 module/ri-engine/src/main/resources/io/trygvis/rules/machine/machine.drl create mode 100644 module/ri-engine/src/main/resources/io/trygvis/rules/terraform/terraform.drl create mode 100644 module/ri-engine/src/test/java/io/trygvis/rules/acme/IpCalcTest.java create mode 100644 module/ri-wireguard/classpath.txt create mode 100644 module/ri-wireguard/pom.xml create mode 100644 module/ri-wireguard/src/main/java/io/trygvis/rules/acme/Foo.java create mode 100644 module/ri-wireguard/src/main/resources/META-INF/kmodule.xml create mode 100644 module/ri-wireguard/src/main/resources/io/trygvis/rules/acme/vpn.drl delete mode 100644 src/main/java/io/trygvis/rules/acme/AcmeIo.java delete mode 100644 src/main/java/io/trygvis/rules/acme/AcmeMyApp.java delete mode 100644 src/main/java/io/trygvis/rules/acme/AcmeObject.java delete mode 100644 src/main/java/io/trygvis/rules/acme/AcmeOps.java delete mode 100644 src/main/java/io/trygvis/rules/acme/IpCalc.java delete mode 100644 src/main/java/io/trygvis/rules/dba/Cluster.java delete mode 100644 src/main/java/io/trygvis/rules/dba/Container.java delete mode 100644 src/main/java/io/trygvis/rules/dns/DnsEntry.java delete mode 100644 src/main/java/io/trygvis/rules/dns/DnsEntryTerraformExpression.java delete mode 100644 src/main/java/io/trygvis/rules/engine/KeyValue.java delete mode 100644 src/main/java/io/trygvis/rules/engine/Main.java delete mode 100644 src/main/java/io/trygvis/rules/engine/TemplateEngine.java delete mode 100644 src/main/java/io/trygvis/rules/machine/Machine.java delete mode 100644 src/main/java/io/trygvis/rules/network/Ipv4Address.java delete mode 100644 src/main/java/io/trygvis/rules/network/Ipv4Cidr.java delete mode 100644 src/main/resources/META-INF/kmodule.xml delete mode 100644 src/main/resources/io/trygvis/rules/acme/acme.drl delete mode 100644 src/main/resources/io/trygvis/rules/acme/vpn.drl delete mode 100644 src/main/resources/io/trygvis/rules/dba/dba.drl delete mode 100644 src/main/resources/io/trygvis/rules/engine/default.drl delete mode 100644 src/main/resources/io/trygvis/rules/machine/machine.drl delete mode 100644 src/main/resources/io/trygvis/rules/terraform/terraform.drl delete mode 100644 src/test/java/io/trygvis/rules/acme/IpCalcTest.java diff --git a/.idea/runConfigurations/Main.xml b/.idea/runConfigurations/Main.xml deleted file mode 100644 index 73974ed..0000000 --- a/.idea/runConfigurations/Main.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - \ No newline at end of file diff --git a/classpath.txt b/classpath.txt index e1fd118..681bb0d 100644 --- a/classpath.txt +++ b/classpath.txt @@ -1,55 +1 @@ -io.trygvis.rules-sandbox:rules-sandbox:1.0-SNAPSHOT:jar -ch.obermuhlner:big-math:2.0.1: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.google.code.findbugs:annotations:3.0.1:jar -com.google.errorprone:error_prone_annotations:2.1.3:jar -com.google.guava:guava:25.0-jre:jar -com.google.j2objc:j2objc-annotations:1.1:jar -com.google.re2j:re2j:1.2:jar -com.googlecode.java-ipv6:java-ipv6:0.17:jar -com.hubspot.jinjava:jinjava:2.5.6:jar -com.thoughtworks.xstream:xstream:1.4.14:jar -com.zaxxer:SparseBitSet:1.2:jar -commons-codec:commons-codec:1.11:jar -commons-io:commons-io:2.8.0:jar -commons-net:commons-net:2.2: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-lang3:3.9: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.checkerframework:checker-compat-qual:2.0.0:jar -org.codehaus.mojo:animal-sniffer-annotations:1.14: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.javassist:javassist:3.26.0-GA:jar -org.jsoup:jsoup:1.8.3: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 +io.trygvis.rules-sandbox:rules-sandbox:1.0-SNAPSHOT:pom diff --git a/module/ri-engine/classpath.txt b/module/ri-engine/classpath.txt new file mode 100644 index 0000000..a1d5666 --- /dev/null +++ b/module/ri-engine/classpath.txt @@ -0,0 +1,56 @@ +io.trygvis.rules-sandbox:ri-engine:1.0-SNAPSHOT:jar +ch.obermuhlner:big-math:2.0.1: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.google.code.findbugs:annotations:3.0.1:jar +com.google.errorprone:error_prone_annotations:2.1.3:jar +com.google.guava:guava:25.0-jre:jar +com.google.j2objc:j2objc-annotations:1.1:jar +com.google.re2j:re2j:1.2:jar +com.googlecode.java-ipv6:java-ipv6:0.17:jar +com.hubspot.jinjava:jinjava:2.5.6:jar +com.thoughtworks.xstream:xstream:1.4.14:jar +com.zaxxer:SparseBitSet:1.2:jar +commons-codec:commons-codec:1.11:jar +commons-io:commons-io:2.8.0:jar +commons-net:commons-net:2.2:jar +io.trygvis.rules-sandbox:ri-wireguard:1.0-SNAPSHOT: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-lang3:3.9: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.checkerframework:checker-compat-qual:2.0.0:jar +org.codehaus.mojo:animal-sniffer-annotations:1.14: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.javassist:javassist:3.26.0-GA:jar +org.jsoup:jsoup:1.8.3: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/module/ri-engine/pom.xml b/module/ri-engine/pom.xml new file mode 100644 index 0000000..addd8c5 --- /dev/null +++ b/module/ri-engine/pom.xml @@ -0,0 +1,93 @@ + + + 4.0.0 + + + io.trygvis.rules-sandbox + rules-sandbox + 1.0-SNAPSHOT + ../../pom.xml + + + ri-engine + + + + ${project.groupId} + ri-wireguard + ${project.version} + compile + + + + 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 + + + + com.hubspot.jinjava + jinjava + 2.5.6 + + + + commons-io + commons-io + 2.8.0 + + + + org.junit.jupiter + junit-jupiter-api + 5.7.0 + test + + + org.junit.jupiter + junit-jupiter-params + 5.7.0 + test + + + diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/acme/AcmeIo.java b/module/ri-engine/src/main/java/io/trygvis/rules/acme/AcmeIo.java new file mode 100644 index 0000000..456195d --- /dev/null +++ b/module/ri-engine/src/main/java/io/trygvis/rules/acme/AcmeIo.java @@ -0,0 +1,260 @@ +package io.trygvis.rules.acme; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.TypeFactory; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; +import org.apache.commons.collections4.OrderedMap; +import org.drools.core.common.DefaultFactHandle; +import org.kie.api.KieBase; +import org.kie.api.runtime.rule.FactHandle; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.*; +import java.util.function.Function; + +@SuppressWarnings("unchecked") +public class AcmeIo { + private final ObjectMapper mapper; + + public AcmeIo(KieBase kieBase) { + var factory = new YAMLFactory(); + factory.enable(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID); + factory.enable(YAMLGenerator.Feature.USE_NATIVE_OBJECT_ID); + mapper = new ObjectMapper(factory); + var typeFactory = TypeFactory.defaultInstance() + .withClassLoader(new AcmeClassLoader(kieBase)); + mapper.setTypeFactory(typeFactory); + 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 = mapper.getTypeFactory().findClass(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 { + dump(s, factHandles, (o) -> true); + } + + // This should just sort by all getters instead. + static class FactCollection { + public final Class type; + public final List values; + + public FactCollection(Class type) { + this.type = type; + this.values = new ArrayList<>(); + } + + public void sort() { + var comparator = comparable(type); + + this.values.sort(comparator); + } + } + + private static final Map, Comparator> comparators = new HashMap<>(); + + private static > Comparator comparable(Class klass) { + var comparator = comparators.get(klass); + if (comparator != null) { + return comparator; + } + + // TODO: check if klass is a Comparable directly. + + var prioritizedKeys = List.of("key", "name", "fqdn"); + + var discoveredFieldsP1 = new LinkedHashMap>(); + var discoveredFieldsP2 = new LinkedHashMap>(); + + var prioritizedTypes = List.of(String.class, int.class, Number.class); + + for (var f : klass.getDeclaredFields()) { + if (f.getDeclaringClass() == Object.class) { + continue; + } + + if (!f.trySetAccessible()) { + continue; + } + + var collection = discoveredFieldsP2; + + if (prioritizedTypes.contains(f.getType())) { + collection = discoveredFieldsP1; + } + + collection.put(f.getName(), (Object o) -> { + try { + return f.get(o); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + }); + } + +// for (var m : klass.getFields()) { +// if (m.getParameterCount() != 0) { +// continue; +// } +// +// var name = m.getName(); +// +// if (name.startsWith("get") && name.length() > 3 && Character.isUpperCase(name.charAt(4))) { +// name = name.substring(3, 3).toLowerCase() + name.substring(4); +// } else { +// continue; +// } +// +// if (!m.isAccessible()) { +// if (!m.trySetAccessible()) +// return null; +// } +// +// discoveredFields.put(name, m); +// } + +// System.out.printf("Sorting %s by:%n", klass.getName()); + + var discoveredFields = new LinkedHashMap<>(discoveredFieldsP1); + discoveredFields.putAll(discoveredFieldsP2); + + List> accessors = new ArrayList<>(); + for (String prioritizedKey : prioritizedKeys) { + var m = discoveredFields.remove(prioritizedKey); + if (m == null) { + continue; + } + + accessors.add(m); +// System.out.println(" + " + prioritizedKey); + } + accessors.addAll(discoveredFields.values()); +// discoveredFields.keySet().forEach((s)-> System.out.println(" - " + s)); + + comparator = (a, b) -> { +// if (klass.getName().contains("AcmeServer")) { +// System.out.println("AcmeIo.comparable"); +// } + + for (var method : accessors) { + var x = method.apply(a); + var y = method.apply(b); + + if (x == null && y == null) { + continue; + } + + if (x == null) { + return -1; + } else if (y == null) { + return 1; + } else { + var res = x.toString().compareTo(y.toString()); + if (res != 0) { + return res; + } + } + } + + return 0; + }; + + comparators.put(klass, comparator); + + return comparator; + } + + public void dump(String s, Collection factHandles, Function filter) throws IOException { + var out = new File("out"); + + if (!out.isDirectory()) { + if (!out.mkdirs()) { + throw new IOException("Could not create directory: " + out); + } + } + + var facts = new TreeMap, FactCollection>(Comparator.comparing(Class::getName)); + for (var handle : factHandles) { + if (handle instanceof DefaultFactHandle h) { + var obj = h.getObject(); + if (!filter.apply(obj)) { + continue; + } + + Class type = obj.getClass(); + var collection = facts.get(type); + + if (collection == null) { + collection = new FactCollection(type); + facts.put(type, collection); + } + + collection.values.add(obj); + } + } + + var factory = mapper.getFactory(); + try (var writer = new FileWriter(new File(out, s + ".yaml")); + var g = factory.createGenerator(writer)) { + for (var e : facts.entrySet()) { + var name = e.getKey().getName(); + + var collection = e.getValue(); + collection.sort(); + for (var fact : collection.values) { + g.writeObject(new AcmeObject(name, mapper.valueToTree(fact))); + } + } + } + } + + private static class AcmeClassLoader extends ClassLoader { + private final KieBase kieBase; + + public AcmeClassLoader(KieBase kieBase) { + this.kieBase = kieBase; + } + + @Override + public Class loadClass(String name) throws ClassNotFoundException { + try { + return super.loadClass(name); + } catch (ClassNotFoundException e) { + var i = name.lastIndexOf('.'); + String pkg, klass; + if (i == -1) { + pkg = null; + klass = name; + } else { + pkg = name.substring(0, i); + klass = name.substring(i + 1); + } + var clazz = kieBase.getFactType(pkg, klass); + if (clazz == null) { + throw e; + } + + return clazz.getFactClass(); + } + } + } +} diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/acme/AcmeMyApp.java b/module/ri-engine/src/main/java/io/trygvis/rules/acme/AcmeMyApp.java new file mode 100644 index 0000000..a1340e7 --- /dev/null +++ b/module/ri-engine/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/module/ri-engine/src/main/java/io/trygvis/rules/acme/AcmeObject.java b/module/ri-engine/src/main/java/io/trygvis/rules/acme/AcmeObject.java new file mode 100644 index 0000000..a75c4ba --- /dev/null +++ b/module/ri-engine/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/module/ri-engine/src/main/java/io/trygvis/rules/acme/AcmeOps.java b/module/ri-engine/src/main/java/io/trygvis/rules/acme/AcmeOps.java new file mode 100644 index 0000000..147fcfa --- /dev/null +++ b/module/ri-engine/src/main/java/io/trygvis/rules/acme/AcmeOps.java @@ -0,0 +1,4 @@ +package io.trygvis.rules.acme; + +public class AcmeOps { +} diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/acme/IpCalc.java b/module/ri-engine/src/main/java/io/trygvis/rules/acme/IpCalc.java new file mode 100644 index 0000000..5369d62 --- /dev/null +++ b/module/ri-engine/src/main/java/io/trygvis/rules/acme/IpCalc.java @@ -0,0 +1,67 @@ +package io.trygvis.rules.acme; + +import io.trygvis.rules.network.Ipv4Cidr; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +public class IpCalc { + private static final Pattern pattern = Pattern.compile("([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})/([0-9]{1,3})"); + + public static class FirstLast { + public final int first; + public final int last; + + public FirstLast(int first, int last) { + this.first = first; + this.last = last; + } + } + + public static Ipv4Cidr cidr(String cidr) { + var matcher = pattern.matcher(cidr); + if (!matcher.matches()) { + throw new IllegalArgumentException("Not a CIDR: " + cidr); + } + + var b1 = matcher.group(1); + var b2 = matcher.group(2); + var b3 = matcher.group(3); + var b4 = matcher.group(4); + + int network = parse(b1) << 24 | + parse(b2) << 16 | + parse(b3) << 8 | + parse(b4); + +// System.out.printf("network = %x%n", network); + + var l = matcher.group(5); + var bits = Integer.parseInt(l); + var hostBits = 32 - bits; + int size = 1 << hostBits; + + int netmask = (-1 >> hostBits) << hostBits; +// System.out.printf("netmask = %08x%n", netmask); + + int x = network & ~netmask; + + if (x != 0) { + throw new IllegalArgumentException("Not a CIDR: " + cidr); + } + + return new Ipv4Cidr(network, netmask, size, bits); + } + + private static int parse(String s) { + var i = Integer.parseInt(s); + if (i > 255) { + throw new IllegalArgumentException("Not a CIDR"); + } + + return i; + } +} diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/dba/Cluster.java b/module/ri-engine/src/main/java/io/trygvis/rules/dba/Cluster.java new file mode 100644 index 0000000..949d9ae --- /dev/null +++ b/module/ri-engine/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/module/ri-engine/src/main/java/io/trygvis/rules/dba/Container.java b/module/ri-engine/src/main/java/io/trygvis/rules/dba/Container.java new file mode 100644 index 0000000..6df939d --- /dev/null +++ b/module/ri-engine/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/module/ri-engine/src/main/java/io/trygvis/rules/dns/DnsEntry.java b/module/ri-engine/src/main/java/io/trygvis/rules/dns/DnsEntry.java new file mode 100644 index 0000000..105ef79 --- /dev/null +++ b/module/ri-engine/src/main/java/io/trygvis/rules/dns/DnsEntry.java @@ -0,0 +1,27 @@ +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"); + } + + public String getFqdn() { + return fqdn; + } + + public String getType() { + return type; + } +} diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/dns/DnsEntryTerraformExpression.java b/module/ri-engine/src/main/java/io/trygvis/rules/dns/DnsEntryTerraformExpression.java new file mode 100644 index 0000000..79bf934 --- /dev/null +++ b/module/ri-engine/src/main/java/io/trygvis/rules/dns/DnsEntryTerraformExpression.java @@ -0,0 +1,21 @@ +package io.trygvis.rules.dns; + +public class DnsEntryTerraformExpression { + public DnsEntry entry; + public String key; + public String expression; + + public DnsEntryTerraformExpression(DnsEntry entry, String key, String expression) { + this.entry = entry; + this.key = key; + this.expression = expression; + } + + public String getKey() { + return key; + } + + public String getExpression() { + return expression; + } +} diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/engine/KeyValue.java b/module/ri-engine/src/main/java/io/trygvis/rules/engine/KeyValue.java new file mode 100644 index 0000000..5046169 --- /dev/null +++ b/module/ri-engine/src/main/java/io/trygvis/rules/engine/KeyValue.java @@ -0,0 +1,14 @@ +package io.trygvis.rules.engine; + +public class KeyValue { + public String key; + public String value; + + public KeyValue() { + } + + public KeyValue(String key, String value) { + this.key = key; + this.value = value; + } +} diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/engine/Main.java b/module/ri-engine/src/main/java/io/trygvis/rules/engine/Main.java new file mode 100644 index 0000000..7c96be6 --- /dev/null +++ b/module/ri-engine/src/main/java/io/trygvis/rules/engine/Main.java @@ -0,0 +1,53 @@ +package io.trygvis.rules.engine; + +import io.trygvis.rules.acme.AcmeIo; +import io.trygvis.rules.dns.DnsEntry; +import io.trygvis.rules.machine.Machine; +import io.trygvis.rules.network.Ipv4Address; +import io.trygvis.rules.network.Ipv4Cidr; +import org.drools.core.audit.WorkingMemoryConsoleLogger; +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 services = KieServices.Factory.get(); + var container = services.getKieClasspathContainer(); + var kieBase = container.getKieBase(); + + var io = new AcmeIo(kieBase); + var objects = io.load("acme.yaml"); + + var session = container.newKieSession(); + + session.setGlobal("te", new TemplateEngine()); + + 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.getAgenda().getAgendaGroup("init").setFocus(); + + session.fireAllRules(); + + io.dump("phase-1", session.getFactHandles()); + + io.dump("vpn0", session.getFactHandles(), (Object o) -> + o.getClass().getName().contains("Wg") + || o instanceof Machine + || o instanceof DnsEntry + || o instanceof Ipv4Cidr + || o instanceof Ipv4Address + ); + + session.dispose(); + } +} 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 new file mode 100644 index 0000000..ace7aaf --- /dev/null +++ b/module/ri-engine/src/main/java/io/trygvis/rules/engine/TemplateEngine.java @@ -0,0 +1,30 @@ +package io.trygvis.rules.engine; + +import ch.qos.logback.core.util.FileUtil; +import com.hubspot.jinjava.Jinjava; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; + +public class TemplateEngine { + private final Jinjava jinjava = new Jinjava(); + + public void template(String name, String output, Map params) throws IOException { + var template = Files.readString(Path.of("j2", name + ".j2")); + String renderedTemplate = jinjava.render(template, params); +// System.out.println("-----------------------------------"); +// for (var item : params.entrySet()) { +// System.out.printf(" %s : %s%n", item.getKey(), item.getValue()); +// } + System.out.println("-----------------------------------"); + System.out.println(renderedTemplate); + System.out.println("-----------------------------------"); + + var f = new File("gen", output); + FileUtil.createMissingParentDirectories(f); + Files.writeString(f.toPath(), renderedTemplate); + } +} diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/machine/Machine.java b/module/ri-engine/src/main/java/io/trygvis/rules/machine/Machine.java new file mode 100644 index 0000000..cc3f2ed --- /dev/null +++ b/module/ri-engine/src/main/java/io/trygvis/rules/machine/Machine.java @@ -0,0 +1,13 @@ +package io.trygvis.rules.machine; + +public class Machine { + public String name; + public String fqdn; + + public Machine() { + } + + public Machine(String name) { + this.name = name; + } +} diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/network/Ipv4Address.java b/module/ri-engine/src/main/java/io/trygvis/rules/network/Ipv4Address.java new file mode 100644 index 0000000..7ca9ca5 --- /dev/null +++ b/module/ri-engine/src/main/java/io/trygvis/rules/network/Ipv4Address.java @@ -0,0 +1,57 @@ +package io.trygvis.rules.network; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import java.io.IOException; +import java.util.Objects; + +@JsonSerialize(using = Ipv4Address.Serializer.class) +public class Ipv4Address implements Comparable { + public final int address; + + public Ipv4Address(int address) { + this.address = address; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o instanceof Ipv4Address other) { + return address == other.address; + } + + return false; + } + + @Override + public int hashCode() { + return Objects.hash(address); + } + + @Override + public int compareTo(Ipv4Address o) { + return address - o.address; + } + + @Override + public String toString() { + return "%d.%d.%d.%d".formatted( + address >> 24 & 0xff, + address >> 16 & 0xff, + address >> 8 & 0xff, + address & 0xff); + } + + public static class Serializer extends JsonSerializer { + @Override + public void serialize(Ipv4Address value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeObjectField("value", value.toString()); + gen.writeEndObject(); + } + } +} diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/network/Ipv4Cidr.java b/module/ri-engine/src/main/java/io/trygvis/rules/network/Ipv4Cidr.java new file mode 100644 index 0000000..e69cd02 --- /dev/null +++ b/module/ri-engine/src/main/java/io/trygvis/rules/network/Ipv4Cidr.java @@ -0,0 +1,54 @@ +package io.trygvis.rules.network; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; + +@JsonSerialize(using = Ipv4Cidr.Serializer.class) +public class Ipv4Cidr { + public final int network; + public final int netmask; + public final int size; + public final int bits; + + public Ipv4Cidr(int network, int netmask, int size, int bits) { + this.network = network; + this.netmask = netmask; + this.size = size; + this.bits = bits; + } + + @Override + public String toString() { + return "%d.%d.%d.%d/%d".formatted( + network >> 24 & 0xff, + network >> 16 & 0xff, + network >> 8 & 0xff, + network & 0xff, + bits); + } + + public Collection addresses() { + var end = network + size; + var addresses = new ArrayList(size); + for (int address = network; address < end; address++) { + addresses.add(new Ipv4Address(address)); + } + + return addresses; + } + + public static class Serializer extends JsonSerializer { + @Override + public void serialize(Ipv4Cidr value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeObjectField("value", value.toString()); + gen.writeEndObject(); + } + } +} diff --git a/module/ri-engine/src/main/resources/META-INF/kmodule.xml b/module/ri-engine/src/main/resources/META-INF/kmodule.xml new file mode 100644 index 0000000..7a46b1a --- /dev/null +++ b/module/ri-engine/src/main/resources/META-INF/kmodule.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/module/ri-engine/src/main/resources/io/trygvis/rules/acme/acme.drl b/module/ri-engine/src/main/resources/io/trygvis/rules/acme/acme.drl new file mode 100644 index 0000000..0465343 --- /dev/null +++ b/module/ri-engine/src/main/resources/io/trygvis/rules/acme/acme.drl @@ -0,0 +1,62 @@ +package io.trygvis.rules.acme; + +import io.trygvis.rules.machine.Machine; +import io.trygvis.rules.dba.Cluster; +import io.trygvis.rules.dba.Container; + +declare AcmeServer + name : String + machine : Machine +end + +//declare MachinePublicName +// machine : Machine +// fqdn : String +//end + +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 + +rule "Create Acme servers" +when + $m : Machine(name.startsWith("acme-")) + not(AcmeServer(name == $m.name)) +then + var s = new AcmeServer(); + s.name = $m.name; + s.machine = $m; + insert(s); +end + +rule "Set public domain for ACME servers" +when + $m : Machine(fqdn == null) + $s : AcmeServer(machine == $m) +then + var fqdn = "%s.machine.acme.com".formatted($s.machine.name); + $s.machine.fqdn = fqdn; + update($s.machine) +end diff --git a/module/ri-engine/src/main/resources/io/trygvis/rules/dba/dba.drl b/module/ri-engine/src/main/resources/io/trygvis/rules/dba/dba.drl new file mode 100644 index 0000000..7beceef --- /dev/null +++ b/module/ri-engine/src/main/resources/io/trygvis/rules/dba/dba.drl @@ -0,0 +1 @@ +package io.trygvis.rules.dba; diff --git a/module/ri-engine/src/main/resources/io/trygvis/rules/engine/default.drl b/module/ri-engine/src/main/resources/io/trygvis/rules/engine/default.drl new file mode 100644 index 0000000..090fddf --- /dev/null +++ b/module/ri-engine/src/main/resources/io/trygvis/rules/engine/default.drl @@ -0,0 +1,15 @@ +package io.trygvis.rules.engine; +import java.util.Map +import org.apache.commons.io.FileSystem +import org.apache.commons.io.FileUtils +import java.io.File + +rule "Clean directories" + agenda-group "init" +when + not(KeyValue(key == "rm-gen")); +then + System.out.println("Cleaning gen!"); + FileUtils.deleteDirectory(new File("gen")); + insert(new KeyValue("rm-gen", null)); +end diff --git a/module/ri-engine/src/main/resources/io/trygvis/rules/machine/machine.drl b/module/ri-engine/src/main/resources/io/trygvis/rules/machine/machine.drl new file mode 100644 index 0000000..a9a379f --- /dev/null +++ b/module/ri-engine/src/main/resources/io/trygvis/rules/machine/machine.drl @@ -0,0 +1,6 @@ +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; diff --git a/module/ri-engine/src/main/resources/io/trygvis/rules/terraform/terraform.drl b/module/ri-engine/src/main/resources/io/trygvis/rules/terraform/terraform.drl new file mode 100644 index 0000000..40b9f7c --- /dev/null +++ b/module/ri-engine/src/main/resources/io/trygvis/rules/terraform/terraform.drl @@ -0,0 +1,60 @@ +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.Map; + +global io.trygvis.rules.engine.TemplateEngine te; + +declare ScalewayMachine + machine : Machine + key : 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 + var a = DnsEntry.a($machine.fqdn); + insert(a); + + var ipv4 = "scaleway_instance_ip.%s.address".formatted($machine.name); + insert(new DnsEntryTerraformExpression(a, $machine.name, ipv4)); +end + +rule "TF for TerraformMachine" +when + $m: Machine() + $scw: ScalewayMachine(machine == $m) +then + var path = "platform/terraform/%s.tf".formatted($scw.getKey()); + te.template("terraform-machine", path, Map.of("m", $m, "scw", $scw)); +end + +rule "Terraform for DNS" +when + $entry: DnsEntry() + $tf : DnsEntryTerraformExpression(entry == $entry) +then + var path = "dns/%s.tf".formatted($tf.key); + te.template("terraform-record-set", path, Map.of( + "entry", $entry, + "tf", $tf) + ); +end diff --git a/module/ri-engine/src/test/java/io/trygvis/rules/acme/IpCalcTest.java b/module/ri-engine/src/test/java/io/trygvis/rules/acme/IpCalcTest.java new file mode 100644 index 0000000..8b1e2c6 --- /dev/null +++ b/module/ri-engine/src/test/java/io/trygvis/rules/acme/IpCalcTest.java @@ -0,0 +1,27 @@ +package io.trygvis.rules.acme; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.junit.jupiter.api.Assertions.*; + +class IpCalcTest { + + @Test + public void basic() { + Assertions.assertThrows(IllegalArgumentException.class, () -> IpCalc.cidr("192.168.1.1/24").addresses()); + assertEquals(256, IpCalc.cidr("192.168.1.0/24").addresses().size()); + assertEquals(128, IpCalc.cidr("192.168.1.128/25").addresses().size()); + } + + @ParameterizedTest + @ValueSource(strings = { + "192.168.1.0/24", + "192.168.1.128/25", + }) + public void testParsing(String s) { + assertEquals(s, IpCalc.cidr(s).toString()); + } +} diff --git a/module/ri-wireguard/classpath.txt b/module/ri-wireguard/classpath.txt new file mode 100644 index 0000000..52ccd4d --- /dev/null +++ b/module/ri-wireguard/classpath.txt @@ -0,0 +1 @@ +io.trygvis.rules-sandbox:ri-wireguard:1.0-SNAPSHOT:jar diff --git a/module/ri-wireguard/pom.xml b/module/ri-wireguard/pom.xml new file mode 100644 index 0000000..085271e --- /dev/null +++ b/module/ri-wireguard/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + io.trygvis.rules-sandbox + rules-sandbox + 1.0-SNAPSHOT + ../../pom.xml + + + ri-wireguard + + diff --git a/module/ri-wireguard/src/main/java/io/trygvis/rules/acme/Foo.java b/module/ri-wireguard/src/main/java/io/trygvis/rules/acme/Foo.java new file mode 100644 index 0000000..44f5eba --- /dev/null +++ b/module/ri-wireguard/src/main/java/io/trygvis/rules/acme/Foo.java @@ -0,0 +1,7 @@ +package io.trygvis.rules.acme; + +public class Foo { + public static void main(String[] args) { + System.out.println("Foo.main"); + } +} diff --git a/module/ri-wireguard/src/main/resources/META-INF/kmodule.xml b/module/ri-wireguard/src/main/resources/META-INF/kmodule.xml new file mode 100644 index 0000000..64cc4d2 --- /dev/null +++ b/module/ri-wireguard/src/main/resources/META-INF/kmodule.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/module/ri-wireguard/src/main/resources/io/trygvis/rules/acme/vpn.drl b/module/ri-wireguard/src/main/resources/io/trygvis/rules/acme/vpn.drl new file mode 100644 index 0000000..7896953 --- /dev/null +++ b/module/ri-wireguard/src/main/resources/io/trygvis/rules/acme/vpn.drl @@ -0,0 +1,105 @@ +package io.trygvis.rules.acme; + +import java.util.ArrayList +import io.trygvis.rules.machine.Machine; +import io.trygvis.rules.dns.DnsEntry; +import io.trygvis.rules.acme.AcmeServer +import io.trygvis.rules.network.Ipv4Address +import io.trygvis.rules.network.Ipv4Cidr + +dialect "mvel" + +declare WgNet + name : String + domain : String + linkCidr : String + networkCidr : String +end + +declare WgIpPool + net : String + role : String + cidr : Ipv4Cidr +end + +rule "Create link network" when + $net : WgNet() + not(Ipv4Cidr(network == IpCalc.cidr($net.linkCidr).network)) +then + insert(new WgIpPool($net.name, "link", IpCalc.cidr($net.linkCidr))) + insert(new WgIpPool($net.name, "network", IpCalc.cidr($net.networkCidr))) +end + +declare WgHost + name : String + net : String + publicName : String + netToNetIp : String + networkIp : String +end + +rule "WgHost VPN machines" +when + $machine : Machine() + $wgNet : WgNet(name == "vpn0") + not(WgHost(name == $machine.name)) +then + var wgHost = new WgHost(); + wgHost.name = $machine.name; + wgHost.net = $wgNet.name; + wgHost.publicName = $machine.fqdn; + insert(wgHost) +end + +rule "Set public name of WgHost" +when + $host : WgHost(publicName == null) + $m : Machine(name == $host.name, fqdn != null) +then + modify($host) { + publicName = $m.fqdn + } +end + +rule "Make DNS entries for all VPN hosts" +when + $h : WgHost() + $net : WgNet(name == $h.net) + not(DnsEntry(fqdn == "%s.%s".formatted($h.name, $net.domain), type == "A")) +then + var fqdn = "%s.%s".formatted($h.name, $net.domain); + insert(DnsEntry.a(fqdn)) +end + +declare WgConnection + host : String + to : String +end + +rule "Connect VPN nodes" + salience -1 +when + $h : WgHost() + $other : WgHost(publicName != null, name != $h.name) +then + insert(new WgConnection($h.name, $other.name)) +end + +declare WgIpAllocation + host : String + role : String + ip : Ipv4Address +end + +rule "Assign IP" +when + $net : WgNet() + $host : WgHost(net == $net.name) + $pool : WgIpPool(net == $net.name) + not(WgIpAllocation(host == $host.name, role == $pool.role)) + $ip : Ipv4Address() from $pool.cidr.addresses() + not(WgIpAllocation(ip == $ip)) +then + System.out.printf("IP: net=%s, pool.role=%s, host=%s, ip=%s%n", $net.name, $pool.role, $host.name, $ip); + insert(new WgIpAllocation($host.name, $pool.role, $ip)) +end diff --git a/pom.xml b/pom.xml index 47b1d04..70a06b2 100644 --- a/pom.xml +++ b/pom.xml @@ -7,6 +7,7 @@ io.trygvis.rules-sandbox rules-sandbox 1.0-SNAPSHOT + pom io.trygvis.rules.sandbox @@ -54,81 +55,13 @@ 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 - - - - com.hubspot.jinjava - jinjava - 2.5.6 - - - - commons-io - commons-io - 2.8.0 - - - - org.junit.jupiter - junit-jupiter-api - 5.7.0 - test - - - org.junit.jupiter - junit-jupiter-params - 5.7.0 - test - - - + + module/ri-engine + module/ri-wireguard + install @@ -145,6 +78,14 @@ ${java.version} + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + --enable-preview + + eu.nets.oss.maven classpath-maven-plugin diff --git a/src/main/java/io/trygvis/rules/acme/AcmeIo.java b/src/main/java/io/trygvis/rules/acme/AcmeIo.java deleted file mode 100644 index 456195d..0000000 --- a/src/main/java/io/trygvis/rules/acme/AcmeIo.java +++ /dev/null @@ -1,260 +0,0 @@ -package io.trygvis.rules.acme; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.type.TypeFactory; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; -import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; -import org.apache.commons.collections4.OrderedMap; -import org.drools.core.common.DefaultFactHandle; -import org.kie.api.KieBase; -import org.kie.api.runtime.rule.FactHandle; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.*; -import java.util.function.Function; - -@SuppressWarnings("unchecked") -public class AcmeIo { - private final ObjectMapper mapper; - - public AcmeIo(KieBase kieBase) { - var factory = new YAMLFactory(); - factory.enable(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID); - factory.enable(YAMLGenerator.Feature.USE_NATIVE_OBJECT_ID); - mapper = new ObjectMapper(factory); - var typeFactory = TypeFactory.defaultInstance() - .withClassLoader(new AcmeClassLoader(kieBase)); - mapper.setTypeFactory(typeFactory); - 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 = mapper.getTypeFactory().findClass(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 { - dump(s, factHandles, (o) -> true); - } - - // This should just sort by all getters instead. - static class FactCollection { - public final Class type; - public final List values; - - public FactCollection(Class type) { - this.type = type; - this.values = new ArrayList<>(); - } - - public void sort() { - var comparator = comparable(type); - - this.values.sort(comparator); - } - } - - private static final Map, Comparator> comparators = new HashMap<>(); - - private static > Comparator comparable(Class klass) { - var comparator = comparators.get(klass); - if (comparator != null) { - return comparator; - } - - // TODO: check if klass is a Comparable directly. - - var prioritizedKeys = List.of("key", "name", "fqdn"); - - var discoveredFieldsP1 = new LinkedHashMap>(); - var discoveredFieldsP2 = new LinkedHashMap>(); - - var prioritizedTypes = List.of(String.class, int.class, Number.class); - - for (var f : klass.getDeclaredFields()) { - if (f.getDeclaringClass() == Object.class) { - continue; - } - - if (!f.trySetAccessible()) { - continue; - } - - var collection = discoveredFieldsP2; - - if (prioritizedTypes.contains(f.getType())) { - collection = discoveredFieldsP1; - } - - collection.put(f.getName(), (Object o) -> { - try { - return f.get(o); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - }); - } - -// for (var m : klass.getFields()) { -// if (m.getParameterCount() != 0) { -// continue; -// } -// -// var name = m.getName(); -// -// if (name.startsWith("get") && name.length() > 3 && Character.isUpperCase(name.charAt(4))) { -// name = name.substring(3, 3).toLowerCase() + name.substring(4); -// } else { -// continue; -// } -// -// if (!m.isAccessible()) { -// if (!m.trySetAccessible()) -// return null; -// } -// -// discoveredFields.put(name, m); -// } - -// System.out.printf("Sorting %s by:%n", klass.getName()); - - var discoveredFields = new LinkedHashMap<>(discoveredFieldsP1); - discoveredFields.putAll(discoveredFieldsP2); - - List> accessors = new ArrayList<>(); - for (String prioritizedKey : prioritizedKeys) { - var m = discoveredFields.remove(prioritizedKey); - if (m == null) { - continue; - } - - accessors.add(m); -// System.out.println(" + " + prioritizedKey); - } - accessors.addAll(discoveredFields.values()); -// discoveredFields.keySet().forEach((s)-> System.out.println(" - " + s)); - - comparator = (a, b) -> { -// if (klass.getName().contains("AcmeServer")) { -// System.out.println("AcmeIo.comparable"); -// } - - for (var method : accessors) { - var x = method.apply(a); - var y = method.apply(b); - - if (x == null && y == null) { - continue; - } - - if (x == null) { - return -1; - } else if (y == null) { - return 1; - } else { - var res = x.toString().compareTo(y.toString()); - if (res != 0) { - return res; - } - } - } - - return 0; - }; - - comparators.put(klass, comparator); - - return comparator; - } - - public void dump(String s, Collection factHandles, Function filter) throws IOException { - var out = new File("out"); - - if (!out.isDirectory()) { - if (!out.mkdirs()) { - throw new IOException("Could not create directory: " + out); - } - } - - var facts = new TreeMap, FactCollection>(Comparator.comparing(Class::getName)); - for (var handle : factHandles) { - if (handle instanceof DefaultFactHandle h) { - var obj = h.getObject(); - if (!filter.apply(obj)) { - continue; - } - - Class type = obj.getClass(); - var collection = facts.get(type); - - if (collection == null) { - collection = new FactCollection(type); - facts.put(type, collection); - } - - collection.values.add(obj); - } - } - - var factory = mapper.getFactory(); - try (var writer = new FileWriter(new File(out, s + ".yaml")); - var g = factory.createGenerator(writer)) { - for (var e : facts.entrySet()) { - var name = e.getKey().getName(); - - var collection = e.getValue(); - collection.sort(); - for (var fact : collection.values) { - g.writeObject(new AcmeObject(name, mapper.valueToTree(fact))); - } - } - } - } - - private static class AcmeClassLoader extends ClassLoader { - private final KieBase kieBase; - - public AcmeClassLoader(KieBase kieBase) { - this.kieBase = kieBase; - } - - @Override - public Class loadClass(String name) throws ClassNotFoundException { - try { - return super.loadClass(name); - } catch (ClassNotFoundException e) { - var i = name.lastIndexOf('.'); - String pkg, klass; - if (i == -1) { - pkg = null; - klass = name; - } else { - pkg = name.substring(0, i); - klass = name.substring(i + 1); - } - var clazz = kieBase.getFactType(pkg, klass); - if (clazz == null) { - throw e; - } - - return clazz.getFactClass(); - } - } - } -} diff --git a/src/main/java/io/trygvis/rules/acme/AcmeMyApp.java b/src/main/java/io/trygvis/rules/acme/AcmeMyApp.java deleted file mode 100644 index a1340e7..0000000 --- a/src/main/java/io/trygvis/rules/acme/AcmeMyApp.java +++ /dev/null @@ -1,6 +0,0 @@ -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 deleted file mode 100644 index a75c4ba..0000000 --- a/src/main/java/io/trygvis/rules/acme/AcmeObject.java +++ /dev/null @@ -1,16 +0,0 @@ -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 deleted file mode 100644 index 147fcfa..0000000 --- a/src/main/java/io/trygvis/rules/acme/AcmeOps.java +++ /dev/null @@ -1,4 +0,0 @@ -package io.trygvis.rules.acme; - -public class AcmeOps { -} diff --git a/src/main/java/io/trygvis/rules/acme/IpCalc.java b/src/main/java/io/trygvis/rules/acme/IpCalc.java deleted file mode 100644 index 5369d62..0000000 --- a/src/main/java/io/trygvis/rules/acme/IpCalc.java +++ /dev/null @@ -1,67 +0,0 @@ -package io.trygvis.rules.acme; - -import io.trygvis.rules.network.Ipv4Cidr; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; - -public class IpCalc { - private static final Pattern pattern = Pattern.compile("([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})/([0-9]{1,3})"); - - public static class FirstLast { - public final int first; - public final int last; - - public FirstLast(int first, int last) { - this.first = first; - this.last = last; - } - } - - public static Ipv4Cidr cidr(String cidr) { - var matcher = pattern.matcher(cidr); - if (!matcher.matches()) { - throw new IllegalArgumentException("Not a CIDR: " + cidr); - } - - var b1 = matcher.group(1); - var b2 = matcher.group(2); - var b3 = matcher.group(3); - var b4 = matcher.group(4); - - int network = parse(b1) << 24 | - parse(b2) << 16 | - parse(b3) << 8 | - parse(b4); - -// System.out.printf("network = %x%n", network); - - var l = matcher.group(5); - var bits = Integer.parseInt(l); - var hostBits = 32 - bits; - int size = 1 << hostBits; - - int netmask = (-1 >> hostBits) << hostBits; -// System.out.printf("netmask = %08x%n", netmask); - - int x = network & ~netmask; - - if (x != 0) { - throw new IllegalArgumentException("Not a CIDR: " + cidr); - } - - return new Ipv4Cidr(network, netmask, size, bits); - } - - private static int parse(String s) { - var i = Integer.parseInt(s); - if (i > 255) { - throw new IllegalArgumentException("Not a CIDR"); - } - - return i; - } -} diff --git a/src/main/java/io/trygvis/rules/dba/Cluster.java b/src/main/java/io/trygvis/rules/dba/Cluster.java deleted file mode 100644 index 949d9ae..0000000 --- a/src/main/java/io/trygvis/rules/dba/Cluster.java +++ /dev/null @@ -1,9 +0,0 @@ -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 deleted file mode 100644 index 6df939d..0000000 --- a/src/main/java/io/trygvis/rules/dba/Container.java +++ /dev/null @@ -1,17 +0,0 @@ -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 deleted file mode 100644 index 105ef79..0000000 --- a/src/main/java/io/trygvis/rules/dns/DnsEntry.java +++ /dev/null @@ -1,27 +0,0 @@ -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"); - } - - public String getFqdn() { - return fqdn; - } - - public String getType() { - return type; - } -} diff --git a/src/main/java/io/trygvis/rules/dns/DnsEntryTerraformExpression.java b/src/main/java/io/trygvis/rules/dns/DnsEntryTerraformExpression.java deleted file mode 100644 index 79bf934..0000000 --- a/src/main/java/io/trygvis/rules/dns/DnsEntryTerraformExpression.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.trygvis.rules.dns; - -public class DnsEntryTerraformExpression { - public DnsEntry entry; - public String key; - public String expression; - - public DnsEntryTerraformExpression(DnsEntry entry, String key, String expression) { - this.entry = entry; - this.key = key; - this.expression = expression; - } - - public String getKey() { - return key; - } - - public String getExpression() { - return expression; - } -} diff --git a/src/main/java/io/trygvis/rules/engine/KeyValue.java b/src/main/java/io/trygvis/rules/engine/KeyValue.java deleted file mode 100644 index 5046169..0000000 --- a/src/main/java/io/trygvis/rules/engine/KeyValue.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.trygvis.rules.engine; - -public class KeyValue { - public String key; - public String value; - - public KeyValue() { - } - - public KeyValue(String key, String value) { - this.key = key; - this.value = value; - } -} diff --git a/src/main/java/io/trygvis/rules/engine/Main.java b/src/main/java/io/trygvis/rules/engine/Main.java deleted file mode 100644 index 7c96be6..0000000 --- a/src/main/java/io/trygvis/rules/engine/Main.java +++ /dev/null @@ -1,53 +0,0 @@ -package io.trygvis.rules.engine; - -import io.trygvis.rules.acme.AcmeIo; -import io.trygvis.rules.dns.DnsEntry; -import io.trygvis.rules.machine.Machine; -import io.trygvis.rules.network.Ipv4Address; -import io.trygvis.rules.network.Ipv4Cidr; -import org.drools.core.audit.WorkingMemoryConsoleLogger; -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 services = KieServices.Factory.get(); - var container = services.getKieClasspathContainer(); - var kieBase = container.getKieBase(); - - var io = new AcmeIo(kieBase); - var objects = io.load("acme.yaml"); - - var session = container.newKieSession(); - - session.setGlobal("te", new TemplateEngine()); - - 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.getAgenda().getAgendaGroup("init").setFocus(); - - session.fireAllRules(); - - io.dump("phase-1", session.getFactHandles()); - - io.dump("vpn0", session.getFactHandles(), (Object o) -> - o.getClass().getName().contains("Wg") - || o instanceof Machine - || o instanceof DnsEntry - || o instanceof Ipv4Cidr - || o instanceof Ipv4Address - ); - - session.dispose(); - } -} diff --git a/src/main/java/io/trygvis/rules/engine/TemplateEngine.java b/src/main/java/io/trygvis/rules/engine/TemplateEngine.java deleted file mode 100644 index ace7aaf..0000000 --- a/src/main/java/io/trygvis/rules/engine/TemplateEngine.java +++ /dev/null @@ -1,30 +0,0 @@ -package io.trygvis.rules.engine; - -import ch.qos.logback.core.util.FileUtil; -import com.hubspot.jinjava.Jinjava; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Map; - -public class TemplateEngine { - private final Jinjava jinjava = new Jinjava(); - - public void template(String name, String output, Map params) throws IOException { - var template = Files.readString(Path.of("j2", name + ".j2")); - String renderedTemplate = jinjava.render(template, params); -// System.out.println("-----------------------------------"); -// for (var item : params.entrySet()) { -// System.out.printf(" %s : %s%n", item.getKey(), item.getValue()); -// } - System.out.println("-----------------------------------"); - System.out.println(renderedTemplate); - System.out.println("-----------------------------------"); - - var f = new File("gen", output); - FileUtil.createMissingParentDirectories(f); - Files.writeString(f.toPath(), renderedTemplate); - } -} diff --git a/src/main/java/io/trygvis/rules/machine/Machine.java b/src/main/java/io/trygvis/rules/machine/Machine.java deleted file mode 100644 index cc3f2ed..0000000 --- a/src/main/java/io/trygvis/rules/machine/Machine.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.trygvis.rules.machine; - -public class Machine { - public String name; - public String fqdn; - - public Machine() { - } - - public Machine(String name) { - this.name = name; - } -} diff --git a/src/main/java/io/trygvis/rules/network/Ipv4Address.java b/src/main/java/io/trygvis/rules/network/Ipv4Address.java deleted file mode 100644 index 7ca9ca5..0000000 --- a/src/main/java/io/trygvis/rules/network/Ipv4Address.java +++ /dev/null @@ -1,57 +0,0 @@ -package io.trygvis.rules.network; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - -import java.io.IOException; -import java.util.Objects; - -@JsonSerialize(using = Ipv4Address.Serializer.class) -public class Ipv4Address implements Comparable { - public final int address; - - public Ipv4Address(int address) { - this.address = address; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - - if (o instanceof Ipv4Address other) { - return address == other.address; - } - - return false; - } - - @Override - public int hashCode() { - return Objects.hash(address); - } - - @Override - public int compareTo(Ipv4Address o) { - return address - o.address; - } - - @Override - public String toString() { - return "%d.%d.%d.%d".formatted( - address >> 24 & 0xff, - address >> 16 & 0xff, - address >> 8 & 0xff, - address & 0xff); - } - - public static class Serializer extends JsonSerializer { - @Override - public void serialize(Ipv4Address value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - gen.writeStartObject(); - gen.writeObjectField("value", value.toString()); - gen.writeEndObject(); - } - } -} diff --git a/src/main/java/io/trygvis/rules/network/Ipv4Cidr.java b/src/main/java/io/trygvis/rules/network/Ipv4Cidr.java deleted file mode 100644 index e69cd02..0000000 --- a/src/main/java/io/trygvis/rules/network/Ipv4Cidr.java +++ /dev/null @@ -1,54 +0,0 @@ -package io.trygvis.rules.network; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; - -@JsonSerialize(using = Ipv4Cidr.Serializer.class) -public class Ipv4Cidr { - public final int network; - public final int netmask; - public final int size; - public final int bits; - - public Ipv4Cidr(int network, int netmask, int size, int bits) { - this.network = network; - this.netmask = netmask; - this.size = size; - this.bits = bits; - } - - @Override - public String toString() { - return "%d.%d.%d.%d/%d".formatted( - network >> 24 & 0xff, - network >> 16 & 0xff, - network >> 8 & 0xff, - network & 0xff, - bits); - } - - public Collection addresses() { - var end = network + size; - var addresses = new ArrayList(size); - for (int address = network; address < end; address++) { - addresses.add(new Ipv4Address(address)); - } - - return addresses; - } - - public static class Serializer extends JsonSerializer { - @Override - public void serialize(Ipv4Cidr value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - gen.writeStartObject(); - gen.writeObjectField("value", value.toString()); - gen.writeEndObject(); - } - } -} diff --git a/src/main/resources/META-INF/kmodule.xml b/src/main/resources/META-INF/kmodule.xml deleted file mode 100644 index ba88a47..0000000 --- a/src/main/resources/META-INF/kmodule.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - diff --git a/src/main/resources/io/trygvis/rules/acme/acme.drl b/src/main/resources/io/trygvis/rules/acme/acme.drl deleted file mode 100644 index 6369c24..0000000 --- a/src/main/resources/io/trygvis/rules/acme/acme.drl +++ /dev/null @@ -1,62 +0,0 @@ -package io.trygvis.rules.acme; - -import io.trygvis.rules.machine.Machine; -import io.trygvis.rules.dba.Cluster; -import io.trygvis.rules.dba.Container; - -declare AcmeServer - name : String - machine : Machine -end - -//declare MachinePublicName -// machine : Machine -// fqdn : String -//end - -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 - -rule "Create Acme servers" -when - $m : Machine(name.startsWith("acme-")) - not(AcmeServer(name == $m.name)) -then - var s = new AcmeServer(); - s.name = $m.name; - s.machine = $m; - insert(s) -end - -rule "Set public domain for ACME servers" -when - $m : Machine(fqdn == null) - $s : AcmeServer(machine == $m) -then - var fqdn = "%s.machine.acme.com".formatted($s.machine.name); - $s.machine.fqdn = fqdn; - update($s.machine) -end diff --git a/src/main/resources/io/trygvis/rules/acme/vpn.drl b/src/main/resources/io/trygvis/rules/acme/vpn.drl deleted file mode 100644 index 88c44f1..0000000 --- a/src/main/resources/io/trygvis/rules/acme/vpn.drl +++ /dev/null @@ -1,110 +0,0 @@ -package io.trygvis.rules.acme; - -import java.util.ArrayList -import io.trygvis.rules.machine.Machine; -import io.trygvis.rules.dns.DnsEntry; -import io.trygvis.rules.acme.AcmeServer -import io.trygvis.rules.network.Ipv4Address -import io.trygvis.rules.network.Ipv4Cidr - -dialect "mvel" - -declare WgNet - name : String - domain : String - linkCidr : String - networkCidr : String -end - -declare WgIpPool - net : String - role : String - cidr : Ipv4Cidr -end - -declare WgIpPool - net : String - cidr : Ipv4Cidr -end - -rule "Create link network" when - $net : WgNet() - not(Ipv4Cidr(network == IpCalc.cidr($net.linkCidr).network)) -then - insert(new WgIpPool($net.name, "link", IpCalc.cidr($net.linkCidr))) - insert(new WgIpPool($net.name, "network", IpCalc.cidr($net.networkCidr))) -end - -declare WgHost - name : String - net : String - publicName : String - netToNetIp : String - networkIp : String -end - -rule "WgHost VPN machines" -when - $machine : Machine() - $wgNet : WgNet(name == "vpn0") - not(WgHost(name == $machine.name)) -then - var wgHost = new WgHost(); - wgHost.name = $machine.name; - wgHost.net = $wgNet.name; - wgHost.publicName = $machine.fqdn; - insert(wgHost) -end - -rule "Set public name of WgHost" -when - $host : WgHost(publicName == null) - $m : Machine(name == $host.name, fqdn != null) -then - modify($host) { - publicName = $m.fqdn - } -end - -rule "Make DNS entries for all VPN hosts" -when - $h : WgHost() - $net : WgNet(name == $h.net) - not(DnsEntry(fqdn == "%s.%s".formatted($h.name, $net.domain), type == "A")) -then - var fqdn = "%s.%s".formatted($h.name, $net.domain); - insert(DnsEntry.a(fqdn)) -end - -declare WgConnection - host : String - to : String -end - -rule "Connect VPN nodes" - salience -1 -when - $h : WgHost() - $other : WgHost(publicName != null, name != $h.name) -then - insert(new WgConnection($h.name, $other.name)) -end - -declare WgIpAllocation - host : String - role : String - ip : Ipv4Address -end - -rule "Assign IP" -when - $net : WgNet() - $host : WgHost(net == $net.name) - $pool : WgIpPool(net == $net.name) - not(WgIpAllocation(host == $host.name, role == $pool.role)) - $ip : Ipv4Address() from $pool.cidr.addresses() - not(WgIpAllocation(ip == $ip)) -then - System.out.printf("IP: net=%s, pool.role=%s, host=%s, ip=%s%n", $net.name, $pool.role, $host.name, $ip); - insert(new WgIpAllocation($host.name, $pool.role, $ip)) -end diff --git a/src/main/resources/io/trygvis/rules/dba/dba.drl b/src/main/resources/io/trygvis/rules/dba/dba.drl deleted file mode 100644 index 7beceef..0000000 --- a/src/main/resources/io/trygvis/rules/dba/dba.drl +++ /dev/null @@ -1 +0,0 @@ -package io.trygvis.rules.dba; diff --git a/src/main/resources/io/trygvis/rules/engine/default.drl b/src/main/resources/io/trygvis/rules/engine/default.drl deleted file mode 100644 index 090fddf..0000000 --- a/src/main/resources/io/trygvis/rules/engine/default.drl +++ /dev/null @@ -1,15 +0,0 @@ -package io.trygvis.rules.engine; -import java.util.Map -import org.apache.commons.io.FileSystem -import org.apache.commons.io.FileUtils -import java.io.File - -rule "Clean directories" - agenda-group "init" -when - not(KeyValue(key == "rm-gen")); -then - System.out.println("Cleaning gen!"); - FileUtils.deleteDirectory(new File("gen")); - insert(new KeyValue("rm-gen", null)); -end diff --git a/src/main/resources/io/trygvis/rules/machine/machine.drl b/src/main/resources/io/trygvis/rules/machine/machine.drl deleted file mode 100644 index a9a379f..0000000 --- a/src/main/resources/io/trygvis/rules/machine/machine.drl +++ /dev/null @@ -1,6 +0,0 @@ -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; diff --git a/src/main/resources/io/trygvis/rules/terraform/terraform.drl b/src/main/resources/io/trygvis/rules/terraform/terraform.drl deleted file mode 100644 index 40b9f7c..0000000 --- a/src/main/resources/io/trygvis/rules/terraform/terraform.drl +++ /dev/null @@ -1,60 +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.Map; - -global io.trygvis.rules.engine.TemplateEngine te; - -declare ScalewayMachine - machine : Machine - key : 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 - var a = DnsEntry.a($machine.fqdn); - insert(a); - - var ipv4 = "scaleway_instance_ip.%s.address".formatted($machine.name); - insert(new DnsEntryTerraformExpression(a, $machine.name, ipv4)); -end - -rule "TF for TerraformMachine" -when - $m: Machine() - $scw: ScalewayMachine(machine == $m) -then - var path = "platform/terraform/%s.tf".formatted($scw.getKey()); - te.template("terraform-machine", path, Map.of("m", $m, "scw", $scw)); -end - -rule "Terraform for DNS" -when - $entry: DnsEntry() - $tf : DnsEntryTerraformExpression(entry == $entry) -then - var path = "dns/%s.tf".formatted($tf.key); - te.template("terraform-record-set", path, Map.of( - "entry", $entry, - "tf", $tf) - ); -end diff --git a/src/test/java/io/trygvis/rules/acme/IpCalcTest.java b/src/test/java/io/trygvis/rules/acme/IpCalcTest.java deleted file mode 100644 index 8b1e2c6..0000000 --- a/src/test/java/io/trygvis/rules/acme/IpCalcTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.trygvis.rules.acme; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -import static org.junit.jupiter.api.Assertions.*; - -class IpCalcTest { - - @Test - public void basic() { - Assertions.assertThrows(IllegalArgumentException.class, () -> IpCalc.cidr("192.168.1.1/24").addresses()); - assertEquals(256, IpCalc.cidr("192.168.1.0/24").addresses().size()); - assertEquals(128, IpCalc.cidr("192.168.1.128/25").addresses().size()); - } - - @ParameterizedTest - @ValueSource(strings = { - "192.168.1.0/24", - "192.168.1.128/25", - }) - public void testParsing(String s) { - assertEquals(s, IpCalc.cidr(s).toString()); - } -} -- cgit v1.2.3