stockholm/krebs/3modules/zones.nix

131 lines
3.9 KiB
Nix

{ config, pkgs, lib, ... }:
with lib; {
options.krebs.zone-head-config = mkOption {
type = lib.types.attrsOf lib.types.str;
description = ''
The zone configuration head which is being used to create the
zone files. The string for each key is pre-pended to the zone file.
'';
default = {
"krebsco.de" = /* bindzone */ ''
$TTL 60
@ 3600 IN SOA spam.krebsco.de. spam.krebsco.de. 0 7200 3600 86400 3600
@ 3600 IN NS ns1
@ 3600 IN NS ni
@ 3600 IN NS ns2.he.net.
@ 3600 IN NS ns3.he.net.
@ 3600 IN NS ns2.hosting.de.
_acme-challenge IN NS ns1
panda NS panda
panda A 130.61.237.100
xkey A 217.197.83.17
xkey AAAA 2a0a:4580:5011::1
'';
};
};
config = {
environment.etc =
mapAttrs'
(name: pkg: {
name = "zones/${name}";
value.source = pkg;
})
pkgs.krebs.zones;
nixpkgs.overlays = [
# Explicit zones generated from config.krebs.hosts.*.extraZones
(self: super: let
stripEmptyLines = s: (concatStringsSep "\n"
(remove "\n" (remove "" (splitString "\n" s)))) + "\n";
all-zones = foldAttrs (sum: current: sum + "\n" + current) ""
([config.krebs.zone-head-config] ++ combined-hosts);
combined-hosts =
mapAttrsToList (name: getAttr "extraZones") config.krebs.hosts;
in {
krebs = super.krebs or {} // {
zones = super.krebs.zones or {} //
mapAttrs'
(name: value: {
name = name;
value = self.writeText "${name}.zone" (stripEmptyLines value);
})
all-zones;
};
})
# Implicit zones generated from config.krebs.hosts.*.nets.*.ip{4,6}.addr
(self: super: let
# record : { name : str, type : enum [ "A" "AAAA" ], data : str }
# toRecord : record.name -> record.type -> record.data -> record
toRecord = name: type: data:
{ inherit name type data; };
# toRecords : str -> host -> [record]
toRecords = netname: host:
let
net = host.nets.${netname};
in
optionals
(hasAttr netname host.nets)
(filter
(x: x.data != null)
(concatLists [
(map
(name: toRecord name "A" (net.ip4.addr or null))
(concatMap
(name: [ "${name}." "4.${name}." ])
(net.aliases or [])))
(map
(name: toRecord name "AAAA" (net.ip6.addr or null))
(concatMap
(name: [ "${name}." "6.${name}." ])
(net.aliases or [])))
]));
# formatRecord : record -> str
formatRecord = { name, type, data }: "${name} IN ${type} ${data}";
# writeZone : attrs -> package
writeZone =
{ name ? "${domain}.zone"
, domain ? substring 0 1 netname
, nameservers ? [ "ni" ]
, netname
, hosts ? config.krebs.hosts
}:
self.writeText name /* bindzone */ ''
$TTL 60
@ IN SOA ns admin 1 3600 600 86400 60
@ IN NS ns
${concatMapStringsSep "\n"
(name: /* bindzone */ "ns IN CNAME ${name}")
nameservers
}
${concatMapStringsSep
"\n"
formatRecord
(concatMap
(toRecords netname)
(attrValues hosts))
}
'';
in {
krebs = super.krebs or {} // {
zones = super.krebs.zones or {} // {
i = writeZone { netname = "internet"; };
r = writeZone { netname = "retiolum"; };
w = writeZone { netname = "wiregrill"; };
};
};
})
];
};
}