From 1772f29314523eddb11f8110eb0772197c095494 Mon Sep 17 00:00:00 2001 From: abriles1216 <110630236+abriles1216@users.noreply.github.com> Date: Tue, 3 Jan 2023 16:09:13 -0700 Subject: [PATCH] mfw-2312 (#119) * added some helper functions to types.go * moved functions around * moved functions around * added unit tests * added some logs for debugging * removed debug logs version: minor --- services/discovery/collectors.go | 71 +++++++++++++++++++++++++ services/discovery/collectors_test.go | 76 +++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 services/discovery/collectors_test.go diff --git a/services/discovery/collectors.go b/services/discovery/collectors.go index 03f12e92..1c483f52 100644 --- a/services/discovery/collectors.go +++ b/services/discovery/collectors.go @@ -1,6 +1,9 @@ package discovery import ( + "fmt" + "strings" + disco "github.com/untangle/golang-shared/structs/protocolbuffers/Discoverd" ) @@ -44,3 +47,71 @@ func fromRPCResponse(rpcResponse disco.CallDiscoveryResponse) CallCollectorsResp int32(rpcResponse.Result), } } + +// Normalizes the data in each collector entry +// Returns an error if the data couldn't be normalized or +// if the provided argument isn't a pointer to a collector struct +func NormalizeCollectorEntry(collector interface{}) error { + switch collectorWithType := collector.(type) { + case *disco.LLDP: + collectorWithType.Ip = strings.ToUpper(collectorWithType.Ip) + collectorWithType.Mac = strings.ToUpper(collectorWithType.Mac) + case *disco.NEIGH: + collectorWithType.Ip = strings.ToUpper(collectorWithType.Ip) + collectorWithType.Mac = strings.ToUpper(collectorWithType.Mac) + case *disco.NMAP: + collectorWithType.Ip = strings.ToUpper(collectorWithType.Ip) + collectorWithType.Mac = strings.ToUpper(collectorWithType.Mac) + default: + return fmt.Errorf("provided argument was not a pointer to a collector struct") + } + + return nil +} + +// Wraps an LLDP, NMAP, or NEIGH collector struct in a device entry +// If the collector struct is missing a field needed to initialize the +// collector struct, and error is returned. +func WrapCollectorInDeviceEntry(collector interface{}) (*DeviceEntry, error) { + var deviceEntry DeviceEntry + + switch collectorWithType := collector.(type) { + case *disco.LLDP: + if collectorWithType.Ip == "" { + return nil, fmt.Errorf("LLDP entry missing IP field") + } + + deviceEntry.MacAddress = collectorWithType.Mac + deviceEntry.LastUpdate = collectorWithType.LastUpdate + + deviceEntry.Lldp = make(map[string]*disco.LLDP) + deviceEntry.Lldp[collectorWithType.Ip] = collectorWithType + + case *disco.NEIGH: + if collectorWithType.Ip == "" { + return nil, fmt.Errorf("NEIGH entry missing IP field") + } + + deviceEntry.MacAddress = collectorWithType.Mac + deviceEntry.LastUpdate = collectorWithType.LastUpdate + + deviceEntry.Neigh = make(map[string]*disco.NEIGH) + deviceEntry.Neigh[collectorWithType.Ip] = collectorWithType + + case *disco.NMAP: + if collectorWithType.Ip == "" { + return nil, fmt.Errorf(("NMAP entry missing IP field")) + } + + deviceEntry.MacAddress = collectorWithType.Mac + deviceEntry.LastUpdate = collectorWithType.LastUpdate + + deviceEntry.Nmap = make(map[string]*disco.NMAP) + deviceEntry.Nmap[collectorWithType.Ip] = collectorWithType + + default: + return nil, fmt.Errorf("argument provided to the function was not an LLDP, NMAP, or NEIGH struct") + } + + return &deviceEntry, nil +} diff --git a/services/discovery/collectors_test.go b/services/discovery/collectors_test.go new file mode 100644 index 00000000..1ac3cb10 --- /dev/null +++ b/services/discovery/collectors_test.go @@ -0,0 +1,76 @@ +package discovery + +import ( + "testing" + + "github.com/stretchr/testify/assert" + disco "github.com/untangle/golang-shared/structs/protocolbuffers/Discoverd" +) + +func TestNormalizeCollectorEntry(t *testing.T) { + expectedIp := "2345:0425:2CA1:0000:0000:0567:5673:23B5" + expectedMac := "FF:FF" + + lldp := &disco.LLDP{Mac: "ff:ff", Ip: "2345:0425:2ca1:0000:0000:0567:5673:23b5"} + nmap := &disco.NMAP{Mac: "ff:ff", Ip: "2345:0425:2ca1:0000:0000:0567:5673:23b5"} + neighbor := &disco.NEIGH{Mac: "ff:ff", Ip: "2345:0425:2ca1:0000:0000:0567:5673:23b5"} + + err := NormalizeCollectorEntry(lldp) + assert.NoError(t, err) + + err = NormalizeCollectorEntry(nmap) + assert.NoError(t, err) + + err = NormalizeCollectorEntry(neighbor) + assert.NoError(t, err) + + err = NormalizeCollectorEntry(nil) + assert.Error(t, err) + + assert.Equal(t, expectedIp, lldp.Ip) + assert.Equal(t, expectedMac, lldp.Mac) + + assert.Equal(t, expectedIp, nmap.Ip) + assert.Equal(t, expectedMac, nmap.Mac) + + assert.Equal(t, expectedIp, neighbor.Ip) + assert.Equal(t, expectedMac, neighbor.Mac) +} + +func TestWrapCollectorInDeviceEntry(t *testing.T) { + testIp := "2345:0425:2ca1:0000:0000:0567:5673:23b5" + testMac := "ff:ff" + + lldp := &disco.LLDP{Mac: testMac, Ip: testIp} + nmap := &disco.NMAP{Mac: testMac, Ip: testIp} + neighbor := &disco.NEIGH{Mac: testMac, Ip: testIp} + + expectedLldp := &DeviceEntry{} + expectedLldp.MacAddress = testMac + expectedLldp.Lldp = map[string]*disco.LLDP{testIp: lldp} + + expectedNmap := &DeviceEntry{} + expectedNmap.MacAddress = testMac + expectedNmap.Nmap = map[string]*disco.NMAP{testIp: nmap} + + expectedNeighbor := &DeviceEntry{} + expectedNeighbor.MacAddress = testMac + expectedNeighbor.Neigh = map[string]*disco.NEIGH{testIp: neighbor} + + actualLldp, err := WrapCollectorInDeviceEntry(lldp) + assert.NoError(t, err) + assert.Equal(t, expectedLldp, actualLldp) + + actualNmap, err := WrapCollectorInDeviceEntry(nmap) + assert.NoError(t, err) + assert.Equal(t, expectedNmap, actualNmap) + + actualNeighbor, err := WrapCollectorInDeviceEntry(neighbor) + assert.NoError(t, err) + assert.Equal(t, expectedNeighbor, actualNeighbor) + + badCollector := &disco.LLDP{Mac: "", Ip: ""} + actualBad, err := WrapCollectorInDeviceEntry(badCollector) + assert.Error(t, err) + assert.Nil(t, actualBad) +}