diff --git a/config.yaml b/config.yaml index 6b6309e..c3c705a 100644 --- a/config.yaml +++ b/config.yaml @@ -1,3 +1,6 @@ server: tftpIp: 192.168.1.1 httpUrl: http://192.168.1.1:8000 + +tailscale: + loginServer: https://headscale.huizinga.dev diff --git a/nodes/_defaults.yaml b/nodes/_defaults.yaml index 29031e8..d8e62db 100644 --- a/nodes/_defaults.yaml +++ b/nodes/_defaults.yaml @@ -26,5 +26,6 @@ patches: - !patch install-disk - !patch network - !patch vip + - !patch tailscale patchesControlPlane: - !patch allow-control-plane-workloads diff --git a/patches/tailscale.yaml b/patches/tailscale.yaml new file mode 100644 index 0000000..0161b7e --- /dev/null +++ b/patches/tailscale.yaml @@ -0,0 +1,7 @@ +apiVersion: v1alpha1 +kind: ExtensionServiceConfig +name: tailscale +environment: + - TS_AUTHKEY={{ config.tailscale.authKey }} + - TS_EXTRA_ARGS=--login-server {{ config.tailscale.loginServer }} + - TS_ROUTES={{ helper.tailscale_subnet(node.gateway, node.netmask) }} diff --git a/requirements.txt b/requirements.txt index 5594b17..db84d6c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ requests==2.32.5 Jinja2==3.1.6 GitPython==3.1.45 mergedeep==1.3.4 +netaddr==1.3.0 diff --git a/schematics/default.yaml b/schematics/default.yaml index a90b6f0..c12043f 100644 --- a/schematics/default.yaml +++ b/schematics/default.yaml @@ -5,3 +5,4 @@ customization: - siderolabs/util-linux-tools - siderolabs/intel-ucode - siderolabs/i915 + - siderolabs/tailscale diff --git a/secrets.yaml b/secrets.yaml new file mode 100644 index 0000000..b187c77 Binary files /dev/null and b/secrets.yaml differ diff --git a/tools/render b/tools/render index 3c5706f..b06232f 100755 --- a/tools/render +++ b/tools/render @@ -12,6 +12,7 @@ import requests import yaml from jinja2 import Environment, FileSystemLoader, StrictUndefined, Template from mergedeep import merge +from netaddr import IPAddress REPO = git.Repo(sys.path[0], search_parent_directories=True) assert REPO.working_dir is not None @@ -53,6 +54,11 @@ def render_templates(node: dict, args: dict): return Inner +def tailscale_subnet(gateway: str, netmask: str): + netmask_bits = IPAddress(netmask).netmask_bits() + return f"{IPAddress(gateway) & IPAddress(netmask)}/{netmask_bits}" + + @functools.cache def get_schematic_id(schematic: str): """Lookup the schematic id associated with a given schematic""" @@ -138,7 +144,11 @@ def main(): with open(ROOT.joinpath("secrets.yaml")) as fyaml: merge(config, yaml.safe_load(fyaml)) - template_args = {"config": config, "root": ROOT} + template_args = { + "config": config, + "root": ROOT, + "helper": {"tailscale_subnet": tailscale_subnet}, + } nodes = [] for fullname in walk_files(NODES):