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 ];
}; };
}; };
}; };
@@ -125,24 +124,12 @@ let
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.0.10.5/24"; example = "10.23.20.126";
description = '' description = ''
The guest's static address, in CIDR form, on its VLAN. Left null, the Expected IP address assigned outside NixOS for this guest.
guest takes its address by DHCP, keeping IP management at the router. Left null, this guest contributes no address to the address registry.
''; '';
}; };
endpoint = {
address = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "10.23.20.126";
description = ''
Expected IP address assigned outside NixOS for this guest's
network endpoint. Left null, this guest contributes no endpoint to
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:
let lib.mapAttrs' (
cfg = host.config.modules.network; entryName: address:
hostEndpoint = lib.optionalAttrs (cfg.endpoint.address != null) { let
${hostName} = endpointFields cfg.endpoint; endpointName = if entryName == "self" then hostName else "${hostName}-${entryName}";
}; in
guestEndpoints = lib.mapAttrs' ( lib.nameValuePair endpointName (endpointFields address)
endpointName: endpoint: lib.nameValuePair "${hostName}-${endpointName}" (endpointFields endpoint) ) (host.config.registry.address.${hostName} or { })
) cfg.endpoints;
in
hostEndpoint // guestEndpoints
) 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);