From 3290a76193dfa1ed4408a135f4cf809b5256189e Mon Sep 17 00:00:00 2001 From: Dreaded_X Date: Sat, 8 Nov 2025 05:47:24 +0100 Subject: [PATCH] Turn talos patches into templates and resolve them --- .prettierrc | 3 +++ nodes/_defaults.yaml | 10 ++++++-- nodes/hellas/_defaults.yaml | 1 + nodes/testing/_defaults.yaml | 3 +++ nodes/testing/talos-vm.yaml | 2 +- patches/hostname.yaml | 2 +- patches/install-disk.yaml | 2 +- patches/network.yaml | 6 ++--- patches/vip.yaml | 4 ++-- requirements.txt | 1 + tools/merge | 45 ++++++++++++++++++++++++++++++++---- 11 files changed, 64 insertions(+), 15 deletions(-) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..bdb2b5f --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "bracketSpacing": false +} diff --git a/nodes/_defaults.yaml b/nodes/_defaults.yaml index 401642c..9e02cf3 100644 --- a/nodes/_defaults.yaml +++ b/nodes/_defaults.yaml @@ -18,6 +18,12 @@ dns: - 1.1.1.1 - 8.8.8.8 ntp: nl.pool.ntp.org +installDisk: /dev/sda install: false -patch: !patch - - hostname +patches: + - !patch hostname + - !patch install-disk + - !patch network + - !patch vip +patchesControlplane: + - !patch allow-controlplane-workloads diff --git a/nodes/hellas/_defaults.yaml b/nodes/hellas/_defaults.yaml index 6dc5f34..c5a369f 100644 --- a/nodes/hellas/_defaults.yaml +++ b/nodes/hellas/_defaults.yaml @@ -1,3 +1,4 @@ netmask: 255.255.252.0 gateway: 10.0.0.1 install: true +controlplaneIp: 10.0.2.1 diff --git a/nodes/testing/_defaults.yaml b/nodes/testing/_defaults.yaml index 70bb7a5..c3171a9 100644 --- a/nodes/testing/_defaults.yaml +++ b/nodes/testing/_defaults.yaml @@ -1,2 +1,5 @@ netmask: 255.255.255.0 gateway: 192.168.1.1 +clusterName: testing +controlplaneIp: 192.168.1.100 +instalDisk: /dev/vda diff --git a/nodes/testing/talos-vm.yaml b/nodes/testing/talos-vm.yaml index f360796..f645fa8 100644 --- a/nodes/testing/talos-vm.yaml +++ b/nodes/testing/talos-vm.yaml @@ -1,4 +1,4 @@ serial: talos-vm -interface: enp1s0 +interface: eth0 ip: 192.168.1.2 install: true diff --git a/patches/hostname.yaml b/patches/hostname.yaml index cb29c62..505d013 100644 --- a/patches/hostname.yaml +++ b/patches/hostname.yaml @@ -1,4 +1,4 @@ --- machine: network: - hostname: talos-vm + hostname: {{hostname}} diff --git a/patches/install-disk.yaml b/patches/install-disk.yaml index 111caa0..07f99fc 100644 --- a/patches/install-disk.yaml +++ b/patches/install-disk.yaml @@ -1,4 +1,4 @@ --- machine: install: - disk: /dev/vda + disk: {{installDisk}} diff --git a/patches/network.yaml b/patches/network.yaml index f5b4e8e..a86fac1 100644 --- a/patches/network.yaml +++ b/patches/network.yaml @@ -2,10 +2,10 @@ machine: network: interfaces: - - interface: eth0 + - interface: {{interface}} dhcp: false addresses: - - 192.168.1.2 + - {{ip}} routes: - network: 0.0.0.0/0 - gateway: 192.168.1.1 + gateway: {{gateway}} diff --git a/patches/vip.yaml b/patches/vip.yaml index 9dd01e5..feac90e 100644 --- a/patches/vip.yaml +++ b/patches/vip.yaml @@ -2,6 +2,6 @@ machine: network: interfaces: - - interface: eth0 + - interface: {{interface}} vip: - ip: 192.168.1.100 + ip: {{controlplaneIp}} diff --git a/requirements.txt b/requirements.txt index 769d3cf..13d6749 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ PyYAML==6.0.3 requests==2.32.5 +Jinja2==3.1.6 diff --git a/tools/merge b/tools/merge index 0ddc118..a278e87 100755 --- a/tools/merge +++ b/tools/merge @@ -8,9 +8,29 @@ import pathlib import requests import yaml +from jinja2 import Environment, FileSystemLoader, StrictUndefined, Template NODES = pathlib.Path("nodes") SCHEMATICS = pathlib.Path("schematics") +PATCHES = Environment(loader=FileSystemLoader("patches"), undefined=StrictUndefined) +TEMPLATES = Environment(loader=FileSystemLoader("templates"), undefined=StrictUndefined) + + +def node_encoder(node: dict): + class Inner(json.JSONEncoder): + def default(self, o): + if isinstance(o, Template): + try: + rendered = o.render(node) + except Exception as e: + e.add_note(f"While rendering for: {node['hostname']}") + raise e + # Parse the rendered yaml and convert it to a json patch + return json.dumps(yaml.safe_load(rendered)) + + return super().default(o) + + return Inner @functools.cache @@ -24,18 +44,28 @@ def get_schematic_id(schematic: str): def schematic_constructor(loader: yaml.SafeLoader, node: yaml.nodes.ScalarNode): """Load specified schematic file and get the assocatied schematic id""" - filename = loader.construct_scalar(node) + schematic_name = loader.construct_yaml_str(node) try: - schematic = SCHEMATICS.joinpath(filename).with_suffix(".yaml").read_text() + schematic = SCHEMATICS.joinpath(schematic_name).with_suffix(".yaml").read_text() return get_schematic_id(schematic) except Exception: raise yaml.MarkedYAMLError("Failed to load schematic", node.start_mark) +def patch_constructor(loader: yaml.SafeLoader, node: yaml.nodes.ScalarNode): + patch_name = loader.construct_scalar(node) + try: + template = PATCHES.get_template(f"{patch_name}.yaml") + return template + except Exception: + raise yaml.MarkedYAMLError("Failed to load patch", node.start_mark) + + def get_loader(): """Add special constructors to yaml loader""" loader = yaml.SafeLoader loader.add_constructor("!schematic", schematic_constructor) + loader.add_constructor("!patch", patch_constructor) return loader @@ -65,7 +95,7 @@ def walk_files(root: pathlib.Path): def main(): - data = [] + nodes = [] for fullname in walk_files(NODES): filename = str(fullname.relative_to(NODES).parent) + "/" + fullname.stem @@ -74,10 +104,15 @@ def main(): yml_data = get_defaults(fullname.parent, NODES) | yml_data yml_data["hostname"] = fullname.stem yml_data["filename"] = filename - data.append(yml_data) + nodes.append(yml_data) + + final_nodes = [] + for node in nodes: + # Quick and dirty way to resolve all the templates using a custom encoder + final_nodes.append(json.loads(json.dumps(node, cls=node_encoder(node)))) # Dump everything to json - print(json.dumps(data, indent=4)) + print(json.dumps(final_nodes, indent=4)) if __name__ == "__main__":