{ hostName, config, lib, pkgs, self, ... }: lib.mkIf config.site.hosts.${hostName}.services.dns.enable { services.bind = let fqdn = "${hostName}.serv.zentralwerk.org"; # public servers (slaves) publicNS = [ "ns.c3d2.de" "ns.spaceboyz.net" ]; # allowed for zone-transfer slaves = [ # ns.c3d2.de "217.197.84.53" "2001:67c:1400:2240::a" # ns.spaceboyz.net "172.22.24.4" "2a01:4f9:4b:39ec::4" ]; serial = let timestamp = toString self.lastModified; datePkg = pkgs.runCommandLocal "date-${timestamp}" {} '' date -d @${timestamp} +%Y%m%d%H > $out ''; in toString (import datePkg); staticZone = { name, ns, records }: { inherit name; master = true; file = builtins.toFile "${name}.zone" '' $ORIGIN ${name}. $TTL 1h @ IN SOA ${fqdn}. astro.spaceboyz.net. ( ${serial} ; serial 1h ; refresh 1m ; retry 2h ; expire 1m ; minimum ) ${lib.concatMapStrings (ns: " IN NS ${ns}.\n") ns} ${lib.concatMapStrings ({ name, type, data }: "${name} IN ${type} ${data}\n" ) records} ''; }; hosts4Records = hosts4: builtins.attrValues ( builtins.mapAttrs (name: addr: { inherit name; type = "A"; data = addr; }) hosts4 ); hosts6Records = hosts6: builtins.attrValues ( builtins.mapAttrs (name: addr: { inherit name; type = "AAAA"; data = addr; }) hosts6 ); # generate zones only for nets with hosts namedNets = lib.filterAttrs (_: { hosts4, hosts6, dynamicDomain, ... }: (hosts4 != [] && hosts6 != []) || dynamicDomain ) config.site.net; in { enable = true; zones = [ (staticZone { name = "zentralwerk.org"; ns = publicNS; records = []; }) (staticZone { name = "zentralwerk.dn42"; ns = [ fqdn ]; records = [ { name = "ipa"; type = "A"; data = config.site.net.serv.hosts4.ipa; } ]; }) (staticZone { name = "dyn.zentralwerk.org"; ns = publicNS; # TODO: implement dyndns records = [ { name = "upstream1"; type = "A"; data = "24.134.104.53"; } { name = "upstream2"; type = "A"; data = "24.134.252.105"; } ]; }) ] ++ (builtins.concatLists ( builtins.attrValues ( builtins.mapAttrs (net: { dynamicDomain, hosts4, hosts6, ... }: [ (if dynamicDomain then throw "TODO" else staticZone { name = "${net}.zentralwerk.dn42"; ns = [ fqdn ]; records = hosts4Records hosts4 ++ lib.optionals (hosts6 ? dn42) (hosts6Records hosts6.dn42); }) (staticZone { name = "${net}.zentralwerk.org"; ns = publicNS; records = lib.optionals (hosts6 ? up1) (hosts6Records hosts6.up1) ++ lib.optionals (hosts6 ? up2) (hosts6Records hosts6.up2); }) ]) namedNets ) )); }; # TODO: zentralwerk.{org,dn42}, reverse, dyn, ipa.zentralwerk.dn42 }