nix: generate device scripts

This commit is contained in:
Astro 2021-02-25 01:06:32 +01:00
parent c23ebe64d2
commit b1fddd0ba7
7 changed files with 173 additions and 3 deletions

View File

@ -6,6 +6,7 @@ let
modules = [
./options.nix
./legacy.nix
./device-templates.nix
];
};
in

54
nix/device-templates.nix Normal file
View File

@ -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)
)
);
}

41
nix/legacy.nix Normal file
View File

@ -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))
);
}

35
nix/netmasks.nix Normal file
View File

@ -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";
}

View File

@ -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 =

View File

@ -0,0 +1,15 @@
{ pkgs ? import <nixpkgs> {}
}:
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
''

View File

@ -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