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>
94 lines
2.3 KiB
Nix
94 lines
2.3 KiB
Nix
{ lib }:
|
|
|
|
with lib;
|
|
|
|
rec {
|
|
# Generate systemd network unit files from nix-nos network config
|
|
generateNetworkdConfig = { interfaces }:
|
|
listToAttrs (map (iface: {
|
|
name = "10-${iface.name}";
|
|
value = {
|
|
matchConfig.Name = iface.name;
|
|
networkConfig = {
|
|
DHCP = "no";
|
|
} // optionalAttrs (iface.mtu != null) {
|
|
MTU = toString iface.mtu;
|
|
};
|
|
address = iface.addresses;
|
|
};
|
|
}) interfaces);
|
|
|
|
# Generate BGP peer configurations in a backend-agnostic format
|
|
generateBgpPeers = { asn, routerId, peers }:
|
|
map (peer: {
|
|
inherit (peer) address description;
|
|
inherit asn;
|
|
peerAsn = peer.asn;
|
|
inherit routerId;
|
|
}) peers;
|
|
|
|
# Generate route table entries
|
|
generateRouteTable = { routes }:
|
|
map (route: {
|
|
inherit (route) destination;
|
|
gateway = route.gateway or null;
|
|
interface = route.interface or null;
|
|
metric = route.metric or 100;
|
|
}) routes;
|
|
|
|
# Helper: Convert CIDR to netmask
|
|
cidrToNetmask = cidr:
|
|
let
|
|
parts = splitString "/" cidr;
|
|
prefixLength = toInt (elemAt parts 1);
|
|
|
|
# IPv4 netmask calculation
|
|
masks = {
|
|
"8" = "255.0.0.0";
|
|
"16" = "255.255.0.0";
|
|
"24" = "255.255.255.0";
|
|
"32" = "255.255.255.255";
|
|
};
|
|
in
|
|
masks.${toString prefixLength} or (throw "Unsupported prefix length: ${toString prefixLength}");
|
|
|
|
# Helper: Extract IP from CIDR notation
|
|
cidrToIp = cidr:
|
|
let
|
|
parts = splitString "/" cidr;
|
|
in
|
|
elemAt parts 0;
|
|
|
|
# Helper: Extract prefix length from CIDR notation
|
|
cidrToPrefixLength = cidr:
|
|
let
|
|
parts = splitString "/" cidr;
|
|
in
|
|
toInt (elemAt parts 1);
|
|
|
|
# Validate IP address format
|
|
isValidIpv4 = ip:
|
|
let
|
|
parts = splitString "." ip;
|
|
validOctet = octet:
|
|
let n = toInt octet;
|
|
in n >= 0 && n <= 255;
|
|
in
|
|
(length parts == 4) && all validOctet parts;
|
|
|
|
# Validate IPv6 address (simplified check)
|
|
isValidIpv6 = ip:
|
|
hasInfix ":" ip;
|
|
|
|
# Validate CIDR notation
|
|
isValidCidr = cidr:
|
|
let
|
|
parts = splitString "/" cidr;
|
|
ip = elemAt parts 0;
|
|
prefixLength = toInt (elemAt parts 1);
|
|
in
|
|
(length parts == 2) &&
|
|
(isValidIpv4 ip || isValidIpv6 ip) &&
|
|
(prefixLength >= 0) &&
|
|
(if isValidIpv4 ip then prefixLength <= 32 else prefixLength <= 128);
|
|
}
|