lib: with lib; (evalModules { modules = [ { options.configurations = mkOption { description = "My configurations."; type = with types; attrsOf (submodule ({name, ...}: { freeformType = attrs; options = let mkConfigurationTypeOption = type: mkOption { description = "Whether the machine is a ${type} one."; type = bool; default = false; }; in { hostname = mkOption { description = "The machine's hostname"; type = str; default = name; readOnly = true; }; system = mkOption { description = "The machine's system"; type = enum ["x86_64-linux" "aarch64-linux"]; default = "x86_64-linux"; }; isHeadless = mkConfigurationTypeOption "headless"; isHeadful = mkConfigurationTypeOption "headful"; isOther = mkConfigurationTypeOption "other"; ipv4 = { address = mkOption { description = "The machine's public IPv4 addresses."; type = nullOr str; default = null; }; gateway = mkOption { description = "The machine's IPv4 gateway."; type = nullOr str; default = null; }; }; ipv6 = { address = mkOption { description = "The machine's public IPv6 addresses."; type = nullOr str; default = null; }; gateway = mkOption { description = "The machine's IPv6 gateway."; type = nullOr str; default = null; }; }; wireguard = { ipv4.address = mkOption { description = "The machine's internal IPv4 addresses."; type = nullOr str; default = null; }; ipv6.address = mkOption { description = "The machine's internal IPv4 addresses."; type = nullOr str; default = null; }; publicKey = mkOption { description = "The machine's public key."; type = nullOr str; default = null; }; }; # TODO Automate filling of this from the NSD service module. # Right now I need to copy domain defenitions from there to here # manually. # # Something like taking `config.services.nsd.zones[$domain]` and # filtering for actual subdomains. We can remove this option # altogether then. domains = mkOption { description = "External domains that resovle to this address."; type = listOf str; default = []; }; syncthing.id = mkOption { description = "Syncthing ID."; type = nullOr str; default = null; }; }; })); default = {}; }; config = { _module.freeformType = types.attrs; fullname = "Azat Bahawi"; username = "azahi"; domain = { azahi = "azahi.cc"; rohan = "rohan.net"; gondor = "gondor.net"; shire = "shire.me"; }; email = "frodo@${my.domain.gondor}"; pgp = { key = "@PGP_KEY@"; fingerprint = "@PGP_FINGERPRINT@"; grip = "@PGP_GRIP@"; }; ssh = rec { type = "ed25519"; id = my.email; key = "ssh-${type} @PUBLIC_KEY@ ${id}"; }; hashedPassword = "@HASHED_PASSWORD@"; configurations = { manwe = { isHeadless = true; ipv4 = { address = "@IPV4_ADDRESS@"; gateway = "@IPV4_ADDRESS@"; }; ipv6 = { address = "@IPV6_ADDRESS@]"; gateway = "@IPV6_ADDRESS@"; }; wireguard = { ipv4.address = "10.69.0.1"; ipv6.address = "fd69::0:1"; publicKey = "@PUBLIC_KEY@"; }; domains = with my.domain; [ "alertmanager.${shire}" "frodo.${rohan}" "frodo.${gondor}" "gotify.${shire}" "grafana.${shire}" "loki.${shire}" "prometheus.${shire}" "radicale.${shire}" "rss-bridge.${shire}" "vaultwarden.${shire}" azahi rohan gondor shire ]; }; varda = { isHeadless = true; ipv4 = { address = "@IPV4_ADDRESS@"; gateway = "@IPV4_ADDRESS@"; }; ipv6 = { address = "@IPV6_ADDRESS@"; gateway = "@IPV6_ADDRESS@"; }; wireguard = { ipv4.address = "10.69.1.1"; ipv6.address = "fd69::1:1"; publicKey = "@PUBLIC_KEY@"; }; domains = with my.domain; ["minecraft.${shire}"]; }; yavanna = { isHeadless = true; ipv4 = { address = "@IPV4_ADDRESS@"; gateway = "@IPV4_ADDRESS@"; }; ipv6 = { address = "@IPV6_ADDRESS@"; gateway = "@IPV6_ADDRESS@"; }; wireguard = { ipv4.address = "10.69.1.2"; ipv6.address = "fd69::1:2"; publicKey = "@PUBLIC_KEY@"; }; domains = with my.domain; ["flood.${shire}"]; syncthing.id = "@SYNCTHING_ID@"; }; melian = { isHeadful = true; wireguard = { ipv4.address = "10.69.4.1"; ipv6.address = "fd69::4:1"; publicKey = "@PUBLIC_KEY@"; }; syncthing.id = "@SYNCTHING_ID@"; }; gothmog = { isOther = true; wireguard = { ipv4.address = "10.69.5.1"; ipv6.address = "fd69::5:1"; publicKey = "@PUBLIC_KEY@"; }; syncthing.id = "@SYNCTHING_ID@"; }; }; }; } ]; }) .config