{ lib, config, ... }: let prefix = "lyn"; #subnets routed through wireguard wg_subnets = { IPv4 = "10.35.0.1/24"; IPv6 = "fd1a:acab:cafe:1337::/64"; }; #hosts are defined here hosts = { wg-gateway = { wg = { enabled = true; pubkey = "Fknzk7lltkPKJZlF3KXWKGQXXSj7CUD9ev0ZEZtpbjY="; port = 51820; }; v4 = { public = "78.47.226.47"; # we use 10.35.0.0/16 as a range for private subnets, specifically 10.35.0.0/24 for wireguard peers internal = "10.35.0.1"; }; v6 = { public = "2a01:4f8:1c1b:d2db::"; # 1aacabcafe is the global ID and 1337 is the wireguard peer subnet ID, resulting in the ULA fd1a:acab:cafe:1337::/64 internal = "fd1a:acab:cafe:1337:8f4c:68cd::"; }; }; supernova = { wg = { enabled = true; pubkey = "jdfbOnP0mFWFobtQunm0h6EtqOZiar9G9jngMU7b+Co="; port = 51820; }; v4 = { public = ""; # we use 10.35.0.0/16 as a range for private subnets, specifically 10.35.0.0/24 for wireguard peers internal = "10.35.0.2"; }; v6 = { public = ""; # 1aacabcafe is the global ID and 1337 is the wireguard peer subnet ID, resulting in the ULA fd1a:acab:cafe:1337::/64 internal = "fd1a:acab:cafe:1337:6722:3657::"; }; }; }; in { options = { ${prefix} = { network.wg_subnets.IPv4 = lib.mkOption { type = lib.types.str; description = "The IPv6 range that wireguard peers will use"; }; network.wg_subnets.IPv6 = lib.mkOption { type = lib.types.str; description = "The IPv4 range that wireguard peers will use"; }; # defining the entire hosts part as a module network.hosts = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule { options = { wg = lib.mkOption { type = lib.types.submodule { options = { enabled = lib.mkOption { type = lib.types.bool; default = false; description = "Enable WireGuard"; }; pubkey = lib.mkOption { type = lib.types.nullOr lib.types.str; default = null; description = "Public key for WireGuard"; }; port = lib.mkOption { type = lib.types.int; default = 51820; description = "Port for WireGuard"; }; }; }; description = "WireGuard configuration"; }; v4 = lib.mkOption { type = lib.types.submodule { options = { public = lib.mkOption { type = lib.types.str; default = ""; description = "Public IPv4 address"; }; internal = lib.mkOption { type = lib.types.str; description = "Wireguard-internal IPv4 address"; }; }; }; description = "IPv4 configuration"; default = {}; }; v6 = lib.mkOption { type = lib.types.submodule { options = { public = lib.mkOption { type = lib.types.str; default = ""; description = "Public IPv6 address"; }; internal = lib.mkOption { type = lib.types.str; description = "Wireguard-internal IPv6 address"; }; }; }; description = "IPv6 configuration"; default = {}; }; }; }); default = {}; description = "All hosts in this network that this config should be aware of"; }; }; }; config = { ${prefix}.network = { inherit hosts wg_subnets; }; assertions = [ { assertion = lib.any (host: host.v4 != null || host.v6 != null) (lib.attrValues hosts); message = "At least one of v4 or v6 must be defined for each host"; } ]; }; }