Includes all pending changes needed for nixos-anywhere: - fiberlb: L7 policy, rule, certificate types - deployer: New service for cluster management - nix-nos: Generic network modules - Various service updates and fixes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
193 lines
5 KiB
Nix
193 lines
5 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
with lib;
|
|
|
|
let
|
|
cfg = config.nix-nos.network;
|
|
ifaceCfg = config.nix-nos.interfaces;
|
|
|
|
interfaceType = types.submodule {
|
|
options = {
|
|
name = mkOption {
|
|
type = types.str;
|
|
description = "Interface name (e.g., eth0, ens3)";
|
|
};
|
|
|
|
addresses = mkOption {
|
|
type = types.listOf types.str;
|
|
default = [];
|
|
description = "List of IP addresses in CIDR notation";
|
|
example = [ "192.168.1.10/24" "2001:db8::1/64" ];
|
|
};
|
|
|
|
mtu = mkOption {
|
|
type = types.nullOr types.int;
|
|
default = null;
|
|
description = "Maximum Transmission Unit (MTU) size";
|
|
example = 9000;
|
|
};
|
|
|
|
vlan = mkOption {
|
|
type = types.nullOr types.int;
|
|
default = null;
|
|
description = "VLAN ID if this is a VLAN interface";
|
|
};
|
|
};
|
|
};
|
|
|
|
# New systemd-networkd based interface type
|
|
systemdInterfaceType = types.submodule {
|
|
options = {
|
|
addresses = mkOption {
|
|
type = types.listOf types.str;
|
|
default = [];
|
|
description = "IP addresses with CIDR (e.g., 192.168.1.10/24)";
|
|
example = [ "192.168.1.10/24" "2001:db8::1/64" ];
|
|
};
|
|
|
|
gateway = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = "Default gateway for this interface";
|
|
example = "192.168.1.1";
|
|
};
|
|
|
|
dns = mkOption {
|
|
type = types.listOf types.str;
|
|
default = [];
|
|
description = "DNS servers";
|
|
example = [ "8.8.8.8" "8.8.4.4" ];
|
|
};
|
|
|
|
dhcp = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = "Enable DHCP on this interface";
|
|
};
|
|
|
|
mtu = mkOption {
|
|
type = types.nullOr types.int;
|
|
default = null;
|
|
description = "MTU size";
|
|
example = 1500;
|
|
};
|
|
};
|
|
};
|
|
|
|
in {
|
|
options.nix-nos.interfaces = mkOption {
|
|
type = types.attrsOf systemdInterfaceType;
|
|
default = {};
|
|
description = "Network interface configurations using systemd-networkd";
|
|
example = literalExpression ''
|
|
{
|
|
eth0 = {
|
|
addresses = [ "192.168.1.10/24" ];
|
|
gateway = "192.168.1.1";
|
|
dns = [ "8.8.8.8" "8.8.4.4" ];
|
|
};
|
|
eth1 = {
|
|
dhcp = true;
|
|
};
|
|
}
|
|
'';
|
|
};
|
|
|
|
options.nix-nos.network = {
|
|
interfaces = mkOption {
|
|
type = types.listOf interfaceType;
|
|
default = [];
|
|
description = "Network interface configurations";
|
|
example = literalExpression ''
|
|
[
|
|
{
|
|
name = "eth0";
|
|
addresses = [ "10.0.0.10/24" ];
|
|
mtu = 1500;
|
|
}
|
|
{
|
|
name = "eth0.100";
|
|
addresses = [ "192.168.100.1/24" ];
|
|
vlan = 100;
|
|
}
|
|
]
|
|
'';
|
|
};
|
|
|
|
enableIpForwarding = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = "Enable IP forwarding (routing)";
|
|
};
|
|
};
|
|
|
|
config = mkMerge [
|
|
# Map nix-nos.interfaces to systemd-networkd
|
|
(mkIf (ifaceCfg != {}) {
|
|
assertions = [
|
|
{
|
|
assertion = all (name: iface:
|
|
(iface.dhcp || (length iface.addresses) > 0)
|
|
) (mapAttrsToList nameValuePair ifaceCfg);
|
|
message = "nix-nos.interfaces: Each interface must have either dhcp=true or at least one address";
|
|
}
|
|
];
|
|
|
|
systemd.network.enable = true;
|
|
systemd.network.networks = mapAttrs' (name: iface: nameValuePair "10-${name}" {
|
|
matchConfig.Name = name;
|
|
|
|
address = iface.addresses;
|
|
|
|
gateway = optional (iface.gateway != null) iface.gateway;
|
|
|
|
dns = iface.dns;
|
|
|
|
DHCP = if iface.dhcp then "yes" else "no";
|
|
|
|
linkConfig = optionalAttrs (iface.mtu != null) {
|
|
MTUBytes = toString iface.mtu;
|
|
};
|
|
}) ifaceCfg;
|
|
})
|
|
|
|
# Legacy: Map nix-nos.network.interfaces to NixOS networking.interfaces
|
|
(mkIf config.nix-nos.enable {
|
|
networking.interfaces = mkMerge (
|
|
map (iface: {
|
|
${iface.name} = {
|
|
ipv4.addresses = map (addr:
|
|
let
|
|
parts = splitString "/" addr;
|
|
ip = elemAt parts 0;
|
|
prefixLength = toInt (elemAt parts 1);
|
|
in {
|
|
address = ip;
|
|
inherit prefixLength;
|
|
}
|
|
) (filter (addr: ! (hasInfix ":" addr)) iface.addresses);
|
|
|
|
ipv6.addresses = map (addr:
|
|
let
|
|
parts = splitString "/" addr;
|
|
ip = elemAt parts 0;
|
|
prefixLength = toInt (elemAt parts 1);
|
|
in {
|
|
address = ip;
|
|
inherit prefixLength;
|
|
}
|
|
) (filter (addr: hasInfix ":" addr) iface.addresses);
|
|
|
|
mtu = mkIf (iface.mtu != null) iface.mtu;
|
|
};
|
|
}) cfg.interfaces
|
|
);
|
|
|
|
# Enable IP forwarding if requested
|
|
boot.kernel.sysctl = mkIf cfg.enableIpForwarding {
|
|
"net.ipv4.ip_forward" = 1;
|
|
"net.ipv6.conf.all.forwarding" = 1;
|
|
};
|
|
})
|
|
];
|
|
}
|