From f2fc5a193743e2a66f748c8baefee949a747ea7f Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Mon, 11 Jan 2021 15:26:06 +0100 Subject: Figured out a way to not need WgNetworkAllocation. --- acme-wireguard/host_vars/acme-1/wireguard.yml | 4 +- acme-wireguard/host_vars/acme-2/wireguard.yml | 4 +- acme-wireguard/host_vars/acme-3/wireguard.yml | 2 +- acme-wireguard/host_vars/ws-1/wireguard.yml | 4 +- acme-wireguard/host_vars/ws-2/wireguard.yml | 4 +- j2/wireguard/ansible-host.j2 | 4 +- .../src/main/resources/io/trygvis/acme/acme.drl | 2 +- .../java/io/trygvis/rules/network/Ipv4Cidr.java | 2 +- .../io/trygvis/rules/wireguard/wireguard.drl | 42 +++++----- out/acme/wireguard.yaml | 90 +++------------------- 10 files changed, 41 insertions(+), 117 deletions(-) diff --git a/acme-wireguard/host_vars/acme-1/wireguard.yml b/acme-wireguard/host_vars/acme-1/wireguard.yml index ed768e2..af0f3a7 100644 --- a/acme-wireguard/host_vars/acme-1/wireguard.yml +++ b/acme-wireguard/host_vars/acme-1/wireguard.yml @@ -1,6 +1,6 @@ # Generated -link_address: 192.168.10.4 -network_cidr: 10.55.251.0/24 +link_address: 192.168.10.3 +network_cidr: 10.55.255.0/24 wireguard_peers: acme-1: - acme-3.machine.acme.com diff --git a/acme-wireguard/host_vars/acme-2/wireguard.yml b/acme-wireguard/host_vars/acme-2/wireguard.yml index 363c50b..4228d87 100644 --- a/acme-wireguard/host_vars/acme-2/wireguard.yml +++ b/acme-wireguard/host_vars/acme-2/wireguard.yml @@ -1,6 +1,6 @@ # Generated -link_address: 192.168.10.3 -network_cidr: 10.55.252.0/24 +link_address: 192.168.10.4 +network_cidr: 10.55.254.0/24 wireguard_peers: acme-2: - acme-3.machine.acme.com diff --git a/acme-wireguard/host_vars/acme-3/wireguard.yml b/acme-wireguard/host_vars/acme-3/wireguard.yml index e032cac..f42f50c 100644 --- a/acme-wireguard/host_vars/acme-3/wireguard.yml +++ b/acme-wireguard/host_vars/acme-3/wireguard.yml @@ -1,5 +1,5 @@ # Generated -link_address: 192.168.10.2 +link_address: 192.168.10.5 network_cidr: 10.55.253.0/24 wireguard_peers: acme-3: diff --git a/acme-wireguard/host_vars/ws-1/wireguard.yml b/acme-wireguard/host_vars/ws-1/wireguard.yml index 2e4a54f..3cafb0b 100644 --- a/acme-wireguard/host_vars/ws-1/wireguard.yml +++ b/acme-wireguard/host_vars/ws-1/wireguard.yml @@ -1,6 +1,6 @@ # Generated -link_address: 192.168.10.1 -network_cidr: 10.55.254.0/24 +link_address: 192.168.10.6 +network_cidr: 10.55.252.0/24 wireguard_peers: ws-1: - acme-3.machine.acme.com diff --git a/acme-wireguard/host_vars/ws-2/wireguard.yml b/acme-wireguard/host_vars/ws-2/wireguard.yml index d3e1eb1..a727689 100644 --- a/acme-wireguard/host_vars/ws-2/wireguard.yml +++ b/acme-wireguard/host_vars/ws-2/wireguard.yml @@ -1,6 +1,6 @@ # Generated -link_address: 192.168.10.0 -network_cidr: 10.55.255.0/24 +link_address: 192.168.10.7 +network_cidr: 10.55.251.0/24 wireguard_peers: ws-2: - acme-3.machine.acme.com diff --git a/j2/wireguard/ansible-host.j2 b/j2/wireguard/ansible-host.j2 index 72273ef..9d684ef 100644 --- a/j2/wireguard/ansible-host.j2 +++ b/j2/wireguard/ansible-host.j2 @@ -1,6 +1,6 @@ # Generated -link_address: {{ link }} -network_cidr: {{ network }} +link_address: {{ host.ip }} +network_cidr: {{ host.networkCidr }} wireguard_peers: {{ host.name }}: {%- for peer in peers %} 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 cb04b09..66623c3 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,6 @@ when $m : Machine(fqdn == null) $s : AcmeServer(machine == $m) then - $s.machine.fqdn = "%s.machine.acme.com.".formatted($s.machine.name); + $s.machine.fqdn = "%s.machine.acme.com".formatted($s.machine.name); update($s.machine) end 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 index 8e812ef..6362107 100644 --- 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 @@ -85,7 +85,7 @@ public class Ipv4Cidr implements Comparable { } var ret = network - o.network; - if (ret == 0) { + if (ret != 0) { return ret; } 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 2e4498f..261374a 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 @@ -27,11 +27,11 @@ declare WgIpPool end declare WgHost - name : String - net : String - publicName : String - netToNetIp : String - networkIp : String + name : String // TODO: rename to machine + net : String + publicName : String + ip : String // This host's IP + networkCidr : String end declare WgConnection @@ -45,12 +45,6 @@ declare WgIpAllocation ip : Ipv4Address end -declare WgNetworkAllocation - host : String - role : String - cidr : Ipv4Cidr -end - rule "Create IP pools" when $net : WgNet() // not(Ipv4Cidr(network == Ipv4Cidr.parseCidr($net.linkCidr).network)) @@ -103,29 +97,33 @@ then insert(new WgConnection($h.name, $other.name)) end -rule "Assign link IP" +// 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() - $host : WgHost(net == $net.name) $pool : WgIpPool(net == $net.name, role == "link") - not(WgIpAllocation(host == $host.name, role == $pool.role)) $ip : Ipv4Address() from $pool.cidr.addresses() - not(WgIpAllocation(ip == $ip)) + not(WgHost(net == $net.name, ip == $ip.toString())) + $host : WgHost(net == $net.name, ip == null) 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)) + modify($host) { + ip = $ip.toString() + } end rule "Assign network CIDR" when $net : WgNet() - $host : WgHost(net == $net.name) $network : Ipv4Cidr() from Ipv4Cidr.parseCidr($net.networkCidr).partition($net.networkBits) - not(WgNetworkAllocation(host == $host.name, role == "network")) - not(WgNetworkAllocation(cidr == $network)) + $host : WgHost(net == $net.name, networkCidr == null) + not(WgHost(net == $net.name, networkCidr == $network.toString())) then System.out.printf("Network CIDR: net=%s, host=%s, network=%s%n", $net.name, $host.name, $network); - insert(new WgNetworkAllocation($host.name, "network", $network)) + modify($host) { + networkCidr = $network.toString() + } end rule "Generate per-net files" @@ -151,8 +149,6 @@ rule "Generate per-net, per-host files" when $net : WgNet() $host : WgHost(net == $net.name) - $link : WgIpAllocation(host == $host.name, role == "link") - $network : WgNetworkAllocation(host == $host.name, role == "network") $peerMachines : ArrayList() from accumulate(WgConnection(host == $host.name, $to: to), collectList($to)) $peers : ArrayList() from accumulate(Machine($peerMachines contains name, $fqdn: fqdn), collectList($fqdn)) then @@ -163,8 +159,6 @@ then te.template("wireguard/ansible-host", output, Map.of( "net", $net, "host", $host, - "link", $link.ip, - "network", $network.cidr, "peers", $peers )); end diff --git a/out/acme/wireguard.yaml b/out/acme/wireguard.yaml index 2a3ff80..de882c3 100644 --- a/out/acme/wireguard.yaml +++ b/out/acme/wireguard.yaml @@ -114,75 +114,40 @@ data: name: "acme-1" net: "vpn0" publicName: "acme-1.machine.acme.com" - netToNetIp: null - networkIp: null + ip: "192.168.10.3" + networkCidr: "10.55.255.0/24" --- type: "io.trygvis.rules.wireguard.WgHost" data: name: "acme-2" net: "vpn0" publicName: "acme-2.machine.acme.com" - netToNetIp: null - networkIp: null + ip: "192.168.10.4" + networkCidr: "10.55.254.0/24" --- type: "io.trygvis.rules.wireguard.WgHost" data: name: "acme-3" net: "vpn0" publicName: "acme-3.machine.acme.com" - netToNetIp: null - networkIp: null + ip: "192.168.10.5" + networkCidr: "10.55.253.0/24" --- type: "io.trygvis.rules.wireguard.WgHost" data: name: "ws-1" net: "vpn0" publicName: null - netToNetIp: null - networkIp: null + ip: "192.168.10.6" + networkCidr: "10.55.252.0/24" --- type: "io.trygvis.rules.wireguard.WgHost" data: name: "ws-2" net: "vpn0" publicName: null - netToNetIp: null - networkIp: null ---- -type: "io.trygvis.rules.wireguard.WgIpAllocation" -data: - host: "acme-1" - role: "link" - ip: - value: "192.168.10.4" ---- -type: "io.trygvis.rules.wireguard.WgIpAllocation" -data: - host: "acme-2" - role: "link" - ip: - value: "192.168.10.3" ---- -type: "io.trygvis.rules.wireguard.WgIpAllocation" -data: - host: "acme-3" - role: "link" - ip: - value: "192.168.10.2" ---- -type: "io.trygvis.rules.wireguard.WgIpAllocation" -data: - host: "ws-1" - role: "link" - ip: - value: "192.168.10.1" ---- -type: "io.trygvis.rules.wireguard.WgIpAllocation" -data: - host: "ws-2" - role: "link" - ip: - value: "192.168.10.0" + ip: "192.168.10.7" + networkCidr: "10.55.251.0/24" --- type: "io.trygvis.rules.wireguard.WgIpPool" data: @@ -205,38 +170,3 @@ data: linkCidr: "192.168.10.0/29" networkCidr: "10.55.0.0/16" networkBits: 24 ---- -type: "io.trygvis.rules.wireguard.WgNetworkAllocation" -data: - host: "acme-1" - role: "network" - cidr: - value: "10.55.251.0/24" ---- -type: "io.trygvis.rules.wireguard.WgNetworkAllocation" -data: - host: "acme-2" - role: "network" - cidr: - value: "10.55.252.0/24" ---- -type: "io.trygvis.rules.wireguard.WgNetworkAllocation" -data: - host: "acme-3" - role: "network" - cidr: - value: "10.55.253.0/24" ---- -type: "io.trygvis.rules.wireguard.WgNetworkAllocation" -data: - host: "ws-1" - role: "network" - cidr: - value: "10.55.254.0/24" ---- -type: "io.trygvis.rules.wireguard.WgNetworkAllocation" -data: - host: "ws-2" - role: "network" - cidr: - value: "10.55.255.0/24" -- cgit v1.2.3 From 5f294077a362d0127146882e6c90b863c4f54703 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Mon, 11 Jan 2021 15:28:56 +0100 Subject: Updating FQDNs. --- acme-apps/terraform/dns-acme-1.tf | 2 +- acme-apps/terraform/dns-acme-2.tf | 2 +- acme-apps/terraform/dns-acme-3.tf | 2 +- j2/terraform-machine.j2 | 2 +- out/acme/apps.yaml | 36 ++++++++++++++++++------------------ 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/acme-apps/terraform/dns-acme-1.tf b/acme-apps/terraform/dns-acme-1.tf index 0b9ede0..bc8c127 100644 --- a/acme-apps/terraform/dns-acme-1.tf +++ b/acme-apps/terraform/dns-acme-1.tf @@ -1,5 +1,5 @@ resource "google_dns_record_set" "acme-1" { - name = "acme-1.machine.acme.com." + name = "acme-1.machine.acme.com" managed_zone = var.acme_zone type = "A" ttl = 300 diff --git a/acme-apps/terraform/dns-acme-2.tf b/acme-apps/terraform/dns-acme-2.tf index 407935e..5fb616f 100644 --- a/acme-apps/terraform/dns-acme-2.tf +++ b/acme-apps/terraform/dns-acme-2.tf @@ -1,5 +1,5 @@ resource "google_dns_record_set" "acme-2" { - name = "acme-2.machine.acme.com." + name = "acme-2.machine.acme.com" managed_zone = var.acme_zone type = "A" ttl = 300 diff --git a/acme-apps/terraform/dns-acme-3.tf b/acme-apps/terraform/dns-acme-3.tf index 4c753df..539ba44 100644 --- a/acme-apps/terraform/dns-acme-3.tf +++ b/acme-apps/terraform/dns-acme-3.tf @@ -1,5 +1,5 @@ resource "google_dns_record_set" "acme-3" { - name = "acme-3.machine.acme.com." + name = "acme-3.machine.acme.com" managed_zone = var.acme_zone type = "A" ttl = 300 diff --git a/j2/terraform-machine.j2 b/j2/terraform-machine.j2 index c83bc48..0ac8b90 100644 --- a/j2/terraform-machine.j2 +++ b/j2/terraform-machine.j2 @@ -11,7 +11,7 @@ resource "scaleway_instance_ip" "{{ scw.key }}" {} resource "scaleway_instance_ip_reverse_dns" "{{ scw.key }}" { ip_id = scaleway_instance_ip.{{ scw.key }}.id - reverse = "{{ m.fqdn }}" + reverse = "{{ m.fqdn }}." } output "{{scw.key}}_public_ip" { diff --git a/out/acme/apps.yaml b/out/acme/apps.yaml index fddeea6..95aed6b 100644 --- a/out/acme/apps.yaml +++ b/out/acme/apps.yaml @@ -4,21 +4,21 @@ data: name: "acme-1" machine: name: "acme-1" - fqdn: "acme-1.machine.acme.com." + fqdn: "acme-1.machine.acme.com" --- type: "io.trygvis.acme.AcmeServer" data: name: "acme-2" machine: name: "acme-2" - fqdn: "acme-2.machine.acme.com." + fqdn: "acme-2.machine.acme.com" --- type: "io.trygvis.acme.AcmeServer" data: name: "acme-3" machine: name: "acme-3" - fqdn: "acme-3.machine.acme.com." + fqdn: "acme-3.machine.acme.com" --- type: "io.trygvis.acme.apps.AcmeMyApp" data: @@ -173,23 +173,23 @@ data: --- type: "io.trygvis.rules.dns.DnsEntry" data: - fqdn: "acme-1.machine.acme.com." + fqdn: "acme-1.machine.acme.com" type: "A" --- type: "io.trygvis.rules.dns.DnsEntry" data: - fqdn: "acme-2.machine.acme.com." + fqdn: "acme-2.machine.acme.com" type: "A" --- type: "io.trygvis.rules.dns.DnsEntry" data: - fqdn: "acme-3.machine.acme.com." + fqdn: "acme-3.machine.acme.com" type: "A" --- type: "io.trygvis.rules.dns.DnsEntryTerraformExpression" data: entry: - fqdn: "acme-1.machine.acme.com." + fqdn: "acme-1.machine.acme.com" type: "A" key: "acme-1" expression: "scaleway_instance_ip.acme-1.address" @@ -197,7 +197,7 @@ data: type: "io.trygvis.rules.dns.DnsEntryTerraformExpression" data: entry: - fqdn: "acme-2.machine.acme.com." + fqdn: "acme-2.machine.acme.com" type: "A" key: "acme-2" expression: "scaleway_instance_ip.acme-2.address" @@ -205,7 +205,7 @@ data: type: "io.trygvis.rules.dns.DnsEntryTerraformExpression" data: entry: - fqdn: "acme-3.machine.acme.com." + fqdn: "acme-3.machine.acme.com" type: "A" key: "acme-3" expression: "scaleway_instance_ip.acme-3.address" @@ -218,17 +218,17 @@ data: type: "io.trygvis.rules.machine.Machine" data: name: "acme-1" - fqdn: "acme-1.machine.acme.com." + fqdn: "acme-1.machine.acme.com" --- type: "io.trygvis.rules.machine.Machine" data: name: "acme-2" - fqdn: "acme-2.machine.acme.com." + fqdn: "acme-2.machine.acme.com" --- type: "io.trygvis.rules.machine.Machine" data: name: "acme-3" - fqdn: "acme-3.machine.acme.com." + fqdn: "acme-3.machine.acme.com" --- type: "io.trygvis.rules.machine.Machine" data: @@ -248,42 +248,42 @@ type: "io.trygvis.rules.terraform.ScalewayMachine" data: machine: name: "acme-1" - fqdn: "acme-1.machine.acme.com." + fqdn: "acme-1.machine.acme.com" key: "acme-1" --- type: "io.trygvis.rules.terraform.ScalewayMachine" data: machine: name: "acme-1" - fqdn: "acme-1.machine.acme.com." + fqdn: "acme-1.machine.acme.com" key: "acme-1" --- type: "io.trygvis.rules.terraform.ScalewayMachine" data: machine: name: "acme-2" - fqdn: "acme-2.machine.acme.com." + fqdn: "acme-2.machine.acme.com" key: "acme-2" --- type: "io.trygvis.rules.terraform.ScalewayMachine" data: machine: name: "acme-2" - fqdn: "acme-2.machine.acme.com." + fqdn: "acme-2.machine.acme.com" key: "acme-2" --- type: "io.trygvis.rules.terraform.ScalewayMachine" data: machine: name: "acme-3" - fqdn: "acme-3.machine.acme.com." + fqdn: "acme-3.machine.acme.com" key: "acme-3" --- type: "io.trygvis.rules.terraform.ScalewayMachine" data: machine: name: "acme-3" - fqdn: "acme-3.machine.acme.com." + fqdn: "acme-3.machine.acme.com" key: "acme-3" --- type: "io.trygvis.rules.terraform.ScalewayMachine" -- cgit v1.2.3 From 250cb0fb4fa9787c78b73b44425676cfec3a7944 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Tue, 12 Jan 2021 20:57:56 +0100 Subject: Starting on generating ansible files for docker-compose setups. --- acme-apps/ansible/dba/acme-myapp-ci.yml | 37 +++++ acme-apps/ansible/dba/acme-myapp-production.yml | 26 ++++ acme-apps/ansible/dba/acme-ops.yml | 18 +++ acme.yaml | 22 +++ j2/dba/cluster.j2 | 19 +++ .../main/resources/io/trygvis/acme/apps/apps.drl | 25 +-- .../main/java/io/trygvis/rules/core/Problem.java | 11 ++ .../main/java/io/trygvis/rules/dba/Container.java | 42 ++++- .../main/java/io/trygvis/rules/dns/DnsZone.java | 9 ++ .../main/resources/io/trygvis/rules/dba/dba.drl | 69 +++++++++ out/acme/apps.yaml | 170 +++++++++++++++------ 11 files changed, 384 insertions(+), 64 deletions(-) create mode 100644 acme-apps/ansible/dba/acme-myapp-ci.yml create mode 100644 acme-apps/ansible/dba/acme-myapp-production.yml create mode 100644 acme-apps/ansible/dba/acme-ops.yml create mode 100644 j2/dba/cluster.j2 create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/core/Problem.java create mode 100644 module/ri-engine/src/main/java/io/trygvis/rules/dns/DnsZone.java create mode 100644 module/ri-engine/src/main/resources/io/trygvis/rules/dba/dba.drl diff --git a/acme-apps/ansible/dba/acme-myapp-ci.yml b/acme-apps/ansible/dba/acme-myapp-ci.yml new file mode 100644 index 0000000..e44b73e --- /dev/null +++ b/acme-apps/ansible/dba/acme-myapp-ci.yml @@ -0,0 +1,37 @@ +# Generated + +# cluster: +--- +- host: + - io.trygvis.rules.machine.Machine@b112b13 + tasks: + import_role: + name: docker-service + vars: + template: | + version: "3" + services: + mdb: + image: mongodb:3.2 + pdb: + image: postgresql:13 + +--- +- host: + - io.trygvis.rules.machine.Machine@d5556bf + tasks: + import_role: + name: docker-service + vars: + template: | + version: "3" + services: + 4tune-api: + image: 4tune-api:development + 4tune-web: + image: 4tune-web:development + statera-console: + image: statera-console:development + statera: + image: statera:development + diff --git a/acme-apps/ansible/dba/acme-myapp-production.yml b/acme-apps/ansible/dba/acme-myapp-production.yml new file mode 100644 index 0000000..3cd0798 --- /dev/null +++ b/acme-apps/ansible/dba/acme-myapp-production.yml @@ -0,0 +1,26 @@ +# Generated + +# cluster: +--- +- host: + - io.trygvis.rules.machine.Machine@3ac3f6f + tasks: + import_role: + name: docker-service + vars: + template: | + version: "3" + services: + mdb: + image: mongodb:3.2 + pdb: + image: postgresql:13 + 4tune-api: + image: 4tune-api:master + 4tune-web: + image: 4tune-web:master + statera-console: + image: statera-console:master + statera: + image: statera:master + diff --git a/acme-apps/ansible/dba/acme-ops.yml b/acme-apps/ansible/dba/acme-ops.yml new file mode 100644 index 0000000..62264b0 --- /dev/null +++ b/acme-apps/ansible/dba/acme-ops.yml @@ -0,0 +1,18 @@ +# Generated + +# cluster: +--- +- host: + - io.trygvis.rules.machine.Machine@b112b13 + tasks: + import_role: + name: docker-service + vars: + template: | + version: "3" + services: + n8n: + image: n8n:0.84.1 + pdb: + image: postgresql:11 + diff --git a/acme.yaml b/acme.yaml index 09bdd0d..e82200a 100644 --- a/acme.yaml +++ b/acme.yaml @@ -21,13 +21,35 @@ type: io.trygvis.rules.machine.Machine data: name: acme-1 --- +type: io.trygvis.rules.dba.DbaMachineRole +data: + machine: acme-1 + roles: + - ci-app + +--- type: io.trygvis.rules.machine.Machine data: name: acme-2 --- +type: io.trygvis.rules.dba.DbaMachineRole +data: + machine: acme-2 + roles: + - ops + - ci-db # This also runs the DB for the non-production environments to keep the other machines stateless + +--- type: io.trygvis.rules.machine.Machine data: name: acme-3 +--- +type: io.trygvis.rules.dba.DbaMachineRole +data: + machine: acme-3 + roles: + - production-app + - production-db # Workstations --- diff --git a/j2/dba/cluster.j2 b/j2/dba/cluster.j2 new file mode 100644 index 0000000..87973ff --- /dev/null +++ b/j2/dba/cluster.j2 @@ -0,0 +1,19 @@ +# Generated + +# cluster: {{ cluster.name }} +{%- for m, containers in containersByMachine.entrySet() %} +--- +- host: + - {{ m }} + tasks: + import_role: + name: docker-service + vars: + template: | + version: "3" + services: +{%- for c in containers %} + {{ c.name }}: + image: {{ c.image }}:{{ c.tag }} +{%- endfor %} +{% endfor %} diff --git a/module/acme/src/main/resources/io/trygvis/acme/apps/apps.drl b/module/acme/src/main/resources/io/trygvis/acme/apps/apps.drl index 95f09c8..e7bdfe3 100644 --- a/module/acme/src/main/resources/io/trygvis/acme/apps/apps.drl +++ b/module/acme/src/main/resources/io/trygvis/acme/apps/apps.drl @@ -2,7 +2,8 @@ package io.trygvis.acme.apps; import io.trygvis.rules.machine.Machine; import io.trygvis.rules.dba.Cluster; -import io.trygvis.rules.dba.Container; +import io.trygvis.rules.dba.Container +import io.trygvis.rules.dns.DnsZone; dialect "mvel" @@ -12,22 +13,28 @@ when 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")); + insert(new Container(cluster, "pdb", "ops", "postgresql", "11")); + insert(new Container(cluster, "n8n", "ops", "n8n", "0.84.1")); end rule "MyApp" when $app: AcmeMyApp() then + var zone = new DnsZone($app.environment + ".acme.com"); + insert(zone) + var cluster = new Cluster("acme-myapp-" + $app.environment); insert(cluster); + var app = $app.environment + "-app"; + var db = $app.environment + "-db"; + 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")); + insert(new Container(cluster, "statera", app, "statera", tag)); + insert(new Container(cluster, "statera-console", app, "statera-console", tag)); + insert(new Container(cluster, "4tune-web", app, "4tune-web", tag)); + insert(new Container(cluster, "4tune-api", app, "4tune-api", tag)); + insert(new Container(cluster, "pdb", db, "postgresql", "13")); + insert(new Container(cluster, "mdb", db, "mongodb", "3.2")); end diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/core/Problem.java b/module/ri-engine/src/main/java/io/trygvis/rules/core/Problem.java new file mode 100644 index 0000000..04d1af3 --- /dev/null +++ b/module/ri-engine/src/main/java/io/trygvis/rules/core/Problem.java @@ -0,0 +1,11 @@ +package io.trygvis.rules.core; + +public class Problem { + public final String message; + public final Object object; + + public Problem(String message, Object object) { + this.message = message; + this.object = object; + } +} 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 index 6df939d..d852115 100644 --- 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 @@ -1,11 +1,15 @@ package io.trygvis.rules.dba; +import io.trygvis.rules.machine.Machine; + public class Container { - public Cluster cluster; - public String name; - public String machineRole; - public String image; - public String tag; + public final Cluster cluster; + public final String name; + public final String machineRole; + public final String image; + public final String tag; + + private Machine machine; public Container(Cluster cluster, String name, String machineRole, String image, String tag) { this.cluster = cluster; @@ -14,4 +18,32 @@ public class Container { this.image = image; this.tag = tag; } + + public Cluster getCluster() { + return cluster; + } + + public String getName() { + return name; + } + + public String getMachineRole() { + return machineRole; + } + + public String getImage() { + return image; + } + + public String getTag() { + return tag; + } + + public Machine getMachine() { + return machine; + } + + public void setMachine(Machine machine) { + this.machine = machine; + } } diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/dns/DnsZone.java b/module/ri-engine/src/main/java/io/trygvis/rules/dns/DnsZone.java new file mode 100644 index 0000000..1af5c8f --- /dev/null +++ b/module/ri-engine/src/main/java/io/trygvis/rules/dns/DnsZone.java @@ -0,0 +1,9 @@ +package io.trygvis.rules.dns; + +public class DnsZone { + public final String name; + + public DnsZone(String name) { + this.name = name; + } +} 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..9bdc0a5 --- /dev/null +++ b/module/ri-engine/src/main/resources/io/trygvis/rules/dba/dba.drl @@ -0,0 +1,69 @@ +package io.trygvis.rules.dba + +import io.trygvis.rules.core.Problem +import io.trygvis.rules.machine.Machine +import java.util.ArrayList +import java.util.Map +import java.util.HashMap +import java.util.List +import java.util.stream.Collectors +import java.util.Collections + +global io.trygvis.rules.engine.TemplateEngine te; + +dialect "mvel" + +declare DbaMachineRole + machine : String + roles : String[] +end + +rule "Assign containers to hosts" +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) { + machine = $machine + } +end + +rule "Containers without hosts" + agenda-group "generate" +when + $container : Container(machine == null) +then + insert(new Problem("No machine for container", $container)) +end + +rule "Generate docker-compose.yaml" + agenda-group "generate" +when + $cluster : Cluster() + $containers : ArrayList(size > 0) from collect(Container(cluster == $cluster)) +then + System.out.println("Docker compose for cluster: " + $cluster.name + " with " + $containers.size() + " containers"); + + Map containersByMachine = new HashMap(); + for (Object o : $containers) { + Container c = (Container) o; + + var list = (List) containersByMachine.get(c.getMachine()); + if (list == null) { + list = new ArrayList(); + containersByMachine.put(c.getMachine(), list); + } + list.add(c); + } + + System.out.println("containersByMachine = " + containersByMachine); + + var path = "ansible/dba/" + $cluster.name + ".yml"; + te.template("dba/cluster", path, Map.of( + "cluster", $cluster, + "containers", $containers, + "containersByMachine", containersByMachine + )); +end diff --git a/out/acme/apps.yaml b/out/acme/apps.yaml index 95aed6b..d6fbe6d 100644 --- a/out/acme/apps.yaml +++ b/out/acme/apps.yaml @@ -49,127 +49,189 @@ type: "io.trygvis.rules.dba.Container" data: cluster: name: "acme-myapp-ci" - name: "app" - machineRole: "4tune-api" + name: "4tune-api" + machineRole: "ci-app" image: "4tune-api" tag: "development" + machine: + name: "acme-1" + fqdn: "acme-1.machine.acme.com" --- type: "io.trygvis.rules.dba.Container" data: cluster: name: "acme-myapp-production" - name: "app" - machineRole: "4tune-api" + name: "4tune-api" + machineRole: "production-app" image: "4tune-api" tag: "master" + machine: + name: "acme-3" + fqdn: "acme-3.machine.acme.com" --- type: "io.trygvis.rules.dba.Container" data: cluster: name: "acme-myapp-ci" - name: "app" - machineRole: "4tune-web" + name: "4tune-web" + machineRole: "ci-app" image: "4tune-web" tag: "development" + machine: + name: "acme-1" + fqdn: "acme-1.machine.acme.com" --- type: "io.trygvis.rules.dba.Container" data: cluster: name: "acme-myapp-production" - name: "app" - machineRole: "4tune-web" + name: "4tune-web" + machineRole: "production-app" image: "4tune-web" tag: "master" + machine: + name: "acme-3" + fqdn: "acme-3.machine.acme.com" +--- +type: "io.trygvis.rules.dba.Container" +data: + cluster: + name: "acme-myapp-ci" + name: "mdb" + machineRole: "ci-db" + image: "mongodb" + tag: "3.2" + machine: + name: "acme-2" + fqdn: "acme-2.machine.acme.com" +--- +type: "io.trygvis.rules.dba.Container" +data: + cluster: + name: "acme-myapp-production" + name: "mdb" + machineRole: "production-db" + image: "mongodb" + tag: "3.2" + machine: + name: "acme-3" + fqdn: "acme-3.machine.acme.com" --- type: "io.trygvis.rules.dba.Container" data: cluster: name: "acme-ops" - name: "app" - machineRole: "n8n" + name: "n8n" + machineRole: "ops" image: "n8n" tag: "0.84.1" + machine: + name: "acme-2" + fqdn: "acme-2.machine.acme.com" +--- +type: "io.trygvis.rules.dba.Container" +data: + cluster: + name: "acme-myapp-ci" + name: "pdb" + machineRole: "ci-db" + image: "postgresql" + tag: "13" + machine: + name: "acme-2" + fqdn: "acme-2.machine.acme.com" --- type: "io.trygvis.rules.dba.Container" data: cluster: name: "acme-ops" - name: "app" - machineRole: "pdb" + name: "pdb" + machineRole: "ops" image: "postgresql" tag: "11" + machine: + name: "acme-2" + fqdn: "acme-2.machine.acme.com" +--- +type: "io.trygvis.rules.dba.Container" +data: + cluster: + name: "acme-myapp-production" + name: "pdb" + machineRole: "production-db" + image: "postgresql" + tag: "13" + machine: + name: "acme-3" + fqdn: "acme-3.machine.acme.com" --- type: "io.trygvis.rules.dba.Container" data: cluster: name: "acme-myapp-ci" - name: "app" - machineRole: "statera" + name: "statera" + machineRole: "ci-app" image: "statera" tag: "development" + machine: + name: "acme-1" + fqdn: "acme-1.machine.acme.com" --- type: "io.trygvis.rules.dba.Container" data: cluster: name: "acme-myapp-production" - name: "app" - machineRole: "statera" + name: "statera" + machineRole: "production-app" image: "statera" tag: "master" + machine: + name: "acme-3" + fqdn: "acme-3.machine.acme.com" --- type: "io.trygvis.rules.dba.Container" data: cluster: name: "acme-myapp-ci" - name: "app" - machineRole: "statera-console" + name: "statera-console" + machineRole: "ci-app" image: "statera-console" tag: "development" + machine: + name: "acme-1" + fqdn: "acme-1.machine.acme.com" --- type: "io.trygvis.rules.dba.Container" data: cluster: name: "acme-myapp-production" - name: "app" - machineRole: "statera-console" + name: "statera-console" + machineRole: "production-app" image: "statera-console" tag: "master" + machine: + name: "acme-3" + fqdn: "acme-3.machine.acme.com" --- -type: "io.trygvis.rules.dba.Container" -data: - cluster: - name: "acme-myapp-production" - name: "db" - machineRole: "mdb" - image: "mongodb" - tag: "3.2" ---- -type: "io.trygvis.rules.dba.Container" +type: "io.trygvis.rules.dba.DbaMachineRole" data: - cluster: - name: "acme-myapp-ci" - name: "db" - machineRole: "mdb" - image: "mongodb" - tag: "3.2" + machine: "acme-1" + roles: + - "ci-app" --- -type: "io.trygvis.rules.dba.Container" +type: "io.trygvis.rules.dba.DbaMachineRole" data: - cluster: - name: "acme-myapp-production" - name: "db" - machineRole: "pdb" - image: "postgresql" - tag: "13" + machine: "acme-2" + roles: + - "ops" + - "ci-db" --- -type: "io.trygvis.rules.dba.Container" +type: "io.trygvis.rules.dba.DbaMachineRole" data: - cluster: - name: "acme-myapp-ci" - name: "db" - machineRole: "pdb" - image: "postgresql" - tag: "13" + machine: "acme-3" + roles: + - "production-app" + - "production-db" --- type: "io.trygvis.rules.dns.DnsEntry" data: @@ -210,6 +272,14 @@ data: key: "acme-3" expression: "scaleway_instance_ip.acme-3.address" --- +type: "io.trygvis.rules.dns.DnsZone" +data: + name: "ci.acme.com" +--- +type: "io.trygvis.rules.dns.DnsZone" +data: + name: "production.acme.com" +--- type: "io.trygvis.rules.engine.KeyValue" data: key: "rm-gen" -- cgit v1.2.3 From 34bb772073b1954ac95b4f1491236eb8b063ef83 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Tue, 12 Jan 2021 22:04:57 +0100 Subject: Fixing host in ansible files. --- acme-apps/ansible/dba/acme-myapp-ci.yml | 28 ++++++++++++------------- acme-apps/ansible/dba/acme-myapp-production.yml | 2 +- acme-apps/ansible/dba/acme-ops.yml | 2 +- j2/dba/cluster.j2 | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/acme-apps/ansible/dba/acme-myapp-ci.yml b/acme-apps/ansible/dba/acme-myapp-ci.yml index e44b73e..584ddf3 100644 --- a/acme-apps/ansible/dba/acme-myapp-ci.yml +++ b/acme-apps/ansible/dba/acme-myapp-ci.yml @@ -3,7 +3,7 @@ # cluster: --- - host: - - io.trygvis.rules.machine.Machine@b112b13 + - acme-1 tasks: import_role: name: docker-service @@ -11,14 +11,18 @@ template: | version: "3" services: - mdb: - image: mongodb:3.2 - pdb: - image: postgresql:13 + 4tune-api: + image: 4tune-api:development + 4tune-web: + image: 4tune-web:development + statera-console: + image: statera-console:development + statera: + image: statera:development --- - host: - - io.trygvis.rules.machine.Machine@d5556bf + - acme-2 tasks: import_role: name: docker-service @@ -26,12 +30,8 @@ template: | version: "3" services: - 4tune-api: - image: 4tune-api:development - 4tune-web: - image: 4tune-web:development - statera-console: - image: statera-console:development - statera: - image: statera:development + mdb: + image: mongodb:3.2 + pdb: + image: postgresql:13 diff --git a/acme-apps/ansible/dba/acme-myapp-production.yml b/acme-apps/ansible/dba/acme-myapp-production.yml index 3cd0798..6b6bf6c 100644 --- a/acme-apps/ansible/dba/acme-myapp-production.yml +++ b/acme-apps/ansible/dba/acme-myapp-production.yml @@ -3,7 +3,7 @@ # cluster: --- - host: - - io.trygvis.rules.machine.Machine@3ac3f6f + - acme-3 tasks: import_role: name: docker-service diff --git a/acme-apps/ansible/dba/acme-ops.yml b/acme-apps/ansible/dba/acme-ops.yml index 62264b0..077c554 100644 --- a/acme-apps/ansible/dba/acme-ops.yml +++ b/acme-apps/ansible/dba/acme-ops.yml @@ -3,7 +3,7 @@ # cluster: --- - host: - - io.trygvis.rules.machine.Machine@b112b13 + - acme-2 tasks: import_role: name: docker-service diff --git a/j2/dba/cluster.j2 b/j2/dba/cluster.j2 index 87973ff..045fbcd 100644 --- a/j2/dba/cluster.j2 +++ b/j2/dba/cluster.j2 @@ -4,7 +4,7 @@ {%- for m, containers in containersByMachine.entrySet() %} --- - host: - - {{ m }} + - {{ m.name }} tasks: import_role: name: docker-service -- cgit v1.2.3 From 0e8048146ddf85adf28c1da09e45b98760f23210 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Tue, 12 Jan 2021 22:08:14 +0100 Subject: Better output YAML. Enabling object references internally in the document. Needed to write all objects in one go for Jackson to resolve all internal references. Applied some sorting magic to write out as many as possible objects on the root level. Will need some more magic later for customers to customize the output ordering. --- .../main/java/io/trygvis/rules/dba/Cluster.java | 4 + .../main/java/io/trygvis/rules/dba/Container.java | 6 + .../main/java/io/trygvis/rules/engine/DbIo.java | 77 ++- .../java/io/trygvis/rules/machine/Machine.java | 4 + out/acme/apps.yaml | 618 +++++++++------------ 5 files changed, 342 insertions(+), 367 deletions(-) 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 index 949d9ae..0b65aaa 100644 --- 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 @@ -1,5 +1,9 @@ package io.trygvis.rules.dba; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; + +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "name") public class Cluster { public String 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 index d852115..f6d2ba4 100644 --- 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 @@ -1,8 +1,13 @@ package io.trygvis.rules.dba; +import com.fasterxml.jackson.annotation.JsonIdentityReference; import io.trygvis.rules.machine.Machine; +//@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") public class Container { + public final String id; + +// @JsonIdentityReference(alwaysAsId = true) public final Cluster cluster; public final String name; public final String machineRole; @@ -12,6 +17,7 @@ public class Container { private Machine machine; public Container(Cluster cluster, String name, String machineRole, String image, String tag) { + this.id = cluster.name + "-" + name; this.cluster = cluster; this.name = name; this.machineRole = machineRole; 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 3173109..b402173 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 @@ -189,6 +189,9 @@ public class DbIo { return comparator; } + static record DbObject2(String type, Object data) { + } + public void dump(String s, Collection factHandles, Function filter) throws IOException { var yamlFile = new File("out", s + ".yaml"); @@ -214,18 +217,35 @@ public class DbIo { } } + var objects = new ArrayList(facts.size()); + for (var e : facts.entrySet()) { + var name = e.getKey().getName(); + + var collection = e.getValue(); + collection.sort(); + for (var fact : collection.values) { + objects.add(new DbObject2(name, fact)); + } + } + + /* + var x = new ArrayList(); + 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(); try (var writer = new FileWriter(yamlFile); 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 DbObject(name, mapper.valueToTree(fact))); - } - } + g.writeObject(objects); } } @@ -259,4 +279,43 @@ public class DbIo { } } } + + private static class DbObjectComparator implements Comparator { + private final List 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"); + + @Override + public int compare(DbObject2 a, DbObject2 b) { + var indexA = a.type.lastIndexOf("."); + String packageA = indexA == -1 ? null : a.type.substring(0, indexA); + String classA = indexA == -1 ? a.type : a.type.substring(indexA + 1); + + var indexB = b.type.lastIndexOf("."); + String packageB = indexB == -1 ? null : b.type.substring(0, indexB); + String classB = indexB == -1 ? b.type : b.type.substring(indexB + 1); + + var priIdxA = prioritizedPackages.indexOf(packageA); + var priIdxB = prioritizedPackages.indexOf(packageB); + + if (priIdxA == -1 && priIdxB == -1) { + return classB.compareTo(classA); + } else if (priIdxA == -1) { + return 1; + } else if (priIdxB == -1) { + return -1; + } + return priIdxA - priIdxB; +// var diff = priIdxB - priIdxA; +// if (diff != 0) { +// return diff; +// } +// +// return classB.compareTo(classA); + } + } } 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 52721e1..8e54d60 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 @@ -1,5 +1,9 @@ package io.trygvis.rules.machine; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; + +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "name") public class Machine { public String name; public String fqdn; diff --git a/out/acme/apps.yaml b/out/acme/apps.yaml index d6fbe6d..3942ed5 100644 --- a/out/acme/apps.yaml +++ b/out/acme/apps.yaml @@ -1,371 +1,273 @@ --- -type: "io.trygvis.acme.AcmeServer" -data: - name: "acme-1" - machine: - name: "acme-1" +- type: "io.trygvis.rules.machine.Machine" + data: + &acme-1 name: "acme-1" fqdn: "acme-1.machine.acme.com" ---- -type: "io.trygvis.acme.AcmeServer" -data: - name: "acme-2" - machine: - name: "acme-2" - fqdn: "acme-2.machine.acme.com" ---- -type: "io.trygvis.acme.AcmeServer" -data: - name: "acme-3" - machine: - name: "acme-3" - fqdn: "acme-3.machine.acme.com" ---- -type: "io.trygvis.acme.apps.AcmeMyApp" -data: - environment: "ci" - dockerTag: "development" ---- -type: "io.trygvis.acme.apps.AcmeMyApp" -data: - environment: "production" - dockerTag: "master" ---- -type: "io.trygvis.acme.apps.AcmeOps" -data: {} ---- -type: "io.trygvis.rules.dba.Cluster" -data: - name: "acme-myapp-ci" ---- -type: "io.trygvis.rules.dba.Cluster" -data: - name: "acme-myapp-production" ---- -type: "io.trygvis.rules.dba.Cluster" -data: - name: "acme-ops" ---- -type: "io.trygvis.rules.dba.Container" -data: - cluster: - name: "acme-myapp-ci" - name: "4tune-api" - machineRole: "ci-app" - image: "4tune-api" - tag: "development" - machine: - name: "acme-1" - fqdn: "acme-1.machine.acme.com" ---- -type: "io.trygvis.rules.dba.Container" -data: - cluster: - name: "acme-myapp-production" - name: "4tune-api" - machineRole: "production-app" - image: "4tune-api" - tag: "master" - machine: - name: "acme-3" - fqdn: "acme-3.machine.acme.com" ---- -type: "io.trygvis.rules.dba.Container" -data: - cluster: - name: "acme-myapp-ci" - name: "4tune-web" - machineRole: "ci-app" - image: "4tune-web" - tag: "development" - machine: - name: "acme-1" - fqdn: "acme-1.machine.acme.com" ---- -type: "io.trygvis.rules.dba.Container" -data: - cluster: - name: "acme-myapp-production" - name: "4tune-web" - machineRole: "production-app" - image: "4tune-web" - tag: "master" - machine: - name: "acme-3" - fqdn: "acme-3.machine.acme.com" ---- -type: "io.trygvis.rules.dba.Container" -data: - cluster: - name: "acme-myapp-ci" - name: "mdb" - machineRole: "ci-db" - image: "mongodb" - tag: "3.2" - machine: - name: "acme-2" - fqdn: "acme-2.machine.acme.com" ---- -type: "io.trygvis.rules.dba.Container" -data: - cluster: - name: "acme-myapp-production" - name: "mdb" - machineRole: "production-db" - image: "mongodb" - tag: "3.2" - machine: - name: "acme-3" - fqdn: "acme-3.machine.acme.com" ---- -type: "io.trygvis.rules.dba.Container" -data: - cluster: - name: "acme-ops" - name: "n8n" - machineRole: "ops" - image: "n8n" - tag: "0.84.1" - machine: - name: "acme-2" +- type: "io.trygvis.rules.machine.Machine" + data: + &acme-2 name: "acme-2" fqdn: "acme-2.machine.acme.com" ---- -type: "io.trygvis.rules.dba.Container" -data: - cluster: - name: "acme-myapp-ci" - name: "pdb" - machineRole: "ci-db" - image: "postgresql" - tag: "13" - machine: - name: "acme-2" - fqdn: "acme-2.machine.acme.com" ---- -type: "io.trygvis.rules.dba.Container" -data: - cluster: - name: "acme-ops" - name: "pdb" - machineRole: "ops" - image: "postgresql" - tag: "11" - machine: - name: "acme-2" - fqdn: "acme-2.machine.acme.com" ---- -type: "io.trygvis.rules.dba.Container" -data: - cluster: - name: "acme-myapp-production" - name: "pdb" - machineRole: "production-db" - image: "postgresql" - tag: "13" - machine: - name: "acme-3" - fqdn: "acme-3.machine.acme.com" ---- -type: "io.trygvis.rules.dba.Container" -data: - cluster: - name: "acme-myapp-ci" - name: "statera" - machineRole: "ci-app" - image: "statera" - tag: "development" - machine: - name: "acme-1" - fqdn: "acme-1.machine.acme.com" ---- -type: "io.trygvis.rules.dba.Container" -data: - cluster: - name: "acme-myapp-production" - name: "statera" - machineRole: "production-app" - image: "statera" - tag: "master" - machine: - name: "acme-3" - fqdn: "acme-3.machine.acme.com" ---- -type: "io.trygvis.rules.dba.Container" -data: - cluster: - name: "acme-myapp-ci" - name: "statera-console" - machineRole: "ci-app" - image: "statera-console" - tag: "development" - machine: - name: "acme-1" - fqdn: "acme-1.machine.acme.com" ---- -type: "io.trygvis.rules.dba.Container" -data: - cluster: - name: "acme-myapp-production" - name: "statera-console" - machineRole: "production-app" - image: "statera-console" - tag: "master" - machine: - name: "acme-3" +- type: "io.trygvis.rules.machine.Machine" + data: + &acme-3 name: "acme-3" fqdn: "acme-3.machine.acme.com" ---- -type: "io.trygvis.rules.dba.DbaMachineRole" -data: - machine: "acme-1" - roles: - - "ci-app" ---- -type: "io.trygvis.rules.dba.DbaMachineRole" -data: - machine: "acme-2" - roles: - - "ops" - - "ci-db" ---- -type: "io.trygvis.rules.dba.DbaMachineRole" -data: - machine: "acme-3" - roles: - - "production-app" - - "production-db" ---- -type: "io.trygvis.rules.dns.DnsEntry" -data: - fqdn: "acme-1.machine.acme.com" - type: "A" ---- -type: "io.trygvis.rules.dns.DnsEntry" -data: - fqdn: "acme-2.machine.acme.com" - type: "A" ---- -type: "io.trygvis.rules.dns.DnsEntry" -data: - fqdn: "acme-3.machine.acme.com" - type: "A" ---- -type: "io.trygvis.rules.dns.DnsEntryTerraformExpression" -data: - entry: +- type: "io.trygvis.rules.machine.Machine" + data: + &ws-1 name: "ws-1" + fqdn: null +- type: "io.trygvis.rules.machine.Machine" + data: + &ws-2 name: "ws-2" + fqdn: null +- type: "io.trygvis.rules.dns.DnsEntry" + data: fqdn: "acme-1.machine.acme.com" type: "A" - key: "acme-1" - expression: "scaleway_instance_ip.acme-1.address" ---- -type: "io.trygvis.rules.dns.DnsEntryTerraformExpression" -data: - entry: +- type: "io.trygvis.rules.dns.DnsEntry" + data: fqdn: "acme-2.machine.acme.com" type: "A" - key: "acme-2" - expression: "scaleway_instance_ip.acme-2.address" ---- -type: "io.trygvis.rules.dns.DnsEntryTerraformExpression" -data: - entry: +- type: "io.trygvis.rules.dns.DnsEntry" + data: fqdn: "acme-3.machine.acme.com" type: "A" - key: "acme-3" - expression: "scaleway_instance_ip.acme-3.address" ---- -type: "io.trygvis.rules.dns.DnsZone" -data: - name: "ci.acme.com" ---- -type: "io.trygvis.rules.dns.DnsZone" -data: - name: "production.acme.com" ---- -type: "io.trygvis.rules.engine.KeyValue" -data: - key: "rm-gen" - value: null ---- -type: "io.trygvis.rules.machine.Machine" -data: - name: "acme-1" - fqdn: "acme-1.machine.acme.com" ---- -type: "io.trygvis.rules.machine.Machine" -data: - name: "acme-2" - fqdn: "acme-2.machine.acme.com" ---- -type: "io.trygvis.rules.machine.Machine" -data: - name: "acme-3" - fqdn: "acme-3.machine.acme.com" ---- -type: "io.trygvis.rules.machine.Machine" -data: - name: "ws-1" - fqdn: null ---- -type: "io.trygvis.rules.machine.Machine" -data: - name: "ws-2" - fqdn: null ---- -type: "io.trygvis.rules.terraform.GoogleManagedZoneTerraformExpression" -data: - name: "acme_zone" ---- -type: "io.trygvis.rules.terraform.ScalewayMachine" -data: - machine: - name: "acme-1" - fqdn: "acme-1.machine.acme.com" - key: "acme-1" ---- -type: "io.trygvis.rules.terraform.ScalewayMachine" -data: - machine: +- type: "io.trygvis.rules.dns.DnsEntryTerraformExpression" + data: + entry: + fqdn: "acme-1.machine.acme.com" + type: "A" + key: "acme-1" + expression: "scaleway_instance_ip.acme-1.address" +- type: "io.trygvis.rules.dns.DnsEntryTerraformExpression" + data: + entry: + fqdn: "acme-2.machine.acme.com" + type: "A" + key: "acme-2" + expression: "scaleway_instance_ip.acme-2.address" +- type: "io.trygvis.rules.dns.DnsEntryTerraformExpression" + data: + entry: + fqdn: "acme-3.machine.acme.com" + type: "A" + key: "acme-3" + expression: "scaleway_instance_ip.acme-3.address" +- type: "io.trygvis.rules.dns.DnsZone" + data: + name: "ci.acme.com" +- type: "io.trygvis.rules.dns.DnsZone" + data: + name: "production.acme.com" +- type: "io.trygvis.rules.dba.Cluster" + data: + &acme-myapp-ci name: "acme-myapp-ci" +- type: "io.trygvis.rules.dba.Cluster" + data: + &acme-myapp-production name: "acme-myapp-production" +- type: "io.trygvis.rules.dba.Cluster" + data: + &acme-ops name: "acme-ops" +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-ci-4tune-api" + cluster: *acme-myapp-ci + name: "4tune-api" + machineRole: "ci-app" + image: "4tune-api" + tag: "development" + machine: *acme-1 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-production-4tune-api" + cluster: *acme-myapp-production + name: "4tune-api" + machineRole: "production-app" + image: "4tune-api" + tag: "master" + machine: *acme-3 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-ci-4tune-web" + cluster: *acme-myapp-ci + name: "4tune-web" + machineRole: "ci-app" + image: "4tune-web" + tag: "development" + machine: *acme-1 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-production-4tune-web" + cluster: *acme-myapp-production + name: "4tune-web" + machineRole: "production-app" + image: "4tune-web" + tag: "master" + machine: *acme-3 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-ci-mdb" + cluster: *acme-myapp-ci + name: "mdb" + machineRole: "ci-db" + image: "mongodb" + tag: "3.2" + machine: *acme-2 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-production-mdb" + cluster: *acme-myapp-production + name: "mdb" + machineRole: "production-db" + image: "mongodb" + tag: "3.2" + machine: *acme-3 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-ops-n8n" + cluster: *acme-ops + name: "n8n" + machineRole: "ops" + image: "n8n" + tag: "0.84.1" + machine: *acme-2 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-ci-pdb" + cluster: *acme-myapp-ci + name: "pdb" + machineRole: "ci-db" + image: "postgresql" + tag: "13" + machine: *acme-2 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-production-pdb" + cluster: *acme-myapp-production + name: "pdb" + machineRole: "production-db" + image: "postgresql" + tag: "13" + machine: *acme-3 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-ops-pdb" + cluster: *acme-ops + name: "pdb" + machineRole: "ops" + image: "postgresql" + tag: "11" + machine: *acme-2 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-ci-statera" + cluster: *acme-myapp-ci + name: "statera" + machineRole: "ci-app" + image: "statera" + tag: "development" + machine: *acme-1 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-production-statera" + cluster: *acme-myapp-production + name: "statera" + machineRole: "production-app" + image: "statera" + tag: "master" + machine: *acme-3 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-ci-statera-console" + cluster: *acme-myapp-ci + name: "statera-console" + machineRole: "ci-app" + image: "statera-console" + tag: "development" + machine: *acme-1 +- type: "io.trygvis.rules.dba.Container" + data: + id: "acme-myapp-production-statera-console" + cluster: *acme-myapp-production + name: "statera-console" + machineRole: "production-app" + image: "statera-console" + tag: "master" + machine: *acme-3 +- type: "io.trygvis.rules.dba.DbaMachineRole" + data: + machine: "acme-1" + roles: + - "ci-app" +- type: "io.trygvis.rules.dba.DbaMachineRole" + data: + machine: "acme-2" + roles: + - "ops" + - "ci-db" +- type: "io.trygvis.rules.dba.DbaMachineRole" + data: + machine: "acme-3" + roles: + - "production-app" + - "production-db" +- type: "io.trygvis.rules.terraform.ScalewayMachine" + data: + machine: *acme-1 + key: "acme-1" +- type: "io.trygvis.rules.terraform.ScalewayMachine" + data: + machine: *acme-1 + key: "acme-1" +- type: "io.trygvis.rules.terraform.ScalewayMachine" + data: + machine: *acme-2 + key: "acme-2" +- type: "io.trygvis.rules.terraform.ScalewayMachine" + data: + machine: *acme-2 + key: "acme-2" +- type: "io.trygvis.rules.terraform.ScalewayMachine" + data: + machine: *acme-3 + key: "acme-3" +- type: "io.trygvis.rules.terraform.ScalewayMachine" + data: + machine: *acme-3 + key: "acme-3" +- type: "io.trygvis.rules.terraform.ScalewayMachine" + data: + machine: *ws-1 + key: "ws-1" +- type: "io.trygvis.rules.terraform.ScalewayMachine" + data: + machine: *ws-2 + key: "ws-2" +- type: "io.trygvis.rules.engine.KeyValue" + data: + key: "rm-gen" + value: null +- type: "io.trygvis.rules.terraform.GoogleManagedZoneTerraformExpression" + data: + name: "acme_zone" +- type: "io.trygvis.acme.AcmeServer" + data: name: "acme-1" - fqdn: "acme-1.machine.acme.com" - key: "acme-1" ---- -type: "io.trygvis.rules.terraform.ScalewayMachine" -data: - machine: + machine: *acme-1 +- type: "io.trygvis.acme.AcmeServer" + data: name: "acme-2" - fqdn: "acme-2.machine.acme.com" - key: "acme-2" ---- -type: "io.trygvis.rules.terraform.ScalewayMachine" -data: - machine: - name: "acme-2" - fqdn: "acme-2.machine.acme.com" - key: "acme-2" ---- -type: "io.trygvis.rules.terraform.ScalewayMachine" -data: - machine: - name: "acme-3" - fqdn: "acme-3.machine.acme.com" - key: "acme-3" ---- -type: "io.trygvis.rules.terraform.ScalewayMachine" -data: - machine: + machine: *acme-2 +- type: "io.trygvis.acme.AcmeServer" + data: name: "acme-3" - fqdn: "acme-3.machine.acme.com" - key: "acme-3" ---- -type: "io.trygvis.rules.terraform.ScalewayMachine" -data: - machine: - name: "ws-1" - fqdn: null - key: "ws-1" ---- -type: "io.trygvis.rules.terraform.ScalewayMachine" -data: - machine: - name: "ws-2" - fqdn: null - key: "ws-2" + machine: *acme-3 +- type: "io.trygvis.acme.apps.AcmeOps" + data: {} +- type: "io.trygvis.acme.apps.AcmeMyApp" + data: + environment: "ci" + dockerTag: "development" +- type: "io.trygvis.acme.apps.AcmeMyApp" + data: + environment: "production" + dockerTag: "master" -- cgit v1.2.3 From e2f4aefa956bb06b1ee52d95ad8275757605678d Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Tue, 12 Jan 2021 23:06:32 +0100 Subject: Switching WG code to use object references. --- acme-apps/ansible/dba/acme-myapp-ci.yml | 28 +- acme-wireguard/host_vars/acme-1/wireguard.yml | 2 +- acme-wireguard/host_vars/acme-2/wireguard.yml | 2 +- acme-wireguard/host_vars/acme-3/wireguard.yml | 2 +- acme-wireguard/host_vars/ws-1/wireguard.yml | 4 +- acme-wireguard/host_vars/ws-2/wireguard.yml | 4 +- acme-wireguard/inventory.yml | 16 +- j2/wireguard/ansible-host.j2 | 4 +- j2/wireguard/inventory.j2 | 8 +- .../src/main/resources/io/trygvis/acme/acme.drl | 6 +- .../main/java/io/trygvis/rules/engine/DbIo.java | 49 ++-- .../java/io/trygvis/rules/machine/Machine.java | 7 +- .../main/resources/io/trygvis/rules/dba/dba.drl | 4 +- .../io/trygvis/rules/terraform/terraform.drl | 2 + .../io/trygvis/rules/wireguard/wireguard.drl | 70 ++--- out/acme/apps.yaml | 30 +- out/acme/wireguard.yaml | 313 ++++++++++----------- 17 files changed, 273 insertions(+), 278 deletions(-) diff --git a/acme-apps/ansible/dba/acme-myapp-ci.yml b/acme-apps/ansible/dba/acme-myapp-ci.yml index 584ddf3..e73360d 100644 --- a/acme-apps/ansible/dba/acme-myapp-ci.yml +++ b/acme-apps/ansible/dba/acme-myapp-ci.yml @@ -3,7 +3,7 @@ # cluster: --- - host: - - acme-1 + - acme-2 tasks: import_role: name: docker-service @@ -11,18 +11,14 @@ template: | version: "3" services: - 4tune-api: - image: 4tune-api:development - 4tune-web: - image: 4tune-web:development - statera-console: - image: statera-console:development - statera: - image: statera:development + mdb: + image: mongodb:3.2 + pdb: + image: postgresql:13 --- - host: - - acme-2 + - acme-1 tasks: import_role: name: docker-service @@ -30,8 +26,12 @@ template: | version: "3" services: - mdb: - image: mongodb:3.2 - pdb: - image: postgresql:13 + 4tune-api: + image: 4tune-api:development + 4tune-web: + image: 4tune-web:development + statera-console: + image: statera-console:development + statera: + image: statera:development diff --git a/acme-wireguard/host_vars/acme-1/wireguard.yml b/acme-wireguard/host_vars/acme-1/wireguard.yml index af0f3a7..d044f69 100644 --- a/acme-wireguard/host_vars/acme-1/wireguard.yml +++ b/acme-wireguard/host_vars/acme-1/wireguard.yml @@ -3,5 +3,5 @@ link_address: 192.168.10.3 network_cidr: 10.55.255.0/24 wireguard_peers: acme-1: - - acme-3.machine.acme.com - acme-2.machine.acme.com + - acme-3.machine.acme.com diff --git a/acme-wireguard/host_vars/acme-2/wireguard.yml b/acme-wireguard/host_vars/acme-2/wireguard.yml index 4228d87..a69f2cc 100644 --- a/acme-wireguard/host_vars/acme-2/wireguard.yml +++ b/acme-wireguard/host_vars/acme-2/wireguard.yml @@ -3,5 +3,5 @@ link_address: 192.168.10.4 network_cidr: 10.55.254.0/24 wireguard_peers: acme-2: - - acme-3.machine.acme.com - acme-1.machine.acme.com + - acme-3.machine.acme.com diff --git a/acme-wireguard/host_vars/acme-3/wireguard.yml b/acme-wireguard/host_vars/acme-3/wireguard.yml index f42f50c..9c2c1eb 100644 --- a/acme-wireguard/host_vars/acme-3/wireguard.yml +++ b/acme-wireguard/host_vars/acme-3/wireguard.yml @@ -3,5 +3,5 @@ link_address: 192.168.10.5 network_cidr: 10.55.253.0/24 wireguard_peers: acme-3: - - acme-2.machine.acme.com - acme-1.machine.acme.com + - acme-2.machine.acme.com diff --git a/acme-wireguard/host_vars/ws-1/wireguard.yml b/acme-wireguard/host_vars/ws-1/wireguard.yml index 3cafb0b..26c1259 100644 --- a/acme-wireguard/host_vars/ws-1/wireguard.yml +++ b/acme-wireguard/host_vars/ws-1/wireguard.yml @@ -3,6 +3,6 @@ link_address: 192.168.10.6 network_cidr: 10.55.252.0/24 wireguard_peers: ws-1: - - acme-3.machine.acme.com - - acme-2.machine.acme.com - acme-1.machine.acme.com + - acme-2.machine.acme.com + - acme-3.machine.acme.com diff --git a/acme-wireguard/host_vars/ws-2/wireguard.yml b/acme-wireguard/host_vars/ws-2/wireguard.yml index a727689..0958829 100644 --- a/acme-wireguard/host_vars/ws-2/wireguard.yml +++ b/acme-wireguard/host_vars/ws-2/wireguard.yml @@ -3,6 +3,6 @@ link_address: 192.168.10.7 network_cidr: 10.55.251.0/24 wireguard_peers: ws-2: - - acme-3.machine.acme.com - - acme-2.machine.acme.com - acme-1.machine.acme.com + - acme-2.machine.acme.com + - acme-3.machine.acme.com diff --git a/acme-wireguard/inventory.yml b/acme-wireguard/inventory.yml index 6f76480..364d472 100644 --- a/acme-wireguard/inventory.yml +++ b/acme-wireguard/inventory.yml @@ -1,7 +1,13 @@ # Generated all: - ws-2: - ws-1: - acme-3: acme-3.machine.acme.com - acme-2: acme-2.machine.acme.com - acme-1: acme-1.machine.acme.com + hosts: + acme-1: + ansible_host: acme-1.machine.acme.com + acme-2: + ansible_host: acme-2.machine.acme.com + acme-3: + ansible_host: acme-3.machine.acme.com + ws-1: + ansible_host: + ws-2: + ansible_host: diff --git a/j2/wireguard/ansible-host.j2 b/j2/wireguard/ansible-host.j2 index 9d684ef..a3c8c40 100644 --- a/j2/wireguard/ansible-host.j2 +++ b/j2/wireguard/ansible-host.j2 @@ -2,7 +2,7 @@ link_address: {{ host.ip }} network_cidr: {{ host.networkCidr }} wireguard_peers: - {{ host.name }}: + {{ host.machine.name }}: {%- for peer in peers %} - - {{ peer }} + - {{ peer.fqdn }} {%- endfor %} diff --git a/j2/wireguard/inventory.j2 b/j2/wireguard/inventory.j2 index c7f38ee..0924bb2 100644 --- a/j2/wireguard/inventory.j2 +++ b/j2/wireguard/inventory.j2 @@ -1,5 +1,7 @@ # Generated all: -{%- for host in hosts %} - {{ host.name }}: {{ host.fqdn }} -{%- endfor %} + hosts: + {%- for host in hosts %} + {{ host.getName() }}: + ansible_host: {{ host.getFqdn() }} + {%- endfor %} 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 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 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>(); var discoveredFieldsP2 = new LinkedHashMap>(); @@ -228,18 +257,6 @@ public class DbIo { } } - /* - var x = new ArrayList(); - 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 { private final List 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, diff --git a/out/acme/apps.yaml b/out/acme/apps.yaml index 3942ed5..0c69b8e 100644 --- a/out/acme/apps.yaml +++ b/out/acme/apps.yaml @@ -212,54 +212,42 @@ - "production-db" - type: "io.trygvis.rules.terraform.ScalewayMachine" data: + &acme-1 key: "acme-1" machine: *acme-1 - key: "acme-1" -- type: "io.trygvis.rules.terraform.ScalewayMachine" - data: - machine: *acme-1 - key: "acme-1" -- type: "io.trygvis.rules.terraform.ScalewayMachine" - data: - machine: *acme-2 - key: "acme-2" - type: "io.trygvis.rules.terraform.ScalewayMachine" data: + &acme-2 key: "acme-2" machine: *acme-2 - key: "acme-2" - type: "io.trygvis.rules.terraform.ScalewayMachine" data: + &acme-3 key: "acme-3" machine: *acme-3 - key: "acme-3" -- type: "io.trygvis.rules.terraform.ScalewayMachine" - data: - machine: *acme-3 - key: "acme-3" - type: "io.trygvis.rules.terraform.ScalewayMachine" data: + &ws-1 key: "ws-1" machine: *ws-1 - key: "ws-1" - type: "io.trygvis.rules.terraform.ScalewayMachine" data: + &ws-2 key: "ws-2" machine: *ws-2 - key: "ws-2" - type: "io.trygvis.rules.engine.KeyValue" data: key: "rm-gen" value: null - type: "io.trygvis.rules.terraform.GoogleManagedZoneTerraformExpression" data: - name: "acme_zone" + &acme_zone name: "acme_zone" - type: "io.trygvis.acme.AcmeServer" data: - name: "acme-1" + &acme-1 name: "acme-1" machine: *acme-1 - type: "io.trygvis.acme.AcmeServer" data: - name: "acme-2" + &acme-2 name: "acme-2" machine: *acme-2 - type: "io.trygvis.acme.AcmeServer" data: - name: "acme-3" + &acme-3 name: "acme-3" machine: *acme-3 - type: "io.trygvis.acme.apps.AcmeOps" data: {} diff --git a/out/acme/wireguard.yaml b/out/acme/wireguard.yaml index de882c3..58572d9 100644 --- a/out/acme/wireguard.yaml +++ b/out/acme/wireguard.yaml @@ -1,172 +1,143 @@ --- -type: "io.trygvis.rules.dns.DnsEntry" -data: - fqdn: "acme-1.vpn.acme.com" - type: "A" ---- -type: "io.trygvis.rules.dns.DnsEntry" -data: - fqdn: "acme-2.vpn.acme.com" - type: "A" ---- -type: "io.trygvis.rules.dns.DnsEntry" -data: - fqdn: "acme-3.vpn.acme.com" - type: "A" ---- -type: "io.trygvis.rules.dns.DnsEntry" -data: - fqdn: "ws-1.vpn.acme.com" - type: "A" ---- -type: "io.trygvis.rules.dns.DnsEntry" -data: - fqdn: "ws-2.vpn.acme.com" - type: "A" ---- -type: "io.trygvis.rules.machine.Machine" -data: - name: "acme-1" - fqdn: "acme-1.machine.acme.com" ---- -type: "io.trygvis.rules.machine.Machine" -data: - name: "acme-2" - fqdn: "acme-2.machine.acme.com" ---- -type: "io.trygvis.rules.machine.Machine" -data: - name: "acme-3" - fqdn: "acme-3.machine.acme.com" ---- -type: "io.trygvis.rules.machine.Machine" -data: - name: "ws-1" - fqdn: null ---- -type: "io.trygvis.rules.machine.Machine" -data: - name: "ws-2" - fqdn: null ---- -type: "io.trygvis.rules.wireguard.WgConnection" -data: - host: "acme-1" - to: "acme-2" ---- -type: "io.trygvis.rules.wireguard.WgConnection" -data: - host: "acme-1" - to: "acme-3" ---- -type: "io.trygvis.rules.wireguard.WgConnection" -data: - host: "acme-2" - to: "acme-1" ---- -type: "io.trygvis.rules.wireguard.WgConnection" -data: - host: "acme-2" - to: "acme-3" ---- -type: "io.trygvis.rules.wireguard.WgConnection" -data: - host: "acme-3" - to: "acme-1" ---- -type: "io.trygvis.rules.wireguard.WgConnection" -data: - host: "acme-3" - to: "acme-2" ---- -type: "io.trygvis.rules.wireguard.WgConnection" -data: - host: "ws-1" - to: "acme-1" ---- -type: "io.trygvis.rules.wireguard.WgConnection" -data: - host: "ws-1" - to: "acme-2" ---- -type: "io.trygvis.rules.wireguard.WgConnection" -data: - host: "ws-1" - to: "acme-3" ---- -type: "io.trygvis.rules.wireguard.WgConnection" -data: - host: "ws-2" - to: "acme-1" ---- -type: "io.trygvis.rules.wireguard.WgConnection" -data: - host: "ws-2" - to: "acme-2" ---- -type: "io.trygvis.rules.wireguard.WgConnection" -data: - host: "ws-2" - to: "acme-3" ---- -type: "io.trygvis.rules.wireguard.WgHost" -data: - name: "acme-1" - net: "vpn0" - publicName: "acme-1.machine.acme.com" - ip: "192.168.10.3" - networkCidr: "10.55.255.0/24" ---- -type: "io.trygvis.rules.wireguard.WgHost" -data: - name: "acme-2" - net: "vpn0" - publicName: "acme-2.machine.acme.com" - ip: "192.168.10.4" - networkCidr: "10.55.254.0/24" ---- -type: "io.trygvis.rules.wireguard.WgHost" -data: - name: "acme-3" - net: "vpn0" - publicName: "acme-3.machine.acme.com" - ip: "192.168.10.5" - networkCidr: "10.55.253.0/24" ---- -type: "io.trygvis.rules.wireguard.WgHost" -data: - name: "ws-1" - net: "vpn0" - publicName: null - ip: "192.168.10.6" - networkCidr: "10.55.252.0/24" ---- -type: "io.trygvis.rules.wireguard.WgHost" -data: - name: "ws-2" - net: "vpn0" - publicName: null - ip: "192.168.10.7" - networkCidr: "10.55.251.0/24" ---- -type: "io.trygvis.rules.wireguard.WgIpPool" -data: - net: "vpn0" - role: "link" - cidr: - value: "192.168.10.0/29" ---- -type: "io.trygvis.rules.wireguard.WgIpPool" -data: - net: "vpn0" - role: "networks" - cidr: - value: "10.55.0.0/16" ---- -type: "io.trygvis.rules.wireguard.WgNet" -data: - name: "vpn0" - domain: "vpn.acme.com" - linkCidr: "192.168.10.0/29" - networkCidr: "10.55.0.0/16" - networkBits: 24 +- type: "io.trygvis.rules.machine.Machine" + data: + &acme-1 name: "acme-1" + fqdn: "acme-1.machine.acme.com" +- type: "io.trygvis.rules.machine.Machine" + data: + &acme-2 name: "acme-2" + fqdn: "acme-2.machine.acme.com" +- type: "io.trygvis.rules.machine.Machine" + data: + &acme-3 name: "acme-3" + fqdn: "acme-3.machine.acme.com" +- type: "io.trygvis.rules.machine.Machine" + data: + &ws-1 name: "ws-1" + fqdn: null +- type: "io.trygvis.rules.machine.Machine" + data: + &ws-2 name: "ws-2" + fqdn: null +- type: "io.trygvis.rules.dns.DnsEntry" + data: + fqdn: "acme-1.vpn.acme.com" + type: "A" +- type: "io.trygvis.rules.dns.DnsEntry" + data: + fqdn: "acme-2.vpn.acme.com" + type: "A" +- type: "io.trygvis.rules.dns.DnsEntry" + data: + fqdn: "acme-3.vpn.acme.com" + type: "A" +- type: "io.trygvis.rules.dns.DnsEntry" + data: + fqdn: "ws-1.vpn.acme.com" + type: "A" +- type: "io.trygvis.rules.dns.DnsEntry" + data: + fqdn: "ws-2.vpn.acme.com" + type: "A" +- type: "io.trygvis.rules.wireguard.WgNet" + data: + &vpn0 name: "vpn0" + domain: "vpn.acme.com" + linkCidr: "192.168.10.0/29" + networkCidr: "10.55.0.0/16" + networkBits: 24 +- type: "io.trygvis.rules.wireguard.WgIpPool" + data: + &1 net: *vpn0 + role: "link" + cidr: + value: "192.168.10.0/29" +- type: "io.trygvis.rules.wireguard.WgIpPool" + data: + &2 net: *vpn0 + role: "networks" + cidr: + value: "10.55.0.0/16" +- type: "io.trygvis.rules.wireguard.WgHost" + data: + &3 machine: *ws-1 + net: *vpn0 + publicName: null + ip: "192.168.10.6" + networkCidr: "10.55.252.0/24" +- type: "io.trygvis.rules.wireguard.WgHost" + data: + &4 machine: *ws-2 + net: *vpn0 + publicName: null + ip: "192.168.10.7" + networkCidr: "10.55.251.0/24" +- type: "io.trygvis.rules.wireguard.WgHost" + data: + &5 machine: *acme-1 + net: *vpn0 + publicName: "acme-1.machine.acme.com" + ip: "192.168.10.3" + networkCidr: "10.55.255.0/24" +- type: "io.trygvis.rules.wireguard.WgHost" + data: + &6 machine: *acme-2 + net: *vpn0 + publicName: "acme-2.machine.acme.com" + ip: "192.168.10.4" + networkCidr: "10.55.254.0/24" +- type: "io.trygvis.rules.wireguard.WgHost" + data: + &7 machine: *acme-3 + net: *vpn0 + publicName: "acme-3.machine.acme.com" + ip: "192.168.10.5" + networkCidr: "10.55.253.0/24" +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &8 host: *3 + to: *7 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &9 host: *3 + to: *5 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &10 host: *3 + to: *6 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &11 host: *4 + to: *7 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &12 host: *4 + to: *5 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &13 host: *4 + to: *6 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &14 host: *7 + to: *5 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &15 host: *7 + to: *6 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &16 host: *5 + to: *7 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &17 host: *5 + to: *6 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &18 host: *6 + to: *7 +- type: "io.trygvis.rules.wireguard.WgConnection" + data: + &19 host: *6 + to: *5 -- cgit v1.2.3