1
1
Fork 1
mirror of https://github.com/oddlama/nix-config.git synced 2025-10-10 14:50:40 +02:00

chore: move topology to subfolder

This commit is contained in:
oddlama 2024-03-14 13:07:05 +01:00
parent 76ec1d9c51
commit fd0069c626
No known key found for this signature in database
GPG key ID: 14EFE510775FE39A
5 changed files with 3 additions and 2 deletions

1
topology/default.nix Normal file
View file

@ -0,0 +1 @@
import ./render.nix

157
topology/module.nix Normal file
View file

@ -0,0 +1,157 @@
{
config,
lib,
...
}: let
inherit
(lib)
flip
filterAttrs
mapAttrs
mapAttrs'
mapAttrsToList
mkMerge
mkOption
nameValuePair
types
;
in {
options.topology = {
id = mkOption {
description = ''
The attribute name in the given `nodes` which corresponds to this host.
Please overwrite it with a unique identifier if your hostnames are not
unique or don't reflect the name you use to refer to that node.
'';
default = config.networking.hostName;
# TODO ensure unique across the board
type = types.str;
};
type = mkOption {
description = "TODO";
default = "normal";
type = types.enum ["normal" "microvm" "nixos-container"];
};
guests = mkOption {
description = "TODO guests ids (topology.node.<name>.id) ensure exists";
default = [];
type = types.listOf types.str;
};
disks = mkOption {
default = {};
type = types.attrsOf (types.submodule (submod: {
options = {
name = mkOption {
description = "The name of this disk";
default = submod.config._module.args.name;
readOnly = true;
type = types.str;
};
};
}));
};
interfaces = mkOption {
description = "TODO";
default = {};
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.";
default = null;
type = types.nullOr types.str;
};
addresses = mkOption {
description = "The configured address(es), or a descriptive string (like DHCP).";
type = types.listOf types.str;
};
network = mkOption {
description = ''
The global name of the attached/spanned network.
If this is given, this interface can be shown in the network graph.
'';
default = null;
type = types.nullOr types.str;
};
};
}));
};
firewallRules = mkOption {
description = "TODO";
default = {};
type = types.attrsOf (types.submodule (submod: {
options = {
name = mkOption {
description = "The name of this firewall rule";
type = types.str;
readOnly = true;
default = submod.config._module.args.name;
};
contents = mkOption {
description = "A human readable summary of this rule's effects";
type = types.lines;
};
};
}));
};
};
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: zfs pools from disko / fileSystems
# TODO: microvm shares
# TODO: container shares
# TODO: OCI containers shares
interfaces = let
isNetwork = netDef: (netDef.matchConfig != {}) && (netDef.address != [] || netDef.DHCP != null);
macsByName = mapAttrs' (flip nameValuePair) (config.networking.renameInterfacesByMac or {});
netNameFor = netName: netDef:
netDef.matchConfig.Name
or (
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: netDef.matchConfig.MACAddress or 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
}
];
}

82
topology/render.nix Normal file
View file

@ -0,0 +1,82 @@
{
pkgs,
# deadnix: skip
renderer ? "graphviz",
nixosConfigurations,
}: let
inherit
(pkgs.lib)
any
attrNames
attrValues
concatLines
concatStringsSep
elem
escapeXML
flip
filterAttrs
imap0
mapAttrs'
nameValuePair
mapAttrsToList
optional
optionalAttrs
optionalString
;
# global = {
# # global entities;
# };
# asjson = builtins.toFile "topology.dot" (
# builtins.toJSON (map (x: x.config.topology) (attrValues nixosConfigurations))
# );
colors.base00 = "#101419";
colors.base01 = "#171B20";
colors.base02 = "#21262e";
colors.base03 = "#242931";
colors.base03b = "#353c48";
colors.base04 = "#485263";
colors.base05 = "#b6beca";
colors.base06 = "#dee1e6";
colors.base07 = "#e3e6eb";
colors.base08 = "#e05f65";
colors.base09 = "#f9a872";
colors.base0A = "#f1cf8a";
colors.base0B = "#78dba9";
colors.base0C = "#74bee9";
colors.base0D = "#70a5eb";
colors.base0E = "#c68aee";
colors.base0F = "#9378de";
nodesById = mapAttrs' (_: node: nameValuePair node.config.topology.id node) nixosConfigurations;
isGuestOfAny = node: any (x: elem node x.config.topology.guests) (attrValues nodesById);
rootNodes = filterAttrs (n: _: !(isGuestOfAny n)) nodesById;
toD2 = node: let
topo = node.config.topology;
in ''
${topo.id}: |md
# ${topo.id}
## Guests:
${concatLines (map (x: "- ${x}") topo.guests)}
## Disks:
${concatLines (mapAttrsToList (_: v: "- ${v.name}") topo.disks)}
## Interfaces:
${concatLines (mapAttrsToList (_: v: "- ${v.name}, mac ${toString v.mac}, addrs ${toString v.addresses}, network ${toString v.network}") topo.interfaces)}
## Firewall Zones:
${concatLines (mapAttrsToList (_: v: "- ${v.name}, mac ${toString v.mac}, addrs ${toString v.addresses}, network ${toString v.network}") topo.firewallRules)}
|
'';
d2ForNodes = mapAttrs' (_: node: nameValuePair node.config.topology.id (toD2 node)) nodesById;
in
pkgs.writeText "topology.d2" ''
${concatLines (map (x: d2ForNodes.${x}) (attrNames rootNodes))}
''