diff --git a/internal/cache/datacache.go b/internal/cache/datacache.go index e6e730c..1ca1fd0 100644 --- a/internal/cache/datacache.go +++ b/internal/cache/datacache.go @@ -8,21 +8,23 @@ import ( func NewDataCache() *DataCache { return &DataCache{ - lock: sync.Mutex{}, - devices: make(map[int]*models.Device), - interfaces: make(map[int]*models.Interface), - cables: make(map[int]*models.Cable), - vms: make(map[int]*models.VM), + lock: sync.Mutex{}, + devices: make(map[int]*models.Device), + interfaces: make(map[int]*models.Interface), + cables: make(map[int]*models.Cable), + vms: make(map[int]*models.VM), + vmInterfaces: make(map[int]*models.VMInterface), } } type DataCache struct { - lock sync.Mutex - devices map[int]*models.Device - interfaces map[int]*models.Interface - cables map[int]*models.Cable - vms map[int]*models.VM - arpRecords []*models.ARPRecord + lock sync.Mutex + devices map[int]*models.Device + interfaces map[int]*models.Interface + cables map[int]*models.Cable + vms map[int]*models.VM + arpRecords []*models.ARPRecord + vmInterfaces map[int]*models.VMInterface } func (d *DataCache) AddDevice(device models.Device) { @@ -124,19 +126,47 @@ func (d *DataCache) ReconcileData() { for _, iif := range d.interfaces { if r.MacAddress == iif.MacAddress { r.Device = &iif.Device + break + } + } + for _, iif := range d.vmInterfaces { + if r.MacAddress == iif.MacAddress { + r.VM = &iif.VM + break } } } } func (d *DataCache) GetUnmonitoredMachines() []models.UnmonitoredDevice { + d.lock.Lock() + defer d.lock.Unlock() + var res []models.UnmonitoredDevice for _, r := range d.arpRecords { - if r.Device == nil { + if r.Device == nil && r.VM == nil { res = append(res, models.UnmonitoredDevice{Address: r.Address, MacAddress: r.MacAddress}) } } return res } + +func (d *DataCache) AddVMInterface(iface models.VMInterface) { + d.lock.Lock() + defer d.lock.Unlock() + + d.vmInterfaces[iface.ID] = &iface +} + +func (d *DataCache) GetVMInterfaces() []*models.VMInterface { + d.lock.Lock() + defer d.lock.Unlock() + + res := []*models.VMInterface{} + for _, iif := range d.vmInterfaces { + res = append(res, iif) + } + return res +} diff --git a/internal/models/mikrotik.go b/internal/models/mikrotik.go index 8a306b9..860ed00 100644 --- a/internal/models/mikrotik.go +++ b/internal/models/mikrotik.go @@ -2,6 +2,7 @@ package models type ARPRecord struct { Device *Device `json:"-"` + VM *VM `json:"-"` Address string `json:"address"` MacAddress string `json:"mac-address"` } diff --git a/internal/models/netbox.go b/internal/models/netbox.go index 7dd7564..ae3a2b4 100644 --- a/internal/models/netbox.go +++ b/internal/models/netbox.go @@ -143,3 +143,10 @@ func (v VM) Elements() []Element { }, } } + +type VMInterface struct { + ID int `json:"id"` + Name string `json:"name"` + MacAddress string `json:"mac_address"` + VM VM `json:"virtual_machine"` +} diff --git a/internal/netbox/netbox.go b/internal/netbox/netbox.go index 1bd7f61..c1108dd 100644 --- a/internal/netbox/netbox.go +++ b/internal/netbox/netbox.go @@ -9,10 +9,11 @@ import ( ) const ( - devicesRoute = "/api/dcim/devices" - cablesRoute = "/api/dcim/cables" - vmsRoute = "/api/virtualization/virtual-machines" - interfaceRoute = "/api/dcim/interfaces" + devicesRoute = "/api/dcim/devices" + cablesRoute = "/api/dcim/cables" + vmsRoute = "/api/virtualization/virtual-machines" + interfaceRoute = "/api/dcim/interfaces" + vmInterfaceRoute = "/api/virtualization/interfaces" ) type vmsResponse struct { @@ -31,6 +32,10 @@ type interfaceResponse struct { Results []models.Interface `json:"results"` } +type vmInterfaceResponse struct { + Results []models.VMInterface `json:"results"` +} + type NetboxClient struct { httpClt *http.Client netboxBaseURL string @@ -115,6 +120,21 @@ func (c *NetboxClient) GetVMs() ([]models.VM, error) { return res.Results, nil } +func (c *NetboxClient) GetVMInterfaces() ([]models.VMInterface, error) { + var res vmInterfaceResponse + + respBody, err := c.queryAPI(vmInterfaceRoute) + if err != nil { + return nil, err + } + + if err := json.Unmarshal(respBody, &res); err != nil { + return nil, err + } + + return res.Results, nil +} + func NewClient(baseURL, token string) *NetboxClient { return &NetboxClient{ httpClt: http.DefaultClient, diff --git a/main.go b/main.go index fe6b46a..cd14899 100644 --- a/main.go +++ b/main.go @@ -61,6 +61,15 @@ func main() { dataCache.AddInterface(i) } + fmt.Println("Getting virtual interfaces") + vmInterfaces, err := netboxClt.GetVMInterfaces() + if err != nil { + panic(err) + } + for _, i := range vmInterfaces { + dataCache.AddVMInterface(i) + } + fmt.Println("Getting data from ARP cache") arpCache, err := mikrotikClt.GetARPRecords() if err != nil {