chore: play with topology generation in graphviz

This commit is contained in:
oddlama 2024-01-08 03:03:59 +01:00
parent fbab6415ca
commit 714dec1c33
No known key found for this signature in database
GPG key ID: 14EFE510775FE39A
6 changed files with 321 additions and 99 deletions

View file

@ -1,85 +0,0 @@
{
config,
lib,
nodes,
...
}: let
inherit
(lib)
attrNames
concatMap
getAttrFromPath
mkMerge
mkOption
optionals
types
;
nodeName = config.node.name;
in {
options.d2diag.text = mkOption {
# TODO readonly, _text
description = "TODO";
type = types.lines;
};
options.d2diag.services = mkOption {
description = "TODO";
type = types.attrsOf (types.submodule {
options = {
};
});
};
config = {
d2diag.text =
''
${nodeName}: ${nodeName} {
disks: Disks {
shape: sql_table
${lib.concatLines (map (x: "${x}: 8TB") (lib.attrNames config.disko.devices.disk))}
}
net: Interfaces {
shape: sql_table
${lib.concatLines (lib.mapAttrsToList (n: v: ''${n}: ${v.mac}'') (config.repo.secrets.local.networking.interfaces or {lan.mac = "?";}))}
}
''
+ (lib.optionalString (config.guests != {}) ''
guests: {
${
lib.concatLines (
lib.flip lib.mapAttrsToList config.guests (
guestName: guestDef:
(
if guestDef.backend == "microvm"
then config.microvm.vms.${guestName}.config
else config.containers.${guestName}.nixosConfiguration
)
.config
.d2diag
.text
)
)
}
}
${
lib.concatLines (
lib.flip lib.mapAttrsToList config.guests (
guestName: guestDef: "net.lan -> guests.${(
if guestDef.backend == "microvm"
then config.microvm.vms.${guestName}.config
else config.containers.${guestName}.nixosConfiguration
)
.config
.node
.name}.net.lan"
)
)
}
'')
+ ''
}
'';
};
}

View file

@ -41,7 +41,7 @@
./wireguard-proxy.nix
./wireguard.nix
./d2diag.nix
./topology.nix
];
nixpkgs.overlays = [

View file

@ -72,6 +72,8 @@ in {
};
networking.renameInterfacesByMac.${guestCfg.networking.mainLinkName} = guestCfg.microvm.mac;
systemd.network.networks."10-${guestCfg.networking.mainLinkName}".matchConfig.MACAddress = guestCfg.microvm.mac;
systemd.network.networks."10-${guestCfg.networking.mainLinkName}".matchConfig = mkForce {
MACAddress = guestCfg.microvm.mac;
};
};
}

126
modules/topology.nix Normal file
View file

@ -0,0 +1,126 @@
{
config,
lib,
...
}: let
inherit
(lib)
attrNames
concatMap
flip
filterAttrs
getAttrFromPath
mapAttrs
mapAttrs'
mapAttrsToList
mkMerge
mkOption
nameValuePair
optionals
types
;
in {
options.topology = {
id = mkOption {
description = ''
The attribute name in nixosConfigurations corresponding to this host.
Please overwrite with a unique identifier if your hostnames are not
unique or don't reflect the name you use to refer to that node.
'';
type = types.str;
};
guests = mkOption {
description = "TODO guests ids (topology.id)";
type = types.listOf types.str;
default = [];
};
type = mkOption {
description = "TODO";
type = types.enum ["normal" "microvm" "nixos-container"];
default = "normal";
};
interfaces = mkOption {
description = "TODO";
type = types.attrsOf (types.submodule (submod: {
options = {
name = mkOption {
description = "The name of this interface";
type = types.str;
readOnly = true;
default = submod.config._module.args.name;
};
mac = mkOption {
description = "The MAC address of this interface, if known.";
type = types.nullOr types.str;
default = null;
};
addresses = mkOption {
description = "The configured address(es), or a descriptive string (like DHCP).";
type = types.listOf types.str;
};
};
}));
default = {};
};
disks = mkOption {
type = types.attrsOf (types.submodule (submod: {
options = {
name = mkOption {
description = "The name of this disk";
type = types.str;
readOnly = true;
default = submod.config._module.args.name;
};
};
}));
default = {};
};
};
config.topology = mkMerge [
{
################### TODO user config! #################
id = config.node.name;
################### END user config #################
guests =
flip mapAttrsToList (config.microvm.vms or {})
(_: vmCfg: vmCfg.config.config.topology.id);
# TODO: container
disks =
flip mapAttrs (config.disko.devices.disk or {})
(_: _: {});
# TODO: microvm shares
# TODO: container shares
interfaces = let
isNetwork = netDef: (netDef.matchConfig != {}) && (netDef.address != [] || netDef.DHCP != null);
macsByName = mapAttrs' (flip nameValuePair) (config.networking.renameInterfacesByMac or {});
netNameFor = netName: netDef:
if netDef ? matchConfig.Name
then netDef.matchConfig.Name
else if netDef ? matchConfig.MACAddress && macsByName ? ${netDef.matchConfig.MACAddress}
then macsByName.${netDef.matchConfig.MACAddress}
else lib.trace "Could not derive network name for systemd network ${netName} on host ${config.node.name}, using unit name as fallback." netName;
netMACFor = netDef:
if netDef ? matchConfig.MACAddress
then netDef.matchConfig.MACAddress
else null;
networks = filterAttrs (_: isNetwork) (config.systemd.network.networks or {});
in
flip mapAttrs' networks (netName: netDef:
nameValuePair (netNameFor netName netDef) {
mac = netMACFor netDef;
addresses =
if netDef.address != []
then netDef.address
else ["DHCP"];
});
# TODO: for each nftable zone show open ports
}
];
}