diff --git a/README.md b/README.md index 9b7df0d..36e5b38 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Here's a working example: package main import "log" -import "github.com/unpoller/unifi" +import "github.com/unpoller/unifi/v5" func main() { c := *unifi.Config{ diff --git a/anomalies.go b/anomalies.go index d6554db..5f30f99 100644 --- a/anomalies.go +++ b/anomalies.go @@ -20,7 +20,7 @@ type Anomaly struct { // DeviceName string // we do not have this.... Anomaly string Datetime time.Time `fake:"{recent_time}"` - DeviceMAC string `fake:"{macaddress}"` + DeviceMAC string `fake:"{macaddress}"` SiteName string SourceName string } diff --git a/devices.go b/devices.go index 0421703..601856a 100644 --- a/devices.go +++ b/devices.go @@ -102,6 +102,34 @@ func (u *Unifi) GetUSGs(site *Site) ([]*USG, error) { return u.parseDevices(response.Data, site).USGs, nil } +// GetUBBs returns all UBB devices, an error, or nil if there are no UBBs. +func (u *Unifi) GetUBBs(site *Site) ([]*UBB, error) { + var response struct { + Data []json.RawMessage `json:"data"` + } + + err := u.GetData(fmt.Sprintf(APIDevicePath, site.Name), &response) + if err != nil { + return nil, err + } + + return u.parseDevices(response.Data, site).UBBs, nil +} + +// GetUCIs returns all UCI devices, an error, or nil if there are no UCIs. +func (u *Unifi) GetUCIs(site *Site) ([]*UCI, error) { + var response struct { + Data []json.RawMessage `json:"data"` + } + + err := u.GetData(fmt.Sprintf(APIDevicePath, site.Name), &response) + if err != nil { + return nil, err + } + + return u.parseDevices(response.Data, site).UCIs, nil +} + type minimalUnmarshalInfo struct { Type string `json:"type"` Model string `json:"model"` @@ -116,7 +144,7 @@ func (u *Unifi) parseDevices(data []json.RawMessage, site *Site) *Devices { var o minimalUnmarshalInfo if u.unmarshalDevice("map", r, &o) != nil { u.ErrorLog("unknown asset type - cannot find asset type in payload - skipping") - + continue } @@ -143,6 +171,10 @@ func (u *Unifi) parseDevices(data []json.RawMessage, site *Site) *Devices { u.unmarshallUDM(site, r, devices) case "uxg": u.unmarshallUXG(site, r, devices) + case "ubb": + u.unmarshallUBB(site, r, devices) + case "uci": + u.unmarshallUCI(site, r, devices) default: u.ErrorLog("unknown asset type - %v - skipping: data=%+v", assetType, string(r)) } @@ -196,6 +228,24 @@ func (u *Unifi) unmarshallUXG(site *Site, payload json.RawMessage, devices *Devi } } +func (u *Unifi) unmarshallUBB(site *Site, payload json.RawMessage, devices *Devices) { + dev := &UBB{SiteName: site.SiteName, SourceName: u.URL} + if u.unmarshalDevice("ubb", payload, dev) == nil { + dev.Name = strings.TrimSpace(pick(dev.Name, dev.Mac)) + dev.site = site + devices.UBBs = append(devices.UBBs, dev) + } +} + +func (u *Unifi) unmarshallUCI(site *Site, payload json.RawMessage, devices *Devices) { + dev := &UCI{SiteName: site.SiteName, SourceName: u.URL} + if u.unmarshalDevice("uci", payload, dev) == nil { + dev.Name = strings.TrimSpace(pick(dev.Name, dev.Mac)) + dev.site = site + devices.UCIs = append(devices.UCIs, dev) + } +} + func (u *Unifi) unmarshallUDM(site *Site, payload json.RawMessage, devices *Devices) { dev := &UDM{SiteName: site.SiteName, SourceName: u.URL} if u.unmarshalDevice("udm", payload, dev) == nil { diff --git a/devmgr.go b/devmgr.go index 6359be2..11e252b 100644 --- a/devmgr.go +++ b/devmgr.go @@ -26,10 +26,10 @@ const ( // devMgrCmd is the type marshalled and sent to APIDevMgrPath. type devMgrCmd struct { - Cmd string `json:"cmd"` // Required. + Cmd string `json:"cmd"` // Required. Inform string `fake:"{url}" json:"inform_url,omitempty"` // Migration only. - Mac string `fake:"{macaddress}" json:"mac"` // Device MAC (required for most, but not all). - Port int `json:"port_idx,omitempty"` // Power Cycle only. + Mac string `fake:"{macaddress}" json:"mac"` // Device MAC (required for most, but not all). + Port int `json:"port_idx,omitempty"` // Power Cycle only. URL string `fake:"{url}" json:"url,omitempty"` // External Upgrade only. } @@ -51,7 +51,7 @@ func (s *Site) devMgrCommandReply(cmd *devMgrCmd) ([]byte, error) { // devMgrCommandSimple is for commands with no return value. func (s *Site) devMgrCommandSimple(cmd *devMgrCmd) error { _, err := s.devMgrCommandReply(cmd) - + return err } diff --git a/events_test.go b/events_test.go index 270d0a9..fa694e3 100644 --- a/events_test.go +++ b/events_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/unpoller/unifi" + "github.com/unpoller/unifi/v5" ) func TestIPGeoUnmarshalJSON(t *testing.T) { diff --git a/mocks/mock_client.go b/mocks/mock_client.go index ff546dc..710b777 100644 --- a/mocks/mock_client.go +++ b/mocks/mock_client.go @@ -223,6 +223,44 @@ func (m *MockUnifi) GetUXGs(_ *unifi.Site) ([]*unifi.UXG, error) { return results, nil } +// GetUBBs returns all UBB devices, an error, or nil if there are no UBBs. +func (m *MockUnifi) GetUBBs(_ *unifi.Site) ([]*unifi.UBB, error) { + results := make([]*unifi.UBB, numItemsMocked) + + for i := 0; i < numItemsMocked; i++ { + var a unifi.UBB + + err := gofakeit.Struct(&a) + + if err != nil { + return results, err + } + + results[i] = &a + } + + return results, nil +} + +// GetUCIs returns all UCI devices, an error, or nil if there are no UCIs. +func (m *MockUnifi) GetUCIs(_ *unifi.Site) ([]*unifi.UCI, error) { + results := make([]*unifi.UCI, numItemsMocked) + + for i := 0; i < numItemsMocked; i++ { + var a unifi.UCI + + err := gofakeit.Struct(&a) + + if err != nil { + return results, err + } + + results[i] = &a + } + + return results, nil +} + // GetUSGs returns all 1Gb gateways, an error, or nil if there are no USGs. func (m *MockUnifi) GetUSGs(_ *unifi.Site) ([]*unifi.USG, error) { results := make([]*unifi.USG, numItemsMocked) diff --git a/networks.go b/networks.go index 9702714..44baaab 100644 --- a/networks.go +++ b/networks.go @@ -35,7 +35,7 @@ func (u *Unifi) GetNetworks(sites []*Site) ([]Network, error) { // parseNetwork parses the raw JSON from the Unifi Controller into network structures. func (u *Unifi) parseNetwork(data json.RawMessage, siteName string) (*Network, error) { network := new(Network) - + return network, u.unmarshalDevice(siteName, data, network) } diff --git a/pdu_test.go b/pdu_test.go index 2919a50..8911284 100644 --- a/pdu_test.go +++ b/pdu_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/unpoller/unifi" + "github.com/unpoller/unifi/v5" ) //go:embed examples/pdu.json diff --git a/types.go b/types.go index 3ec4654..bdf716a 100644 --- a/types.go +++ b/types.go @@ -194,6 +194,8 @@ type Devices struct { UDMs []*UDM `fakesize:"5"` UXGs []*UXG `fakesize:"5"` PDUs []*PDU `fakesize:"5"` + UBBs []*UBB `fakesize:"5"` + UCIs []*UCI `fakesize:"5"` } // Config is the data passed into our library. This configures things and allows @@ -235,6 +237,10 @@ type UnifiClient interface { //nolint: revive GetUXGs(site *Site) ([]*UXG, error) // GetUSGs returns all 1Gb gateways, an error, or nil if there are no USGs. GetUSGs(site *Site) ([]*USG, error) + // GetUBBs returns all UBB devices, an error, or nil if there are no UBBs. + GetUBBs(site *Site) ([]*UBB, error) + // GetUCIs returns all UCI devices, an error, or nil if there are no UCIs. + GetUCIs(site *Site) ([]*UCI, error) // GetEvents returns a response full of UniFi Events for the last 1 hour from multiple sites. GetEvents(sites []*Site, hours time.Duration) ([]*Event, error) // GetSiteEvents retrieves the last 1 hour's worth of events from a single site. diff --git a/types_test.go b/types_test.go index ce13a3f..53fc931 100644 --- a/types_test.go +++ b/types_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/unpoller/unifi" + "github.com/unpoller/unifi/v5" ) func TestFlexInt(t *testing.T) { diff --git a/ubb.go b/ubb.go index ed58d1a..59860c7 100644 --- a/ubb.go +++ b/ubb.go @@ -134,6 +134,9 @@ func (v *UBBStat) UnmarshalJSON(data []byte) error { } type UBB struct { + SiteName string `json:"-"` + SourceName string `json:"-"` + site *Site RequiredVersion string `json:"required_version"` HasSpeaker FlexBool `json:"has_speaker"` LicenseState string `json:"license_state"` diff --git a/uci.go b/uci.go index b82f276..2a9a864 100644 --- a/uci.go +++ b/uci.go @@ -34,6 +34,9 @@ type CIStateTable struct { } type UCI struct { + SiteName string `json:"-"` + SourceName string `json:"-"` + site *Site RequiredVersion string `json:"required_version"` PortTable []*Port `json:"port_table"` LicenseState string `json:"license_state"`