feat(network): add fleet endpoint registry #51

Merged
alexion merged 1 commits from impl/network-endpoint-registry into main 2026-08-20 18:43:49 -04:00
5 changed files with 134 additions and 0 deletions

View File

@@ -173,6 +173,57 @@
touch $out
'';
network-endpoint-fleet-registry =
let
hostEndpointConfig =
lib.nixosSystem {
system = "x86_64-linux";
specialArgs.my = self.lib;
modules = [
./modules/network.nix
{
modules.network.endpoint.address = "10.23.50.146";
}
];
};
guestEndpointConfig =
lib.nixosSystem {
system = "x86_64-linux";
specialArgs.my = self.lib;
modules = [
inputs.sops-nix.nixosModules.sops
./modules/network.nix
./modules/reverse-proxy.nix
(self.lib.guest { name = "copyparty"; })
{
modules.network.vlans = [ 20 ];
guests.copyparty = {
enable = true;
vlan = 20;
endpoint.address = "10.23.20.126";
};
}
];
};
fleetEndpoints = self.lib.networkEndpoints.collectFleetEndpoints {
neogaia = hostEndpointConfig;
pikachu = guestEndpointConfig;
};
in
pkgs.runCommand "network-endpoint-fleet-registry-check" { } ''
${
lib.optionalString (
!(
fleetEndpoints.neogaia.address == "10.23.50.146"
&& fleetEndpoints."pikachu-copyparty".address == "10.23.20.126"
&& !(fleetEndpoints ? pikachu)
&& guestEndpointConfig.config.containers.copyparty.config.systemd.network.networks."20-eth0".networkConfig.DHCP == "yes"
)
) "exit 1"
}
touch $out
'';
reverse-proxy-fleet-routes =
let
routeHost =

View File

@@ -14,6 +14,7 @@ let
;
serviceIdentityRegistry = import ./service-identities.nix { inherit lib; };
networkEndpoints = import ./network-endpoints.nix { inherit lib; };
reverseProxyRoutes = import ./reverse-proxy-routes.nix { inherit lib; };
collectNixFiles =
@@ -36,6 +37,7 @@ let
specialArgs = {
inherit inputs self;
my = self.lib;
networkFleetEndpoints = self.lib.networkEndpoints.collectFleetEndpoints self.nixosConfigurations;
reverseProxyFleetRoutes = self.lib.reverseProxyRoutes.collectFleetRoutes self.nixosConfigurations;
};
@@ -85,6 +87,7 @@ in
mkHost
mkHosts
bridgeName
networkEndpoints
reverseProxyRoutes
;

View File

@@ -131,6 +131,18 @@ let
guest takes its address by DHCP, keeping IP management at the router.
'';
};
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 {
subject = "guest route";
enableDefault = false;
@@ -278,6 +290,10 @@ let
config = lib.mkIf cfg.enable {
sops.secrets = lib.genAttrs cfg.secrets (_: { });
modules.network.endpoints.${machineName} = lib.mkIf (cfg.endpoint.address != null) {
inherit (cfg.endpoint) address;
};
modules.reverse-proxy.routes.${machineName} = lib.mkIf cfg.reverseProxy.enable (
reverseProxyRoutes.routeFields cfg.reverseProxy
);

42
lib/network-endpoints.nix Normal file
View File

@@ -0,0 +1,42 @@
{ lib }:
let
endpointOptions = {
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 {
options = endpointOptions;
};
endpointFields = endpoint: {
inherit (endpoint) address;
};
collectFleetEndpoints =
hosts:
lib.concatMapAttrs (
hostName: host:
let
cfg = host.config.modules.network;
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
hostEndpoint // guestEndpoints
) hosts;
in
{
inherit
collectFleetEndpoints
endpointFields
endpointOptions
endpointType
;
}

View File

@@ -43,6 +43,28 @@ 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 = {
vlan = lib.mkOption {
type = lib.types.nullOr (lib.types.ints.between 1 4094);