60 lines
1.5 KiB
Nix
60 lines
1.5 KiB
Nix
|
{ config, 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 string;
|
||
|
default = null;
|
||
|
};
|
||
|
subnets6 = mkOption {
|
||
|
description = "IPv6 subnets w/o prefixlen (always 64)";
|
||
|
type = with types; attrsOf string;
|
||
|
default = {};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
in
|
||
|
{
|
||
|
options.warnings = mkOption {
|
||
|
type = types.listOf types.str;
|
||
|
default = [];
|
||
|
internal = true;
|
||
|
};
|
||
|
|
||
|
options.site = {
|
||
|
net = mkOption {
|
||
|
default = {};
|
||
|
type = with types; attrsOf (submodule netOpts);
|
||
|
};
|
||
|
};
|
||
|
|
||
|
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);
|
||
|
}
|