diff options
Diffstat (limited to 'module')
6 files changed, 83 insertions, 55 deletions
diff --git a/module/acme/src/main/resources/io/trygvis/acme/acme.drl b/module/acme/src/main/resources/io/trygvis/acme/acme.drl index 66623c3..76bad0a 100644 --- a/module/acme/src/main/resources/io/trygvis/acme/acme.drl +++ b/module/acme/src/main/resources/io/trygvis/acme/acme.drl @@ -27,6 +27,8 @@ when $m : Machine(fqdn == null) $s : AcmeServer(machine == $m) then - $s.machine.fqdn = "%s.machine.acme.com".formatted($s.machine.name); - update($s.machine) + var fqdn = "%s.machine.acme.com".formatted($m.name); + modify ($m) { + fqdn = fqdn + } end diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/engine/DbIo.java b/module/ri-engine/src/main/java/io/trygvis/rules/engine/DbIo.java index b402173..b8ee03a 100644 --- a/module/ri-engine/src/main/java/io/trygvis/rules/engine/DbIo.java +++ b/module/ri-engine/src/main/java/io/trygvis/rules/engine/DbIo.java @@ -1,12 +1,18 @@ package io.trygvis.rules.engine; import ch.qos.logback.core.util.FileUtil; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.PropertyName; import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.introspect.Annotated; +import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; +import com.fasterxml.jackson.databind.introspect.ObjectIdInfo; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; import org.drools.core.common.DefaultFactHandle; +import org.drools.core.factmodel.GeneratedFact; import org.kie.api.KieBase; import org.kie.api.runtime.rule.FactHandle; @@ -21,6 +27,8 @@ import java.util.function.Function; public class DbIo { private final ObjectMapper mapper; + private static final List<String> prioritizedKeys = List.of("key", "name", "fqdn"); + public DbIo(KieBase kieBase) { var factory = new YAMLFactory(); factory.enable(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID); @@ -31,6 +39,29 @@ public class DbIo { .withClassLoader(new AcmeClassLoader(kieBase)); mapper.setTypeFactory(typeFactory); mapper.findAndRegisterModules(); + + mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() { + @Override + public ObjectIdInfo findObjectIdInfo(Annotated a) { + final Class<?> klass = a.getRawType(); + if (GeneratedFact.class.isAssignableFrom(klass)) { + System.out.println("klass = " + klass); + + for (String name : prioritizedKeys) { + try { + final String getter = "get" + name.substring(0, 1).toUpperCase() + name.substring(1); + var f = klass.getMethod(getter); + return new ObjectIdInfo(PropertyName.construct(name), null, ObjectIdGenerators.PropertyGenerator.class, null); + } catch (NoSuchMethodException ignore) { + } + } + System.out.println("a.getRawType() = " + klass); + return new ObjectIdInfo(null, null, ObjectIdGenerators.IntSequenceGenerator.class, null); + } + + return super.findObjectIdInfo(a); + } + }); } public List<Object> load(String file) throws IOException { @@ -86,8 +117,6 @@ public class DbIo { // TODO: check if klass is a Comparable directly. - var prioritizedKeys = List.of("key", "name", "fqdn"); - var discoveredFieldsP1 = new LinkedHashMap<String, Function<Object, Object>>(); var discoveredFieldsP2 = new LinkedHashMap<String, Function<Object, Object>>(); @@ -228,18 +257,6 @@ public class DbIo { } } - /* - var x = new ArrayList<DbObject2>(); - x.add(new DbObject2("io.trygvis.rules.dba.Container", null)); - x.add(new DbObject2("io.trygvis.rules.machine.Machine", null)); - x.add(new DbObject2("io.trygvis.acme.apps.AcmeMyApp", null)); - - System.out.println("xxxxxx"); - x.sort(new DbObjectComparator()); - x.forEach(System.out::println); - System.out.println("xxxxxx"); - */ - objects.sort(new DbObjectComparator()); var factory = mapper.getFactory(); @@ -282,12 +299,12 @@ public class DbIo { private static class DbObjectComparator implements Comparator<DbObject2> { private final List<String> prioritizedPackages = List.of( - "io.trygvis.rules.core", "io.trygvis.rules.machine", "io.trygvis.rules.network", "io.trygvis.rules.dns", "io.trygvis.rules.dba", - "io.trygvis.rules"); + "io.trygvis.rules", + "io.trygvis.rules.core"); @Override public int compare(DbObject2 a, DbObject2 b) { 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 index 8e54d60..34c17ca 100644 --- 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 @@ -3,10 +3,11 @@ package io.trygvis.rules.machine; import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.ObjectIdGenerators; +@SuppressWarnings("unused") @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "name") public class Machine { public String name; - public String fqdn; + private String fqdn; public Machine() { } @@ -22,4 +23,8 @@ public class Machine { public String getFqdn() { return fqdn; } + + public void setFqdn(String fqdn) { + this.fqdn = fqdn; + } } 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 index 9bdc0a5..0bee004 100644 --- 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 @@ -18,14 +18,14 @@ declare DbaMachineRole roles : String[] end -rule "Assign containers to hosts" +rule "Assign containers to machine" when $machine : Machine() $machineRole : DbaMachineRole(machine == $machine.name) $container : Container(machine == null, $machineRole.roles contains machineRole) then System.out.println("Assigning container to machine: " + $machine.name); - modify($container) { + modify ($container) { machine = $machine } end 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 index c1293fe..07a96e2 100644 --- 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 @@ -10,6 +10,8 @@ import java.util.Map; global io.trygvis.rules.engine.TemplateEngine te; +dialect "mvel" + declare ScalewayMachine machine : Machine key : String diff --git a/module/ri-wireguard/src/main/resources/io/trygvis/rules/wireguard/wireguard.drl b/module/ri-wireguard/src/main/resources/io/trygvis/rules/wireguard/wireguard.drl index 261374a..d971696 100644 --- a/module/ri-wireguard/src/main/resources/io/trygvis/rules/wireguard/wireguard.drl +++ b/module/ri-wireguard/src/main/resources/io/trygvis/rules/wireguard/wireguard.drl @@ -21,26 +21,26 @@ declare WgNet end declare WgIpPool - net : String + net : WgNet role : String cidr : Ipv4Cidr end declare WgHost - name : String // TODO: rename to machine - net : String + machine : Machine + net : WgNet publicName : String ip : String // This host's IP networkCidr : String end declare WgConnection - host : String - to : String + host : WgHost + to : WgHost end declare WgIpAllocation - host : String + host : WgHost role : String ip : Ipv4Address end @@ -50,19 +50,19 @@ rule "Create IP pools" when // not(Ipv4Cidr(network == Ipv4Cidr.parseCidr($net.linkCidr).network)) then System.out.println("Creating main IP pools"); - insert(new WgIpPool($net.name, "link", Ipv4Cidr.parseCidr($net.linkCidr))) - insert(new WgIpPool($net.name, "networks", Ipv4Cidr.parseCidr($net.networkCidr))) + insert(new WgIpPool($net, "link", Ipv4Cidr.parseCidr($net.linkCidr))) + insert(new WgIpPool($net, "networks", Ipv4Cidr.parseCidr($net.networkCidr))) end rule "WgHost VPN machines" when $machine : Machine() $wgNet : WgNet(name == "vpn0") - not(WgHost(name == $machine.name)) + not(WgHost(machine == $machine)) then var wgHost = new WgHost(); - wgHost.name = $machine.name; - wgHost.net = $wgNet.name; + wgHost.machine = $machine; + wgHost.net = $wgNet; wgHost.publicName = $machine.fqdn; insert(wgHost) end @@ -70,7 +70,7 @@ end rule "Set public name of WgHost" when $host : WgHost(publicName == null) - $m : Machine(name == $host.name, fqdn != null) + $m : Machine(this == $host.machine, fqdn != null) then modify($host) { publicName = $m.fqdn @@ -80,10 +80,9 @@ 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")) + not(DnsEntry(fqdn == "%s.%s".formatted($h.machine.name, $h.net.domain), type == "A")) then - var fqdn = "%s.%s".formatted($h.name, $net.domain); + var fqdn = "%s.%s".formatted($h.machine.name, $h.net.domain); insert(DnsEntry.a(fqdn)) end @@ -91,23 +90,22 @@ rule "Connect VPN nodes" salience -1 when $h : WgHost() - $other : WgHost(publicName != null, name != $h.name) + $other : WgHost(publicName != null, this != $h) then - System.out.printf("VPN connection from %s to %s%n", $h.name, $other.name); - insert(new WgConnection($h.name, $other.name)) + System.out.printf("VPN connection from %s to %s%n", $h.machine.name, $other.machine.name); + insert(new WgConnection($h, $other)) end // This and the next rule needs to use .toString(), the specific objects might be generated multiple times, // but Drools use identityHashCode() to find equal objects, not equals(). rule "Assign IP" when - $net : WgNet() - $pool : WgIpPool(net == $net.name, role == "link") + $pool : WgIpPool(role == "link") $ip : Ipv4Address() from $pool.cidr.addresses() - not(WgHost(net == $net.name, ip == $ip.toString())) - $host : WgHost(net == $net.name, ip == null) + not(WgHost(net == $pool.net, ip == $ip.toString())) + $host : WgHost(net == $pool.net, ip == null) then - System.out.printf("IP: net=%s, pool.role=%s, host=%s, ip=%s%n", $net.name, $pool.role, $host.name, $ip); + System.out.printf("IP: net=%s, pool.role=%s, host=%s, ip=%s%n", $pool.net.name, $pool.role, $host.machine.name, $ip); modify($host) { ip = $ip.toString() } @@ -117,10 +115,10 @@ rule "Assign network CIDR" when $net : WgNet() $network : Ipv4Cidr() from Ipv4Cidr.parseCidr($net.networkCidr).partition($net.networkBits) - $host : WgHost(net == $net.name, networkCidr == null) - not(WgHost(net == $net.name, networkCidr == $network.toString())) + $host : WgHost(net == $net, networkCidr == null) + not(WgHost(net == $net, networkCidr == $network.toString())) then - System.out.printf("Network CIDR: net=%s, host=%s, network=%s%n", $net.name, $host.name, $network); + System.out.printf("Network CIDR: net=%s, host=%s, network=%s%n", $net.name, $host.machine.name, $network); modify($host) { networkCidr = $network.toString() } @@ -131,15 +129,20 @@ rule "Generate per-net files" salience 10 when $net : WgNet() - $names : ArrayList() from accumulate(WgHost(net == $net.name, $name: name), collectList($name)) - $hosts : ArrayList() from accumulate(Machine($names contains name, $m: this), collectList($m)) + $hosts : ArrayList() from collect(WgHost(net == $net)) then te.template("wireguard/ansible", "wireguard-" + $net.name + ".yml", Map.of( "net", $net )); + var machines = new ArrayList(); + for (Object o : $hosts) { + WgHost m = (WgHost) o; + machines.add(m.machine); + } + te.template("wireguard/inventory", "inventory.yml", Map.of( - "hosts", $hosts + "hosts", machines )); end @@ -148,13 +151,12 @@ rule "Generate per-net, per-host files" salience 10 when $net : WgNet() - $host : WgHost(net == $net.name) - $peerMachines : ArrayList() from accumulate(WgConnection(host == $host.name, $to: to), collectList($to)) - $peers : ArrayList() from accumulate(Machine($peerMachines contains name, $fqdn: fqdn), collectList($fqdn)) + $host : WgHost(net == $net) + $peers : ArrayList() from accumulate(WgConnection(host == $host, $to: to), collectList($to.machine)) then - System.out.printf("Generating per-host files: net=%s, host=%s%n", $net.name, $host.name); + System.out.printf("Generating per-host files: net=%s, host=%s%n", $net.name, $host.machine.name); - String output = "host_vars/%s/wireguard.yml".formatted($host.name); + String output = "host_vars/%s/wireguard.yml".formatted($host.machine.name); te.template("wireguard/ansible-host", output, Map.of( "net", $net, |