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:
parent
76ec1d9c51
commit
fd0069c626
5 changed files with 3 additions and 2 deletions
1
topology/default.nix
Normal file
1
topology/default.nix
Normal file
|
@ -0,0 +1 @@
|
|||
import ./render.nix
|
157
topology/module.nix
Normal file
157
topology/module.nix
Normal 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
82
topology/render.nix
Normal 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))}
|
||||
''
|
Loading…
Add table
Add a link
Reference in a new issue