network/nix/lib/config/options.nix

84 lines
2.2 KiB
Nix

{ config, options, lib, ... }:
with lib;
let
netOpts = { name, ... }: {
options = {
vlan = mkOption {
description = "VLAN tag number";
type = types.int;
};
subnet4 = mkOption {
description = "v.w.x.y/z";
type = with types; nullOr str;
default = null;
};
subnets6 = mkOption {
description = "IPv6 subnets w/o prefixlen (always 64)";
type = with types; attrsOf str;
default = {};
};
};
};
hostOpts = { name, ... }: {
options = {
role = mkOption {
type = types.enum [ "ap" "switch" "server" "container" "client" ];
default = "client";
};
model = mkOption {
type = types.str;
default = {
ap = "unknown";
switch = "unknown";
server = "pc";
container = "lxc";
client = "any";
}."${config.site.hosts.${name}.role}";
};
password = mkOption {
type = with types; nullOr str;
default = null;
};
location = mkOption {
type = with types; nullOr str;
default = null;
};
};
};
in
{
options.site = {
net = mkOption {
default = {};
type = with types; attrsOf (submodule netOpts);
};
hosts = mkOption {
default = {};
type = with types; attrsOf (submodule hostOpts);
};
};
config.warnings =
let
findCollisions = getter: xs:
(builtins.foldl' ({ known, dup }: k:
let
ks = builtins.toString k;
in
if known ? ${ks}
then { inherit known; dup = dup ++ [ks]; }
else { known = known // { ${ks} = true; }; inherit dup; }
) {
known = {}; dup = [];
} (
concatMap getter (builtins.attrValues xs)
)).dup;
reportCollisions = name: getter: xs:
map (k: "Duplicate ${name}: ${k}") (findCollisions getter xs);
in
(reportCollisions "VLAN tag" (x: [x.vlan]) config.site.net) ++
(reportCollisions "IPv4 subnet" (x: if x.subnet4 == null then [] else [x.subnet4]) config.site.net) ++
(reportCollisions "IPv6 subnet" (x: builtins.attrValues x.subnets6) config.site.net);
}