diff --git a/dlink-dgs1016d.png b/dlink-dgs1016d.png new file mode 100644 index 0000000..09f1279 Binary files /dev/null and b/dlink-dgs1016d.png differ diff --git a/dlink-dgs105.png b/dlink-dgs105.png new file mode 100644 index 0000000..4dddecd Binary files /dev/null and b/dlink-dgs105.png differ diff --git a/flake.nix b/flake.nix index 1a078cb..5ea13f1 100644 --- a/flake.nix +++ b/flake.nix @@ -187,30 +187,12 @@ renderer = "elk"; nixosConfigurations = self.nodes; - nodes.fritzbox = { - name = "FritzBox"; - deviceType = "router"; - hardware.image = ./fritzbox.png; - # interfaces.wan0.network = "internet"; - interfaces.wan0 = {}; - interfaces.lan0.physicalConnections = [ - { - node = "ward"; - interface = "wan"; - } - { - node = "sire"; - interface = "lan"; - } - ]; - }; - nodes.internet = { name = "Internet"; deviceType = "internet"; hardware.image = ./cloud.svg; - # interfaces.wan0.network = "internet"; - interfaces.wan0.physicalConnections = [ + # interfaces.eth0.network = "internet"; + interfaces.eth0.physicalConnections = [ { node = "fritzbox"; interface = "wan0"; @@ -222,6 +204,63 @@ ]; }; + nodes.fritzbox = { + name = "FritzBox"; + deviceType = "router"; + hardware.image = ./fritzbox.png; + # interfaces.wan0.network = "internet"; + interfaces.wan0 = {}; + interfaces.eth0.physicalConnections = [ + { + node = "ward"; + interface = "wan"; + } + ]; + }; + + nodes.switch-attic = { + name = "Switch Attic"; + deviceType = "switch"; + hardware.image = ./dlink-dgs1016d.png; + interfaces.eth0.physicalConnections = [ + { + node = "ward"; + interface = "lan"; + } + ]; + interfaces.eth1.physicalConnections = [ + { + node = "sire"; + interface = "lan"; + } + ]; + interfaces.eth2 = {}; + }; + + nodes.switch-bedroom-1 = { + name = "Switch Bedroom 1"; + deviceType = "switch"; + hardware.image = ./dlink-dgs105.png; + interfaces.eth0.physicalConnections = [ + { + node = "switch-attic"; + interface = "eth2"; + } + ]; + interfaces.eth1.physicalConnections = [ + { + node = "kroma"; + interface = "lan1"; + } + ]; + interfaces.eth2.physicalConnections = [ + { + node = "nom"; + interface = "lan1"; + } + ]; + }; + #nodes.fritzbox-no-img = { # name = "FritzBox No HImg"; # deviceType = "router"; diff --git a/hosts/ward/default.nix b/hosts/ward/default.nix index 9537563..6622525 100644 --- a/hosts/ward/default.nix +++ b/hosts/ward/default.nix @@ -21,6 +21,8 @@ ./kea.nix ]; + topology.self.hardware.image = ../../odroid-h3.png; + boot.mode = "efi"; boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" "r8169"]; diff --git a/odroid-h3.png b/odroid-h3.png new file mode 100644 index 0000000..431f344 Binary files /dev/null and b/odroid-h3.png differ diff --git a/topology/nixos/extractors/services.nix b/topology/nixos/extractors/services.nix index e914623..151b6d4 100644 --- a/topology/nixos/extractors/services.nix +++ b/topology/nixos/extractors/services.nix @@ -5,10 +5,17 @@ }: let inherit (lib) + attrNames + concatLines concatStringsSep + flatten + flip + mapAttrsToList mkDefault mkEnableOption mkIf + optional + replaceStrings ; in { options.topology.extractors.services.enable = mkEnableOption "topology service extractor" // {default = true;}; @@ -42,6 +49,22 @@ in { nginx = mkIf config.services.nginx.enable { name = "NGINX"; icon = "services.nginx"; + details.reverse = let + lines = flatten (flip mapAttrsToList config.services.nginx.virtualHosts ( + server: vh: + flip mapAttrsToList vh.locations ( + path: location: let + upstreamName = replaceStrings ["http://" "https://"] ["" ""] location.proxyPass; + passTo = + if config.services.nginx.upstreams ? ${upstreamName} + then toString (attrNames config.services.nginx.upstreams.${upstreamName}.servers) + else location.proxyPass; + in + optional (path == "/" && location.proxyPass != null) "${server} -> ${passTo}" + ) + )); + in + mkIf (lines != []) {text = concatLines lines;}; }; radicale = mkIf config.services.radicale.enable { @@ -57,6 +80,7 @@ in { oauth2_proxy = mkIf config.services.oauth2_proxy.enable { name = "OAuth2 Proxy"; icon = "services.oauth2-proxy"; + info = config.services.oauth2_proxy.httpAddress; }; openssh = mkIf config.services.openssh.enable { diff --git a/topology/topology/renderers/d2/default.nix b/topology/topology/renderers/d2/default.nix deleted file mode 100644 index 315a6a0..0000000 --- a/topology/topology/renderers/d2/default.nix +++ /dev/null @@ -1,25 +0,0 @@ -{ - lib, - pkgs, - ... -} @ args: let - inherit - (lib) - mkOption - types - ; -in { - options.renderers.d2 = { - output = mkOption { - description = "The derivation containing the rendered output"; - type = types.path; - readOnly = true; - }; - }; - - config.renderers.d2.output = pkgs.runCommand "topology-d2" {} '' - mkdir -p $out - # cp ${import ./network.nix args} $out/network.d2 - ln -s ${import ./network.nix args} $out/svgs - ''; -} diff --git a/topology/topology/renderers/d2/network.nix b/topology/topology/renderers/d2/network.nix deleted file mode 100644 index c832dad..0000000 --- a/topology/topology/renderers/d2/network.nix +++ /dev/null @@ -1,51 +0,0 @@ -{ - lib, - config, - pkgs, - ... -}: let - inherit - (lib) - any - attrValues - concatLines - flip - optionalString - ; - - netToD2 = net: '' - net_${net.id}: ${net.name} { - info: |md - ${net.cidrv4} - ${net.cidrv6} - | - } - ''; - - nodeInterfaceToD2 = node: interface: - concatLines (flip map interface.physicalConnections (x: - optionalString ( - (!any (y: y.node == node.id && y.interface == interface.id) config.nodes.${x.node}.interfaces.${x.interface}.physicalConnections) - || (node.id < x.node) - ) - '' - node_${node.id} -- node_${x.node}: "" { - source-arrowhead.label: ${interface.id} - target-arrowhead.label: ${x.interface} - } - '')); - - nodeToD2 = node: '' - node_${node.id}: "" { - shape: image - width: 680 - icon: ${config.lib.renderers.svg.node.mkPreferredRender node} - } - - ${concatLines (map (nodeInterfaceToD2 node) (attrValues node.interfaces))} - ''; -in - pkgs.writeText "network.d2" '' - ${concatLines (map netToD2 (attrValues config.networks))} - ${concatLines (map nodeToD2 (attrValues config.nodes))} - '' diff --git a/topology/topology/renderers/elk/default.nix b/topology/topology/renderers/elk/default.nix index 83929ac..923a93e 100644 --- a/topology/topology/renderers/elk/default.nix +++ b/topology/topology/renderers/elk/default.nix @@ -19,9 +19,10 @@ mapAttrsToList mkOption optional - optionals optionalAttrs + optionals recursiveUpdate + stringLength types ; @@ -71,16 +72,15 @@ (optionalAttrs (node.preferredRenderType == "card") { children."node:${node.id}".ports."interface:${interface.id}" = { properties."port.side" = "WEST"; - #x = 0; - #y = 82 + 42 * lib.lists.findFirstIndex (x: x == interface.id) 0 (builtins.attrNames node.interfaces); # FIXME: just pass index along in function call width = 8; height = 8; - # TODO: FIXME: not shown currently in svg - # labels.name = { - # text = interface.id; - # width = 33.0; - # height = 15.0; - # }; + style.stroke = "#70a5eb"; + style.fill = "#74bee9"; + labels.name = { + height = 12; + width = 7.5 * (stringLength interface.id); + text = interface.id; + }; }; }) ] @@ -104,6 +104,7 @@ scale = 0.8; }; properties."portConstraints" = "FIXED_SIDE"; + properties."portLabels.placement" = "OUTSIDE"; }; } ] @@ -112,6 +113,8 @@ properties."port.side" = "EAST"; width = 8; height = 8; + style.stroke = "#49d18d"; + style.fill = "#78dba9"; }; edges."node:${node.parent}.ports.guests-to-node:${node.id}" = { sources = ["children.node:${node.parent}.ports.guests"]; diff --git a/topology/topology/renderers/svg/default.nix b/topology/topology/renderers/svg/default.nix index 3b27aba..dc0cfe9 100644 --- a/topology/topology/renderers/svg/default.nix +++ b/topology/topology/renderers/svg/default.nix @@ -1,15 +1,16 @@ # TODO: +# - ip labels on edges +# - network centric view +# - better layout for interfaces in svg +# - sevice infos # - disks (from disko) + render # - hardware info (image small top and image big bottom and full (no card), maybe just image and render position) -# - render router and other devices (card with interfaces, card with just image) -# - render nodes with guests, guests in short form -# - nginx proxy pass render, with upstream support # - more service info # - impermanence render? +# - nixos nftables firewall render? # - stable pseudorandom colors from palette with no-reuse until necessary # - search todo and do # - podman / docker harvesting -# - adjust device icon based on guest type # - nixos-container extractor { config, @@ -310,6 +311,7 @@ in { config = { lib.renderers.svg = { + # FIXME: networks.mkOverview = renderHtmlToSvg html.networks.mkOverview "networks-overview"; services.mkOverview = renderHtmlToSvg html.services.mkOverview "services-overview"; node = {