pkgs/network-graphs: init
This commit is contained in:
parent
2deaff488f
commit
f156ab6f05
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
'';
|
||||
}
|
Loading…
Reference in New Issue