-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathclients.go
More file actions
295 lines (261 loc) · 12.6 KB
/
Copy pathclients.go
File metadata and controls
295 lines (261 loc) · 12.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
package unifi
import (
"fmt"
"net/url"
"strconv"
"strings"
)
// GetClients returns a response full of clients' data from the UniFi Controller.
func (u *Unifi) GetClients(sites []*Site) ([]*Client, error) {
if u == nil {
return nil, ErrNilUnifi
}
data := make([]*Client, 0)
for _, site := range sites {
var response struct {
Data []*Client `json:"data"`
}
u.DebugLog("Polling Controller, retreiving UniFi Clients, site %s ", site.SiteName)
clientPath := fmt.Sprintf(APIClientPath, site.Name)
if err := u.GetData(clientPath, &response); err != nil {
return nil, err
}
for i, d := range response.Data {
// Add special SourceName value.
response.Data[i].SourceName = u.URL
// Add the special "Site Name" to each client. This becomes a Grafana filter somewhere.
response.Data[i].SiteName = site.SiteName
// Fix name and hostname fields. Sometimes one or the other is blank.
response.Data[i].Hostname = strings.TrimSpace(pick(d.Hostname, d.Name, d.Mac))
response.Data[i].Name = strings.TrimSpace(pick(d.Name, d.Hostname))
}
data = append(data, response.Data...)
}
return data, nil
}
// GetClientsDPI garners dpi data for clients.
func (u *Unifi) GetClientsDPI(sites []*Site) ([]*DPITable, error) {
var data []*DPITable
for _, site := range sites {
u.DebugLog("Polling Controller, retreiving Client DPI data, site %s", site.SiteName)
var response struct {
Data []*DPITable `json:"data"`
}
clientDPIpath := fmt.Sprintf(APIClientDPI, site.Name)
if err := u.GetData(clientDPIpath, &response, `{"type":"by_app"}`); err != nil {
return nil, err
}
for _, d := range response.Data {
d.SourceName = site.SourceName
d.SiteName = site.SiteName
data = append(data, d)
}
}
return data, nil
}
// GetClientHistory returns client history data from the controller for clients that conform to the provided filter options within the requested site(s).
func (u *Unifi) GetClientHistory(sites []*Site, opts *ClientHistoryOpts) ([]*ClientHistory, error) {
if opts == nil {
opts = NewClientHistoryOpts()
}
params := url.Values{}
params.Add("onlyNonBlocked", strconv.FormatBool(opts.OnlyNonBlocked))
params.Add("includeUnifiDevices", strconv.FormatBool(opts.IncludeUnifiDevices))
params.Add("withinHours", strconv.FormatUint(uint64(opts.WithinHours), 10))
paramStr := params.Encode()
data := make([]*ClientHistory, 0)
for _, site := range sites {
response := []*ClientHistory{}
u.DebugLog("Polling Controller, retreiving UniFi Client History, site %s ", site.SiteName)
clientPath := fmt.Sprintf(APIClientHistoryPath, site.Name, paramStr)
if err := u.GetData(clientPath, &response, ""); err != nil {
return nil, err
}
for i, d := range response {
// Add special SourceName value.
response[i].SourceName = u.URL
// Add the special "Site Name" to each client. This becomes a Grafana filter somewhere.
response[i].SiteName = site.SiteName
// Fix name and hostname fields. Sometimes one or the other is blank.
response[i].Hostname = strings.TrimSpace(pick(d.Hostname, d.Name, d.Mac))
response[i].Name = strings.TrimSpace(pick(d.Name, d.Hostname))
}
data = append(data, response...)
}
return data, nil
}
// Client defines all the data a connected-network client contains.
type Client struct {
Anomalies FlexInt `json:"anomalies,omitempty"`
ApMac string `fake:"{macaddress}" json:"ap_mac"`
ApName string `json:"-"`
AssocTime FlexInt `json:"assoc_time"`
Blocked bool `json:"blocked,omitempty"`
Bssid string `fake:"{macaddress}" json:"bssid"`
BytesR FlexInt `json:"bytes-r"`
Ccq FlexInt `json:"ccq"`
Channel FlexInt `json:"channel"`
DevCat FlexInt `json:"dev_cat"`
DevFamily FlexInt `json:"dev_family"`
DevID FlexInt `json:"dev_id"`
DevVendor FlexInt `json:"dev_vendor,omitempty"`
DhcpendTime FlexInt `json:"dhcpend_time,omitempty"`
Essid string `fake:"{macaddress}" json:"essid"`
FirstSeen FlexInt `json:"first_seen"`
FixedIP string `fake:"{ipv4address}" json:"fixed_ip"`
GwMac string `fake:"{macaddress}" json:"gw_mac"`
GwName string `json:"-"`
Hostname string `json:"hostname"`
ID string `fake:"{uuid}" json:"_id"`
IP string `fake:"{ipv4address}" json:"ip"`
IdleTime FlexInt `json:"idle_time"`
Is11R FlexBool `json:"is_11r"`
IsGuest FlexBool `json:"is_guest"`
IsGuestByUAP FlexBool `json:"_is_guest_by_uap"`
IsGuestByUGW FlexBool `json:"_is_guest_by_ugw"`
IsGuestByUSW FlexBool `json:"_is_guest_by_usw"`
IsWired FlexBool `json:"is_wired"`
LastSeen FlexInt `json:"last_seen"`
LastSeenByUAP FlexInt `json:"_last_seen_by_uap"`
LastSeenByUGW FlexInt `json:"_last_seen_by_ugw"`
LastSeenByUSW FlexInt `json:"_last_seen_by_usw"`
LatestAssocTime FlexInt `json:"latest_assoc_time"`
Mac string `fake:"{macaddress}" json:"mac"`
Name string `fake:"{randomstring:[client-1,client-2,client-3]}" json:"name"`
Network string `json:"network"`
NetworkID string `fake:"{uuid}" json:"network_id"`
Noise FlexInt `json:"noise"`
Note string `fake:"{sentence 20}" json:"note"`
Noted FlexBool `json:"noted"`
OsClass FlexInt `json:"os_class"`
OsName FlexInt `json:"os_name"`
Oui string `json:"oui"`
PowersaveEnabled FlexBool `json:"powersave_enabled"`
QosPolicyApplied FlexBool `json:"qos_policy_applied"`
Radio string `json:"radio"`
RadioDescription string `json:"-"`
RadioName string `json:"radio_name"`
RadioProto string `json:"radio_proto"`
RoamCount FlexInt `json:"roam_count"`
Rssi FlexInt `json:"rssi"`
RxBytes FlexInt `json:"rx_bytes"`
RxBytesR FlexInt `json:"rx_bytes-r"`
RxMcs FlexInt `json:"rx_mcs"`
RxNSS FlexInt `json:"rx_nss"`
RxPackets FlexInt `json:"rx_packets"`
RxRate FlexInt `json:"rx_rate"`
Satisfaction FlexInt `json:"satisfaction,omitempty"`
Signal FlexInt `json:"signal"`
SiteID string `fake:"{uuid}" json:"site_id"`
SiteName string `json:"-"`
SourceName string `json:"-"`
SwDepth int `json:"sw_depth"`
SwMac string `fake:"{macaddress}" json:"sw_mac"`
SwName string `json:"-"`
SwPort FlexInt `json:"sw_port"`
TxBytes FlexInt `json:"tx_bytes"`
TxBytesR FlexInt `json:"tx_bytes-r"`
TxMcs FlexInt `json:"tx_mcs"`
TxNSS FlexInt `json:"tx_nss"`
TxPackets FlexInt `json:"tx_packets"`
TxPower FlexInt `json:"tx_power"`
TxRate FlexInt `json:"tx_rate"`
TxRetries FlexInt `json:"tx_retries"`
Uptime FlexInt `json:"uptime"`
UptimeByUAP FlexInt `json:"_uptime_by_uap"`
UptimeByUGW FlexInt `json:"_uptime_by_ugw"`
UptimeByUSW FlexInt `json:"_uptime_by_usw"`
UseFixedIP FlexBool `json:"use_fixedip"`
UserGroupID string `fake:"{uuid}" json:"usergroup_id"`
UserID string `fake:"{uuid}" json:"user_id"`
Vlan FlexInt `json:"vlan"`
WifiTxAttempts FlexInt `json:"wifi_tx_attempts"`
WiredRxBytes FlexInt `json:"wired-rx_bytes"`
WiredRxBytesR FlexInt `json:"wired-rx_bytes-r"`
WiredRxPackets FlexInt `json:"wired-rx_packets"`
WiredTxBytes FlexInt `json:"wired-tx_bytes"`
WiredTxBytesR FlexInt `json:"wired-tx_bytes-r"`
WiredTxPackets FlexInt `json:"wired-tx_packets"`
}
// ClientHistory defines the data of a connected or previously connected client
type ClientHistory struct {
Blocked FlexBool `json:"blocked"`
Channel FlexInt `json:"channel"`
DisplayName string `json:"display_name"`
Fingerprint struct {
HasOverride FlexBool `json:"has_override"`
} `json:"fingerprint"`
FirstSeen FlexInt `json:"first_seen"`
FixedApEnabled FlexBool `json:"fixed_ap_enabled,omitempty"`
Hostname string `fake:"noun" json:"hostname,omitempty"`
ID string `fake:"{uuid}" json:"id"`
IsAllowedInVisualProgramming FlexBool `json:"is_allowed_in_visual_programming"`
IsGuest FlexBool `json:"is_guest"`
IsMlo FlexBool `json:"is_mlo"`
IsWired FlexBool `json:"is_wired"`
LastIP string `fake:"ipv4address" json:"last_ip"`
LastRadio string `json:"last_radio"`
LastSeen FlexInt `json:"last_seen"`
LastUplinkMac string `fake:"macaddress" json:"last_uplink_mac"`
LastUplinkName string `json:"last_uplink_name"`
LastUplinkPort FlexInt `json:"last_uplink_remote_port"`
LocalDNSRecord string `json:"local_dns_record,omitempty"`
LocalDNSRecordEnabled FlexBool `json:"local_dns_record_enabled"`
Mac string `fake:"macaddress" json:"mac"`
Note string `json:"note"`
Noted FlexBool `json:"noted"`
Oui string `json:"oui"`
SiteID string `json:"site_id"`
Status string `json:"status"`
Tags []FlexString `json:"tags"`
Type string `json:"type"`
UnifiDevice FlexBool `json:"unifi_device"`
UplinkMac string `fake:"macaddress" json:"uplink_mac"`
UseFixedip FlexBool `json:"use_fixedip"`
UserID string `json:"user_id"`
UsergroupID string `json:"usergroup_id"`
VirtualNetworkOverrideEnabled FlexBool `json:"virtual_network_override_enabled"`
VirtualNetworkOverrideID string `json:"virtual_network_override_id,omitempty"`
WlanconfID string `json:"wlanconf_id"`
Name string `json:"name,omitempty"`
UnifiDeviceInfo struct {
IconFilename string `json:"icon_filename"`
IconResolutions [][]int `json:"icon_resolutions"`
ViewInApplication bool `json:"view_in_application"`
} `json:"unifi_device_info,omitempty"`
SiteName string `json:"-"`
SourceName string `json:"-"`
FixedIP string `json:"fixed_ip,omitempty"`
}
// ClientHistoryOpts contains the query options for GetClientHistory
type ClientHistoryOpts struct {
OnlyNonBlocked bool
IncludeUnifiDevices bool
WithinHours uint // WithinHours is the length of time since the controller has seen the device(s). Use 0 for no limit
}
// NewClientHistoryOpts returns a new ClientHistoryOpts with values set to include all device history
func NewClientHistoryOpts() *ClientHistoryOpts {
return &ClientHistoryOpts{
OnlyNonBlocked: false,
IncludeUnifiDevices: true,
WithinHours: 0,
}
}
// SetOnlyNonBlocked sets the OnlyNonBlocked field of the ClientHistoryOpts struct
// returns a pointer to the ClientHistoryOpts struct to allow for chaining of the options methods
func (c *ClientHistoryOpts) SetOnlyNonBlocked(onlyNonBlocked bool) *ClientHistoryOpts {
c.OnlyNonBlocked = onlyNonBlocked
return c
}
// SetIncludeUnifiDevices sets the IncludeUnifiDevices field of the ClientHistoryOpts struct
// returns a pointer to the ClientHistoryOpts struct to allow for chaining of the options methods
func (c *ClientHistoryOpts) SetIncludeUnifiDevices(includeUnifiDevices bool) *ClientHistoryOpts {
c.IncludeUnifiDevices = includeUnifiDevices
return c
}
// SetWithinHours sets the WithinHours field of the ClientHistoryOpts struct
// returns a pointer to the ClientHistoryOpts struct to allow for chaining of the options methods
func (c *ClientHistoryOpts) SetWithinHours(withinHours uint) *ClientHistoryOpts {
c.WithinHours = withinHours
return c
}