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/ --- .../main/java/io/trygvis/rules/core/Problem.java | 11 ++ .../main/java/io/trygvis/rules/dba/Cluster.java | 15 ++ .../main/java/io/trygvis/rules/dba/Container.java | 59 ++++++ .../main/java/io/trygvis/rules/dns/DnsEntry.java | 27 +++ .../rules/dns/DnsEntryTerraformExpression.java | 21 ++ .../main/java/io/trygvis/rules/dns/DnsZone.java | 9 + .../java/io/trygvis/rules/engine/KeyValue.java | 14 ++ .../java/io/trygvis/rules/machine/Machine.java | 29 +++ .../rules/machine/MachineSpecification.java | 21 ++ .../main/java/io/trygvis/rules/network/IpCalc.java | 6 + .../java/io/trygvis/rules/network/Ipv4Address.java | 58 ++++++ .../java/io/trygvis/rules/network/Ipv4Cidr.java | 150 +++++++++++++++ .../rules/terraform/TerraformInputVariable.java | 41 ++++ .../io/trygvis/rules/terraform/TerraformMain.java | 21 ++ .../trygvis/rules/terraform/TerraformProvider.java | 22 +++ .../trygvis/rules/terraform/TerraformResource.java | 213 +++++++++++++++++++++ 16 files changed, 717 insertions(+) create mode 100644 modules/ri-base/src/main/java/io/trygvis/rules/core/Problem.java create mode 100644 modules/ri-base/src/main/java/io/trygvis/rules/dba/Cluster.java create mode 100644 modules/ri-base/src/main/java/io/trygvis/rules/dba/Container.java create mode 100644 modules/ri-base/src/main/java/io/trygvis/rules/dns/DnsEntry.java create mode 100644 modules/ri-base/src/main/java/io/trygvis/rules/dns/DnsEntryTerraformExpression.java create mode 100644 modules/ri-base/src/main/java/io/trygvis/rules/dns/DnsZone.java create mode 100644 modules/ri-base/src/main/java/io/trygvis/rules/engine/KeyValue.java create mode 100644 modules/ri-base/src/main/java/io/trygvis/rules/machine/Machine.java create mode 100644 modules/ri-base/src/main/java/io/trygvis/rules/machine/MachineSpecification.java create mode 100644 modules/ri-base/src/main/java/io/trygvis/rules/network/IpCalc.java create mode 100644 modules/ri-base/src/main/java/io/trygvis/rules/network/Ipv4Address.java create mode 100644 modules/ri-base/src/main/java/io/trygvis/rules/network/Ipv4Cidr.java create mode 100644 modules/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformInputVariable.java create mode 100644 modules/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformMain.java create mode 100644 modules/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformProvider.java create mode 100644 modules/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformResource.java (limited to 'modules/ri-base/src/main/java/io') diff --git a/modules/ri-base/src/main/java/io/trygvis/rules/core/Problem.java b/modules/ri-base/src/main/java/io/trygvis/rules/core/Problem.java new file mode 100644 index 0000000..04d1af3 --- /dev/null +++ b/modules/ri-base/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/modules/ri-base/src/main/java/io/trygvis/rules/dba/Cluster.java b/modules/ri-base/src/main/java/io/trygvis/rules/dba/Cluster.java new file mode 100644 index 0000000..6b23cdd --- /dev/null +++ b/modules/ri-base/src/main/java/io/trygvis/rules/dba/Cluster.java @@ -0,0 +1,15 @@ +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; + + public Cluster(String name) { + this.name = name; + } + + protected Cluster() {} +} diff --git a/modules/ri-base/src/main/java/io/trygvis/rules/dba/Container.java b/modules/ri-base/src/main/java/io/trygvis/rules/dba/Container.java new file mode 100644 index 0000000..a420671 --- /dev/null +++ b/modules/ri-base/src/main/java/io/trygvis/rules/dba/Container.java @@ -0,0 +1,59 @@ +package io.trygvis.rules.dba; + +import io.trygvis.rules.machine.Machine; +import io.trygvis.rules.machine.MachineSpecification; + +//@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") +public class Container { + public String id; + public Cluster cluster; + public String name; + public String machineRole; + public String image; + public String tag; + + private Machine machine; + public MachineSpecification machineSpecification; + + public Container(Cluster cluster, String name, String machineRole, String image, String tag, + MachineSpecification machineSpecification) { + this.id = cluster.name + "-" + name; + this.cluster = cluster; + this.name = name; + this.machineRole = machineRole; + this.image = image; + this.tag = tag; + this.machineSpecification = machineSpecification; + } + + protected Container() { + } + + 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/modules/ri-base/src/main/java/io/trygvis/rules/dns/DnsEntry.java b/modules/ri-base/src/main/java/io/trygvis/rules/dns/DnsEntry.java new file mode 100644 index 0000000..105ef79 --- /dev/null +++ b/modules/ri-base/src/main/java/io/trygvis/rules/dns/DnsEntry.java @@ -0,0 +1,27 @@ +package io.trygvis.rules.dns; + +public class DnsEntry { + public String fqdn; + public String type; + + public DnsEntry(String fqdn, String type) { + this.fqdn = fqdn; + this.type = type; + } + + public static DnsEntry a(String fqdn) { + return new DnsEntry(fqdn, "A"); + } + + public static DnsEntry aaaa(String fqdn) { + return new DnsEntry(fqdn, "AAAA"); + } + + public String getFqdn() { + return fqdn; + } + + public String getType() { + return type; + } +} diff --git a/modules/ri-base/src/main/java/io/trygvis/rules/dns/DnsEntryTerraformExpression.java b/modules/ri-base/src/main/java/io/trygvis/rules/dns/DnsEntryTerraformExpression.java new file mode 100644 index 0000000..79bf934 --- /dev/null +++ b/modules/ri-base/src/main/java/io/trygvis/rules/dns/DnsEntryTerraformExpression.java @@ -0,0 +1,21 @@ +package io.trygvis.rules.dns; + +public class DnsEntryTerraformExpression { + public DnsEntry entry; + public String key; + public String expression; + + public DnsEntryTerraformExpression(DnsEntry entry, String key, String expression) { + this.entry = entry; + this.key = key; + this.expression = expression; + } + + public String getKey() { + return key; + } + + public String getExpression() { + return expression; + } +} diff --git a/modules/ri-base/src/main/java/io/trygvis/rules/dns/DnsZone.java b/modules/ri-base/src/main/java/io/trygvis/rules/dns/DnsZone.java new file mode 100644 index 0000000..1af5c8f --- /dev/null +++ b/modules/ri-base/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/modules/ri-base/src/main/java/io/trygvis/rules/engine/KeyValue.java b/modules/ri-base/src/main/java/io/trygvis/rules/engine/KeyValue.java new file mode 100644 index 0000000..5046169 --- /dev/null +++ b/modules/ri-base/src/main/java/io/trygvis/rules/engine/KeyValue.java @@ -0,0 +1,14 @@ +package io.trygvis.rules.engine; + +public class KeyValue { + public String key; + public String value; + + public KeyValue() { + } + + public KeyValue(String key, String value) { + this.key = key; + this.value = value; + } +} diff --git a/modules/ri-base/src/main/java/io/trygvis/rules/machine/Machine.java b/modules/ri-base/src/main/java/io/trygvis/rules/machine/Machine.java new file mode 100644 index 0000000..8f162c6 --- /dev/null +++ b/modules/ri-base/src/main/java/io/trygvis/rules/machine/Machine.java @@ -0,0 +1,29 @@ +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; + private String fqdn; + + public Machine() { + } + + public Machine(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public String getFqdn() { + return fqdn; + } + + public void setFqdn(String fqdn) { + this.fqdn = fqdn; + } +} diff --git a/modules/ri-base/src/main/java/io/trygvis/rules/machine/MachineSpecification.java b/modules/ri-base/src/main/java/io/trygvis/rules/machine/MachineSpecification.java new file mode 100644 index 0000000..9d38b2d --- /dev/null +++ b/modules/ri-base/src/main/java/io/trygvis/rules/machine/MachineSpecification.java @@ -0,0 +1,21 @@ +package io.trygvis.rules.machine; + +public class MachineSpecification { + public int cpu; + public int memory; + + protected MachineSpecification() {} + + public MachineSpecification(int cpu, int memory) { + this.cpu = cpu; + this.memory = memory; + } + + public int getCpu() { + return cpu; + } + + public int getMemory() { + return memory; + } +} diff --git a/modules/ri-base/src/main/java/io/trygvis/rules/network/IpCalc.java b/modules/ri-base/src/main/java/io/trygvis/rules/network/IpCalc.java new file mode 100644 index 0000000..7ec344c --- /dev/null +++ b/modules/ri-base/src/main/java/io/trygvis/rules/network/IpCalc.java @@ -0,0 +1,6 @@ +package io.trygvis.rules.network; + +import java.util.regex.Pattern; + +public class IpCalc { +} diff --git a/modules/ri-base/src/main/java/io/trygvis/rules/network/Ipv4Address.java b/modules/ri-base/src/main/java/io/trygvis/rules/network/Ipv4Address.java new file mode 100644 index 0000000..9021198 --- /dev/null +++ b/modules/ri-base/src/main/java/io/trygvis/rules/network/Ipv4Address.java @@ -0,0 +1,58 @@ +package io.trygvis.rules.network; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import java.io.IOException; +import java.util.Objects; + +@JsonSerialize(using = Ipv4Address.Serializer.class) +public class Ipv4Address implements Comparable { + public final int address; + + public Ipv4Address(int address) { + this.address = address; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o instanceof Ipv4Address) { + Ipv4Address other = (Ipv4Address) o; + return address == other.address; + } + + return false; + } + + @Override + public int hashCode() { + return Objects.hash(address); + } + + @Override + public int compareTo(Ipv4Address o) { + return address - o.address; + } + + @Override + public String toString() { + return "%d.%d.%d.%d".formatted( + address >> 24 & 0xff, + address >> 16 & 0xff, + address >> 8 & 0xff, + address & 0xff); + } + + public static class Serializer extends JsonSerializer { + @Override + public void serialize(Ipv4Address value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeObjectField("value", value.toString()); + gen.writeEndObject(); + } + } +} diff --git a/modules/ri-base/src/main/java/io/trygvis/rules/network/Ipv4Cidr.java b/modules/ri-base/src/main/java/io/trygvis/rules/network/Ipv4Cidr.java new file mode 100644 index 0000000..851af95 --- /dev/null +++ b/modules/ri-base/src/main/java/io/trygvis/rules/network/Ipv4Cidr.java @@ -0,0 +1,150 @@ +package io.trygvis.rules.network; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.regex.Pattern; + +@JsonSerialize(using = Ipv4Cidr.Serializer.class) +public class Ipv4Cidr implements Comparable { + public final int network; + public final int bits; + + public Ipv4Cidr(int network, int bits) { + if (bits < 0 || bits > 32) { + throw new IllegalArgumentException("bits must be [0, 32]"); + } + + int hostBits = 32 - bits; + int netmask = (-1 >> hostBits) << hostBits; + + int x = network & ~netmask; + + if (x != 0) { + throw new IllegalArgumentException("The host part of the address must be 0."); + } + + this.network = network; + this.bits = bits; + } + + @Override + public String toString() { + return "%d.%d.%d.%d/%d".formatted( + network >> 24 & 0xff, + network >> 16 & 0xff, + network >> 8 & 0xff, + network & 0xff, + bits); + } + + private String formatIpv4(int address) { + return "%d.%d.%d.%d".formatted(address >> 24 & 0xff, address >> 16 & 0xff, address >> 8 & 0xff, address & 0xff); + } + + public List partition(int bits) { + if (bits <= 0 || bits <= this.bits || bits > 32) { + throw new IllegalArgumentException("Invalid new network size"); + } + + var list = new ArrayList(); + + int count = 1 << (bits - this.bits); + for (int i = 0; i < count; i++) { + var network = this.network | (i << (32 - bits)); + + list.add(new Ipv4Cidr(network, bits)); + } + + return list; + } + + public List addresses() { + int size = 1 << 32 - bits; + var end = network + size; + var addresses = new ArrayList(size); + for (int address = network; address < end; address++) { + addresses.add(new Ipv4Address(address)); + } + + return addresses; + } + + @Override + public int compareTo(Ipv4Cidr o) { + if (this == o) { + return 0; + } + + var ret = network - o.network; + if (ret != 0) { + return ret; + } + + return bits - o.bits; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Ipv4Cidr ipv4Cidr = (Ipv4Cidr) o; + return network == ipv4Cidr.network && bits == ipv4Cidr.bits; + } + + @Override + public int hashCode() { + return Objects.hash(network, bits); + } + + private static final Pattern pattern = Pattern.compile("([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})/([0-9]{1,3})"); + + public static Ipv4Cidr parseCidr(String cidr) { + var matcher = pattern.matcher(cidr); + if (!matcher.matches()) { + throw new IllegalArgumentException("Not a CIDR: " + cidr); + } + + var b1 = matcher.group(1); + var b2 = matcher.group(2); + var b3 = matcher.group(3); + var b4 = matcher.group(4); + + int network = parse(b1) << 24 | + parse(b2) << 16 | + parse(b3) << 8 | + parse(b4); + +// System.out.printf("network = %x%n", network); + + var l = matcher.group(5); + var bits = Integer.parseInt(l); +// System.out.printf("netmask = %08x%n", netmask); + + return new Ipv4Cidr(network, bits); + } + + private static int parse(String s) { + var i = Integer.parseInt(s); + if (i > 255) { + throw new IllegalArgumentException("Not a CIDR"); + } + + return i; + } + + public static class Serializer extends JsonSerializer { + @Override + public void serialize(Ipv4Cidr value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeObjectField("value", value.toString()); + gen.writeEndObject(); + } + } +} diff --git a/modules/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformInputVariable.java b/modules/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformInputVariable.java new file mode 100644 index 0000000..1415767 --- /dev/null +++ b/modules/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformInputVariable.java @@ -0,0 +1,41 @@ +package io.trygvis.rules.terraform; + +public class TerraformInputVariable { + private String module; + + private String name; + private String type; + private String default_; + + public TerraformInputVariable(String module) { + this.module = module; + } + + public String getModule() { + return module; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getDefault() { + return default_; + } + + public void setDefault(String default_) { + this.default_ = default_; + } +} diff --git a/modules/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformMain.java b/modules/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformMain.java new file mode 100644 index 0000000..82626d2 --- /dev/null +++ b/modules/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformMain.java @@ -0,0 +1,21 @@ +package io.trygvis.rules.terraform; + +import java.util.Map; +import java.util.TreeMap; + +public class TerraformMain { + private String module; + private Map providers = new TreeMap(); + + public TerraformMain(String module) { + this.module = module; + } + + public String getModule() { + return module; + } + + public Map getProviders() { + return providers; + } +} diff --git a/modules/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformProvider.java b/modules/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformProvider.java new file mode 100644 index 0000000..613d953 --- /dev/null +++ b/modules/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformProvider.java @@ -0,0 +1,22 @@ +package io.trygvis.rules.terraform; + +public class TerraformProvider { + private String source; + private String version; + + protected TerraformProvider() { + } + + public TerraformProvider(String source, String version) { + this.source = source; + this.version = version; + } + + public String getSource() { + return source; + } + + public String getVersion() { + return version; + } +} diff --git a/modules/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformResource.java b/modules/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformResource.java new file mode 100644 index 0000000..351a3e1 --- /dev/null +++ b/modules/ri-base/src/main/java/io/trygvis/rules/terraform/TerraformResource.java @@ -0,0 +1,213 @@ +package io.trygvis.rules.terraform; + +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.*; + +@SuppressWarnings("unused") +public class TerraformResource { + private static final String EOL = System.getProperty("line.separator"); + private final String output; + private final String kind; + private final String instance; + private final Map values = new LinkedHashMap<>(); + + public TerraformResource(String output, String kind, String instance) { + this.output = output; + this.kind = kind; + this.instance = instance; + } + + public String getOutput() { + return output; + } + + public String getName() { + return kind + "." + instance; + } + + public String getKind() { + return kind; + } + + public String getInstance() { + return instance; + } + + public Map getValues() { + return values; + } + + public TerraformResource set(String key, String value) { + values.put(key, new StringTerraformValue(value)); + return this; + } + + public TerraformResource set(String key, boolean value) { + values.put(key, new BooleanTerraformValue(value)); + return this; + } + + public TerraformResource set(String key, int value) { + values.put(key, new IntegerTerraformValue(value)); + return this; + } + + public TerraformResource setExpression(String key, String value) { + values.put(key, new ExpressionTerraformValue(value)); + return this; + } + + public ArrayTerraformValue array(String key) { + var array = new ArrayTerraformValue(); + values.put(key, array); + return array; + } + + public String asString() { + var buf = new StringBuilder(); + + buf.append("resource "); + buf.append(quote(kind)); + buf.append(" "); + buf.append(quote(instance)); + buf.append(" {"); + buf.append(EOL); + + for (var entry : values.entrySet()) { + buf.append(" "); + buf.append(entry.getKey()); + buf.append(" = "); + buf.append(entry.getValue().asString()); + buf.append(EOL); + } + + buf.append("}"); + + return buf.toString(); + } + + public interface TerraformValue { + String asString(); + } + + public static class StringTerraformValue implements TerraformValue { + private final String value; + + public StringTerraformValue(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String asString() { + return quote(value); + } + } + + public static class BooleanTerraformValue implements TerraformValue { + private final boolean value; + + public BooleanTerraformValue(boolean value) { + this.value = value; + } + + @JsonValue + public boolean getValue() { + return value; + } + + @Override + public String asString() { + return String.valueOf(value); + } + } + + public static class IntegerTerraformValue implements TerraformValue { + private final int value; + + public IntegerTerraformValue(int value) { + this.value = value; + } + + @JsonValue + public int getValue() { + return value; + } + + @Override + public String asString() { + return String.valueOf(value); + } + } + + public static class ExpressionTerraformValue implements TerraformValue { + private final String value; + + public ExpressionTerraformValue(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String asString() { + return value; + } + } + + public static class ArrayTerraformValue implements TerraformValue { + private final List values = new ArrayList<>(); + + @JsonValue + public List getValues() { + return values; + } + + public ArrayTerraformValue add(String value) { + values.add(new StringTerraformValue(value)); + return this; + } + + public ArrayTerraformValue add(int value) { + values.add(new IntegerTerraformValue(value)); + return this; + } + + public ArrayTerraformValue add(boolean value) { + values.add(new BooleanTerraformValue(value)); + return this; + } + + public ArrayTerraformValue addExpression(String value) { + values.add(new ExpressionTerraformValue(value)); + return this; + } + + @Override + public String asString() { + if (values.isEmpty()) { + return "[]"; + } + + if (values.size() == 1) { + return "[" + values.get(0).asString() + "]"; + } + + var j = new StringJoiner(",\n ", "[\n", "\n ]"); + values.forEach(value -> j.add(value.asString())); + return j.toString(); + } + } + + private static String quote(String value) { + return "\"%s\"".formatted(value); + } +} -- cgit v1.2.3