From bb86f7c3d443062bffc3cf829c4bd50f778fea9a Mon Sep 17 00:00:00 2001 From: Cody Lee Date: Mon, 24 Jul 2023 14:40:22 -0500 Subject: [PATCH 1/3] local dev of integration tests working --- events.go | 4 +- ids.go | 6 +- mocks/mock_client.go | 104 +++++++++++++--------------- mocks/mock_server.go | 92 ++++++++++++++++++------- pdu.go | 30 ++++---- site.go | 6 +- types.go | 159 +++++++++++++++++++++++++++++++++++++------ uap.go | 30 ++++---- udm.go | 40 +++++------ users.go | 6 +- usg.go | 22 +++--- usw.go | 2 +- uxg.go | 12 ++-- 13 files changed, 335 insertions(+), 178 deletions(-) diff --git a/events.go b/events.go index a4e30d7..6bd063c 100644 --- a/events.go +++ b/events.go @@ -110,7 +110,7 @@ type Event struct { InnerAlertCategory string `json:"inner_alert_category"` InnerAlertSignature string `json:"inner_alert_signature"` Key string `json:"key" fake:"{uuid}"` - Msg string `json:"msg" fake:"{sentence:20}"` + Msg string `json:"msg" fake:"{buzzword}"` Network string `json:"network"` Proto string `json:"proto"` Radio string `json:"radio"` @@ -140,7 +140,7 @@ type Event struct { // IPGeo is part of the UniFi Event data. Each event may have up to three of these. // One for source, one for dest and one for the USG location. type IPGeo struct { - Asn int64 `json:"asn" fake:"{address}"` + Asn int64 `json:"asn"` Latitude float64 `json:"latitude" fake:"{latitude}"` Longitude float64 `json:"longitude" fake:"{longitude}"` City string `json:"city" fake:"{city}"` diff --git a/ids.go b/ids.go index 5fa2a21..f274f84 100644 --- a/ids.go +++ b/ids.go @@ -12,7 +12,7 @@ type IDS struct { Archived FlexBool `json:"archived"` DestPort int `json:"dest_port,omitempty" fake:"{port}"` SrcPort int `json:"src_port,omitempty" fake:"{port}"` - FlowID int64 `json:"flow_id" fake:"{uuid}"` + FlowID int64 `json:"flow_id"` InnerAlertRev int64 `json:"inner_alert_rev"` InnerAlertSeverity int64 `json:"inner_alert_severity"` InnerAlertGID int64 `json:"inner_alert_gid"` @@ -34,7 +34,7 @@ type IDS struct { InnerAlertCategory string `json:"inner_alert_category"` InnerAlertSignature string `json:"inner_alert_signature"` Key string `json:"key" fake:"{uuid}"` - Msg string `json:"msg" fake:"{sentence:20}"` + Msg string `json:"msg" fake:"{buzzword}"` Proto string `json:"proto"` SiteID string `json:"site_id" fake:"{uuid}"` SiteName string `json:"-"` @@ -44,7 +44,7 @@ type IDS struct { SrcIPCountry string `json:"srcipCountry" fake:"{country}"` SrcMAC string `json:"src_mac" fake:"{macaddress}"` Subsystem string `json:"subsystem"` - UniqueAlertID string `json:"unique_alertid" fake:"{uuid}"` + UniqueAlertID string `json:"unique_alertid"` USGIP string `json:"usgip" fake:"{ipv4address}"` USGIPASN string `json:"usgipASN" fake:"{address}"` USGIPCountry string `json:"usgipCountry" fake:"{country}"` diff --git a/mocks/mock_client.go b/mocks/mock_client.go index a9128e2..43497bb 100644 --- a/mocks/mock_client.go +++ b/mocks/mock_client.go @@ -1,6 +1,7 @@ package mocks import ( + "math/rand" "os" "strconv" "time" @@ -28,24 +29,17 @@ func fakeSeedValue() int64 { } func NewMockUnifi() *MockUnifi { - return NewMockUnifiWithSeed(fakeSeedValue()) + return &MockUnifi{} } -func NewMockUnifiWithSeed(seed int64) *MockUnifi { - faker := gofakeit.New(seed) - return &MockUnifi{ - faker: faker, - } -} - // GetAlarms returns Alarms for a list of Sites. func (m *MockUnifi) GetAlarms(sites []*unifi.Site) ([]*unifi.Alarm, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 alarms := make([]*unifi.Alarm, qty) for i := 0; i < qty; i++ { var a unifi.Alarm - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return alarms, err } @@ -56,11 +50,11 @@ func (m *MockUnifi) GetAlarms(sites []*unifi.Site) ([]*unifi.Alarm, error) { // GetAlarmsSite retreives the Alarms for a single Site. func (m *MockUnifi) GetAlarmsSite(site *unifi.Site) ([]*unifi.Alarm, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 alarms := make([]*unifi.Alarm, qty) for i := 0; i < qty; i++ { var a unifi.Alarm - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return alarms, err } @@ -71,11 +65,11 @@ func (m *MockUnifi) GetAlarmsSite(site *unifi.Site) ([]*unifi.Alarm, error) { // GetAnomalies returns Anomalies for a list of Sites. func (m *MockUnifi) GetAnomalies(sites []*unifi.Site, timeRange ...time.Time) ([]*unifi.Anomaly, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.Anomaly, qty) for i := 0; i < qty; i++ { var a unifi.Anomaly - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -86,11 +80,11 @@ func (m *MockUnifi) GetAnomalies(sites []*unifi.Site, timeRange ...time.Time) ([ // GetAnomaliesSite retreives the Anomalies for a single Site. func (m *MockUnifi) GetAnomaliesSite(site *unifi.Site, timeRange ...time.Time) ([]*unifi.Anomaly, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.Anomaly, qty) for i := 0; i < qty; i++ { var a unifi.Anomaly - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -101,11 +95,11 @@ func (m *MockUnifi) GetAnomaliesSite(site *unifi.Site, timeRange ...time.Time) ( // GetClients returns a response full of clients' data from the UniFi Controller. func (m *MockUnifi) GetClients(sites []*unifi.Site) ([]*unifi.Client, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.Client, qty) for i := 0; i < qty; i++ { var a unifi.Client - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -116,11 +110,11 @@ func (m *MockUnifi) GetClients(sites []*unifi.Site) ([]*unifi.Client, error) { // GetClientsDPI garners dpi data for clients. func (m *MockUnifi) GetClientsDPI(sites []*unifi.Site) ([]*unifi.DPITable, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.DPITable, qty) for i := 0; i < qty; i++ { var a unifi.DPITable - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -132,7 +126,7 @@ func (m *MockUnifi) GetClientsDPI(sites []*unifi.Site) ([]*unifi.DPITable, error // GetDevices returns a response full of devices' data from the UniFi Controller. func (m *MockUnifi) GetDevices(sites []*unifi.Site) (*unifi.Devices, error) { var d unifi.Devices - err := m.faker.Struct(&d) + err := gofakeit.Struct(&d) if err != nil { return nil, err } @@ -141,11 +135,11 @@ func (m *MockUnifi) GetDevices(sites []*unifi.Site) (*unifi.Devices, error) { // GetUSWs returns all switches, an error, or nil if there are no switches. func (m *MockUnifi) GetUSWs(site *unifi.Site) ([]*unifi.USW, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.USW, qty) for i := 0; i < qty; i++ { var a unifi.USW - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -156,11 +150,11 @@ func (m *MockUnifi) GetUSWs(site *unifi.Site) ([]*unifi.USW, error) { // GetUAPs returns all access points, an error, or nil if there are no APs. func (m *MockUnifi) GetUAPs(site *unifi.Site) ([]*unifi.UAP, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.UAP, qty) for i := 0; i < qty; i++ { var a unifi.UAP - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -171,11 +165,11 @@ func (m *MockUnifi) GetUAPs(site *unifi.Site) ([]*unifi.UAP, error) { // GetUDMs returns all dream machines, an error, or nil if there are no UDMs. func (m *MockUnifi) GetUDMs(site *unifi.Site) ([]*unifi.UDM, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.UDM, qty) for i := 0; i < qty; i++ { var a unifi.UDM - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -186,11 +180,11 @@ func (m *MockUnifi) GetUDMs(site *unifi.Site) ([]*unifi.UDM, error) { // GetUXGs returns all 10Gb gateways, an error, or nil if there are no UXGs. func (m *MockUnifi) GetUXGs(site *unifi.Site) ([]*unifi.UXG, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.UXG, qty) for i := 0; i < qty; i++ { var a unifi.UXG - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -201,11 +195,11 @@ func (m *MockUnifi) GetUXGs(site *unifi.Site) ([]*unifi.UXG, error) { // GetUSGs returns all 1Gb gateways, an error, or nil if there are no USGs. func (m *MockUnifi) GetUSGs(site *unifi.Site) ([]*unifi.USG, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.USG, qty) for i := 0; i < qty; i++ { var a unifi.USG - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -216,11 +210,11 @@ func (m *MockUnifi) GetUSGs(site *unifi.Site) ([]*unifi.USG, error) { // GetEvents returns a response full of UniFi Events for the last 1 hour from multiple sites. func (m *MockUnifi) GetEvents(sites []*unifi.Site, hours time.Duration) ([]*unifi.Event, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.Event, qty) for i := 0; i < qty; i++ { var a unifi.Event - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -231,11 +225,11 @@ func (m *MockUnifi) GetEvents(sites []*unifi.Site, hours time.Duration) ([]*unif // GetSiteEvents retrieves the last 1 hour's worth of events from a single site. func (m *MockUnifi) GetSiteEvents(site *unifi.Site, hours time.Duration) ([]*unifi.Event, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.Event, qty) for i := 0; i < qty; i++ { var a unifi.Event - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -248,11 +242,11 @@ func (m *MockUnifi) GetSiteEvents(site *unifi.Site, hours time.Duration) ([]*uni // timeRange may have a length of 0, 1 or 2. The first time is Start, the second is End. // Events between start and end are returned. End defaults to time.Now(). func (m *MockUnifi) GetIDS(sites []*unifi.Site, timeRange ...time.Time) ([]*unifi.IDS, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.IDS, qty) for i := 0; i < qty; i++ { var a unifi.IDS - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -265,11 +259,11 @@ func (m *MockUnifi) GetIDS(sites []*unifi.Site, timeRange ...time.Time) ([]*unif // timeRange may have a length of 0, 1 or 2. The first time is Start, the second is End. // Events between start and end are returned. End defaults to time.Now(). func (m *MockUnifi) GetIDSSite(site *unifi.Site, timeRange ...time.Time) ([]*unifi.IDS, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.IDS, qty) for i := 0; i < qty; i++ { var a unifi.IDS - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -280,11 +274,11 @@ func (m *MockUnifi) GetIDSSite(site *unifi.Site, timeRange ...time.Time) ([]*uni // GetNetworks returns a response full of network data from the UniFi Controller. func (m *MockUnifi) GetNetworks(sites []*unifi.Site) ([]unifi.Network, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]unifi.Network, qty) for i := 0; i < qty; i++ { var a unifi.Network - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -295,11 +289,11 @@ func (m *MockUnifi) GetNetworks(sites []*unifi.Site) ([]unifi.Network, error) { // GetSites returns a list of configured sites on the UniFi controller. func (m *MockUnifi) GetSites() ([]*unifi.Site, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.Site, qty) for i := 0; i < qty; i++ { var a unifi.Site - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -310,11 +304,11 @@ func (m *MockUnifi) GetSites() ([]*unifi.Site, error) { // GetSiteDPI garners dpi data for sites. func (m *MockUnifi) GetSiteDPI(sites []*unifi.Site) ([]*unifi.DPITable, error) { - qty := m.faker.Rand.Intn(5) + qty := 1 results := make([]*unifi.DPITable, qty) for i := 0; i < qty; i++ { var a unifi.DPITable - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -326,11 +320,11 @@ func (m *MockUnifi) GetSiteDPI(sites []*unifi.Site) ([]*unifi.DPITable, error) { // GetRogueAPs returns RogueAPs for a list of Sites. // Use GetRogueAPsSite if you want more control. func (m *MockUnifi) GetRogueAPs(sites []*unifi.Site) ([]*unifi.RogueAP, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.RogueAP, qty) for i := 0; i < qty; i++ { var a unifi.RogueAP - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -341,11 +335,11 @@ func (m *MockUnifi) GetRogueAPs(sites []*unifi.Site) ([]*unifi.RogueAP, error) { // GetRogueAPsSite returns RogueAPs for a single Site. func (m *MockUnifi) GetRogueAPsSite(site *unifi.Site) ([]*unifi.RogueAP, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.RogueAP, qty) for i := 0; i < qty; i++ { var a unifi.RogueAP - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } @@ -367,25 +361,23 @@ func (m *MockUnifi) Logout() error { // GetServerData sets the controller's version and UUID. Only call this if you // previously called Login and suspect the controller version has changed. func (m *MockUnifi) GetServerData() (*unifi.ServerStatus, error) { - var response struct { - Data unifi.ServerStatus `json:"meta"` - } + var response unifi.ServerStatus - err := m.faker.Struct(&response) + err := gofakeit.Struct(&response) if err != nil { return nil, err } - return &response.Data, nil + return &response, nil } // GetUsers returns a response full of clients that connected to the UDM within the provided amount of time // using the insight historical connection data set. func (m *MockUnifi) GetUsers(sites []*unifi.Site, hours int) ([]*unifi.User, error) { - qty := m.faker.Rand.Intn(5) + qty := rand.Intn(5) + 1 results := make([]*unifi.User, qty) for i := 0; i < qty; i++ { var a unifi.User - err := m.faker.Struct(&a) + err := gofakeit.Struct(&a) if err != nil { return results, err } diff --git a/mocks/mock_server.go b/mocks/mock_server.go index d48fe87..1bffff2 100644 --- a/mocks/mock_server.go +++ b/mocks/mock_server.go @@ -27,7 +27,7 @@ func NewMockHTTPTestServer() *MockHTTPTestServer { } func convertPathToRegexPattern(s string) string { - tmp := strings.ReplaceAll(strings.ReplaceAll(s, "%s", "[a-zA-Z-_,.]+"), "%d", "[0-9]+") + tmp := strings.ReplaceAll(strings.ReplaceAll(s, "%s", "[^/]+"), "%d", "[0-9]+") return fmt.Sprintf("(%s)?%s", unifi.APIPrefixNew, tmp) } @@ -54,15 +54,60 @@ var ( apiDevMgrPath = regexp.MustCompile(convertPathToRegexPattern(unifi.APIDevMgrPath)) ) -func respondResultOrErr(w http.ResponseWriter, v any, err error) { - log.Printf("[DEBUG] Answering mock response err=%+v value=%+v\n", err, v) +type errorResponse struct { + Error string `json:"error"` +} + +type dataWrapper struct { + Data any `json:"data"` +} + +func respondResultOrErr(w http.ResponseWriter, v any, err error, wrapWithDataAttribute bool) { if err != nil { - b, _ := json.Marshal(err) + log.Printf("[ERROR] Answering mock response err=%+v value=%+v\n", err, v) + } else { + log.Printf("[DEBUG] Answering mock response value=%+v\n", v) + } + w.Header().Add("Content-Type", "application/json") + w.Header().Add("Via", "unifi-mock-server") + if err != nil { + e := errorResponse{ + Error: err.Error(), + } + b, _ := json.Marshal(e) + w.WriteHeader(500) + _, _ = w.Write(b) + return + } + + if wrapWithDataAttribute { + response := dataWrapper{Data: v} + b, err := json.Marshal(response) + if err != nil { + e := errorResponse{ + Error: err.Error(), + } + b, _ := json.Marshal(e) + w.WriteHeader(500) + _, _ = w.Write(b) + return + } + w.WriteHeader(200) + _, _ = w.Write(b) + return + } + + // no data wrapper + b, err := json.Marshal(v) + if err != nil { + e := errorResponse{ + Error: err.Error(), + } + b, _ := json.Marshal(e) w.WriteHeader(500) _, _ = w.Write(b) return } - b, _ := json.Marshal(v) w.WriteHeader(200) _, _ = w.Write(b) } @@ -73,68 +118,69 @@ func (m *MockHTTPTestServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { switch { case apiRogueAP.MatchString(p): aps, err := m.mocked.GetRogueAPs(nil) - respondResultOrErr(w, aps, err) + respondResultOrErr(w, aps, err, true) return case apiStatusPath.MatchString(p): s, err := m.mocked.GetServerData() - respondResultOrErr(w, s, err) + respondResultOrErr(w, s, err, true) return case apiEventPath.MatchString(p): events, err := m.mocked.GetEvents(nil, time.Hour) - respondResultOrErr(w, events, err) + respondResultOrErr(w, events, err, true) return - case apiSiteList.MatchString(p): sites, err := m.mocked.GetSites() - respondResultOrErr(w, sites, err) + respondResultOrErr(w, sites, err, true) return case apiSiteDPI.MatchString(p): dpi, err := m.mocked.GetSiteDPI(nil) - respondResultOrErr(w, dpi, err) + respondResultOrErr(w, dpi, err, true) return case apiClientDPI.MatchString(p): dpi, err := m.mocked.GetClientsDPI(nil) - respondResultOrErr(w, dpi, err) + respondResultOrErr(w, dpi, err, true) return case apiClientPath.MatchString(p): clients, err := m.mocked.GetClients(nil) - respondResultOrErr(w, clients, err) + respondResultOrErr(w, clients, err, true) return case apiAllUserPath.MatchString(p): users, err := m.mocked.GetUsers(nil, 1) - respondResultOrErr(w, users, err) + respondResultOrErr(w, users, err, true) return case apiNetworkPath.MatchString(p): networks, err := m.mocked.GetNetworks(nil) - respondResultOrErr(w, networks, err) + respondResultOrErr(w, networks, err, true) return case apiDevicePath.MatchString(p): - devices, err := m.mocked.GetDevices(nil) - respondResultOrErr(w, devices, err) + device, err := m.mocked.GetDevices(nil) + // we need to wrap devices more so + devices := []*unifi.Devices{device} + respondResultOrErr(w, devices, err, true) return case apiLoginPath.MatchString(p): err := m.mocked.Login() - respondResultOrErr(w, nil, err) + respondResultOrErr(w, nil, err, true) return case apiLoginPathNew.MatchString(p): err := m.mocked.Login() - respondResultOrErr(w, nil, err) + respondResultOrErr(w, nil, err, true) return case apiLogoutPath.MatchString(p): err := m.mocked.Logout() - respondResultOrErr(w, nil, err) + respondResultOrErr(w, nil, err, true) return case apiEventPathIDS.MatchString(p): ids, err := m.mocked.GetIDS(nil, time.Now()) - respondResultOrErr(w, ids, err) + respondResultOrErr(w, ids, err, true) return case apiEventPathAlarms.MatchString(p): alarms, err := m.mocked.GetAlarms(nil) - respondResultOrErr(w, alarms, err) + respondResultOrErr(w, alarms, err, true) return case apiAnomaliesPath.MatchString(p): anomalies, err := m.mocked.GetAnomalies(nil, time.Now()) - respondResultOrErr(w, anomalies, err) + respondResultOrErr(w, anomalies, err, true) return case apiDevMgrPath.MatchString(p): // todo diff --git a/pdu.go b/pdu.go index 78e3188..e2e49c3 100644 --- a/pdu.go +++ b/pdu.go @@ -15,16 +15,16 @@ type PDU struct { Architecture string `json:"architecture"` BoardRev FlexInt `json:"board_rev"` Bytes FlexInt `json:"bytes"` - CfgVersion string `json:"cfgversion"` + CfgVersion string `json:"cfgversion" fake:"{appversion}"` ConfigNetwork *ConfigNetwork `json:"config_network"` ConnectRequestIP string `json:"connect_request_ip" fake:"{ipv4address}"` - ConnectRequestPort FlexInt `json:"connect_request_port" fake:"{port}"` - ConnectedAt FlexInt `json:"connected_at" fake:"{timestamp}"` + ConnectRequestPort FlexInt `json:"connect_request_port"` + ConnectedAt FlexInt `json:"connected_at"` ConnectionNetworkName string `json:"connection_network_name"` Default FlexBool `json:"default"` DeviceID string `json:"device_id" fake:"{uuid}"` DiscoveredVia string `json:"discovered_via"` - DisplayableVersion string `json:"displayable_version"` + DisplayableVersion string `json:"displayable_version" fake:"{appversion}"` Dot1xPortCtrlEnabled FlexBool `json:"dot1x_portctrl_enabled"` DownlinkTable []*DownlinkTable `json:"downlink_table" fakesize:"5"` EthernetTable []*EthernetTable `json:"ethernet_table" fakesize:"5"` @@ -41,9 +41,9 @@ type PDU struct { Internet FlexBool `json:"internet"` IP string `json:"ip" fake:"{ipv4address}"` JumboframeEnabled FlexBool `json:"jumboframe_enabled"` - KernelVersion string `json:"kernel_version"` - KnownCfgVersion string `json:"known_cfgversion"` - LastSeen FlexInt `json:"last_seen" fake:"{timestamp}"` + KernelVersion string `json:"kernel_version" fake:"{appversion}"` + KnownCfgVersion string `json:"known_cfgversion" fake:"{appversion}"` + LastSeen FlexInt `json:"last_seen"` LastUplink Uplink `json:"last_uplink"` LcmBrightness FlexInt `json:"lcm_brightness"` LcmBrightnessOverride FlexBool `json:"lcm_brightness_override"` @@ -72,8 +72,8 @@ type PDU struct { PowerSource FlexInt `json:"power_source"` PowerSourceCtrlEnabled FlexBool `json:"power_source_ctrl_enabled"` PrevNonBusyState FlexInt `json:"prev_non_busy_state"` - ProvisionedAt FlexInt `json:"provisioned_at" fake:"{timestamp}"` - RequiredVersion string `json:"required_version"` + ProvisionedAt FlexInt `json:"provisioned_at"` + RequiredVersion string `json:"required_version" fake:"{appversion}"` RollUpgrade FlexBool `json:"rollupgrade"` RxBytes FlexInt `json:"rx_bytes"` Satisfaction FlexInt `json:"satisfaction"` @@ -82,13 +82,13 @@ type PDU struct { SiteID string `json:"site_id" fake:"{uuid}"` SiteName string `json:"site_name"` SourceName string `json:"source_name"` - StartConnectedMillis FlexInt `json:"start_connected_millis" fake:"{timestamp}"` - StartDisconnectedMillis FlexInt `json:"start_disconnected_millis" fake:"{timestamp}"` - StartupTimestamp FlexInt `json:"startup_timestamp" fake:"{timestamp}"` + StartConnectedMillis FlexInt `json:"start_connected_millis"` + StartDisconnectedMillis FlexInt `json:"start_disconnected_millis"` + StartupTimestamp FlexInt `json:"startup_timestamp"` Stat PDUStat `json:"stat"` State FlexInt `json:"state"` StpPriority FlexInt `json:"stp_priority"` - StpVersion string `json:"stp_version"` + StpVersion string `json:"stp_version" fake:"{appversion}"` SwitchCaps *SwitchCaps `json:"switch_caps"` SysErrorCaps FlexInt `json:"sys_error_caps"` SysStats SysStats `json:"sys_stats"` @@ -103,9 +103,9 @@ type PDU struct { Upgradeable FlexBool `json:"upgradable"` Uplink Uplink `json:"uplink"` UplinkDepth FlexBool `json:"uplink_depth"` - Uptime FlexInt `json:"uptime" fake:"{timestamp}"` + Uptime FlexInt `json:"uptime"` UserNumSta FlexInt `json:"user-num_sta"` - Version string `json:"version"` + Version string `json:"version" fake:"{appversion}"` } // OutletOverride hold the PDU outlet override data. diff --git a/site.go b/site.go index 1e48daf..1c73ddf 100644 --- a/site.go +++ b/site.go @@ -72,8 +72,8 @@ type Site struct { controller *Unifi SourceName string `json:"-"` ID string `json:"_id" fake:"{uuid}"` - Name string `json:"name"` - Desc string `json:"desc" fake:"{sentence:20}"` + Name string `json:"name" fake:"{company}"` + Desc string `json:"desc" fake:"{buzzword}"` SiteName string `json:"-"` AttrHiddenID string `json:"attr_hidden_id"` AttrNoDelete FlexBool `json:"attr_no_delete"` @@ -103,7 +103,7 @@ type Site struct { Mem FlexInt `json:"mem"` Uptime FlexInt `json:"uptime"` } `json:"gw_system-stats,omitempty"` - GwVersion string `json:"gw_version,omitempty"` + GwVersion string `json:"gw_version,omitempty" fake:"{appversion}"` Latency FlexInt `json:"latency,omitempty"` Uptime FlexInt `json:"uptime,omitempty"` Drops FlexInt `json:"drops,omitempty"` diff --git a/types.go b/types.go index 37c6fad..53f7112 100644 --- a/types.go +++ b/types.go @@ -133,12 +133,12 @@ func discardLogs(msg string, v ...interface{}) { // Devices contains a list of all the unifi devices from a controller. // Contains Access points, security gateways and switches. type Devices struct { - UAPs []*UAP - USGs []*USG - USWs []*USW - UDMs []*UDM - UXGs []*UXG - PDUs []*PDU + UAPs []*UAP `fakesize:"5"` + USGs []*USG `fakesize:"5"` + USWs []*USW `fakesize:"5"` + UDMs []*UDM `fakesize:"5"` + UXGs []*UXG `fakesize:"5"` + PDUs []*PDU `fakesize:"5"` } // Config is the data passed into our library. This configures things and allows @@ -247,7 +247,7 @@ func (f fingerprints) Contains(s string) bool { // ServerStatus is the /status endpoint from the Unifi controller. type ServerStatus struct { Up FlexBool `json:"up"` - ServerVersion string `json:"server_version"` + ServerVersion string `json:"server_version" fake:"{appversion}"` UUID string `json:"uuid" fake:"{uuid}"` } @@ -291,6 +291,10 @@ func (f *FlexInt) UnmarshalJSON(b []byte) error { return nil } +func (f *FlexInt) MarshalJSON() ([]byte, error) { + return json.Marshal(f.Val) +} + func (f *FlexInt) Int() int { return int(f.Val) } @@ -316,14 +320,17 @@ func (f *FlexInt) AddFloat64(v float64) { // Fake implements gofakeit Fake interface func (f *FlexInt) Fake(faker *gofakeit.Faker) interface{} { randValue := faker.Rand.Float64() - opts := []interface{}{ - randValue, - int64(randValue), - strconv.FormatInt(int64(randValue), 10), - strconv.FormatFloat(randValue, 'f', 8, 64), + if faker.Rand.Intn(2) == 0 { + // int-value + return FlexInt{ + Val: float64(int64(randValue)), + Txt: strconv.FormatInt(int64(randValue), 10), + } + } + return FlexInt{ + Val: randValue, + Txt: strconv.FormatFloat(randValue, 'f', 8, 64), } - - return opts[faker.Rand.Intn(2)] } // FlexBool provides a container and unmarshalling for fields that may be @@ -345,24 +352,136 @@ func (f *FlexBool) UnmarshalJSON(b []byte) error { return nil } +func (f *FlexBool) MarshalJSON() ([]byte, error) { + return json.Marshal(f.Val) +} + func (f *FlexBool) String() string { return f.Txt } // Fake implements gofakeit Fake interface func (f *FlexBool) Fake(faker *gofakeit.Faker) interface{} { - opts := []interface{}{ - "true", + opts := []bool{ true, - "false", false, } - return opts[faker.Rand.Intn(4)] + + v := opts[faker.Rand.Intn(2)] + return FlexBool{ + Val: v, + Txt: strconv.FormatBool(v), + } +} + +// FlexTemp provides a container and unmarshalling for fields that may be +// numbers or strings in the Unifi API as temperatures. +type FlexTemp struct { + Val float64 // in Celsius + Txt string +} + +func NewFlexTemp(v float64) *FlexTemp { + return &FlexTemp{ + Val: v, + Txt: strconv.FormatFloat(v, 'f', -1, 64), + } +} + +// UnmarshalJSON converts a string or number to an integer. +// Generally, do call this directly, it's used in the json interface. +func (f *FlexTemp) UnmarshalJSON(b []byte) error { + var unk interface{} + + if err := json.Unmarshal(b, &unk); err != nil { + return fmt.Errorf("json unmarshal: %w", err) + } + + switch i := unk.(type) { + case float64: + f.Val = i + f.Txt = strconv.FormatFloat(i, 'f', -1, 64) + case string: + f.Txt = i + parts := strings.SplitN(string(b), " ", 2) + if len(parts) == 2 { + // format is: $val(int or float) $unit(C or F) + f.Val, _ = strconv.ParseFloat(parts[0], 64) + } else { + // assume Celsius + f.Val, _ = strconv.ParseFloat(i, 64) + } + case nil: + f.Txt = "0" + f.Val = 0 + default: + return fmt.Errorf("%v: %w", b, ErrCannotUnmarshalFlexInt) + } + + return nil +} + +func (f *FlexTemp) MarshalJSON() ([]byte, error) { + return json.Marshal(f.Val) +} + +func (f *FlexTemp) Celsius() float64 { + return f.Val +} + +func (f *FlexTemp) CelsiusInt() int { + return int(f.Val) +} + +func (f *FlexTemp) CelsiusInt64() int64 { + return int64(f.Val) +} + +func (f *FlexTemp) Fahrenheit() float64 { + return (f.Val * (9 / 5)) + 32 +} + +func (f *FlexTemp) FahrenheitInt() int { + return int(f.Fahrenheit()) +} + +func (f *FlexTemp) FahrenheitInt64() int64 { + return int64(f.Fahrenheit()) +} + +func (f *FlexTemp) String() string { + return f.Txt +} + +func (f *FlexTemp) Add(o *FlexTemp) { + f.Val += o.Val + f.Txt = strconv.FormatFloat(f.Val, 'f', -1, 64) +} + +func (f *FlexTemp) AddFloat64(v float64) { + f.Val += v + f.Txt = strconv.FormatFloat(f.Val, 'f', -1, 64) +} + +// Fake implements gofakeit Fake interface +func (f *FlexTemp) Fake(faker *gofakeit.Faker) interface{} { + randValue := faker.Rand.Float64() + if faker.Rand.Intn(2) == 0 { + // int-value + return FlexTemp{ + Val: float64(int64(randValue)), + Txt: strconv.FormatInt(int64(randValue), 10) + " C", + } + } + return FlexTemp{ + Val: randValue, + Txt: strconv.FormatFloat(randValue, 'f', 8, 64) + " C", + } } // DownlinkTable is part of a UXG and UDM output. type DownlinkTable struct { - PortIdx FlexInt `json:"port_idx" fake:"{port}"` + PortIdx FlexInt `json:"port_idx"` Speed FlexInt `json:"speed"` FullDuplex FlexBool `json:"full_duplex"` Mac string `json:"mac" fake:"{macaddress}"` @@ -376,7 +495,7 @@ type ConfigNetwork struct { type EthernetTable struct { Mac string `json:"mac" fake:"{macaddress}"` - NumPort FlexInt `json:"num_port" fake:"{port}"` + NumPort FlexInt `json:"num_port"` Name string `json:"name" fake:"{animal}"` } diff --git a/uap.go b/uap.go index ac6c67f..b195a0c 100644 --- a/uap.go +++ b/uap.go @@ -15,7 +15,7 @@ type UAP struct { Adopted FlexBool `json:"adopted"` AntennaTable []struct { Default FlexBool `json:"default"` - ID FlexInt `json:"id" fake:"{uuid}"` + ID FlexInt `json:"id"` Name string `json:"name" fake:"{animal}"` Wifi0Gain FlexInt `json:"wifi0_gain"` Wifi1Gain FlexInt `json:"wifi1_gain"` @@ -26,11 +26,11 @@ type UAP struct { Bytes FlexInt `json:"bytes"` BytesD FlexInt `json:"bytes-d"` BytesR FlexInt `json:"bytes-r"` - Cfgversion string `json:"cfgversion"` + Cfgversion string `json:"cfgversion" fake:"{appversion}"` ConfigNetwork *ConfigNetwork `json:"config_network"` ConnectRequestIP string `json:"connect_request_ip" fake:"{ipv4address}"` ConnectRequestPort string `json:"connect_request_port"` - ConnectedAt FlexInt `json:"connected_at" fake:"{timestamp}"` + ConnectedAt FlexInt `json:"connected_at"` CountryCode FlexInt `json:"country_code"` CountrycodeTable []int `json:"countrycode_table" fakesize:"5"` DeviceID string `json:"device_id" fake:"{uuid}"` @@ -54,8 +54,8 @@ type UAP struct { InformURL string `json:"inform_url" fake:"{url}"` Internet FlexBool `json:"internet"` Isolated FlexBool `json:"isolated"` - KernelVersion string `json:"kernel_version"` - KnownCfgversion string `json:"known_cfgversion"` + KernelVersion string `json:"kernel_version" fake:"{appversion}"` + KnownCfgversion string `json:"known_cfgversion" fake:"{appversion}"` LastSeen FlexInt `json:"last_seen"` LastUplink struct { UplinkMac string `json:"uplink_mac" fake:"{macaddress}"` @@ -116,7 +116,7 @@ type UAP struct { ProvisionedAt FlexInt `json:"provisioned_at"` RadioTable RadioTable `json:"radio_table"` RadioTableStats RadioTableStats `json:"radio_table_stats"` - RequiredVersion string `json:"required_version"` + RequiredVersion string `json:"required_version" fake:"{appversion}"` Rollupgrade FlexBool `json:"rollupgrade"` RxBytes FlexInt `json:"rx_bytes"` RxBytesD FlexInt `json:"rx_bytes-d"` @@ -129,9 +129,9 @@ type UAP struct { SiteName string `json:"-"` SourceName string `json:"-"` SpectrumScanning FlexBool `json:"spectrum_scanning"` - StartConnectedMillis FlexInt `json:"start_connected_millis" fake:"{timestamp}"` - StartDisconnectedMillis FlexInt `json:"start_disconnected_millis" fake:"{timestamp}"` - StartupTimestamp FlexInt `json:"startup_timestamp" fake:"{timestamp}"` + StartConnectedMillis FlexInt `json:"start_connected_millis"` + StartDisconnectedMillis FlexInt `json:"start_disconnected_millis"` + StartupTimestamp FlexInt `json:"startup_timestamp"` Stat UAPStat `json:"stat"` State FlexInt `json:"state"` SupportsFingerprintML FlexBool `json:"supports_fingerprint_ml"` @@ -181,7 +181,7 @@ type UAP struct { UserNumSta FlexInt `json:"user-num_sta"` UserWlanNumSta FlexInt `json:"user-wlan-num_sta"` VapTable VapTable `json:"vap_table"` - Version string `json:"version"` + Version string `json:"version" fake:"{appversion}"` VwireEnabled FlexBool `json:"vwireEnabled"` VwireTable []interface{} `json:"vwire_table"` VwireVapTable []interface{} `json:"vwire_vap_table"` @@ -202,7 +202,7 @@ type Ap struct { O string `json:"o"` Oid string `json:"oid"` Ap string `json:"ap"` - Time FlexInt `json:"time" fake:"{timestamp}"` + Time FlexInt `json:"time"` Datetime time.Time `json:"datetime"` Bytes FlexInt `json:"bytes"` Duration FlexInt `json:"duration"` @@ -541,10 +541,10 @@ type VapTable []struct { } `json:"rx_tcp_stats"` TxTCPStats struct { Goodbytes FlexInt `json:"goodbytes"` - LatAvg FlexInt `json:"lat_avg" fake:"{latitude}"` - LatMax FlexInt `json:"lat_max" fake:"{latitude}"` - LatMin FlexInt `json:"lat_min" fake:"{longitude}"` - Stalls FlexInt `json:"stalls" fake:"{longitude}"` + LatAvg FlexInt `json:"lat_avg"` + LatMax FlexInt `json:"lat_max"` + LatMin FlexInt `json:"lat_min"` + Stalls FlexInt `json:"stalls"` } `json:"tx_tcp_stats"` WifiTxLatencyMov struct { Avg FlexInt `json:"avg"` diff --git a/udm.go b/udm.go index 8ed4ba8..4e8f932 100644 --- a/udm.go +++ b/udm.go @@ -20,17 +20,17 @@ type UDM struct { Bytes FlexInt `json:"bytes"` BytesD FlexInt `json:"bytes-d"` BytesR FlexInt `json:"bytes-r"` - Cfgversion string `json:"cfgversion"` + Cfgversion string `json:"cfgversion" fake:"{appversion}"` ConfigNetwork *ConfigNetwork `json:"config_network"` ConnectRequestIP string `json:"connect_request_ip" fake:"{ipv4address}"` ConnectRequestPort string `json:"connect_request_port"` - ConnectedAt FlexInt `json:"connected_at" fake:"{timestamp}"` + ConnectedAt FlexInt `json:"connected_at"` ConnectionNetworkName string `json:"connection_network_name"` Default FlexBool `json:"default"` DeviceDomain string `json:"device_domain"` DeviceID string `json:"device_id" fake:"{uuid}"` DiscoveredVia string `json:"discovered_via"` - DisplayableVersion string `json:"displayable_version"` + DisplayableVersion string `json:"displayable_version" fake:"{appversion}"` Dot1XPortctrlEnabled FlexBool `json:"dot1x_portctrl_enabled"` DownlinkTable []*DownlinkTable `json:"downlink_table" fakesize:"5"` EthernetOverrides []*EthernetOverrides `json:"ethernet_overrides" fakesize:"5"` @@ -55,12 +55,12 @@ type UDM struct { Internet FlexBool `json:"internet"` IsAccessPoint FlexBool `json:"is_access_point"` JumboframeEnabled FlexBool `json:"jumboframe_enabled"` - KernelVersion string `json:"kernel_version"` - KnownCfgversion string `json:"known_cfgversion"` + KernelVersion string `json:"kernel_version" fake:"{appversion}"` + KnownCfgversion string `json:"known_cfgversion" fake:"{appversion}"` LanIP string `json:"lan_ip" fake:"{ipv4address}"` LanNumSta FlexInt `json:"lan-num_sta"` // USW - LastLteFailoverTransitionTimestamp FlexInt `json:"last_lte_failover_transition_timestamp" fake:"{timestamp}"` - LastSeen FlexInt `json:"last_seen" fake:"{timestamp}"` + LastLteFailoverTransitionTimestamp FlexInt `json:"last_lte_failover_transition_timestamp"` + LastSeen FlexInt `json:"last_seen"` LastWlanIP string `json:"last_wan_ip" fake:"{ipv4address}"` LcmBrightness FlexInt `json:"lcm_brightness"` LcmNightModeBegins string `json:"lcm_night_mode_begins"` @@ -86,15 +86,15 @@ type UDM struct { NumSta FlexInt `json:"num_sta"` // USG Overheating FlexBool `json:"overheating"` PortOverrides []struct { - PortIdx FlexInt `json:"port_idx" fake:"{port}"` + PortIdx FlexInt `json:"port_idx"` PortconfID string `json:"portconf_id"` } `json:"port_overrides" fakesize:"5"` PortTable []Port `json:"port_table" fakesize:"5"` PowerSourceCtrlEnabled FlexBool `json:"power_source_ctrl_enabled"` - ProvisionedAt FlexInt `json:"provisioned_at" fake:"{timestamp}"` + ProvisionedAt FlexInt `json:"provisioned_at"` RadioTable *RadioTable `json:"radio_table,omitempty"` RadioTableStats *RadioTableStats `json:"radio_table_stats,omitempty"` - RequiredVersion string `json:"required_version"` + RequiredVersion string `json:"required_version" fake:"{appversion}"` RollUpgrade FlexBool `json:"rollupgrade"` RulesetInterfaces interface{} `json:"ruleset_interfaces"` /* struct { @@ -119,14 +119,14 @@ type UDM struct { SourceName string `json:"-"` SpeedtestStatus SpeedtestStatus `json:"speedtest-status"` SpeedtestStatusSaved FlexBool `json:"speedtest-status-saved"` - StartupConnectedMillis FlexInt `json:"start_connected_millis" fake:"{timestamp}"` - StartupDisconnectedMillis FlexInt `json:"start_disconnected_millis" fake:"{timestamp}"` - StartupTimestamp FlexInt `json:"startup_timestamp" fake:"{timestamp}"` + StartupConnectedMillis FlexInt `json:"start_connected_millis"` + StartupDisconnectedMillis FlexInt `json:"start_disconnected_millis"` + StartupTimestamp FlexInt `json:"startup_timestamp"` Stat UDMStat `json:"stat"` State FlexInt `json:"state"` Storage []*Storage `json:"storage" fakesize:"5"` StpPriority FlexInt `json:"stp_priority"` - StpVersion string `json:"stp_version"` + StpVersion string `json:"stp_version" fake:"{appversion}"` SwitchCaps struct { MaxMirrorSessions FlexInt `json:"max_mirror_sessions"` MaxAggregateSessions FlexInt `json:"max_aggregate_sessions"` @@ -143,11 +143,11 @@ type UDM struct { UdapiCaps FlexInt `json:"udapi_caps"` UnifiCare struct { ActivationDismissed FlexBool `json:"activation_dismissed"` - ActivationEnd FlexInt `json:"activation_end" fake:"{timestamp}"` + ActivationEnd FlexInt `json:"activation_end"` ActivationUrl string `json:"activation_url" fake:"{url}"` - CoverageEnd FlexInt `json:"coverage_end" fake:"{timestamp}"` - CoverageStart FlexInt `json:"coverage_start" fake:"{timestamp}"` - Registration FlexInt `json:"registration" fake:"{timestamp}"` + CoverageEnd FlexInt `json:"coverage_end"` + CoverageStart FlexInt `json:"coverage_start"` + Registration FlexInt `json:"registration"` RmaUrl string `json:"rma_url" fake:"{url}"` State string `json:"state"` TrackingUrl string `json:"tracking_url" fake:"{url}"` @@ -157,13 +157,13 @@ type UDM struct { UpgradeState FlexInt `json:"upgrade_state"` Upgradeable FlexBool `json:"upgradable"` Uplink Uplink `json:"uplink"` - Uptime FlexInt `json:"uptime" fake:"{timestamp}"` + Uptime FlexInt `json:"uptime"` UserLanNumSta FlexInt `json:"user-lan-num_sta"` // USW UserNumSta FlexInt `json:"user-num_sta"` // USG UserWlanNumSta FlexInt `json:"user-wlan-num_sta"` // UAP UsgCaps FlexInt `json:"usg_caps"` VapTable *VapTable `json:"vap_table"` - Version string `json:"version"` + Version string `json:"version" fake:"{appversion}"` VwireTable []interface{} `json:"vwire_table"` Wan1 Wan `json:"wan1"` Wan2 Wan `json:"wan2"` diff --git a/users.go b/users.go index cae0c71..81145b8 100644 --- a/users.go +++ b/users.go @@ -50,8 +50,8 @@ type User struct { SiteID string `json:"site_id" fake:"{uuid}"` Oui string `json:"oui,omitempty"` IsGuest bool `json:"is_guest"` - FirstSeen FlexInt `json:"first_seen,omitempty" fake:"{timestamp}"` - LastSeen FlexInt `json:"last_seen,omitempty" fake:"{timestamp}"` + FirstSeen FlexInt `json:"first_seen,omitempty"` + LastSeen FlexInt `json:"last_seen,omitempty"` IsWired bool `json:"is_wired,omitempty"` Hostname string `json:"hostname,omitempty"` Duration FlexInt `json:"duration,omitempty"` @@ -63,7 +63,7 @@ type User struct { TxRetries FlexInt `json:"tx_retries,omitempty"` UsergroupID string `json:"usergroup_id,omitempty"` Name string `json:"name,omitempty" fake:"{animal}"` - Note string `json:"note,omitempty" fake:"{sentence:20}"` + Note string `json:"note,omitempty" fake:"{buzzword}"` Noted FlexBool `json:"noted,omitempty"` Blocked FlexBool `json:"blocked,omitempty"` DevIDOverride FlexInt `json:"dev_id_override,omitempty"` diff --git a/usg.go b/usg.go index aefbed2..5486dcd 100644 --- a/usg.go +++ b/usg.go @@ -11,7 +11,7 @@ type USG struct { SourceName string `json:"-"` ID string `json:"_id" fake:"{uuid}"` Adopted FlexBool `json:"adopted"` - Cfgversion string `json:"cfgversion"` + Cfgversion string `json:"cfgversion" fake:"{appversion}"` ConfigNetwork *ConfigNetwork `json:"config_network"` EthernetTable []*EthernetTable `json:"ethernet_table" fakesize:"5"` FwCaps FlexInt `json:"fw_caps"` @@ -29,8 +29,8 @@ type USG struct { SiteName string `json:"-"` Type string `json:"type"` UsgCaps FlexInt `json:"usg_caps"` - Version string `json:"version"` - RequiredVersion string `json:"required_version"` + Version string `json:"version" fake:"{appversion}"` + RequiredVersion string `json:"required_version" fake:"{appversion}"` EthernetOverrides []*EthernetOverrides `json:"ethernet_overrides" fakesize:"5"` HwCaps FlexInt `json:"hw_caps"` BoardRev FlexInt `json:"board_rev"` @@ -38,12 +38,12 @@ type USG struct { UnsupportedReason FlexInt `json:"unsupported_reason"` DeviceID string `json:"device_id" fake:"{uuid}"` State FlexInt `json:"state"` - LastSeen FlexInt `json:"last_seen" fake:"{timestamp}"` + LastSeen FlexInt `json:"last_seen"` Upgradable FlexBool `json:"upgradable"` AdoptableWhenUpgraded FlexBool `json:"adoptable_when_upgraded"` Rollupgrade FlexBool `json:"rollupgrade"` - KnownCfgversion string `json:"known_cfgversion"` - Uptime FlexInt `json:"uptime" fake:"{timestamp}"` + KnownCfgversion string `json:"known_cfgversion" fake:"{appversion}"` + Uptime FlexInt `json:"uptime"` Locating FlexBool `json:"locating"` ConnectRequestIP string `json:"connect_request_ip" fake:"{ipv4address}"` ConnectRequestPort string `json:"connect_request_port"` @@ -106,7 +106,7 @@ type Uplink struct { TxRate FlexInt `json:"tx_rate"` Type string `json:"type"` Up FlexBool `json:"up"` - Uptime FlexInt `json:"uptime" fake:"{timestamp}"` + Uptime FlexInt `json:"uptime"` XputDown FlexInt `json:"xput_down,omitempty"` XputUp FlexInt `json:"xput_up,omitempty"` } @@ -174,8 +174,8 @@ type SpeedtestServer struct { Cc string `json:"cc"` City string `json:"city" fake:"{city}"` Country string `json:"country" fake:"{country}"` - Lat FlexInt `json:"lat" fake:"{latitude}"` - Lon FlexInt `json:"lon" fake:"{longitude}"` + Lat FlexInt `json:"lat"` + Lon FlexInt `json:"lon"` Provider string `json:"provider"` ProviderURL string `json:"provider_url" fake:"{url}"` } @@ -184,10 +184,10 @@ type SpeedtestServer struct { type SystemStats struct { CPU FlexInt `json:"cpu"` Mem FlexInt `json:"mem"` - Uptime FlexInt `json:"uptime" fake:"{timestamp}"` + Uptime FlexInt `json:"uptime"` // This exists on at least USG4, may others, maybe not. // {"Board (CPU)":"51 C","Board (PHY)":"51 C","CPU":"72 C","PHY":"77 C"} - Temps map[string]string `json:"temps,omitempty" fakesize:"5"` + Temps map[string]FlexTemp `json:"temps,omitempty" fakesize:"5"` } // SysStats is load info for a UDM, USG, USW. diff --git a/usw.go b/usw.go index b86f05f..610b1b2 100644 --- a/usw.go +++ b/usw.go @@ -144,7 +144,7 @@ type Sw struct { O string `json:"o"` Oid string `json:"oid"` Sw string `json:"sw"` - Time FlexInt `json:"time" fake:"{timestamp}"` + Time FlexInt `json:"time"` Datetime time.Time `json:"datetime"` RxPackets FlexInt `json:"rx_packets"` RxBytes FlexInt `json:"rx_bytes"` diff --git a/uxg.go b/uxg.go index c9f8db9..01a3c31 100644 --- a/uxg.go +++ b/uxg.go @@ -18,8 +18,8 @@ type UXG struct { ConnectRequestIP string `json:"connect_request_ip"` ConnectRequestPort string `json:"connect_request_port"` ConnectionNetworkName string `json:"connection_network_name"` - ConnectedAt FlexInt `json:"connected_at" fake:"{timestamp}"` - ConsideredLostAt FlexInt `json:"considered_lost_at" fake:"{timestamp}"` + ConnectedAt FlexInt `json:"connected_at"` + ConsideredLostAt FlexInt `json:"considered_lost_at"` DeviceID string `json:"device_id" fake:"{uuid}"` DisplayableVersion string `json:"displayable_version"` DownlinkTable []*DownlinkTable `json:"downlink_table" fakesize:"5"` @@ -61,7 +61,7 @@ type UXG struct { LedState *LedState `json:"led_state"` LicenseState string `json:"license_state"` Locating FlexBool `json:"locating"` - Mac string `json:"mac" fake:"{timestamp}"` + Mac string `json:"mac" fake:"{macaddress}"` ManufacturerID FlexInt `json:"manufacturer_id"` MinInformIntervalSeconds FlexInt `json:"min_inform_interval_seconds"` Model string `json:"model"` @@ -142,15 +142,15 @@ type LedState struct { type GeoInfo struct { Accuracy FlexInt `json:"accuracy"` Address string `json:"address" fake:"{address}"` - Asn FlexInt `json:"asn" fake:"{address}"` + Asn FlexInt `json:"asn"` City string `json:"city" fake:"{city}"` ContinentCode string `json:"continent_code"` CountryCode string `json:"country_code"` CountryName string `json:"country_name" fake:"{country}"` IspName string `json:"isp_name"` IspOrganization string `json:"isp_organization"` - Latitude FlexInt `json:"latitude" fake:"{latitude}"` - Longitude FlexInt `json:"longitude" fake:"{longitude}"` + Latitude FlexInt `json:"latitude"` + Longitude FlexInt `json:"longitude"` Timezone string `json:"timezone"` } From 03c22efaadaf38ea2b7f15396f660c8ac5d4844c Mon Sep 17 00:00:00 2001 From: Cody Lee Date: Tue, 25 Jul 2023 17:32:48 -0500 Subject: [PATCH 2/3] always generate positive numbers for flexint/flexfloat fakes --- types.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/types.go b/types.go index 53f7112..0747b1f 100644 --- a/types.go +++ b/types.go @@ -3,6 +3,7 @@ package unifi import ( "encoding/json" "fmt" + "math" "math/rand" "net/http" "strconv" @@ -319,7 +320,7 @@ func (f *FlexInt) AddFloat64(v float64) { // Fake implements gofakeit Fake interface func (f *FlexInt) Fake(faker *gofakeit.Faker) interface{} { - randValue := faker.Rand.Float64() + randValue := math.Abs(faker.Rand.Float64()) if faker.Rand.Intn(2) == 0 { // int-value return FlexInt{ @@ -465,7 +466,7 @@ func (f *FlexTemp) AddFloat64(v float64) { // Fake implements gofakeit Fake interface func (f *FlexTemp) Fake(faker *gofakeit.Faker) interface{} { - randValue := faker.Rand.Float64() + randValue := math.Abs(faker.Rand.Float64()) if faker.Rand.Intn(2) == 0 { // int-value return FlexTemp{ From f15e86171af40d8b8fc915cff3f71433ededcbb8 Mon Sep 17 00:00:00 2001 From: Cody Lee Date: Tue, 25 Jul 2023 17:41:23 -0500 Subject: [PATCH 3/3] lint --- mocks/mock_client.go | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/mocks/mock_client.go b/mocks/mock_client.go index 43497bb..a0f7a2d 100644 --- a/mocks/mock_client.go +++ b/mocks/mock_client.go @@ -2,8 +2,6 @@ package mocks import ( "math/rand" - "os" - "strconv" "time" "github.com/brianvoe/gofakeit/v6" @@ -11,23 +9,12 @@ import ( ) type MockUnifi struct { - faker *gofakeit.Faker *unifi.Config } // ensure MockUnifi implements the interface fully, this will fail to compile otherwise var _ unifi.UnifiClient = &MockUnifi{} -func fakeSeedValue() int64 { - seedVal := os.Getenv("UNPOLLER_FAKE_GEN_SEED") - if seedVal != "" { - if seed, err := strconv.ParseInt(seedVal, 10, 64); err != nil { - return seed - } - } - return 0 -} - func NewMockUnifi() *MockUnifi { return &MockUnifi{}