pkgs/network-graphs: init

This commit is contained in:
Astro 2021-11-06 19:47:34 +01:00
parent 2deaff488f
commit f156ab6f05
2 changed files with 165 additions and 1 deletions

View File

@ -25,6 +25,8 @@ let
) (builtins.attrNames config.site.hosts)
);
network-graphs = pkgs.callPackage ./network-graphs.nix { inherit config; };
mkRootfs = hostName:
self.nixosConfigurations.${hostName}.config.system.build.toplevel;
@ -63,6 +65,6 @@ let
inherit pkgs;
};
in
salt-pillars // rootfs-packages // vm-packages // device-templates // starlink // {
salt-pillars // rootfs-packages // vm-packages // device-templates // network-graphs // starlink // {
inherit export-openwrt-models export-config dns-slaves;
}

162
nix/pkgs/network-graphs.nix Normal file
View File

@ -0,0 +1,162 @@
{ lib, config, runCommand, graphviz, ... }:
let
netColor = net:
if net == "core"
then "grey"
else if net == "mgmt"
then "brown"
else if net == "c3d2"
then "orange"
else if net == "serv"
then "orange2"
else if net == "pub"
then "green"
else if builtins.match "up.+" net != null
then "red"
else if builtins.match "priv.+" net != null
then "blue"
else "black";
dedupLinks = links:
builtins.attrValues (
builtins.foldl' (result: { pair, attrs ? {}, startLabel ? "" }:
let
peer1 = builtins.elemAt pair 0;
peer2 = builtins.elemAt pair 1;
sorted =
if peer1 < peer2
then { from = peer1; to = peer2; }
else { from = peer2; to = peer1; };
key = with sorted; "${from} ${to}";
prevAttrs =
if result ? ${key}
then result.${key}.attrs
else {};
newAttrs = attrs // (
if peer1 < peer2
then { taillabel = startLabel; }
else { headlabel = startLabel; }
);
in result // {
"${key}" = {
inherit (sorted) from to;
attrs = prevAttrs // newAttrs;
};
}
) {} links
);
toDot = { nodes, links, ... }: ''
digraph {
graph [splines=ortho, nodesep=64]
node []
edge [arrowhead=none, labelfontsize=8]
${lib.concatMapStrings (name:
let
nodeAttrs = nodes.${name};
in ''
"${name}" [${lib.concatMapStringsSep ", " (attr:
let
value = nodeAttrs.${attr};
in
if builtins.isString value
then "${attr}=\"${value}\""
else "${attr}=${toString value}"
) (builtins.attrNames nodeAttrs)}]
'') (builtins.attrNames nodes)}
${lib.concatMapStrings ({ from, to, attrs }: ''
"${from}" -> "${to}" [${lib.concatMapStringsSep ", " (attr:
let
value = attrs.${attr};
in
if builtins.isString value
then "${attr}=\"${value}\""
else "${attr}=${toString value}"
) (builtins.attrNames attrs)}]
'') (dedupLinks links)}
}
'';
renderGraph = args@{ name, engine, ... }:
runCommand "${name}.png" {
src = builtins.toFile "${name}.dot" (
toDot args
);
} ''
echo $src
${graphviz}/bin/${engine} -Tpng $src > $out
'';
in rec {
# Layer 2
physical-graph = renderGraph {
name = "physical";
engine = "fdp";
nodes =
builtins.mapAttrs (_: { role, ... }: {
shape = {
switch = "box";
server = "house";
container = "oval";
ap = "doubleoctagon";
client = "doublecircle";
}.${role};
}) (
lib.filterAttrs (_: { links, ... }:
links != {}
) config.site.hosts
);
links =
builtins.concatMap (hostName:
map (link: {
pair = [ hostName link ];
startLabel = lib.concatStringsSep ","
config.site.hosts.${hostName}.links.${link}.ports;
}) (
builtins.filter (link:
config.site.hosts ? ${link}
) (builtins.attrNames config.site.hosts.${hostName}.links)
)
) (builtins.attrNames config.site.hosts);
};
# Layer 3
logical-graph =
let
containers =
lib.filterAttrs (_: { isRouter, role, ... }:
role == "container"
) config.site.hosts;
in
renderGraph {
name = "logical";
engine = "sfdp";
nodes =
builtins.foldl' (result: hostName:
result // {
"${hostName}".shape = "box";
} // builtins.mapAttrs (_: _: {
shape = "circle";
}) containers.${hostName}.interfaces
) {} (builtins.attrNames containers);
links =
builtins.concatMap (hostName:
map (net: {
pair = [ hostName net ];
attrs.color = netColor net;
}) (builtins.attrNames containers.${hostName}.interfaces)
) (builtins.attrNames containers);
};
network-graphs = runCommand "network-graphs" {} ''
DIR=$out/share/doc/zentralwerk
mkdir -p $DIR
ln -s ${physical-graph} $DIR/physical.png
ln -s ${logical-graph} $DIR/logical.png
mkdir -p $out/nix-support
echo doc image $DIR/physical.png >> $out/nix-support/hydra-build-products
echo doc image $DIR/logical.png >> $out/nix-support/hydra-build-products
'';
}