From f0915d35b728de394b38ec170181da46b7985ece Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 1 Nov 2024 08:43:55 +0100 Subject: [PATCH] Add support to generate dot files of the network The resulting image (after running `dot`) isn't perfect but good enough to get a quick overview of the network. --- dot.go | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 12 ++++++++-- 2 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 dot.go diff --git a/dot.go b/dot.go new file mode 100644 index 0000000..c49c3bb --- /dev/null +++ b/dot.go @@ -0,0 +1,68 @@ +// Write dot file showing the network architecture. + +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (C) 2024 Simon Ruderich + +package main + +import ( + "bufio" + "fmt" + "html" + "os" + "strings" +) + +func writeDot(cfg *Config, path string) error { + f, err := os.Create(path) + if err != nil { + return err + } + defer f.Close() + w := bufio.NewWriter(f) + + fmt.Fprintf(w, "graph {\n") + fmt.Fprintf(w, "graph [nodesep=3]\n") + + for _, node := range cfg.Nodes { + var as []string + as = append(as, html.EscapeString(node.Name)+"
") + for _, x := range node.Loopbacks { + as = append(as, fmt.Sprintf(" %s 
", + html.EscapeString(x.String()))) + } + fmt.Fprintf(w, "%s [label=<%s>]\n", + node.Name, strings.Join(as, "")) + } + + for _, link := range cfg.Links { + var aas []string + for _, x := range link.A.Addrs { + aas = append(aas, fmt.Sprintf(" %s 
", + html.EscapeString(x.Addr().String()))) + } + var abs []string + for _, x := range link.B.Addrs { + abs = append(abs, fmt.Sprintf(" %s 
", + html.EscapeString(x.Addr().String()))) + } + fmt.Fprintf(w, "%s -- %s [taillabel=<%s>,headlabel=<%s>,labelfontsize=10]\n", + link.A.Node.Name, link.B.Node.Name, + strings.Join(aas, ""), strings.Join(abs, ""), + ) + } + + fmt.Fprintf(w, "}\n") + + err = w.Flush() + if err != nil { + return err + } + err = f.Sync() + if err != nil { + return err + } + return nil +} + +// vi: set noet ts=4 sw=4 sts=4: diff --git a/main.go b/main.go index a935b5c..5c1e9cc 100644 --- a/main.go +++ b/main.go @@ -18,9 +18,9 @@ import ( ) func main() { - if len(os.Args) != 2 { + if len(os.Args) != 2 && len(os.Args) != 3 { log.SetFlags(0) - log.Fatalf("usage: %s ", os.Args[0]) + log.Fatalf("usage: %s []", os.Args[0]) } cfg, err := LoadConfig(os.Args[1]) @@ -28,6 +28,14 @@ func main() { log.Fatalf("config %q: %v", os.Args[1], err) } + // Write dot file showing the network architecture + if len(os.Args) == 3 { + err := writeDot(cfg, os.Args[2]) + if err != nil { + log.Fatal(err) + } + } + for _, node := range cfg.Nodes { log.Printf("Setting up node %q ...", node.Name) -- 2.45.2