{ self, nixpkgs, system }: with nixpkgs.legacyPackages.${system}; let config = self.lib.config; reportHosts = lib.concatMapStrings (hostName: let inherit (config.site.hosts.${hostName}) links model location; linksByPorts = builtins.foldl' (linksByPorts: linkName: if links.${linkName}.group != null then # group ports linksByPorts // { ${lib.concatMapStringsSep "
" (port: "`${port}`" ) links.${linkName}.ports} = linkName; } else # expand lists of access ports to seperate rows builtins.foldl' (linksByPorts': port: linksByPorts' // { "`${port}`" = linkName; } ) linksByPorts links.${linkName}.ports ) {} (builtins.attrNames links); in '' ## ${hostName} `${model}` @ **${location}** |Ports|Target|Networks| |-:|:-:|:-| ${lib.concatMapStrings (ports: let linkName = linksByPorts.${ports}; link = links.${linkName}; in '' |${ lib.optionalString (link.group != null) "**Group ${toString link.group}**
" }${ ports }|**${ linkName }**|${ if link.trunk then "**Trunk:** " else "**Access:** " }${ lib.concatStringsSep ", " ( map (net: "${net} (`${toString config.site.net.${net}.vlan}`)" ) (builtins.sort (a: b: let vlanA = config.site.net.${a}.vlan; vlanB = config.site.net.${b}.vlan; in ( if vlanA == null then 4096 else vlanA ) < ( if vlanB == null then 4096 else vlanB ) ) link.nets) ) }| '') (lib.naturalSort ( builtins.attrNames linksByPorts ))} ''); reportRole = role: reportHosts ( lib.naturalSort ( builtins.filter (hostName: config.site.hosts.${hostName}.role == role ) (builtins.attrNames config.site.hosts) ) ); in writeText "switch-report.md" '' # Switch Report ${reportRole "switch"} # Access Point Report ${reportRole "ap"} ''