From bafe762ac01d16904c18404283027e426e19bc73 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Wed, 3 Feb 2021 16:35:48 +0100 Subject: Code reorganization. Moving main code to src, keeping modules in modules/ --- .../src/main/resources/META-INF/kmodule.xml | 9 + .../io/trygvis/rules/wireguard/wireguard.drl | 185 +++++++++++++++++++++ .../ri-wireguard/src/main/resources/logback.xml | 13 ++ .../resources/templates/wireguard/ansible-host.j2 | 12 ++ .../main/resources/templates/wireguard/ansible.j2 | 7 + .../resources/templates/wireguard/inventory.j2 | 13 ++ 6 files changed, 239 insertions(+) create mode 100644 modules/ri-wireguard/src/main/resources/META-INF/kmodule.xml create mode 100644 modules/ri-wireguard/src/main/resources/io/trygvis/rules/wireguard/wireguard.drl create mode 100644 modules/ri-wireguard/src/main/resources/logback.xml create mode 100644 modules/ri-wireguard/src/main/resources/templates/wireguard/ansible-host.j2 create mode 100644 modules/ri-wireguard/src/main/resources/templates/wireguard/ansible.j2 create mode 100644 modules/ri-wireguard/src/main/resources/templates/wireguard/inventory.j2 (limited to 'modules/ri-wireguard/src') diff --git a/modules/ri-wireguard/src/main/resources/META-INF/kmodule.xml b/modules/ri-wireguard/src/main/resources/META-INF/kmodule.xml new file mode 100644 index 0000000..de617f7 --- /dev/null +++ b/modules/ri-wireguard/src/main/resources/META-INF/kmodule.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/modules/ri-wireguard/src/main/resources/io/trygvis/rules/wireguard/wireguard.drl b/modules/ri-wireguard/src/main/resources/io/trygvis/rules/wireguard/wireguard.drl new file mode 100644 index 0000000..5630ab6 --- /dev/null +++ b/modules/ri-wireguard/src/main/resources/io/trygvis/rules/wireguard/wireguard.drl @@ -0,0 +1,185 @@ +package io.trygvis.rules.wireguard; + +import io.trygvis.rules.dns.DnsEntry; +import io.trygvis.rules.machine.Machine; +import io.trygvis.rules.network.IpCalc +import io.trygvis.rules.network.Ipv4Address +import io.trygvis.rules.network.Ipv4Cidr +import java.util.ArrayList +import java.util.List +import java.util.Map + +global io.trygvis.rules.engine.TemplateEngine te; + +dialect "mvel" + +declare WgNet + name : String + domain : String + port : int + linkCidr : String + networkCidr : String + networkBits : int +end + +declare WgIpPool + net : WgNet + role : String + cidr : Ipv4Cidr +end + +declare WgHost + machine : Machine + net : WgNet + publicName : String + publicPort : int + ip : String // This host's IP + networkCidr : String +end + +declare WgConnection + name : String + host : WgHost + to : WgHost +end + +declare WgIpAllocation + host : WgHost + role : String + ip : Ipv4Address +end + +rule "Create IP pools" when + $net : WgNet() +// not(Ipv4Cidr(network == Ipv4Cidr.parseCidr($net.linkCidr).network)) +then + System.out.println("Creating main IP pools"); + insert(new WgIpPool($net, "link", Ipv4Cidr.parseCidr($net.getLinkCidr()))) + insert(new WgIpPool($net, "networks", Ipv4Cidr.parseCidr($net.getNetworkCidr()))) +end + +rule "WgHost VPN machines" +when + $machine : Machine() + $wgNet : WgNet(name == "vpn0") + not(WgHost(machine == $machine)) +then + WgHost wgHost = new WgHost(); + wgHost.machine = $machine; + wgHost.net = $wgNet; + wgHost.publicName = $machine.fqdn; + wgHost.publicPort = $wgNet.port; + insert(wgHost) +end + +rule "Set public name of WgHost" +when + $host : WgHost(publicName == null) + $m : Machine(this == $host.machine, fqdn != null) +then + modify($host) { + publicName = $m.fqdn + } +end + +rule "Make DNS entries for all VPN hosts" +when + $h : WgHost() + not(DnsEntry(fqdn == "%s.%s".formatted($h.machine.name, $h.net.domain), type == "A")) +then + String fqdn = "%s.%s".formatted($h.machine.name, $h.net.domain); + insert(DnsEntry.a(fqdn)) +end + +rule "Connect VPN nodes" + salience -1 +when + $h : WgHost() + $other : WgHost(publicName != null, this != $h) +then + System.out.printf("VPN connection from %s to %s%n", $h.machine.name, $other.machine.name); + WgConnection c = new WgConnection(); + c.host = $h; + c.to = $other; + insert(c) +end + +rule "Name connections" +when + $c : WgConnection(name == null, host != null, to != null) +then + String n = $c.host.machine.name + "_x_" + $c.to.machine.name; + modify($c) { + name = n + } +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 + $pool : WgIpPool(role == "link") + $ip : Ipv4Address() from $pool.cidr.addresses() + 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", $pool.net.name, $pool.role, $host.machine.name, $ip); + modify($host) { + ip = $ip.toString() + } +end + +rule "Assign network CIDR" +when + $net : WgNet() + $network : Ipv4Cidr() from Ipv4Cidr.parseCidr($net.networkCidr).partition($net.networkBits) + $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.machine.name, $network); + modify($host) { + networkCidr = $network.toString() + } +end + +rule "Generate per-net files" + agenda-group "generate" + salience 10 +when + $net : WgNet() + $hosts : ArrayList() from collect(WgHost(net == $net)) +then + te.template("wireguard/ansible", "wireguard-" + $net.name + ".yml", Map.of( + "net", $net + )); + + List machines = new ArrayList(); + for (Object o : $hosts) { + WgHost m = (WgHost) o; + machines.add(m.getMachine()); + } + + te.template("wireguard/inventory", "inventory.yml", Map.of( + "net", $net, + "hosts", machines + )); +end + +rule "Generate per-net, per-host files" + agenda-group "generate" + salience 10 +when + $net : WgNet() + $host : WgHost(net == $net) + $peers : ArrayList() from accumulate(WgConnection(host == $host, $to: to), collectList($to)) +then + 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.machine.name); + + te.template("wireguard/ansible-host", output, Map.of( + "net", $net, + "host", $host, + "peers", $peers + )); +end diff --git a/modules/ri-wireguard/src/main/resources/logback.xml b/modules/ri-wireguard/src/main/resources/logback.xml new file mode 100644 index 0000000..66ae905 --- /dev/null +++ b/modules/ri-wireguard/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + diff --git a/modules/ri-wireguard/src/main/resources/templates/wireguard/ansible-host.j2 b/modules/ri-wireguard/src/main/resources/templates/wireguard/ansible-host.j2 new file mode 100644 index 0000000..6cb3a05 --- /dev/null +++ b/modules/ri-wireguard/src/main/resources/templates/wireguard/ansible-host.j2 @@ -0,0 +1,12 @@ +# Generated +wireguard_port: {{ host.publicPort }} +link_address: {{ host.ip }} +network_cidr: {{ host.networkCidr }} +wireguard_peers: +{%- for peer in peers %} + {{ peer.machine.name }}: + public_address: {{ peer.publicName }} + public_port: {{ peer.publicPort }} + gateway: {{ peer.ip }} + network: {{ peer.networkCidr }} +{%- endfor %} diff --git a/modules/ri-wireguard/src/main/resources/templates/wireguard/ansible.j2 b/modules/ri-wireguard/src/main/resources/templates/wireguard/ansible.j2 new file mode 100644 index 0000000..ad4d034 --- /dev/null +++ b/modules/ri-wireguard/src/main/resources/templates/wireguard/ansible.j2 @@ -0,0 +1,7 @@ +- hosts: wireguard_{{ net.name }} + vars: + wireguard_if: {{ net.name }} + tasks: + - name: wireguard + import_role: + name: wireguard diff --git a/modules/ri-wireguard/src/main/resources/templates/wireguard/inventory.j2 b/modules/ri-wireguard/src/main/resources/templates/wireguard/inventory.j2 new file mode 100644 index 0000000..64f3b5b --- /dev/null +++ b/modules/ri-wireguard/src/main/resources/templates/wireguard/inventory.j2 @@ -0,0 +1,13 @@ +# Generated +all: + hosts: + {%- for host in hosts %} + {{ host.getName() }}: + ansible_host: {{ host.getFqdn() }} + {%- endfor %} + children: + wireguard_{{ net.name }}: + hosts: +{%- for host in hosts %} + {{ host.getName() }}: +{%- endfor %} -- cgit v1.2.3