Compare commits
3 Commits
1b4eb34ec4
...
3290a76193
| Author | SHA1 | Date | |
|---|---|---|---|
|
3290a76193
|
|||
|
0642fde397
|
|||
|
d163e0b9bc
|
3
.prettierrc
Normal file
3
.prettierrc
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"bracketSpacing": false
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
schematicID: !schematic "_schematic.yaml"
|
||||
schematicID: !schematic default
|
||||
arch: amd64
|
||||
talosVersion: v1.11.3
|
||||
kernelArgs:
|
||||
@@ -18,4 +18,12 @@ dns:
|
||||
- 1.1.1.1
|
||||
- 8.8.8.8
|
||||
ntp: nl.pool.ntp.org
|
||||
installDisk: /dev/sda
|
||||
install: false
|
||||
patches:
|
||||
- !patch hostname
|
||||
- !patch install-disk
|
||||
- !patch network
|
||||
- !patch vip
|
||||
patchesControlplane:
|
||||
- !patch allow-controlplane-workloads
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
netmask: 255.255.252.0
|
||||
gateway: 10.0.0.1
|
||||
install: true
|
||||
controlplaneIp: 10.0.2.1
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
netmask: 255.255.255.0
|
||||
gateway: 192.168.1.1
|
||||
clusterName: testing
|
||||
controlplaneIp: 192.168.1.100
|
||||
instalDisk: /dev/vda
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
serial: talos-vm
|
||||
interface: enp1s0
|
||||
interface: eth0
|
||||
ip: 192.168.1.2
|
||||
install: true
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
---
|
||||
machine:
|
||||
network:
|
||||
hostname: talos-vm
|
||||
hostname: {{hostname}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
---
|
||||
machine:
|
||||
install:
|
||||
disk: /dev/vda
|
||||
disk: {{installDisk}}
|
||||
|
||||
@@ -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}}
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
machine:
|
||||
network:
|
||||
interfaces:
|
||||
- interface: eth0
|
||||
- interface: {{interface}}
|
||||
vip:
|
||||
ip: 192.168.1.100
|
||||
ip: {{controlplaneIp}}
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
PyYAML==6.0.3
|
||||
requests==2.32.5
|
||||
Jinja2==3.1.6
|
||||
|
||||
77
tools/merge
77
tools/merge
@@ -2,13 +2,35 @@
|
||||
|
||||
# Adapted from: https://enix.io/en/blog/pxe-talos/
|
||||
|
||||
import argparse
|
||||
import functools
|
||||
import json
|
||||
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
|
||||
@@ -20,24 +42,30 @@ def get_schematic_id(schematic: str):
|
||||
return data["id"]
|
||||
|
||||
|
||||
def schematic_constructor(directory: pathlib.Path):
|
||||
def schematic_constructor(loader: yaml.SafeLoader, node: yaml.nodes.ScalarNode):
|
||||
"""Load specified schematic file and get the assocatied schematic id"""
|
||||
|
||||
def constructor(loader: yaml.SafeLoader, node: yaml.nodes.ScalarNode):
|
||||
filename = str(loader.construct_scalar(node))
|
||||
schematic_name = loader.construct_yaml_str(node)
|
||||
try:
|
||||
schematic = directory.joinpath(filename).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)
|
||||
|
||||
return constructor
|
||||
|
||||
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(directory: pathlib.Path):
|
||||
def get_loader():
|
||||
"""Add special constructors to yaml loader"""
|
||||
loader = yaml.SafeLoader
|
||||
loader.add_constructor("!schematic", schematic_constructor(directory))
|
||||
loader.add_constructor("!schematic", schematic_constructor)
|
||||
loader.add_constructor("!patch", patch_constructor)
|
||||
|
||||
return loader
|
||||
|
||||
@@ -47,7 +75,7 @@ def get_defaults(directory: pathlib.Path, root: pathlib.Path):
|
||||
"""Compute the defaults from the provided directory and parents."""
|
||||
try:
|
||||
with open(directory.joinpath("_defaults.yaml")) as fyaml:
|
||||
yml_data = yaml.load(fyaml, Loader=get_loader(directory))
|
||||
yml_data = yaml.load(fyaml, Loader=get_loader())
|
||||
except OSError:
|
||||
yml_data = {}
|
||||
|
||||
@@ -67,29 +95,24 @@ def walk_files(root: pathlib.Path):
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("directory", type=pathlib.Path)
|
||||
parser.add_argument("-f", "--filter")
|
||||
args = parser.parse_args()
|
||||
|
||||
data = []
|
||||
for fullname in walk_files(args.directory):
|
||||
filename = (
|
||||
str(fullname.relative_to(args.directory).parent) + "/" + fullname.stem
|
||||
)
|
||||
|
||||
if args.filter is not None and not filename.startswith(args.filter):
|
||||
continue
|
||||
nodes = []
|
||||
for fullname in walk_files(NODES):
|
||||
filename = str(fullname.relative_to(NODES).parent) + "/" + fullname.stem
|
||||
|
||||
with open(fullname) as fyaml:
|
||||
yml_data = yaml.load(fyaml, Loader=get_loader(fullname.parent))
|
||||
yml_data = get_defaults(fullname.parent, args.directory) | yml_data
|
||||
yml_data = yaml.load(fyaml, Loader=get_loader())
|
||||
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))
|
||||
print(json.dumps(final_nodes, indent=4))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user