refactor(network): use address registry #60

Merged
alexion merged 1 commits from impl/address-registry-migration into main 2026-08-23 23:31:10 -04:00
5 changed files with 55 additions and 94 deletions

View File

@@ -291,51 +291,63 @@
touch $out touch $out
''; '';
network-endpoint-fleet-registry = address-registry =
let let
hostEndpointConfig = hostAddressConfig =
lib.nixosSystem { lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
specialArgs.my = self.lib; specialArgs.my = self.lib;
modules = [ modules = [
./modules/network.nix self.lib.registry.module
{ {
modules.network.endpoint.address = "10.23.50.146"; registry.address.neogaia.self = "10.23.50.146";
system.stateVersion = "26.11";
} }
]; ];
}; };
guestEndpointConfig = guestAddressConfig =
lib.nixosSystem { lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
specialArgs.my = self.lib; specialArgs.my = self.lib;
modules = [ modules = [
inputs.sops-nix.nixosModules.sops inputs.sops-nix.nixosModules.sops
self.lib.registry.module
./modules/network.nix ./modules/network.nix
./modules/reverse-proxy.nix ./modules/reverse-proxy.nix
(self.lib.guest { name = "copyparty"; }) (self.lib.guest { name = "copyparty"; })
{ {
networking.hostName = "pikachu";
modules.network.vlans = [ 20 ]; modules.network.vlans = [ 20 ];
guests.copyparty = { guests.copyparty = {
enable = true; enable = true;
vlan = 20; vlan = 20;
endpoint.address = "10.23.20.126"; address = "10.23.20.126";
}; };
system.stateVersion = "26.11";
} }
]; ];
}; };
registry = self.lib.registry.collect {
hosts = {
neogaia = hostAddressConfig;
pikachu = guestAddressConfig;
};
};
fleetEndpoints = self.lib.networkEndpoints.collectFleetEndpoints { fleetEndpoints = self.lib.networkEndpoints.collectFleetEndpoints {
neogaia = hostEndpointConfig; neogaia = hostAddressConfig;
pikachu = guestEndpointConfig; pikachu = guestAddressConfig;
}; };
in in
pkgs.runCommand "network-endpoint-fleet-registry-check" { } '' pkgs.runCommand "address-registry-check" { } ''
${ ${
lib.optionalString ( lib.optionalString (
!( !(
fleetEndpoints.neogaia.address == "10.23.50.146" registry.address.neogaia.self == "10.23.50.146"
&& registry.address.pikachu.copyparty == "10.23.20.126"
&& fleetEndpoints.neogaia.address == "10.23.50.146"
&& fleetEndpoints."pikachu-copyparty".address == "10.23.20.126" && fleetEndpoints."pikachu-copyparty".address == "10.23.20.126"
&& !(fleetEndpoints ? pikachu) && !(fleetEndpoints ? pikachu)
&& guestEndpointConfig.config.containers.copyparty.config.systemd.network.networks."20-eth0".networkConfig.DHCP == "yes" && guestAddressConfig.config.containers.copyparty.config.systemd.network.networks."20-eth0".networkConfig.DHCP == "yes"
) )
) "exit 1" ) "exit 1"
} }
@@ -393,9 +405,10 @@
system = "x86_64-linux"; system = "x86_64-linux";
specialArgs.my = self.lib; specialArgs.my = self.lib;
modules = [ modules = [
./modules/network.nix self.lib.registry.module
{ {
modules.network.endpoint.address = "10.23.50.146"; registry.address.worker.self = "10.23.50.146";
system.stateVersion = "26.11";
} }
]; ];
}; };
@@ -420,6 +433,7 @@
specialArgs.my = self.lib; specialArgs.my = self.lib;
modules = [ modules = [
inputs.sops-nix.nixosModules.sops inputs.sops-nix.nixosModules.sops
self.lib.registry.module
./modules/network.nix ./modules/network.nix
./modules/reverse-proxy.nix ./modules/reverse-proxy.nix
(self.lib.guest { name = "files"; }) (self.lib.guest { name = "files"; })
@@ -429,13 +443,14 @@
guests.files = { guests.files = {
enable = true; enable = true;
vlan = 20; vlan = 20;
endpoint.address = "10.23.20.126"; address = "10.23.20.126";
reverseProxy = { reverseProxy = {
enable = true; enable = true;
host = "files.alexion.dev"; host = "files.alexion.dev";
port = 3923; port = 3923;
}; };
}; };
system.stateVersion = "26.11";
} }
]; ];
}; };

View File

@@ -1,4 +1,9 @@
{ config, pkgs, ... }: {
config,
pkgs,
registry,
...
}:
# pikachu — AZW ME Pro server. # pikachu — AZW ME Pro server.
# Disk layout is in ./disk.nix. # Disk layout is in ./disk.nix.
# `fileSystems` for the root disk are derived from it. # `fileSystems` for the root disk are derived from it.
@@ -79,7 +84,7 @@
vlan = 20; vlan = 20;
mac = "BC:24:11:C1:CD:28"; mac = "BC:24:11:C1:CD:28";
dataPath = "/pikachu/data/actualbudget"; dataPath = "/pikachu/data/actualbudget";
endpoint.address = "10.23.20.42"; address = "10.23.20.42";
reverseProxy = { reverseProxy = {
enable = true; enable = true;
host = "budget.alexion.dev"; host = "budget.alexion.dev";
@@ -91,7 +96,7 @@
enable = true; enable = true;
vlan = 20; vlan = 20;
mac = "02:98:64:5a:07:4f"; mac = "02:98:64:5a:07:4f";
endpoint.address = "10.23.20.109"; address = "10.23.20.109";
}; };
guests.copyparty = { guests.copyparty = {
@@ -99,12 +104,12 @@
vlan = 20; vlan = 20;
mac = "02:23:20:39:23:01"; mac = "02:23:20:39:23:01";
statePath = "/pikachu/data/copyparty"; statePath = "/pikachu/data/copyparty";
endpoint.address = "10.23.20.126"; address = "10.23.20.126";
reverseProxy = { reverseProxy = {
enable = true; enable = true;
host = "files.alexion.dev"; host = "files.alexion.dev";
port = 3923; port = 3923;
trustedSources = [ "${config.modules.network.endpoints."reverse-proxy".address}/32" ]; trustedSources = [ "${registry.address.${config.networking.hostName}."reverse-proxy"}/32" ];
}; };
volumes = { volumes = {
"/inbox" = { "/inbox" = {

View File

@@ -78,8 +78,7 @@ let
systemd.network.networks."20-eth0" = { systemd.network.networks."20-eth0" = {
matchConfig.Name = "eth0"; matchConfig.Name = "eth0";
linkConfig.MACAddress = cfg.mac; linkConfig.MACAddress = cfg.mac;
networkConfig = lib.mkIf (cfg.address == null) { DHCP = "yes"; }; networkConfig.DHCP = "yes";
address = lib.mkIf (cfg.address != null) [ cfg.address ];
}; };
}; };
}; };
@@ -122,27 +121,15 @@ let
from the guest's namespace path in the locally-administered range. from the guest's namespace path in the locally-administered range.
''; '';
}; };
address = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "10.0.10.5/24";
description = ''
The guest's static address, in CIDR form, on its VLAN. Left null, the
guest takes its address by DHCP, keeping IP management at the router.
'';
};
endpoint = {
address = lib.mkOption { address = lib.mkOption {
type = lib.types.nullOr lib.types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
example = "10.23.20.126"; example = "10.23.20.126";
description = '' description = ''
Expected IP address assigned outside NixOS for this guest's Expected IP address assigned outside NixOS for this guest.
network endpoint. Left null, this guest contributes no endpoint to Left null, this guest contributes no address to the address registry.
the fleet endpoint registry.
''; '';
}; };
};
reverseProxy = reverseProxyRoutes.mkRouteOptions { reverseProxy = reverseProxyRoutes.mkRouteOptions {
subject = "guest route"; subject = "guest route";
enableDefault = false; enableDefault = false;
@@ -290,9 +277,7 @@ let
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
sops.secrets = lib.genAttrs cfg.secrets (_: { }); sops.secrets = lib.genAttrs cfg.secrets (_: { });
modules.network.endpoints.${machineName} = lib.mkIf (cfg.endpoint.address != null) { registry.address.${config.networking.hostName}.${machineName} = lib.mkIf (cfg.address != null) cfg.address;
inherit (cfg.endpoint) address;
};
modules.reverse-proxy.routes.${machineName} = lib.mkIf cfg.reverseProxy.enable ( modules.reverse-proxy.routes.${machineName} = lib.mkIf cfg.reverseProxy.enable (
reverseProxyRoutes.routeFields ( reverseProxyRoutes.routeFields (

View File

@@ -1,42 +1,20 @@
{ lib }: { lib }:
# TODO: Remove this compatibility bridge when route backend resolution reads registry.address directly.
let let
endpointOptions = { endpointFields = address: { inherit address; };
address = lib.mkOption {
type = lib.types.str;
example = "10.23.20.126";
description = "Expected IP address assigned outside NixOS for this network endpoint.";
};
};
endpointType = lib.types.submodule { collectFleetEndpoints = hosts:
options = endpointOptions;
};
endpointFields = endpoint: {
inherit (endpoint) address;
};
collectFleetEndpoints =
hosts:
lib.concatMapAttrs ( lib.concatMapAttrs (
hostName: host: hostName: host:
lib.mapAttrs' (
entryName: address:
let let
cfg = host.config.modules.network; endpointName = if entryName == "self" then hostName else "${hostName}-${entryName}";
hostEndpoint = lib.optionalAttrs (cfg.endpoint.address != null) {
${hostName} = endpointFields cfg.endpoint;
};
guestEndpoints = lib.mapAttrs' (
endpointName: endpoint: lib.nameValuePair "${hostName}-${endpointName}" (endpointFields endpoint)
) cfg.endpoints;
in in
hostEndpoint // guestEndpoints lib.nameValuePair endpointName (endpointFields address)
) (host.config.registry.address.${hostName} or { })
) hosts; ) hosts;
in in
{ {
inherit inherit collectFleetEndpoints endpointFields;
collectFleetEndpoints
endpointFields
endpointOptions
endpointType
;
} }

View File

@@ -43,28 +43,6 @@ in
''; '';
}; };
endpoint = {
address = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "10.23.50.146";
description = ''
Expected IP address assigned outside NixOS for this host's network
endpoint. Left null, this host contributes no host endpoint to the
fleet endpoint registry.
'';
};
};
endpoints = lib.mkOption {
type = lib.types.attrsOf my.networkEndpoints.endpointType;
default = { };
description = ''
Network endpoint declarations contributed by placed workloads on this
host, keyed by their local stable endpoint name.
'';
};
management = { management = {
vlan = lib.mkOption { vlan = lib.mkOption {
type = lib.types.nullOr (lib.types.ints.between 1 4094); type = lib.types.nullOr (lib.types.ints.between 1 4094);