Skip to content

Commit a9251b6

Browse files
committed
Added License, update to 0.79
1 parent aeb423b commit a9251b6

File tree

14 files changed

+656
-74
lines changed

14 files changed

+656
-74
lines changed

lib/check_mk/base/plugins/agent_based/unifi_controller.py

Lines changed: 281 additions & 62 deletions
Large diffs are not rendered by default.

share/check_mk/agents/special/agent_unifi_controller

Lines changed: 180 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,29 @@
11
#!/usr/bin/env python3
22
# -*- encoding: utf-8; py-indent-offset: 4 -*-
3+
## MIT License
4+
##
5+
## Copyright (c) 2021 Bash Club
6+
##
7+
## Permission is hereby granted, free of charge, to any person obtaining a copy
8+
## of this software and associated documentation files (the "Software"), to deal
9+
## in the Software without restriction, including without limitation the rights
10+
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
## copies of the Software, and to permit persons to whom the Software is
12+
## furnished to do so, subject to the following conditions:
13+
##
14+
## The above copyright notice and this permission notice shall be included in all
15+
## copies or substantial portions of the Software.
16+
##
17+
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
## SOFTWARE.
324

425
###
5-
__VERSION__ = 0.75
26+
__VERSION__ = 0.79
627

728
import sys
829
import socket
@@ -14,7 +35,127 @@ from statistics import mean
1435
from collections import defaultdict
1536

1637
from pprint import pprint
17-
38+
try:
39+
import cmk.utils.paths
40+
AGENT_TMP_PATH = cmk.utils.paths.Path(cmk.utils.paths.tmp_dir, "agents/agent_unifi")
41+
except ImportError:
42+
AGENT_TMP_PATH = None
43+
44+
UNIFI_DEVICE_TABLE = {
45+
'BZ2' : 'UAP',
46+
'BZ2LR' : 'UAP-LR',
47+
'U2HSR' : 'UAP-Outdoor+',
48+
'U2IW' : 'UAP-IW',
49+
'U2L48' : 'UAP-AC-LR',
50+
'U2Lv2' : 'UAP-AC-LR',
51+
'U2M' : 'UAP-Mini',
52+
'U2O' : 'UAP-Outdoor',
53+
'U2S48' : 'UAP-AC',
54+
'U2Sv2' : 'UAP-AC',
55+
'U5O' : 'UAP-Outdoor5',
56+
'U7E' : 'UAP-AC',
57+
'U7EDU' : 'UAP-AC-EDU',
58+
'U7Ev2' : 'UAP-AC',
59+
'U7HD' : 'UAP-AC-HD',
60+
'U7SHD' : 'UAP-AC-SHD',
61+
'U7NHD' : 'UAP-nanoHD',
62+
'UFLHD' : 'UAP-FlexHD',
63+
'UHDIW' : 'UAP-IW-HD',
64+
'UAIW6' : 'U6-IW',
65+
'UAE6' : 'U6-Extender',
66+
'UAL6' : 'U6-Lite',
67+
'UAM6' : 'U6-Mesh',
68+
'UALR6' : 'U6-LR-EA',
69+
'UAP6' : 'U6-LR',
70+
'UALR6v2' : 'U6-LR',
71+
'UALR6v3' : 'U6-LR',
72+
'UCXG' : 'UAP-XG',
73+
'UXSDM' : 'UWB-XG',
74+
'UXBSDM' : 'UWB-XG-BK',
75+
'UCMSH' : 'UAP-XG-Mesh',
76+
'U7IW' : 'UAP-AC-IW',
77+
'U7IWP' : 'UAP-AC-IW-Pro',
78+
'U7MP' : 'UAP-AC-M-Pro',
79+
'U7LR' : 'UAP-AC-LR',
80+
'U7LT' : 'UAP-AC-Lite',
81+
'U7O' : 'UAP-AC-Outdoor',
82+
'U7P' : 'UAP-Pro',
83+
'U7MSH' : 'UAP-AC-M',
84+
'U7PG2' : 'UAP-AC-Pro',
85+
'p2N' : 'PICOM2HP',
86+
'UDMB' : 'UAP-BeaconHD',
87+
'USF5P' : 'USW-Flex',
88+
'US8' : 'US-8',
89+
'US8P60' : 'US-8-60W',
90+
'US8P150' : 'US-8-150W',
91+
'S28150' : 'US-8-150W',
92+
'USC8' : 'US-8',
93+
'USC8P60' : 'US-8-60W',
94+
'USC8P150' : 'US-8-150W',
95+
'US16P150' : 'US-16-150W',
96+
'S216150' : 'US-16-150W',
97+
'US24' : 'US-24-G1',
98+
'US24PRO' : 'USW-Pro-24-PoE',
99+
'US24PRO2' : 'USW-Pro-24',
100+
'US24P250' : 'US-24-250W',
101+
'US24PL2' : 'US-L2-24-PoE',
102+
'US24P500' : 'US-24-500W',
103+
'S224250' : 'US-24-250W',
104+
'S224500' : 'US-24-500W',
105+
'US48' : 'US-48-G1',
106+
'US48PRO' : 'USW-Pro-48-PoE',
107+
'US48PRO2' : 'USW-Pro-48',
108+
'US48P500' : 'US-48-500W',
109+
'US48PL2' : 'US-L2-48-PoE',
110+
'US48P750' : 'US-48-750W',
111+
'S248500' : 'US-48-500W',
112+
'S248750' : 'US-48-750W',
113+
'US6XG150' : 'US-XG-6PoE',
114+
'USMINI' : 'USW-Flex-Mini',
115+
'USXG' : 'US-16-XG',
116+
'USC8P450' : 'USW-Industrial',
117+
'UDC48X6' : 'USW-Leaf',
118+
'USL8A' : 'UniFi Switch Aggregation',
119+
'USAGGPRO' : 'UniFi Switch Aggregation Pro',
120+
'USL8LP' : 'USW-Lite-8-PoE',
121+
'USL8MP' : 'USW-Mission-Critical',
122+
'USL16P' : 'USW-16-PoE',
123+
'USL16LP' : 'USW-Lite-16-PoE',
124+
'USL24' : 'USW-24-G2',
125+
'USL48' : 'USW-48-G2',
126+
'USL24P' : 'USW-24-PoE',
127+
'USL48P' : 'USW-48-PoE',
128+
'UGW3' : 'USG-3P',
129+
'UGW4' : 'USG-Pro-4',
130+
'UGWHD4' : 'USG',
131+
'UGWXG' : 'USG-XG-8',
132+
'UDM' : 'UDM',
133+
'UDMSE' : 'UDM-SE',
134+
'UDMPRO' : 'UDM-Pro',
135+
'UP4' : 'UVP-X',
136+
'UP5' : 'UVP',
137+
'UP5t' : 'UVP-Pro',
138+
'UP7' : 'UVP-Executive',
139+
'UP5c' : 'UVP',
140+
'UP5tc' : 'UVP-Pro',
141+
'UP7c' : 'UVP-Executive',
142+
'UCK' : 'UCK',
143+
'UCK-v2' : 'UCK',
144+
'UCK-v3' : 'UCK',
145+
'UCKG2' : 'UCK-G2',
146+
'UCKP' : 'UCK-G2-Plus',
147+
'UASXG' : 'UAS-XG',
148+
'ULTE' : 'U-LTE',
149+
'ULTEPUS' : 'U-LTE-Pro',
150+
'ULTEPEU' : 'U-LTE-Pro',
151+
'UP1' : 'USP-Plug',
152+
'UP6' : 'USP-Strip',
153+
'USPPDUP' : 'USP - Power Distribution Unit Pro',
154+
'USPRPS' : 'USP-RPS',
155+
'US624P' : 'UniFi6 Switch 24',
156+
'UBB' : 'UBB',
157+
'UXGPRO' : 'UniFi NeXt-Gen Gateway PRO'
158+
}
18159

19160
try:
20161
from cmk.special_agents.utils.argument_parsing import create_default_argument_parser
@@ -40,6 +181,9 @@ class unifi_object(object):
40181
if hasattr(self,"_init"):
41182
self._init()
42183

184+
def __repr__(self):
185+
return repr([(_k,_v) for _k,_v in self.__dict__.items() if type(_v) in (int,str)])
186+
43187
########################################
44188
######
45189
###### S S I D
@@ -51,9 +195,17 @@ class unifi_network_ssid(unifi_object):
51195
self._UNIFI_SITE = self._PARENT._PARENT
52196
for _k,_v in getattr(self,"reasons_bar_chart_now",{}).items():
53197
setattr(self,_k,_v)
198+
setattr(self,f"{self.radio}_num_sta",self.num_sta)
199+
setattr(self,f"{self.radio}_tcp_packet_loss",self.tcp_packet_loss)
200+
setattr(self,f"{self.radio}_wifi_retries",self.wifi_retries)
201+
setattr(self,f"{self.radio}_wifi_latency",self.wifi_latency)
202+
setattr(self,f"{self.radio}_avg_client_signal",self.avg_client_signal)
54203
def __str__(self):
55204
_ret = []
56-
_unwanted = ["essid","radio","id","t","name","radio_name","wlanconf_id","is_wep","up","site_id","ap_mac","state"]
205+
_unwanted = ["essid","radio","id","t","name","radio_name","wlanconf_id","is_wep","up","site_id","ap_mac","state",
206+
"na_num_sta","ng_num_sta","ng_tcp_packet_loss","na_tcp_packet_loss","na_wifi_retries","ng_wifi_retries",
207+
"na_wifi_latency","ng_wifi_latency","na_avg_client_signal","ng_avg_client_signal"
208+
]
57209
for _k,_v in self.__dict__.items():
58210
if _k.startswith("_") or _k in _unwanted or type(_v) not in (str,int,float):
59211
continue
@@ -101,6 +253,9 @@ class unifi_network_port(unifi_object):
101253
self.name = self.ifname
102254
if not hasattr(self,"port_idx") and hasattr(self,"ifname"):
103255
self.port_idx = int(self.ifname[-1])+1 ## ethX
256+
257+
self.portconf = self._PARENT._PARENT._PORTCONFIGS.get(getattr(self,"portconf_id",None))
258+
104259

105260
def _get_state(self,state):
106261
return {
@@ -135,6 +290,7 @@ class unifi_device(unifi_object):
135290
for _k,_v in getattr(self,"sys_stats",{}).items():
136291
_k = _k.replace("-","_")
137292
setattr(self,_k,_v)
293+
self.model_name = UNIFI_DEVICE_TABLE.get(self.model)
138294
if self.type in ("ugw","udm"):
139295
## change ip to local ip
140296
self.wan_ip = self.ip
@@ -172,7 +328,7 @@ class unifi_device(unifi_object):
172328

173329
def _get_short_info(self):
174330
_ret = []
175-
_wanted = ["version","ip","mac","serial","model","uptime","upgradeable","num_sta"]
331+
_wanted = ["version","ip","mac","serial","model","model_name","uptime","upgradeable","num_sta","adopted","state"]
176332
for _k,_v in self.__dict__.items():
177333
if _k.startswith("_") or _k not in _wanted or type(_v) not in (str,int,float):
178334
continue
@@ -234,6 +390,8 @@ class unifi_site(unifi_object):
234390

235391
##pprint(_api.get_data("/stat/rogueap"))
236392
self._SITE_DEVICES = []
393+
self._PORTCONFIGS = {}
394+
self._get_portconfig()
237395
self._get_devices()
238396
_satisfaction = list(filter(
239397
lambda x: x != None,map(
@@ -242,6 +400,10 @@ class unifi_site(unifi_object):
242400
))
243401
self.satisfaction = max(0,int(mean(_satisfaction)) if _satisfaction else 0)
244402

403+
def _get_portconfig(self):
404+
_data = self._API.get_portconfig(site=self.name)
405+
for _config in _data:
406+
self._PORTCONFIGS[_config["_id"]] = _config.get("name")
245407

246408
def _get_devices(self):
247409
_data = self._API.get_devices(site=self.name)
@@ -308,7 +470,11 @@ class unifi_controller(unifi_object):
308470

309471
_ret = []
310472
for _ssid,_obj in _dict.items():
311-
_ret.append("|".join([_ssid,"num_sta",str(sum(map(lambda x: getattr(x,"num_sta",0),_obj)))]))
473+
pprint(_obj)
474+
for _key in ("num_sta","ng_num_sta","na_num_sta","ng_tcp_packet_loss","na_tcp_packet_loss","ng_wifi_retries","na_wifi_retries","ng_wifi_latency","na_wifi_latency"):
475+
_ret.append("|".join([_ssid,_key,str(sum(map(lambda x: getattr(x,_key,0),_obj)))]))
476+
_ret.append("|".join([_ssid,"ng_avg_client_signal",str(mean(map(lambda x: getattr(x,"ng_avg_client_signal",0),filter(lambda x: x.radio == "ng",_obj))))]))
477+
_ret.append("|".join([_ssid,"na_avg_client_signal",str(mean(map(lambda x: getattr(x,"na_avg_client_signal",0),filter(lambda x: x.radio == "na",_obj))))]))
312478
_ret.append("|".join([_ssid,"channels",",".join(
313479
sorted(
314480
set(map(lambda x: str(getattr(x,"channel","0")),_obj))
@@ -338,7 +504,7 @@ class unifi_controller(unifi_object):
338504
for _site in self._UNIFI_SITES:
339505
_ret.append(str(_site))
340506

341-
_ret.append("<<<unifi_device_shortlist>>>")
507+
_ret.append("<<<unifi_device_shortlist:sep(124)>>>")
342508
for _device in self._UNIFI_DEVICES:
343509
if _device._piggy_back:
344510
_ret.append(_device._get_short_info())
@@ -351,7 +517,7 @@ class unifi_controller(unifi_object):
351517
if self._API.PIGGYBACK_ATTRIBUT.lower() != "none":
352518
## PIGGYBACK DEVICES ##
353519
for _device in self._UNIFI_DEVICES:
354-
if _device._piggy_back:
520+
if _device._piggy_back and _device.adopted:
355521
_ret.append(str(_device))
356522
return "\n".join(_ret)
357523

@@ -388,6 +554,9 @@ class unifi_controller_api(object):
388554
def get_sites(self):
389555
return self.get_data("/stat/sites",site=None)
390556

557+
def get_portconfig(self,site):
558+
return self.get_data("/rest/portconf",site=site)
559+
391560
def get_devices(self,site):
392561
return self.get_data("/stat/device",site=site)
393562

@@ -409,8 +578,8 @@ class unifi_controller_api(object):
409578
return
410579
raise unifi_api_exception("Login failed")
411580

412-
def get_data(self,path,site="default",method="GET"):
413-
_json = self.request(method=method,path=path,site=site).json()
581+
def get_data(self,path,site="default",method="GET",**kwargs):
582+
_json = self.request(method=method,path=path,site=site,**kwargs).json()
414583
_meta = _json.get("meta",{})
415584
if _meta.get("rc") == "ok":
416585
return _json.get("data",[])
@@ -470,11 +639,10 @@ if __name__ == '__main__':
470639

471640
if _api.is_unifios:
472641
print("AgentOS: UnifiOS")
473-
#pprint(_api.get_data("rest/portconf",site="default",method="GET"))
474-
##pprint(_api.get_data("/stat/rogueap"))
642+
##pprint(_api.get_data("/stat/rogueap?within=4"))
475643
##pprint(_api.get_data("/rest/user",site="default",method="GET"))
476644
##pprint(_api.get_data("/stat/sta",site="default",method="GET"))
477-
#sys.exit(0)
645+
##sys.exit(0)
478646
_controller = unifi_controller(_API=_api)
479647
if args.rawapi == False:
480648
print(_controller)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
title: Unifi Controller
2+
agents: unifi_controller
3+
catalog: networking
4+
licence: MIT
5+
description:
6+
plz fill me
7+
8+
item:
9+
The name of the device
10+
11+
inventory:
12+
One Service for each device
13+

share/check_mk/checkman/unifi_device

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
title: Unifi Device
2+
agents: unifi_controller
3+
catalog: networking
4+
licence: MIT
5+
description:
6+
plz fill me
7+
8+
item:
9+
The name of the device
10+
11+
inventory:
12+
One Service for each device
13+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
title: Unifi Devicelist
2+
catalog: networking
3+
agents: unifi_controller
4+
licence: MIT
5+
description:
6+
plz fill me
7+
8+
item:
9+
The name of the device
10+
11+
inventory:
12+
One Service for each device
13+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
title: Unifi Network Port
2+
agents: unifi_controller
3+
catalog: networking
4+
licence: MIT
5+
description:
6+
plz fill me
7+
8+
item:
9+
The name of the Port
10+
11+
inventory:
12+
One Service for each Port
13+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
title: Unifi WLAN Radio
2+
agents: unifi_controller
3+
catalog: networking
4+
licence: MIT
5+
description:
6+
plz fill me
7+
8+
item:
9+
The name of the Radio
10+
11+
inventory:
12+
One Service for each Radio
13+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
title: Unifi SSID
2+
agents: unifi_controller
3+
catalog: networking
4+
licence: MIT
5+
description:
6+
plz fill me
7+
8+
item:
9+
The name of the SSID
10+
11+
inventory:
12+
One Service for each SSID
13+

0 commit comments

Comments
 (0)