infrastructure/modules/nixos/network/resolve.nix
2024-05-13 15:31:34 -07:00

89 lines
2.1 KiB
Nix

{
config,
lib,
...
}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkOptionDefault;
inherit (lib.lists) filter optional;
inherit (lib.strings) hasInfix concatStrings;
inherit (config.services) resolved;
enabledNameservers = filter (ns: ns.enable) (config.networking.nameservers');
nameserverModule = {config, ...}: let
dnsPort = 53;
mkResolvedValue = {
address,
port,
interface ? null,
host ? null,
}: let
isIpv6 = hasInfix ":" address;
isPlain = port == dnsPort && interface == null && host == null;
addr =
if isIpv6 && !isPlain
then "[${address}]"
else address;
in
concatStrings (
[addr]
++ optional (port != dnsPort) ":${toString port}"
++ optional (interface != null) "%${interface}"
++ optional (host != null) "#${host}"
);
in {
options = with lib.types; {
enable =
mkEnableOption "nameserver"
// {
default = true;
};
address = mkOption {
type = str;
};
port = mkOption {
type = port;
default = dnsPort;
};
interface = mkOption {
type = nullOr str;
default = null;
};
host = mkOption {
type = nullOr str;
default = null;
};
resolvedValue = mkOption {
type = str;
readOnly = true;
};
value = mkOption {
type = str;
internal = true;
};
};
config = {
resolvedValue = mkOptionDefault (mkResolvedValue {
inherit (config) address port interface host;
});
value = mkOptionDefault (mkResolvedValue {
inherit (config) address port;
});
};
};
in {
options.networking = with lib.types; {
nameservers' = mkOption {
type = listOf (submodule nameserverModule);
default = {};
};
};
config = {
networking.nameservers = mkIf (config.networking.nameservers' != []) (
map (ns:
if resolved.enable
then ns.resolvedValue
else ns.value)
enabledNameservers
);
};
}