Files
PVV-DNS/pvv-host-forwards.nix
T

52 lines
1.6 KiB
Nix

# Generate forward records (A, AAAA and CNAME) for hosts in ./hosts.nix
{ dns, lib, ... }:
with dns.lib.combinators;
let
hosts = import ./hosts.nix;
duplicateKeys = lhs: rhs: builtins.attrNames (builtins.intersectAttrs lhs rhs);
# Normal host forward records
hostRecords = lib.mapAttrs (
_: host:
let
ensureList = val: if builtins.isList val || builtins.isAttrs val then val else [ val ];
in
lib.optionalAttrs (host ? ipv4) {
A = ensureList host.ipv4;
}
// lib.optionalAttrs (host ? ipv6) {
AAAA = ensureList host.ipv6;
}
) hosts;
# CNAMEs
allAliases = lib.flatten (lib.mapAttrsToList (_: host: host.aliases or [ ]) hosts);
duplicateAliases = lib.pipe allAliases [
(lib.groupBy lib.id)
(lib.filterAttrs (_: list: lib.length list > 1))
lib.attrNames
];
aliasRecords =
if builtins.length duplicateAliases > 0 then
throw "Duplicate aliases: '${builtins.concatStringsSep ", " duplicateAliases}' exist as aliases for multiple different hosts. If this is intentional, add an exception or configure the aliases directly in the zone config."
else
lib.concatMapAttrs (
target: host:
builtins.listToAttrs (
builtins.map (alias: {
name = alias;
value.CNAME = [ target ];
}) host.aliases or [ ]
)
) hosts;
setCollisions = duplicateKeys hostRecords aliasRecords;
in
if builtins.length setCollisions > 0 then
throw "Duplicate keys: '${builtins.concatStringsSep ", " setCollisions}' exist as both a host (A/AAAA) and alias (CNAME)"
else
(hostRecords // aliasRecords)