entities/lib.nix

157 lines
4.5 KiB
Nix

{ lib, entities, ... }:
with lib;
let
getHostSite = hostname:
let site-name = entities.hosts."${hostname}".site;
in entities.sites."${site-name}";
getHostDomain = hostname:
let domain-name = entities.hosts."${hostname}".domain;
in entities.domains."${domain-name}";
getHostRealm = hostname: (getHostDomain hostname).gssapi-realm;
getHostFqdn = hostname:
let hostDomain = entities.hosts."${hostname}".domain;
in "${hostname}.${hostDomain}";
getHostNetworkSettings = hostname:
let
hostDomain = entities.hosts."${hostname}".domain;
hostNetwork = entities.zones."${hostDomain}";
in hostNetwork.hosts."${hostname}";
getIfAttr = as: a: if hasAttr as a then getAttr as a else null;
getHostIpv4 = hostname:
getIfAttr "ipv4-address" (getHostNetworkSettings hostname);
getHostIpv6 = hostname:
getIfAttr "ipv6-address" (getHostNetworkSettings hostname);
getHostIps = hostname:
filter (o: o != null) [ (getHostIpv4 hostname) (getHostIpv6 hostname) ];
getDomainPostgresqlServer = domain:
getHostFqdn entities.domains."${domain}".postgresql-server;
getSiteHosts = site:
attrNames (filterAttrs (_: hostOpts: hostOpts.site == site) entities.hosts);
getDomainHosts = domain:
attrNames
(filterAttrs (_: hostOpts: hostOpts.domain == domain) entities.hosts);
getSiteGatewayV4 = siteName:
let site = entities.sites."${siteName}";
in if hasAttr "local-gateway" site then
getHostIpv4 site.local-gateway
else
site.gateway-v4;
getHostGatewayV4 = hostname:
getSiteGatewayV4 entities.hosts."${hostname}".site;
getSiteGatewayV6 = siteName:
let site = entities.sites."${siteName}";
in if hasAttr "local-gateway" site then
getHostIpv6 site.local-gateway
else
site.gateway-v6;
getHostGatewayV6 = hostname:
getSiteGatewayV6 entities.hosts."${hostname}".site;
getSiteNetwork = siteName: entities.sites."${siteName}".network;
getSiteV4PrefixLength = siteName:
toInt (elemAt (splitString "/" (getSiteNetwork siteName)));
getSiteV6PrefixLength = siteName:
abort "not implemented: getSiteV6PrefixLength";
in {
inherit getHostSite getHostDomain getHostRealm getHostFqdn getHostIpv4
getHostIpv6 getHostIps getDomainPostgresqlServer getSiteHosts getDomainHosts
getSiteGatewayV4 getHostGatewayV4 getSiteGatewayV6 getHostGatewayV6
getSiteV4PrefixLength getSiteV6PrefixLength;
types.fudo = with lib.types; rec {
networkHost = {
hostname = mkOption {
type = str;
description = "Hostname";
default = name;
};
ipv4-address = mkOption {
type = nullOr str;
description = "The V4 IP of a given host, if any.";
default = null;
};
ipv6-address = mkOption {
type = nullOr str;
description = "The V6 IP of a given host, if any.";
default = null;
};
mac-address = mkOption {
type = nullOr str;
description =
"The MAC address of a given host, if desired for IP reservation.";
default = null;
};
description = mkOption {
type = nullOr str;
description = "Description of the host.";
default = null;
};
sshfp-records = mkOption {
type = listOf str;
description = "List of SSHFP records for this host.";
default = [ ];
};
};
networkHosts = let
# This is necessary because of the default 'name'...sigh.
networkHostOpt = { name, ... }: {
hostname = mkOption {
type = str;
description = "Hostname";
default = name;
};
ipv4-address = mkOption {
type = nullOr str;
description = "The V4 IP of a given host, if any.";
default = null;
};
ipv6-address = mkOption {
type = nullOr str;
description = "The V6 IP of a given host, if any.";
default = null;
};
mac-address = mkOption {
type = nullOr str;
description =
"The MAC address of a given host, if desired for IP reservation.";
default = null;
};
description = mkOption {
type = nullOr str;
description = "Description of the host.";
default = null;
};
sshfp-records = mkOption {
type = listOf str;
description = "List of SSHFP records for this host.";
default = [ ];
};
};
in attrsOf (submodule networkHostOpt);
};
}