photoncloud-monorepo/nix/modules/plasmacloud-network.nix
centra ce4bab07d6
Some checks failed
Nix CI / filter (push) Failing after 1s
Nix CI / gate () (push) Has been skipped
Nix CI / gate (shared crates) (push) Has been skipped
Nix CI / build () (push) Has been skipped
Nix CI / ci-status (push) Failing after 1s
fiberlb: add native BGP speaker and VM smoke test
2026-03-30 16:13:14 +09:00

125 lines
3.5 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.plasmacloud.network;
clusterCfg = config.plasmacloud.cluster;
# BGP peer type for FiberLB
bgpPeerType = types.submodule {
options = {
address = mkOption {
type = types.str;
description = "Peer IP address (ToR switch, upstream router)";
example = "192.168.1.1";
};
asn = mkOption {
type = types.int;
description = "Peer AS number";
example = 65001;
};
description = mkOption {
type = types.str;
default = "";
description = "Human-readable peer description";
example = "ToR switch rack1";
};
};
};
in {
options.plasmacloud.network = {
fiberlbBgp = {
enable = mkEnableOption "FiberLB BGP VIP advertisement";
vips = mkOption {
type = types.listOf types.str;
default = [];
description = "Legacy static VIP hints. FiberLB native BGP ignores this list and advertises active load balancer VIPs dynamically.";
example = [ "203.0.113.10/32" "203.0.113.11/32" ];
};
peers = mkOption {
type = types.listOf bgpPeerType;
default = [];
description = "BGP peers (ToR switches, upstream routers)";
example = literalExpression ''
[
{ address = "192.168.1.1"; asn = 65001; description = "ToR switch rack1"; }
{ address = "192.168.1.2"; asn = 65001; description = "ToR switch rack2"; }
]
'';
};
routerId = mkOption {
type = types.nullOr types.str;
default = null;
description = "BGP router ID (auto-detected from primary IP if null)";
};
};
prismnetIntegration = {
enable = mkEnableOption "PrismNET OVN integration";
};
};
config = mkMerge [
# FiberLB BGP configuration
(mkIf cfg.fiberlbBgp.enable {
# Assertions
assertions = [
{
assertion = clusterCfg.bgp.asn > 0;
message = "plasmacloud.cluster.bgp.asn must be configured for FiberLB BGP";
}
{
assertion = (length cfg.fiberlbBgp.peers) > 0;
message = "plasmacloud.network.fiberlbBgp.peers must contain at least one BGP peer";
}
{
assertion = config.services.fiberlb.enable or false;
message = "plasmacloud.network.fiberlbBgp.enable requires services.fiberlb.enable";
}
];
services.fiberlb.bgp = {
enable = true;
localAs = clusterCfg.bgp.asn;
routerId =
if cfg.fiberlbBgp.routerId != null
then cfg.fiberlbBgp.routerId
else
let
hostname = config.networking.hostName;
node = clusterCfg.nodes.${hostname} or null;
in
if node != null then node.ip else "127.0.0.1";
peers = cfg.fiberlbBgp.peers;
};
})
# PrismNET OVN integration
(mkIf cfg.prismnetIntegration.enable {
# Enable OVN Controller
virtualisation.switch.enable = true;
virtualisation.ovn = {
enable = true;
controller = {
enable = true;
# Use Geneve encapsulation to avoid VXLAN VNI limitations and allow richer metadata
encapType = "geneve";
# Auto-detect IP from cluster config
encapIp =
let
hostname = config.networking.hostName;
node = clusterCfg.nodes.${hostname} or null;
in
if node != null then node.ip else "127.0.0.1";
};
};
})
];
}