diff --git a/lib/addressing/default.nix b/lib/addressing/default.nix index ec45cfa..4e580a3 100644 --- a/lib/addressing/default.nix +++ b/lib/addressing/default.nix @@ -270,19 +270,18 @@ let spec.domain or (throw "metatron-addressing: spec.domain is required for FQDN generation"); in concatMapAttrs - (locationName: locCfg: + (locationName: locationCfg: let loc = locationId locationName; locCode = mkLocationCode locationName; - # Strip meta-level hints; what’s left are subnets (main, dmz, etc.) + # Only treat attributes that are attrsets with a `hosts` attr as subnets subnets = - builtins.removeAttrs locCfg [ "owner" "admins" "users" ]; + lib.filterAttrs (_: v: builtins.isAttrs v && v ? hosts) locationCfg; in concatMapAttrs (typeName: subnetCfg: let - # New shape: subnetCfg.hosts = { hostName = { role = "..."; ... }; ... } hostsForSubnet = subnetCfg.hosts or { }; # Only treat non-underscore-prefixed keys as hosts @@ -347,7 +346,7 @@ let subnets) locations; - # Subnet map: { "home-dmz" = { cidr = "..."; vlan = ...; zone = "..."; ... }; ... } + # Subnet map: { "home-dmz" = "10.1.0.0/19"; "home-main" = "..."; ... } mkSubnetsFromSpec = spec: let @@ -358,20 +357,18 @@ let spec.domain or (throw "metatron-addressing: spec.domain is required"); in concatMapAttrs - (locationName: locCfg: + (locationName: locationCfg: let loc = locationId locationName; locCode = mkLocationCode locationName; - # Strip meta-level hints; remaining attrs are subnets + # Only attributes with `hosts` are subnets subnets = - builtins.removeAttrs locCfg [ "owner" "admins" "users" ]; + lib.filterAttrs (_: v: builtins.isAttrs v && v ? hosts) locationCfg; in mapAttrs' (typeName: subnetCfg: let - hostsForSubnet = subnetCfg.hosts or { }; - cidr = mkSubnetNamed { location = loc; inherit typeName; }; subnetSlug = @@ -382,21 +379,42 @@ let zone = "${subnetSlug}.${locCode}.${domain}"; vlan = - # Priority: explicit vlan on subnet > old-style _vlan > computed subnetCfg.vlan or - hostsForSubnet._vlan or + subnetCfg._vlan or (mkVlanNamed { location = loc; inherit typeName; }); + + dhcpCfg = subnetCfg.dhcp or null; + + dhcpRange = + if dhcpCfg == null then null else { + startIp = mkIpNamed { + location = loc; + inherit typeName; + roleName = "pool"; + host = dhcpCfg.start; + }; + endIp = mkIpNamed { + location = loc; + inherit typeName; + roleName = "pool"; + host = dhcpCfg.end; + }; + }; in nameValuePair "${locationName}-${typeName}" - { - inherit cidr locationName typeName zone vlan; - }) + ( + { + inherit cidr locationName typeName zone vlan; + } + // optionalAttrs (dhcpCfg != null) { + dhcp = dhcpCfg; + dhcpRange = dhcpRange; + } + )) subnets) locations; - - # Combined view, if you want both mkNetworkFromSpec = spec: diff --git a/meta.nix b/meta.nix index 9957a74..f283c77 100644 --- a/meta.nix +++ b/meta.nix @@ -84,6 +84,11 @@ main = { vlan = 10; + dhcp = { + start = 1; + end = 1; + }; + hosts = { europa = { role = "router"; @@ -131,40 +136,21 @@ role = "phone"; hw-address = "80:5e:c0:de:3d:66"; }; - - home-main-dhcp-start = { - role = "pool"; - hostId = 1; - dns = false; - }; - - home-main-dhcp-end = { - role = "pool"; - hostId = 250; - dns = false; - }; }; }; guest = { vlan = 20; + dhcp = { + start = 1; + end = 250; + }; + hosts = { europa-guest = { role = "router"; }; - - home-guest-dhcp-start = { - role = "pool"; - hostId = 1; - dns = false; - }; - - home-guest-dhcp-end = { - role = "pool"; - hostId = 250; - dns = false; - }; }; }; @@ -223,6 +209,11 @@ storage = { vlan = 40; + dhcp = { + start = 1; + end = 250; + }; + hosts = { europa-storage = { role = "router"; @@ -232,18 +223,6 @@ role = "nas"; aliases = [ "storage.kasear.net" ]; }; - - home-storage-dhcp-start = { - role = "pool"; - hostId = 1; - dns = false; - }; - - home-storage-dhcp-end = { - role = "pool"; - hostId = 250; - dns = false; - }; }; };