Turn talos patches into templates and resolve them
This commit is contained in:
3
.prettierrc
Normal file
3
.prettierrc
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"bracketSpacing": false
|
||||||
|
}
|
||||||
@@ -18,6 +18,12 @@ dns:
|
|||||||
- 1.1.1.1
|
- 1.1.1.1
|
||||||
- 8.8.8.8
|
- 8.8.8.8
|
||||||
ntp: nl.pool.ntp.org
|
ntp: nl.pool.ntp.org
|
||||||
|
installDisk: /dev/sda
|
||||||
install: false
|
install: false
|
||||||
patch: !patch
|
patches:
|
||||||
- hostname
|
- !patch hostname
|
||||||
|
- !patch install-disk
|
||||||
|
- !patch network
|
||||||
|
- !patch vip
|
||||||
|
patchesControlplane:
|
||||||
|
- !patch allow-controlplane-workloads
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
netmask: 255.255.252.0
|
netmask: 255.255.252.0
|
||||||
gateway: 10.0.0.1
|
gateway: 10.0.0.1
|
||||||
install: true
|
install: true
|
||||||
|
controlplaneIp: 10.0.2.1
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
netmask: 255.255.255.0
|
netmask: 255.255.255.0
|
||||||
gateway: 192.168.1.1
|
gateway: 192.168.1.1
|
||||||
|
clusterName: testing
|
||||||
|
controlplaneIp: 192.168.1.100
|
||||||
|
instalDisk: /dev/vda
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
serial: talos-vm
|
serial: talos-vm
|
||||||
interface: enp1s0
|
interface: eth0
|
||||||
ip: 192.168.1.2
|
ip: 192.168.1.2
|
||||||
install: true
|
install: true
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
machine:
|
machine:
|
||||||
network:
|
network:
|
||||||
hostname: talos-vm
|
hostname: {{hostname}}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
machine:
|
machine:
|
||||||
install:
|
install:
|
||||||
disk: /dev/vda
|
disk: {{installDisk}}
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
machine:
|
machine:
|
||||||
network:
|
network:
|
||||||
interfaces:
|
interfaces:
|
||||||
- interface: eth0
|
- interface: {{interface}}
|
||||||
dhcp: false
|
dhcp: false
|
||||||
addresses:
|
addresses:
|
||||||
- 192.168.1.2
|
- {{ip}}
|
||||||
routes:
|
routes:
|
||||||
- network: 0.0.0.0/0
|
- network: 0.0.0.0/0
|
||||||
gateway: 192.168.1.1
|
gateway: {{gateway}}
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
machine:
|
machine:
|
||||||
network:
|
network:
|
||||||
interfaces:
|
interfaces:
|
||||||
- interface: eth0
|
- interface: {{interface}}
|
||||||
vip:
|
vip:
|
||||||
ip: 192.168.1.100
|
ip: {{controlplaneIp}}
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
PyYAML==6.0.3
|
PyYAML==6.0.3
|
||||||
requests==2.32.5
|
requests==2.32.5
|
||||||
|
Jinja2==3.1.6
|
||||||
|
|||||||
45
tools/merge
45
tools/merge
@@ -8,9 +8,29 @@ import pathlib
|
|||||||
|
|
||||||
import requests
|
import requests
|
||||||
import yaml
|
import yaml
|
||||||
|
from jinja2 import Environment, FileSystemLoader, StrictUndefined, Template
|
||||||
|
|
||||||
NODES = pathlib.Path("nodes")
|
NODES = pathlib.Path("nodes")
|
||||||
SCHEMATICS = pathlib.Path("schematics")
|
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
|
@functools.cache
|
||||||
@@ -24,18 +44,28 @@ def get_schematic_id(schematic: str):
|
|||||||
|
|
||||||
def schematic_constructor(loader: yaml.SafeLoader, node: yaml.nodes.ScalarNode):
|
def schematic_constructor(loader: yaml.SafeLoader, node: yaml.nodes.ScalarNode):
|
||||||
"""Load specified schematic file and get the assocatied schematic id"""
|
"""Load specified schematic file and get the assocatied schematic id"""
|
||||||
filename = loader.construct_scalar(node)
|
schematic_name = loader.construct_yaml_str(node)
|
||||||
try:
|
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)
|
return get_schematic_id(schematic)
|
||||||
except Exception:
|
except Exception:
|
||||||
raise yaml.MarkedYAMLError("Failed to load schematic", node.start_mark)
|
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():
|
def get_loader():
|
||||||
"""Add special constructors to yaml loader"""
|
"""Add special constructors to yaml loader"""
|
||||||
loader = yaml.SafeLoader
|
loader = yaml.SafeLoader
|
||||||
loader.add_constructor("!schematic", schematic_constructor)
|
loader.add_constructor("!schematic", schematic_constructor)
|
||||||
|
loader.add_constructor("!patch", patch_constructor)
|
||||||
|
|
||||||
return loader
|
return loader
|
||||||
|
|
||||||
@@ -65,7 +95,7 @@ def walk_files(root: pathlib.Path):
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
data = []
|
nodes = []
|
||||||
for fullname in walk_files(NODES):
|
for fullname in walk_files(NODES):
|
||||||
filename = str(fullname.relative_to(NODES).parent) + "/" + fullname.stem
|
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 = get_defaults(fullname.parent, NODES) | yml_data
|
||||||
yml_data["hostname"] = fullname.stem
|
yml_data["hostname"] = fullname.stem
|
||||||
yml_data["filename"] = filename
|
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
|
# Dump everything to json
|
||||||
print(json.dumps(data, indent=4))
|
print(json.dumps(final_nodes, indent=4))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in New Issue
Block a user