From b1fddd0ba75bc2cc3bc49be8526156ece37921d5 Mon Sep 17 00:00:00 2001 From: Astro Date: Thu, 25 Feb 2021 01:06:32 +0100 Subject: [PATCH] nix: generate device scripts --- nix/default.nix | 1 + nix/device-templates.nix | 54 ++++++++++++++++++++++++++++ nix/legacy.nix | 41 +++++++++++++++++++++ nix/netmasks.nix | 35 ++++++++++++++++++ nix/options.nix | 28 +++++++++++++-- nix/salt-support/expand-template.nix | 15 ++++++++ nix/salt-support/load-yaml.nix | 2 +- 7 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 nix/device-templates.nix create mode 100644 nix/legacy.nix create mode 100644 nix/netmasks.nix create mode 100644 nix/salt-support/expand-template.nix diff --git a/nix/default.nix b/nix/default.nix index 07f5a27..0ff706a 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -6,6 +6,7 @@ let modules = [ ./options.nix ./legacy.nix + ./device-templates.nix ]; }; in diff --git a/nix/device-templates.nix b/nix/device-templates.nix new file mode 100644 index 000000000..006c07f --- /dev/null +++ b/nix/device-templates.nix @@ -0,0 +1,54 @@ +{ config, lib, pkgs, ... }: +with lib; +let + templates = role: { + ap = _: ../salt/cpe/ap.sh; + switch = model: ../salt/switches + "/${model}.expect"; + }.${role}; + replaceNetmasks = template: + builtins.toFile (builtins.baseNameOf template) ( + builtins.replaceStrings [''{%- import_yaml "netmasks.yaml" as netmasks -%}''] [""] ( + builtins.readFile template + ) + ); + expandTemplate = name: template: data: + import ./salt-support/expand-template.nix { + inherit pkgs; + } name (replaceNetmasks template) data; +in +{ + options.site.device-scripts = mkOption { + type = with types; attrsOf path; + }; + options.site.all-device-scripts = mkOption { + type = types.path; + }; + + config.site.device-scripts = + builtins.mapAttrs (hostname: { role, model, ... }: + expandTemplate "${hostname}.sh" (templates role model) ({ + inherit hostname; + pillar = config.salt-pillar; + netmasks = import ./netmasks.nix; + logging = config.salt-pillar.hosts-inet.mgmt.logging; + } // optionalAttrs (config.salt-pillar.switches ? ${hostname}) { + switch = config.salt-pillar.switches.${hostname}; + } // optionalAttrs (config.salt-pillar.cpe ? ${hostname}) { + conf = config.salt-pillar.cpe.${hostname}; + }) + ) (filterAttrs (_: { role, ... }: + role == "ap" || role == "switch" + ) config.site.hosts); + + config.site.all-device-scripts = + pkgs.runCommandLocal "all-device-scripts" {} ( + '' + mkdir -p $out/bin + '' + + builtins.concatStringsSep "\n" ( + map (hostname: + "ln -s ${config.site.device-scripts.${hostname}} $out/bin/${hostname}.sh" + ) (builtins.attrNames config.site.device-scripts) + ) + ); +} diff --git a/nix/legacy.nix b/nix/legacy.nix new file mode 100644 index 000000000..6f8cb85 --- /dev/null +++ b/nix/legacy.nix @@ -0,0 +1,41 @@ +{ pkgs, lib, ... }: + +let + pillar = import ./salt-support/salt-pillar.nix { inherit pkgs; }; +in +{ + options.salt-pillar = lib.mkOption {}; + config.salt-pillar = pillar; + + config.site.net = lib.mkMerge ([ + (builtins.mapAttrs (_: vlan: { vlan = vlan; }) pillar.vlans) + (builtins.mapAttrs (_: subnet: { subnet4 = subnet; }) pillar.subnets-inet) + ] ++ ( + map (ctx: + builtins.mapAttrs (_: subnet: { subnets6.${ctx} = subnet; }) pillar.subnets-inet6.${ctx} + ) (builtins.attrNames pillar.subnets-inet6) + )); + + config.site.hosts = lib.mkMerge ( + [ + (builtins.mapAttrs (_: switch: { + inherit (switch) model location password; + role = "switch"; + }) pillar.switches) + (builtins.mapAttrs (_: ap: { + inherit (ap) model location password; + role = "ap"; + }) pillar.cpe) + ] ++ + (map (net: + builtins.mapAttrs (_: addr4: { + }) pillar.hosts-inet.${net} + ) (builtins.attrNames pillar.hosts-inet)) ++ + (builtins.concatMap (ctx: + map (net: + builtins.mapAttrs (_: addr6: { + }) pillar.hosts-inet6.${ctx}.${net} + ) (builtins.attrNames pillar.hosts-inet6.${ctx}) + ) (builtins.attrNames pillar.hosts-inet6)) + ); +} diff --git a/nix/netmasks.nix b/nix/netmasks.nix new file mode 100644 index 000000000..7ceb270 --- /dev/null +++ b/nix/netmasks.nix @@ -0,0 +1,35 @@ +{ + "0" = "0.0.0.0"; + "1" = "128.0.0.0"; + "2" = "192.0.0.0"; + "3" = "224.0.0.0"; + "4" = "240.0.0.0"; + "5" = "248.0.0.0"; + "6" = "252.0.0.0"; + "7" = "254.0.0.0"; + "8" = "255.0.0.0"; + "9" = "255.128.0.0"; + "10" = "255.192.0.0"; + "11" = "255.224.0.0"; + "12" = "255.240.0.0"; + "13" = "255.248.0.0"; + "14" = "255.252.0.0"; + "15" = "255.254.0.0"; + "16" = "255.255.0.0"; + "17" = "255.255.128.0"; + "18" = "255.255.192.0"; + "19" = "255.255.224.0"; + "20" = "255.255.240.0"; + "21" = "255.255.248.0"; + "22" = "255.255.252.0"; + "23" = "255.255.254.0"; + "24" = "255.255.255.0"; + "25" = "255.255.255.128"; + "26" = "255.255.255.192"; + "27" = "255.255.255.224"; + "28" = "255.255.255.240"; + "29" = "255.255.255.248"; + "30" = "255.255.255.252"; + "31" = "255.255.255.254"; + "32" = "255.255.255.255"; +} diff --git a/nix/options.nix b/nix/options.nix index ac92106..98232be 100644 --- a/nix/options.nix +++ b/nix/options.nix @@ -10,16 +10,36 @@ let }; subnet4 = mkOption { description = "v.w.x.y/z"; - type = with types; nullOr string; + type = with types; nullOr str; default = null; }; subnets6 = mkOption { description = "IPv6 subnets w/o prefixlen (always 64)"; - type = with types; attrsOf string; + type = with types; attrsOf str; default = {}; }; }; }; + hostOpts = { name, ... }: { + options = { + role = mkOption { + type = types.enum [ "ap" "switch" "server" "gateway" "client" ]; + default = "client"; + }; + model = mkOption { + type = types.str; + default = "pc"; + }; + password = mkOption { + type = with types; nullOr str; + default = null; + }; + location = mkOption { + type = with types; nullOr str; + default = null; + }; + }; + }; in { options.warnings = mkOption { @@ -33,6 +53,10 @@ in default = {}; type = with types; attrsOf (submodule netOpts); }; + hosts = mkOption { + default = {}; + type = with types; attrsOf (submodule hostOpts); + }; }; config.warnings = diff --git a/nix/salt-support/expand-template.nix b/nix/salt-support/expand-template.nix new file mode 100644 index 000000000..f3cf49b --- /dev/null +++ b/nix/salt-support/expand-template.nix @@ -0,0 +1,15 @@ +{ pkgs ? import {} +}: + +name: template: data: +let + jsonFile = + builtins.toFile "data.json" (builtins.toJSON data); +in +pkgs.runCommandLocal name { + nativeBuildInputs = with pkgs; [ + pythonPackages.j2cli yaml2json + ]; +} '' + j2 -f json ${template} ${jsonFile} > $out +'' diff --git a/nix/salt-support/load-yaml.nix b/nix/salt-support/load-yaml.nix index 027b930..be24111 100644 --- a/nix/salt-support/load-yaml.nix +++ b/nix/salt-support/load-yaml.nix @@ -4,7 +4,7 @@ path: let - json = pkgs.runCommand "json-from-j2yaml" { + json = pkgs.runCommandLocal "desalinated-${builtins.baseNameOf path}" { nativeBuildInputs = with pkgs; [ gnupg pythonPackages.j2cli ruby yaml2json