Add duplicate detection when reading hosts.nix

This commit is contained in:
2026-01-21 20:46:14 +01:00
parent 6ef9eaa00d
commit 2713d657fb
3 changed files with 56 additions and 41 deletions

View File

@@ -80,21 +80,14 @@ in
"homepvvm"
"homepvvt"
"homepvvz"
"list" # MX/A record handled in ./zones/pvv.ntnu.no.nix
"mail"
"samba" # TODO: Remove?
"sambapvv" # TODO: Remove?
"list" # MX/A record handled in ./zones/pvv.ntnu.no.nix
"mail" # Special alias handled in ./zones/pvv.ntnu.no.nix
];
};
mail.aliases = [
"drift"
"imap"
"mailhost"
"pop"
"smtp"
];
tom = pvvHost 180;
knutsen.ipv4 = pvvv4 190;

View File

@@ -4,6 +4,7 @@
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 (
@@ -19,20 +20,31 @@ let
}
) hosts;
# TODO:
# Above can be replaced using dns.nix helpers, without support for roundrobin, custom TTL, etc;
# (lib.mapAttrs (name: host: dns.lib.host (host.ipv4 or null) (host.ipv6 or null)) hosts)
# CNAMEs
aliasRecords = lib.concatMapAttrs (
target: host:
builtins.listToAttrs (
builtins.map (alias: {
name = alias;
value.CNAME = [ target ];
}) host.aliases or [ ]
)
) hosts;
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
# TODO: Merge such that an error is raised if a label exists in more than one of these sets:
(hostRecords // aliasRecords)
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)

View File

@@ -56,22 +56,7 @@ in
"ns2.stack.it.ntnu.no."
];
"mail._domainkey".TXT = [
"v=DKIM1; h=sha256; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsLAI4Fj8lGS1gQbumMCftoynu9G5LCOrs8G/EzbXysKuV5EtCCS3ioJVdt3Bbu5RoTZq0lv0KbIClzW7qPa3u0spt9skOQswkSOhzoraPIwPacEUBRMyc2NYSmnIPthKyb6BTAYB1qcKpRswrNzZ6zbsG8DFD8zEJsbpPGjYSxbluLm+FsQXiX21Biha+psCpDTAGcQODri+Fh5UChYi7MnT7UGd8rvNIYlVPAYPeU0xoUcRRZxHfxLNyOU6TrFQ3MhjSKq06p35y3nN2z/6hjbkxQ8aKc30GB+y2SPrTE8TAXKmIMlWbmhaReFHhOS25XGWfzNVhUfNxa21b5UY7wIDAQAB"
];
_dmarc.TXT = [ "v=DMARC1; p=quarantine; fo=1;" ];
list = {
A = pvvHostRecords.microbel.A;
MX = [
{
preference = 10;
exchange = "microbel.pvv.ntnu.no.";
}
];
};
# Special services:
minecraft.SRV = [
{
@@ -83,5 +68,30 @@ in
];
_kerberos.TXT = [ "PVV.NTNU.NO" ];
# E-mail:
"mail._domainkey".TXT = [
"v=DKIM1; h=sha256; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsLAI4Fj8lGS1gQbumMCftoynu9G5LCOrs8G/EzbXysKuV5EtCCS3ioJVdt3Bbu5RoTZq0lv0KbIClzW7qPa3u0spt9skOQswkSOhzoraPIwPacEUBRMyc2NYSmnIPthKyb6BTAYB1qcKpRswrNzZ6zbsG8DFD8zEJsbpPGjYSxbluLm+FsQXiX21Biha+psCpDTAGcQODri+Fh5UChYi7MnT7UGd8rvNIYlVPAYPeU0xoUcRRZxHfxLNyOU6TrFQ3MhjSKq06p35y3nN2z/6hjbkxQ8aKc30GB+y2SPrTE8TAXKmIMlWbmhaReFHhOS25XGWfzNVhUfNxa21b5UY7wIDAQAB"
];
_dmarc.TXT = [ "v=DMARC1; p=quarantine; fo=1;" ];
drift.CNAME = [ "mail" ];
imap.CNAME = [ "mail" ];
mailhost.CNAME = [ "mail" ];
pop.CNAME = [ "mail" ];
smtp.CNAME = [ "mail" ];
list = {
A = pvvHostRecords.microbel.A;
MX = [
{
preference = 10;
exchange = "microbel.pvv.ntnu.no.";
}
];
};
};
}