nixfiles/lib/dns.nix

102 lines
2.7 KiB
Nix
Raw Normal View History

{ lib }:
let
inherit (builtins) filter;
inherit (lib)
concatStringsSep concatMapStringsSep mapAttrsToList filterAttrs flatten optionalString;
in
rec {
genRecords =
{
allAssignments,
domain,
names,
f,
}:
concatStringsSep
"\n"
(filter
(s: s != "")
(flatten
(map
(name: (mapAttrsToList
(_: as: f as."${name}")
(filterAttrs
(_: as: as ? "${name}" && as."${name}".domain == domain && as."${name}".visible)
allAssignments)))
names)));
fwdRecords =
{
allAssignments,
domain,
names,
}:
genRecords {
inherit allAssignments domain names;
f = a: ''
${a.name} IN A ${a.ipv4.address}
${optionalString (a.ipv6.address != null) "${a.name} IN AAAA ${a.ipv6.address}"}
${concatMapStringsSep "\n" (alt: "${alt} IN CNAME ${a.name}") a.altNames}
'';
};
ptrRecords =
{
allAssignments,
domain,
names,
ndots,
}:
genRecords {
inherit allAssignments domain names;
f = a:
optionalString
a.ipv4.genPTR
''@@PTR:${a.ipv4.address}:${toString ndots}@@ IN PTR ${a.name}.${domain}.'';
};
ptr6Records =
{
allAssignments,
domain,
names,
ndots,
}:
genRecords {
inherit allAssignments domain names;
f = a:
optionalString
(a.ipv6.address != null && a.ipv6.genPTR)
''@@PTR:${a.ipv6.address}:${toString ndots}@@ IN PTR ${a.name}.${domain}.'';
};
ifaceA = { pkgs, iface, skipBroadcasts ? [] }:
let
extraFilters = concatMapStringsSep " " (b: ''and .broadcast != \"${b}\"'') skipBroadcasts;
script = pkgs.writeText "if-${iface}-a.lua" ''
local proc = io.popen("${pkgs.iproute2}/bin/ip -j addr show dev ${iface} | ${pkgs.jq}/bin/jq -r '.[0].addr_info[] | select(.family == \"inet\" and .scope == \"global\" ${extraFilters}).local'", "r")
assert(proc, "failed to popen")
local addr_line = proc:read("*l")
assert(proc:close(), "command failed")
assert(addr_line, "no output from command")
return addr_line
'';
in
''A "dofile('${script}')"'';
lookupIP = { pkgs, hostname, server, type ? "A" }:
let
script = pkgs.writeScript "drill-${hostname}-${server}.lua" ''
local proc = io.popen("${pkgs.ldns}/bin/drill -Q @${server} ${hostname} ${type}", "r")
assert(proc, "failed to popen")
local addr_line = proc:read("*l")
assert(proc:close(), "command failed")
assert(addr_line, "no output from command")
return addr_line
'';
in
''${type} "dofile('${script}')"'';
}