From d2e668cfb1bdb8dc3f979dd2ca4d95d8efb208ec Mon Sep 17 00:00:00 2001 From: kylerisse Date: Thu, 12 Feb 2026 20:35:10 -0800 Subject: [PATCH 1/4] nixosModules.facts: add building fact definition --- nix/nixos-modules/facts.nix | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nix/nixos-modules/facts.nix b/nix/nixos-modules/facts.nix index 9c763b0b4..ff5a62930 100644 --- a/nix/nixos-modules/facts.nix +++ b/nix/nixos-modules/facts.nix @@ -26,5 +26,10 @@ in type = types.str; }; + building = mkOption { + type = types.str; + default = "expo"; + }; + }; } From 4c6e7711de5f0b06e544658a80e6e911ab5b7600 Mon Sep 17 00:00:00 2001 From: kylerisse Date: Thu, 12 Feb 2026 20:16:56 -0800 Subject: [PATCH 2/4] nixosConfigurations.core-{conf,expo}: add fact for building --- nix/nixos-configurations/core-conf/default.nix | 1 + nix/nixos-configurations/core-expo/default.nix | 1 + 2 files changed, 2 insertions(+) diff --git a/nix/nixos-configurations/core-conf/default.nix b/nix/nixos-configurations/core-conf/default.nix index d1b05a2cc..b6444bbf8 100644 --- a/nix/nixos-configurations/core-conf/default.nix +++ b/nix/nixos-configurations/core-conf/default.nix @@ -26,6 +26,7 @@ ipv4 = "10.128.3.20/24"; ipv6 = "2001:470:f026:503::20/64"; eth = "virbr0"; + building = "conf"; }; # disable legacy networking bits as recommended by: diff --git a/nix/nixos-configurations/core-expo/default.nix b/nix/nixos-configurations/core-expo/default.nix index 914851459..8d1d9f13c 100644 --- a/nix/nixos-configurations/core-expo/default.nix +++ b/nix/nixos-configurations/core-expo/default.nix @@ -26,6 +26,7 @@ ipv4 = "10.0.3.20/24"; ipv6 = "2001:470:f026:103::20/64"; eth = "virbr0"; + building = "expo"; }; # disable legacy networking bits as recommended by: From 270e61a44971a213b944334a7f38488c482c4116 Mon Sep 17 00:00:00 2001 From: kylerisse Date: Thu, 12 Feb 2026 20:52:26 -0800 Subject: [PATCH 3/4] facts.inventory: create building specific kea v6 subnet confs --- facts/inventory.py | 63 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/facts/inventory.py b/facts/inventory.py index 5e26f671c..63c9c6ef6 100755 --- a/facts/inventory.py +++ b/facts/inventory.py @@ -5,6 +5,7 @@ SCaLE specific text files to produce a sane inventory to ansible """ +import copy import ipaddress import json import math @@ -862,7 +863,9 @@ def generatekeaconfig(servers, aps, vlans, outputdir): with open(f"{outputdir}/dhcp4-server.conf", "w") as f: f.write(json.dumps(kea_config, indent=2)) - subnets6_dict = [] + # Store 2 subnet6, 1 per building, see below + expo_subnets6 = [] + conf_subnets6 = [] for vlan in vlans: # Make sure to skip vlans that have no ranges # TODO: filtering out vlan 112 for the soda machine @@ -891,19 +894,51 @@ def generatekeaconfig(servers, aps, vlans, outputdir): # TODO: This should probably be broken into its own config and dynamically included since each core # server will only be local per building. For now we are defaulting to exInfra - if vlan["name"] in ["exInfra"]: - # This is only required for the subnets that will allocate dhcpv6 addresses without a relay - # in our case this is only ever the cf* vlan since thats where the VMs nic will be bridge to - # TODO: we should figure out a better way of dynamically allocating this config of the - # interface so is not hardcoded - # https://kea.readthedocs.io/en/kea-2.2.0/arm/dhcp6-srv.html#ipv6-subnet-selection - subnet["interface"] = "@@INTERFACE@@" - subnets6_dict.append(subnet) - - keav6_config["Dhcp6"]["subnet6"] = subnets6_dict - - with open(f"{outputdir}/dhcp6-server.conf", "w") as f: - f.write(json.dumps(keav6_config, indent=2)) + + # This is only required for the subnets that will allocate dhcpv6 addresses without a relay + # in our case this is only ever the cf* vlan since thats where the VMs nic will be bridge to + # TODO: we should figure out a better way of dynamically allocating this config of the + # interface so is not hardcoded + # https://kea.readthedocs.io/en/kea-2.2.0/arm/dhcp6-srv.html#ipv6-subnet-selection + + # This is a hack to work around the above and generate building specific configs + # TODO: fix this at the jinja level when refactoring this entire file where it'll be cleaner + # Populate building specific subnets list and break out of loop (continue), otherwise + # progress and append to the global dict as normal. + # Merge them later when we write the 2 files. + if vlan["name"] == "cfInfra": + # add the conf subnet to the expo list before the interface key + expo_subnets6.append(subnet) + conf_interface_subnet6 = copy.deepcopy(subnet) + conf_interface_subnet6["interface"] = "@@INTERFACE@@" + conf_subnets6.append(conf_interface_subnet6) + continue + if vlan["name"] == "exInfra": + # add the expo subnet to the conf list before the interface key + conf_subnets6.append(subnet) + expo_interface_subnet6 = copy.deepcopy(subnet) + expo_interface_subnet6["interface"] = "@@INTERFACE@@" + expo_subnets6.append(expo_interface_subnet6) + continue + + conf_subnets6.append(subnet) + expo_subnets6.append(subnet) + + # make copies of each config + expo_keav6_config = copy.deepcopy(keav6_config) + conf_keav6_config = copy.deepcopy(keav6_config) + + # Building specific files - expo + expo_keav6_config["Dhcp6"]["subnet6"] = expo_subnets6 + + with open(f"{outputdir}/dhcp6-server-expo.conf", "w") as f: + f.write(json.dumps(expo_keav6_config, indent=2)) + + # Building specific files - conf + conf_keav6_config["Dhcp6"]["subnet6"] = conf_subnets6 + + with open(f"{outputdir}/dhcp6-server-conf.conf", "w") as f: + f.write(json.dumps(conf_keav6_config, indent=2)) def generatepromconfigs(switches, pis, aps, outputdir): From 1339f97bc82ecdcea96f00dfd5d79fdf0bc31861 Mon Sep 17 00:00:00 2001 From: kylerisse Date: Thu, 12 Feb 2026 20:53:39 -0800 Subject: [PATCH 4/4] nixosModules.kea-master: consume building specific v6 subnet configs --- nix/nixos-modules/services/kea-master.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix/nixos-modules/services/kea-master.nix b/nix/nixos-modules/services/kea-master.nix index 23c3a8989..e5d731cab 100644 --- a/nix/nixos-modules/services/kea-master.nix +++ b/nix/nixos-modules/services/kea-master.nix @@ -56,7 +56,7 @@ in let dhcp6PopulateConfig = pkgs.runCommand "replace" { } '' mkdir $out - cp ${pkgs.scale-network.scale-inventory}/config/dhcp6-server.conf $TMP/dhcp6-server.conf + cp ${pkgs.scale-network.scale-inventory}/config/dhcp6-server-${config.scale-network.facts.building}.conf $TMP/dhcp6-server.conf substituteInPlace "$TMP/dhcp6-server.conf" \ --replace-fail '@@SERVERADDRESS@@' '${builtins.head (lib.splitString "/" config.scale-network.facts.ipv6)}' \ --replace-fail '@@INTERFACE@@' '${config.scale-network.facts.eth}'