From 9c5eac6e8cd2b6f5cfab05de0bf33ab7cc039475 Mon Sep 17 00:00:00 2001 From: Serge Bazanski Date: Sat, 6 Oct 2018 12:13:57 +0100 Subject: [PATCH] basic connectivity graph from netbox --- graph/graph.go | 57 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/graph/graph.go b/graph/graph.go index 1fdb5ab2..8681b8f3 100644 --- a/graph/graph.go +++ b/graph/graph.go @@ -4,9 +4,9 @@ import ( "context" "fmt" - "github.com/davecgh/go-spew/spew" "github.com/digitalocean/go-netbox/netbox/client" "github.com/digitalocean/go-netbox/netbox/client/dcim" + "github.com/digitalocean/go-netbox/netbox/models" "github.com/golang/glog" confpb "code.hackerspace.pl/q3k/topo/proto/config" @@ -137,6 +137,22 @@ func (g *Graph) LoadConfig(conf *confpb.Config) error { } func (g *Graph) FeedFromNetbox(ctx context.Context, nb *client.NetBox) error { + // Clear all connections first, because it's easier that way. + for _, machine := range g.Machines { + for _, port := range machine.Ports { + port.OtherEnd = nil + } + } + for _, sw := range g.Switches { + for _, port := range sw.Ports { + port.OtherEnd = nil + } + } + + // Load new connections. + // Iterating over just machines should be fine if all connections are + // guaranteed to be between machines and switches (which is the model for + // now). for _, machine := range g.Machines { req := &dcim.DcimInterfaceConnectionsListParams{ Device: &machine.Name, @@ -147,7 +163,44 @@ func (g *Graph) FeedFromNetbox(ctx context.Context, nb *client.NetBox) error { return fmt.Errorf("while querying information about %q: %v", machine.Name, err) } for _, connection := range res.Payload.Results { - glog.Info(spew.Sdump(connection)) + ia := connection.InterfaceA + ib := connection.InterfaceB + if ia == nil || ib == nil { + continue + } + + // Find which way this thing actually connects. + var thisSide, otherSide *models.PeerInterface + if ia.Device.Name == machine.Name { + thisSide = ia + otherSide = ib + } else if ib.Device.Name == machine.Name { + thisSide = ib + otherSide = ia + } else { + glog.Warning("Netbox connectivity for %q reported a link without it involced..?", machine.Name) + continue + } + + thisPort, ok := machine.Ports[*thisSide.Name] + if !ok { + continue + } + sw, ok := g.Switches[otherSide.Device.Name] + if !ok { + glog.Warningf("Machine %q port %q is managed but connected to unknown device %q", machine.Name, thisPort.Name, otherSide.Device.Name) + continue + } + otherPort, ok := sw.Ports[*otherSide.Name] + if !ok { + glog.Warningf("Machine %q port %q is managed but connected to unmanaged port %q on %q", machine.Name, thisPort.Name, otherSide.Name, sw.Name) + continue + } + + // Connect the two together! + thisPort.OtherEnd = otherPort + otherPort.OtherEnd = thisPort + glog.Infof("Connected: %s/%s <-> %s/%s", machine.Name, thisPort.Name, sw.Name, otherPort.Name) } } return nil