mirror of
https://github.com/bashclub/check-unifi-controller.git
synced 2024-11-07 20:31:58 +01:00
Added License, update to 0.79
This commit is contained in:
parent
aeb423bf0b
commit
a9251b6dfc
@ -1,6 +1,28 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||||
#
|
#
|
||||||
|
## MIT License
|
||||||
|
##
|
||||||
|
## Copyright (c) 2021 Bash Club
|
||||||
|
##
|
||||||
|
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
## of this software and associated documentation files (the "Software"), to deal
|
||||||
|
## in the Software without restriction, including without limitation the rights
|
||||||
|
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
## copies of the Software, and to permit persons to whom the Software is
|
||||||
|
## furnished to do so, subject to the following conditions:
|
||||||
|
##
|
||||||
|
## The above copyright notice and this permission notice shall be included in all
|
||||||
|
## copies or substantial portions of the Software.
|
||||||
|
##
|
||||||
|
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
## SOFTWARE.
|
||||||
|
|
||||||
from cmk.gui.i18n import _
|
from cmk.gui.i18n import _
|
||||||
|
|
||||||
from .agent_based_api.v1 import (
|
from .agent_based_api.v1 import (
|
||||||
@ -8,9 +30,13 @@ from .agent_based_api.v1 import (
|
|||||||
register,
|
register,
|
||||||
render,
|
render,
|
||||||
Result,
|
Result,
|
||||||
|
IgnoreResults,
|
||||||
Service,
|
Service,
|
||||||
State,
|
State,
|
||||||
|
TableRow,
|
||||||
|
Attributes
|
||||||
)
|
)
|
||||||
|
|
||||||
from .agent_based_api.v1.type_defs import CheckResult, DiscoveryResult
|
from .agent_based_api.v1.type_defs import CheckResult, DiscoveryResult
|
||||||
from typing import Any, Dict, Mapping, Sequence, Optional
|
from typing import Any, Dict, Mapping, Sequence, Optional
|
||||||
|
|
||||||
@ -38,6 +64,12 @@ def _safe_float(val):
|
|||||||
except (TypeError,ValueError):
|
except (TypeError,ValueError):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def _safe_int(val,default=0):
|
||||||
|
try:
|
||||||
|
return int(val)
|
||||||
|
except (TypeError,ValueError):
|
||||||
|
return default
|
||||||
|
|
||||||
def _unifi_status2state(status):
|
def _unifi_status2state(status):
|
||||||
return {
|
return {
|
||||||
"ok" : State.OK,
|
"ok" : State.OK,
|
||||||
@ -59,6 +91,13 @@ def parse_unifi_nested_dict(string_table):
|
|||||||
_ret[_line[0]][_line[1]] = _line[2]
|
_ret[_line[0]][_line[1]] = _line[2]
|
||||||
return _ret
|
return _ret
|
||||||
|
|
||||||
|
UNIFI_DEVICE_STATES = {
|
||||||
|
"0" : "disconnected",
|
||||||
|
"1" : "connected",
|
||||||
|
"2" : "pending"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
############ Controller ############
|
############ Controller ############
|
||||||
def discovery_unifi_controller(section):
|
def discovery_unifi_controller(section):
|
||||||
yield Service(item="Unifi Controller")
|
yield Service(item="Unifi Controller")
|
||||||
@ -88,6 +127,14 @@ def check_unifi_controller(item,section):
|
|||||||
notice=_("Update available")
|
notice=_("Update available")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def inventory_unifi_controller(section):
|
||||||
|
yield Attributes(
|
||||||
|
path=["software","os"],
|
||||||
|
inventory_attributes={
|
||||||
|
"controller_version" : section.get("controller_version")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
register.agent_section(
|
register.agent_section(
|
||||||
name = 'unifi_controller',
|
name = 'unifi_controller',
|
||||||
parse_function = parse_unifi_dict
|
parse_function = parse_unifi_dict
|
||||||
@ -99,6 +146,12 @@ register.check_plugin(
|
|||||||
discovery_function=discovery_unifi_controller,
|
discovery_function=discovery_unifi_controller,
|
||||||
check_function=check_unifi_controller,
|
check_function=check_unifi_controller,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
register.inventory_plugin(
|
||||||
|
name = "unifi_controller",
|
||||||
|
inventory_function = inventory_unifi_controller
|
||||||
|
)
|
||||||
|
|
||||||
############ SITES ###########
|
############ SITES ###########
|
||||||
|
|
||||||
def discovery_unifi_sites(section):
|
def discovery_unifi_sites(section):
|
||||||
@ -107,15 +160,15 @@ def discovery_unifi_sites(section):
|
|||||||
|
|
||||||
def check_unifi_sites(item,section):
|
def check_unifi_sites(item,section):
|
||||||
site = next(filter(lambda x: x.desc == item,section.values()))
|
site = next(filter(lambda x: x.desc == item,section.values()))
|
||||||
yield Metric("satisfaction",max(0,interfaces.saveint(site.satisfaction)))
|
yield Metric("satisfaction",max(0,_safe_int(site.satisfaction)))
|
||||||
|
|
||||||
if site.lan_status != "unknown":
|
if site.lan_status != "unknown":
|
||||||
yield Metric("lan_user_sta",interfaces.saveint(site.lan_num_user))
|
yield Metric("lan_user_sta",_safe_int(site.lan_num_user))
|
||||||
yield Metric("lan_guest_sta",interfaces.saveint(site.lan_num_guest))
|
yield Metric("lan_guest_sta",_safe_int(site.lan_num_guest))
|
||||||
yield Metric("if_in_octets",interfaces.saveint(site.lan_rx_bytes_r))
|
yield Metric("if_in_octets",_safe_int(site.lan_rx_bytes_r))
|
||||||
#yield Metric("if_in_bps",interfaces.saveint(site.lan_rx_bytes_r)*8)
|
#yield Metric("if_in_bps",_safe_int(site.lan_rx_bytes_r)*8)
|
||||||
yield Metric("if_out_octets",interfaces.saveint(site.lan_tx_bytes_r))
|
yield Metric("if_out_octets",_safe_int(site.lan_tx_bytes_r))
|
||||||
#yield Metric("if_out_bps",interfaces.saveint(site.lan_tx_bytes_r)*8)
|
#yield Metric("if_out_bps",_safe_int(site.lan_tx_bytes_r)*8)
|
||||||
|
|
||||||
yield Result(
|
yield Result(
|
||||||
state=_unifi_status2state(site.lan_status),
|
state=_unifi_status2state(site.lan_status),
|
||||||
@ -127,11 +180,11 @@ def check_unifi_sites(item,section):
|
|||||||
#)
|
#)
|
||||||
|
|
||||||
if site.wlan_status != "unknown":
|
if site.wlan_status != "unknown":
|
||||||
yield Metric("wlan_user_sta",interfaces.saveint(site.wlan_num_user))
|
yield Metric("wlan_user_sta",_safe_int(site.wlan_num_user))
|
||||||
yield Metric("wlan_guest_sta",interfaces.saveint(site.wlan_num_guest))
|
yield Metric("wlan_guest_sta",_safe_int(site.wlan_num_guest))
|
||||||
yield Metric("wlan_iot_sta",interfaces.saveint(site.wlan_num_iot))
|
yield Metric("wlan_iot_sta",_safe_int(site.wlan_num_iot))
|
||||||
yield Metric("wlan_if_in_octets",interfaces.saveint(site.wlan_rx_bytes_r))
|
yield Metric("wlan_if_in_octets",_safe_int(site.wlan_rx_bytes_r))
|
||||||
yield Metric("wlan_if_out_octets",interfaces.saveint(site.wlan_tx_bytes_r))
|
yield Metric("wlan_if_out_octets",_safe_int(site.wlan_tx_bytes_r))
|
||||||
yield Result(
|
yield Result(
|
||||||
state=_unifi_status2state(site.wlan_status),
|
state=_unifi_status2state(site.wlan_status),
|
||||||
summary=f"WLAN: {site.wlan_num_ap}/{site.wlan_num_adopted} AP ({site.wlan_status})"
|
summary=f"WLAN: {site.wlan_num_ap}/{site.wlan_num_adopted} AP ({site.wlan_status})"
|
||||||
@ -173,6 +226,36 @@ register.check_plugin(
|
|||||||
check_function=check_unifi_sites,
|
check_function=check_unifi_sites,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
############ DEVICE_SHORTLIST ##########
|
||||||
|
|
||||||
|
def inventory_unifi_device_shortlist(section):
|
||||||
|
for _name,_device in section.items():
|
||||||
|
yield TableRow(
|
||||||
|
path=["hardware","networkdevices"],
|
||||||
|
key_columns={"_name" : _name},
|
||||||
|
inventory_columns={
|
||||||
|
"serial" : _device.get("serial"),
|
||||||
|
"_state" : UNIFI_DEVICE_STATES.get(_device.state,"unknown"),
|
||||||
|
"vendor" : "ubiquiti",
|
||||||
|
"model" : _device.get("model_name",_device.get("model")),
|
||||||
|
"version" : _device.version,
|
||||||
|
"ip_address": _device.ip,
|
||||||
|
"mac" : _device.mac
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
register.agent_section(
|
||||||
|
name = 'unifi_device_shortlist',
|
||||||
|
parse_function = parse_unifi_nested_dict
|
||||||
|
)
|
||||||
|
|
||||||
|
register.inventory_plugin(
|
||||||
|
name = "unifi_device_shortlist",
|
||||||
|
inventory_function = inventory_unifi_device_shortlist
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
############ DEVICE ###########
|
############ DEVICE ###########
|
||||||
def discovery_unifi_device(section):
|
def discovery_unifi_device(section):
|
||||||
yield Service(item="Unifi Device")
|
yield Service(item="Unifi Device")
|
||||||
@ -188,29 +271,32 @@ def discovery_unifi_device(section):
|
|||||||
yield Service(item="Speedtest")
|
yield Service(item="Speedtest")
|
||||||
|
|
||||||
def check_unifi_device(item,section):
|
def check_unifi_device(item,section):
|
||||||
|
if section.state != "1":
|
||||||
|
yield IgnoreResults(f"device not active State: {section.state}")
|
||||||
|
|
||||||
if item == "Unifi Device":
|
if item == "Unifi Device":
|
||||||
yield Result(
|
yield Result(
|
||||||
state=State.OK,
|
state=State.OK,
|
||||||
summary=f"Version: {section.version}"
|
summary=f"Version: {section.version}"
|
||||||
)
|
)
|
||||||
if interfaces.saveint(section.upgradable) > 0:
|
if _safe_int(section.upgradable) > 0:
|
||||||
yield Result(
|
yield Result(
|
||||||
state=State.WARN,
|
state=State.WARN,
|
||||||
notice=_("Update available")
|
notice=_("Update available")
|
||||||
)
|
)
|
||||||
if item == "Active-User":
|
if item == "Active-User":
|
||||||
_active_user = interfaces.saveint(section.user_num_sta)
|
_active_user = _safe_int(section.user_num_sta)
|
||||||
yield Result(
|
yield Result(
|
||||||
state=State.OK,
|
state=State.OK,
|
||||||
summary=f"{_active_user}"
|
summary=f"{_active_user}"
|
||||||
)
|
)
|
||||||
if interfaces.saveint(section.guest_num_sta) > -1:
|
if _safe_int(section.guest_num_sta) > -1:
|
||||||
yield Result(
|
yield Result(
|
||||||
state=State.OK,
|
state=State.OK,
|
||||||
summary=f"Guest: {section.guest_num_sta}"
|
summary=f"Guest: {section.guest_num_sta}"
|
||||||
)
|
)
|
||||||
yield Metric("user_sta",_active_user)
|
yield Metric("user_sta",_active_user)
|
||||||
yield Metric("guest_sta",interfaces.saveint(section.guest_num_sta))
|
yield Metric("guest_sta",_safe_int(section.guest_num_sta))
|
||||||
if item == "Uptime":
|
if item == "Uptime":
|
||||||
_uptime = int(section.uptime) if section.uptime else -1
|
_uptime = int(section.uptime) if section.uptime else -1
|
||||||
if _uptime > 0:
|
if _uptime > 0:
|
||||||
@ -224,7 +310,7 @@ def check_unifi_device(item,section):
|
|||||||
state=State.OK,
|
state=State.OK,
|
||||||
summary=f"{section.satisfaction}%"
|
summary=f"{section.satisfaction}%"
|
||||||
)
|
)
|
||||||
yield Metric("satisfaction",max(0,interfaces.saveint(section.satisfaction)))
|
yield Metric("satisfaction",max(0,_safe_int(section.satisfaction)))
|
||||||
if item == "Temperature":
|
if item == "Temperature":
|
||||||
yield Metric("temp",_safe_float(section.general_temperature))
|
yield Metric("temp",_safe_float(section.general_temperature))
|
||||||
yield Result(
|
yield Result(
|
||||||
@ -264,6 +350,33 @@ def check_unifi_device(item,section):
|
|||||||
summary=f"Device {section.uplink_device} Port: {section.uplink_remote_port}"
|
summary=f"Device {section.uplink_device} Port: {section.uplink_remote_port}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def inventory_unifi_device(section):
|
||||||
|
yield Attributes(
|
||||||
|
path=["software","os"],
|
||||||
|
inventory_attributes={
|
||||||
|
"version" : section.get("version")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
yield Attributes(
|
||||||
|
path=["software","configuration","snmp_info"],
|
||||||
|
inventory_attributes = {
|
||||||
|
"name" : section.get("name"),
|
||||||
|
"contact" : section.get("snmp_contact"),
|
||||||
|
"location" : section.get("snmp_location")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
_hwdict = {
|
||||||
|
"vendor" : "ubiquiti",
|
||||||
|
}
|
||||||
|
for _key in ("model","board_rev","serial","mac"):
|
||||||
|
_val = section.get(_key)
|
||||||
|
if _val:
|
||||||
|
_hwdict[_key] = _val
|
||||||
|
yield Attributes(
|
||||||
|
path=["hardware","system"],
|
||||||
|
inventory_attributes= _hwdict
|
||||||
|
)
|
||||||
|
|
||||||
register.agent_section(
|
register.agent_section(
|
||||||
name = 'unifi_device',
|
name = 'unifi_device',
|
||||||
parse_function = parse_unifi_dict
|
parse_function = parse_unifi_dict
|
||||||
@ -275,6 +388,12 @@ register.check_plugin(
|
|||||||
discovery_function=discovery_unifi_device,
|
discovery_function=discovery_unifi_device,
|
||||||
check_function=check_unifi_device,
|
check_function=check_unifi_device,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
register.inventory_plugin(
|
||||||
|
name = "unifi_device",
|
||||||
|
inventory_function = inventory_unifi_device
|
||||||
|
)
|
||||||
|
|
||||||
############ DEVICEPORT ###########
|
############ DEVICEPORT ###########
|
||||||
@dataclass
|
@dataclass
|
||||||
class unifi_interface(interfaces.Interface):
|
class unifi_interface(interfaces.Interface):
|
||||||
@ -290,34 +409,87 @@ class unifi_interface(interfaces.Interface):
|
|||||||
dot1x_mode : Optional[str] = None
|
dot1x_mode : Optional[str] = None
|
||||||
dot1x_status : Optional[str] = None
|
dot1x_status : Optional[str] = None
|
||||||
ip_address : Optional[str] = None
|
ip_address : Optional[str] = None
|
||||||
|
portconf : Optional[str] = None
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
self.finalize()
|
self.finalize()
|
||||||
|
|
||||||
def _convert_unifi_counters_if(section: Section) -> interfaces.Section:
|
def _convert_unifi_counters_if(section: Section) -> interfaces.Section:
|
||||||
|
## 10|port_idx|10
|
||||||
|
## 10|port_poe|1
|
||||||
|
## 10|poe_caps|7
|
||||||
|
## 10|op_mode|switch
|
||||||
|
## 10|poe_mode|auto
|
||||||
|
## 10|anomalies|0
|
||||||
|
## 10|autoneg|1
|
||||||
|
## 10|dot1x_mode|unknown
|
||||||
|
## 10|dot1x_status|disabled
|
||||||
|
## 10|enable|1
|
||||||
|
## 10|full_duplex|1
|
||||||
|
## 10|is_uplink|0
|
||||||
|
## 10|jumbo|1
|
||||||
|
## 10|poe_class|Unknown
|
||||||
|
## 10|poe_current|0.00
|
||||||
|
## 10|poe_enable|0
|
||||||
|
## 10|poe_good|0
|
||||||
|
## 10|poe_power|0.00
|
||||||
|
## 10|poe_voltage|0.00
|
||||||
|
## 10|rx_broadcast|1290
|
||||||
|
## 10|rx_bytes|38499976384
|
||||||
|
## 10|rx_dropped|0
|
||||||
|
## 10|rx_errors|0
|
||||||
|
## 10|rx_multicast|16423
|
||||||
|
## 10|rx_packets|125489263
|
||||||
|
## 10|satisfaction|100
|
||||||
|
## 10|satisfaction_reason|0
|
||||||
|
## 10|speed|1000
|
||||||
|
## 10|stp_pathcost|20000
|
||||||
|
## 10|stp_state|forwarding
|
||||||
|
## 10|tx_broadcast|20791854
|
||||||
|
## 10|tx_bytes|238190158091
|
||||||
|
## 10|tx_dropped|0
|
||||||
|
## 10|tx_errors|0
|
||||||
|
## 10|tx_multicast|262691
|
||||||
|
## 10|tx_packets|228482694
|
||||||
|
## 10|tx_bytes_r|17729
|
||||||
|
## 10|rx_bytes_r|176941
|
||||||
|
## 10|bytes_r|194671
|
||||||
|
## 10|name|Port 10
|
||||||
|
## 10|aggregated_by|0
|
||||||
|
## 10|oper_status|1
|
||||||
|
## 10|admin_status|1
|
||||||
|
## 10|portconf|ALL
|
||||||
|
## unifi_interface(index='10', descr='Port 10', alias='Port 10', type='6', speed=1000000000, oper_status='1',
|
||||||
|
## in_octets=38448560321, in_ucast=125404491, in_mcast=16414, in_bcast=1290, in_discards=0, in_errors=0,
|
||||||
|
## out_octets=238185160794, out_ucast=228451699, out_mcast=262551, out_bcast=20783341, out_discards=0, out_errors=0,
|
||||||
|
## out_qlen=0, phys_address='', oper_status_name='up', speed_as_text='', group=None, node=None, admin_status='1',
|
||||||
|
## total_octets=276633721115, jumbo=True, satisfaction=100,
|
||||||
|
## poe_enable=False, poe_mode='auto', poe_good=None, poe_current=0.0, poe_power=0.0, poe_voltage=0.0, poe_class='Unknown',
|
||||||
|
## dot1x_mode='unknown',dot1x_status='disabled', ip_address='', portconf='ALL')
|
||||||
|
|
||||||
return [
|
return [
|
||||||
unifi_interface(
|
unifi_interface(
|
||||||
index=str(netif.port_idx),
|
index=str(netif.port_idx),
|
||||||
descr=netif.name,
|
descr=netif.name,
|
||||||
alias=netif.name,
|
alias=netif.name,
|
||||||
type='6',
|
type='6',
|
||||||
speed=interfaces.saveint(netif.speed)*1000000,
|
speed=_safe_int(netif.speed)*1000000,
|
||||||
oper_status=netif.oper_status,
|
oper_status=netif.oper_status,
|
||||||
admin_status=netif.admin_status,
|
admin_status=netif.admin_status,
|
||||||
in_octets=interfaces.saveint(netif.rx_bytes),
|
in_octets=_safe_int(netif.rx_bytes),
|
||||||
in_ucast=interfaces.saveint(netif.rx_packets),
|
in_ucast=_safe_int(netif.rx_packets),
|
||||||
in_mcast=interfaces.saveint(netif.rx_multicast),
|
in_mcast=_safe_int(netif.rx_multicast),
|
||||||
in_bcast=interfaces.saveint(netif.rx_broadcast),
|
in_bcast=_safe_int(netif.rx_broadcast),
|
||||||
in_discards=interfaces.saveint(netif.rx_dropped),
|
in_discards=_safe_int(netif.rx_dropped),
|
||||||
in_errors=interfaces.saveint(netif.rx_errors),
|
in_errors=_safe_int(netif.rx_errors),
|
||||||
out_octets=interfaces.saveint(netif.tx_bytes),
|
out_octets=_safe_int(netif.tx_bytes),
|
||||||
out_ucast=interfaces.saveint(netif.tx_packets),
|
out_ucast=_safe_int(netif.tx_packets),
|
||||||
out_mcast=interfaces.saveint(netif.tx_multicast),
|
out_mcast=_safe_int(netif.tx_multicast),
|
||||||
out_bcast=interfaces.saveint(netif.tx_broadcast),
|
out_bcast=_safe_int(netif.tx_broadcast),
|
||||||
out_discards=interfaces.saveint(netif.tx_dropped),
|
out_discards=_safe_int(netif.tx_dropped),
|
||||||
out_errors=interfaces.saveint(netif.tx_errors),
|
out_errors=_safe_int(netif.tx_errors),
|
||||||
jumbo=True if netif.jumbo == "1" else False,
|
jumbo=True if netif.jumbo == "1" else False,
|
||||||
satisfaction=interfaces.saveint(netif.satisfaction) if netif.satisfaction and netif.oper_status == "1" else 0,
|
satisfaction=_safe_int(netif.satisfaction) if netif.satisfaction and netif.oper_status == "1" else 0,
|
||||||
poe_enable=True if netif.poe_enable == "1" else False,
|
poe_enable=True if netif.poe_enable == "1" else False,
|
||||||
poe_mode=netif.poe_mode,
|
poe_mode=netif.poe_mode,
|
||||||
poe_current=float(netif.poe_current) if netif.poe_current else 0,
|
poe_current=float(netif.poe_current) if netif.poe_current else 0,
|
||||||
@ -326,7 +498,8 @@ def _convert_unifi_counters_if(section: Section) -> interfaces.Section:
|
|||||||
poe_class=netif.poe_class,
|
poe_class=netif.poe_class,
|
||||||
dot1x_mode=netif.dot1x_mode,
|
dot1x_mode=netif.dot1x_mode,
|
||||||
dot1x_status=netif.dot1x_status,
|
dot1x_status=netif.dot1x_status,
|
||||||
ip_address=netif.ip
|
ip_address=netif.ip,
|
||||||
|
portconf=netif.portconf
|
||||||
) for netif in parse_unifi_nested_dict(section).values()
|
) for netif in parse_unifi_nested_dict(section).values()
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -348,13 +521,19 @@ def check_unifi_network_port_if( ##fixme parsed_section_name
|
|||||||
section: Section,
|
section: Section,
|
||||||
) -> CheckResult:
|
) -> CheckResult:
|
||||||
_converted_ifs = _convert_unifi_counters_if(section)
|
_converted_ifs = _convert_unifi_counters_if(section)
|
||||||
iface = next(filter(lambda x: item in (x.index,x.alias),_converted_ifs),None) ## fix Service Discovery appearance alias/descr
|
iface = next(filter(lambda x: _safe_int(item,-1) == _safe_int(x.index) or item == x.alias,_converted_ifs),None) ## fix Service Discovery appearance alias/descr
|
||||||
yield from interfaces.check_multiple_interfaces(
|
yield from interfaces.check_multiple_interfaces(
|
||||||
item,
|
item,
|
||||||
params,
|
params,
|
||||||
_converted_ifs,
|
_converted_ifs,
|
||||||
)
|
)
|
||||||
if iface:
|
if iface:
|
||||||
|
#pprint(iface)
|
||||||
|
if iface.portconf:
|
||||||
|
yield Result(
|
||||||
|
state=State.OK,
|
||||||
|
summary=f"Network: {iface.portconf}"
|
||||||
|
)
|
||||||
yield Metric("satisfaction",max(0,iface.satisfaction))
|
yield Metric("satisfaction",max(0,iface.satisfaction))
|
||||||
#pprint(iface)
|
#pprint(iface)
|
||||||
if iface.poe_enable:
|
if iface.poe_enable:
|
||||||
@ -371,6 +550,35 @@ def check_unifi_network_port_if( ##fixme parsed_section_name
|
|||||||
summary=f"IP: {iface.ip_address}"
|
summary=f"IP: {iface.ip_address}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def inventory_unifi_network_ports(section):
|
||||||
|
_total_ethernet_ports = 0
|
||||||
|
_available_ethernet_ports = 0
|
||||||
|
for _iface in parse_unifi_nested_dict(section).values():
|
||||||
|
_total_ethernet_ports +=1
|
||||||
|
_available_ethernet_ports +=1 if _iface.oper_status == '2' else 0
|
||||||
|
yield TableRow(
|
||||||
|
path=["networking","interfaces"],
|
||||||
|
key_columns={"index" : _safe_int(_iface.port_idx)},
|
||||||
|
inventory_columns={
|
||||||
|
"description" : _iface.name,
|
||||||
|
"alias" : _iface.name,
|
||||||
|
"speed" : _safe_int(_iface.speed)*1000000,
|
||||||
|
"oper_status" : _safe_int(_iface.oper_status),
|
||||||
|
"admin_status" : _safe_int(_iface.admin_status),
|
||||||
|
"available" : _iface.oper_status == '2',
|
||||||
|
"vlans" : _iface.portconf,
|
||||||
|
"port_type" : 6,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
yield Attributes(
|
||||||
|
path=["networking"],
|
||||||
|
inventory_attributes={
|
||||||
|
"available_ethernet_ports" : _available_ethernet_ports,
|
||||||
|
"total_ethernet_ports" : _total_ethernet_ports,
|
||||||
|
"total_interfaces" : _total_ethernet_ports
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
register.check_plugin(
|
register.check_plugin(
|
||||||
name='unifi_network_ports_if',
|
name='unifi_network_ports_if',
|
||||||
@ -384,6 +592,12 @@ register.check_plugin(
|
|||||||
check_default_parameters=interfaces.CHECK_DEFAULT_PARAMETERS,
|
check_default_parameters=interfaces.CHECK_DEFAULT_PARAMETERS,
|
||||||
check_function=check_unifi_network_port_if,
|
check_function=check_unifi_network_port_if,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
register.inventory_plugin(
|
||||||
|
name = "unifi_network_ports",
|
||||||
|
inventory_function = inventory_unifi_network_ports
|
||||||
|
)
|
||||||
|
|
||||||
############ DEVICERADIO ###########
|
############ DEVICERADIO ###########
|
||||||
def discovery_unifi_radios(section):
|
def discovery_unifi_radios(section):
|
||||||
#pprint(section)
|
#pprint(section)
|
||||||
@ -396,12 +610,12 @@ def discovery_unifi_radios(section):
|
|||||||
def check_unifi_radios(item,section):
|
def check_unifi_radios(item,section):
|
||||||
_item = { "2.4Ghz" : "ng", "5Ghz" : "na" }.get(item)
|
_item = { "2.4Ghz" : "ng", "5Ghz" : "na" }.get(item)
|
||||||
radio = next(filter(lambda x: x.radio == _item,section.values()))
|
radio = next(filter(lambda x: x.radio == _item,section.values()))
|
||||||
yield Metric("read_data",interfaces.saveint(radio.rx_bytes))
|
yield Metric("read_data",_safe_int(radio.rx_bytes))
|
||||||
yield Metric("write_data",interfaces.saveint(radio.tx_bytes))
|
yield Metric("write_data",_safe_int(radio.tx_bytes))
|
||||||
yield Metric("satisfaction",max(0,interfaces.saveint(radio.satisfaction)))
|
yield Metric("satisfaction",max(0,_safe_int(radio.satisfaction)))
|
||||||
yield Metric("wlan_user_sta",interfaces.saveint(radio.user_num_sta))
|
yield Metric("wlan_user_sta",_safe_int(radio.user_num_sta))
|
||||||
yield Metric("wlan_guest_sta",interfaces.saveint(radio.guest_num_sta))
|
yield Metric("wlan_guest_sta",_safe_int(radio.guest_num_sta))
|
||||||
yield Metric("wlan_iot_sta",interfaces.saveint(radio.iot_num_sta))
|
yield Metric("wlan_iot_sta",_safe_int(radio.iot_num_sta))
|
||||||
|
|
||||||
yield Result(
|
yield Result(
|
||||||
state=State.OK,
|
state=State.OK,
|
||||||
@ -440,41 +654,41 @@ def discovery_unifi_ssids(section):
|
|||||||
|
|
||||||
def check_unifi_ssids(item,section):
|
def check_unifi_ssids(item,section):
|
||||||
ssid = section.get(item)
|
ssid = section.get(item)
|
||||||
_channels = ",".join(list(filter(lambda x: interfaces.saveint(x) > 0,[ssid.ng_channel,ssid.na_channel])))
|
_channels = ",".join(list(filter(lambda x: _safe_int(x) > 0,[ssid.ng_channel,ssid.na_channel])))
|
||||||
yield Result(
|
yield Result(
|
||||||
state=State.OK,
|
state=State.OK,
|
||||||
summary=f"Channels: {_channels}"
|
summary=f"Channels: {_channels}"
|
||||||
)
|
)
|
||||||
if (interfaces.saveint(ssid.ng_is_guest) + interfaces.saveint(ssid.na_is_guest)) > 0:
|
if (_safe_int(ssid.ng_is_guest) + _safe_int(ssid.na_is_guest)) > 0:
|
||||||
yield Result(
|
yield Result(
|
||||||
state=State.OK,
|
state=State.OK,
|
||||||
summary="Guest"
|
summary="Guest"
|
||||||
)
|
)
|
||||||
_satisfaction = max(0,min(interfaces.saveint(ssid.ng_satisfaction),interfaces.saveint(ssid.na_satisfaction)))
|
_satisfaction = max(0,min(_safe_int(ssid.ng_satisfaction),_safe_int(ssid.na_satisfaction)))
|
||||||
yield Result(
|
yield Result(
|
||||||
state=State.OK,
|
state=State.OK,
|
||||||
summary=f"Satisfaction: {_satisfaction}"
|
summary=f"Satisfaction: {_satisfaction}"
|
||||||
)
|
)
|
||||||
_num_sta = interfaces.saveint(ssid.na_num_sta) + interfaces.saveint(ssid.ng_num_sta)
|
_num_sta = _safe_int(ssid.na_num_sta) + _safe_int(ssid.ng_num_sta)
|
||||||
if _num_sta > 0:
|
if _num_sta > 0:
|
||||||
yield Result(
|
yield Result(
|
||||||
state=State.OK,
|
state=State.OK,
|
||||||
summary=f"User: {_num_sta}"
|
summary=f"User: {_num_sta}"
|
||||||
)
|
)
|
||||||
yield Metric("satisfaction",max(0,_satisfaction))
|
yield Metric("satisfaction",max(0,_satisfaction))
|
||||||
yield Metric("wlan_24Ghz_num_user",interfaces.saveint(ssid.ng_num_sta) )
|
yield Metric("wlan_24Ghz_num_user",_safe_int(ssid.ng_num_sta) )
|
||||||
yield Metric("wlan_5Ghz_num_user",interfaces.saveint(ssid.na_num_sta) )
|
yield Metric("wlan_5Ghz_num_user",_safe_int(ssid.na_num_sta) )
|
||||||
|
|
||||||
yield Metric("na_avg_client_signal",interfaces.saveint(ssid.na_avg_client_signal))
|
yield Metric("na_avg_client_signal",_safe_int(ssid.na_avg_client_signal))
|
||||||
yield Metric("ng_avg_client_signal",interfaces.saveint(ssid.ng_avg_client_signal))
|
yield Metric("ng_avg_client_signal",_safe_int(ssid.ng_avg_client_signal))
|
||||||
|
|
||||||
yield Metric("na_tcp_packet_loss",interfaces.saveint(ssid.na_tcp_packet_loss))
|
yield Metric("na_tcp_packet_loss",_safe_int(ssid.na_tcp_packet_loss))
|
||||||
yield Metric("ng_tcp_packet_loss",interfaces.saveint(ssid.ng_tcp_packet_loss))
|
yield Metric("ng_tcp_packet_loss",_safe_int(ssid.ng_tcp_packet_loss))
|
||||||
|
|
||||||
yield Metric("na_wifi_retries",interfaces.saveint(ssid.na_wifi_retries))
|
yield Metric("na_wifi_retries",_safe_int(ssid.na_wifi_retries))
|
||||||
yield Metric("ng_wifi_retries",interfaces.saveint(ssid.ng_wifi_retries))
|
yield Metric("ng_wifi_retries",_safe_int(ssid.ng_wifi_retries))
|
||||||
yield Metric("na_wifi_latency",interfaces.saveint(ssid.na_wifi_latency))
|
yield Metric("na_wifi_latency",_safe_int(ssid.na_wifi_latency))
|
||||||
yield Metric("ng_wifi_latency",interfaces.saveint(ssid.ng_wifi_latency))
|
yield Metric("ng_wifi_latency",_safe_int(ssid.ng_wifi_latency))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -503,19 +717,22 @@ def check_unifi_ssidlist(item,section):
|
|||||||
state=State.OK,
|
state=State.OK,
|
||||||
summary=f"Channels: {ssid.channels}"
|
summary=f"Channels: {ssid.channels}"
|
||||||
)
|
)
|
||||||
# if (interfaces.saveint(ssid.ng_is_guest) + interfaces.saveint(ssid.na_is_guest)) > 0:
|
|
||||||
# yield Result(
|
|
||||||
# state=State.OK,
|
|
||||||
# summary="Guest"
|
|
||||||
# )
|
|
||||||
# yield Result(
|
|
||||||
# state=State.OK,
|
|
||||||
# summary=f"Satisfaction: {_satisfaction}"
|
|
||||||
# )
|
|
||||||
yield Result(
|
yield Result(
|
||||||
state=State.OK,
|
state=State.OK,
|
||||||
summary=f"User: {ssid.num_sta}"
|
summary=f"User: {ssid.num_sta}"
|
||||||
)
|
)
|
||||||
|
yield Metric("wlan_24Ghz_num_user",_safe_int(ssid.ng_num_sta) )
|
||||||
|
yield Metric("wlan_5Ghz_num_user",_safe_int(ssid.na_num_sta) )
|
||||||
|
yield Metric("na_avg_client_signal",_safe_int(ssid.na_avg_client_signal))
|
||||||
|
yield Metric("ng_avg_client_signal",_safe_int(ssid.ng_avg_client_signal))
|
||||||
|
|
||||||
|
yield Metric("na_tcp_packet_loss",_safe_int(ssid.na_tcp_packet_loss))
|
||||||
|
yield Metric("ng_tcp_packet_loss",_safe_int(ssid.ng_tcp_packet_loss))
|
||||||
|
|
||||||
|
yield Metric("na_wifi_retries",_safe_int(ssid.na_wifi_retries))
|
||||||
|
yield Metric("ng_wifi_retries",_safe_int(ssid.ng_wifi_retries))
|
||||||
|
yield Metric("na_wifi_latency",_safe_int(ssid.na_wifi_latency))
|
||||||
|
yield Metric("ng_wifi_latency",_safe_int(ssid.ng_wifi_latency))
|
||||||
|
|
||||||
register.agent_section(
|
register.agent_section(
|
||||||
name = 'unifi_ssid_list',
|
name = 'unifi_ssid_list',
|
||||||
@ -530,3 +747,5 @@ register.check_plugin(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,29 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||||
|
## MIT License
|
||||||
|
##
|
||||||
|
## Copyright (c) 2021 Bash Club
|
||||||
|
##
|
||||||
|
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
## of this software and associated documentation files (the "Software"), to deal
|
||||||
|
## in the Software without restriction, including without limitation the rights
|
||||||
|
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
## copies of the Software, and to permit persons to whom the Software is
|
||||||
|
## furnished to do so, subject to the following conditions:
|
||||||
|
##
|
||||||
|
## The above copyright notice and this permission notice shall be included in all
|
||||||
|
## copies or substantial portions of the Software.
|
||||||
|
##
|
||||||
|
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
## SOFTWARE.
|
||||||
|
|
||||||
###
|
###
|
||||||
__VERSION__ = 0.75
|
__VERSION__ = 0.79
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import socket
|
import socket
|
||||||
@ -14,7 +35,127 @@ from statistics import mean
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
try:
|
||||||
|
import cmk.utils.paths
|
||||||
|
AGENT_TMP_PATH = cmk.utils.paths.Path(cmk.utils.paths.tmp_dir, "agents/agent_unifi")
|
||||||
|
except ImportError:
|
||||||
|
AGENT_TMP_PATH = None
|
||||||
|
|
||||||
|
UNIFI_DEVICE_TABLE = {
|
||||||
|
'BZ2' : 'UAP',
|
||||||
|
'BZ2LR' : 'UAP-LR',
|
||||||
|
'U2HSR' : 'UAP-Outdoor+',
|
||||||
|
'U2IW' : 'UAP-IW',
|
||||||
|
'U2L48' : 'UAP-AC-LR',
|
||||||
|
'U2Lv2' : 'UAP-AC-LR',
|
||||||
|
'U2M' : 'UAP-Mini',
|
||||||
|
'U2O' : 'UAP-Outdoor',
|
||||||
|
'U2S48' : 'UAP-AC',
|
||||||
|
'U2Sv2' : 'UAP-AC',
|
||||||
|
'U5O' : 'UAP-Outdoor5',
|
||||||
|
'U7E' : 'UAP-AC',
|
||||||
|
'U7EDU' : 'UAP-AC-EDU',
|
||||||
|
'U7Ev2' : 'UAP-AC',
|
||||||
|
'U7HD' : 'UAP-AC-HD',
|
||||||
|
'U7SHD' : 'UAP-AC-SHD',
|
||||||
|
'U7NHD' : 'UAP-nanoHD',
|
||||||
|
'UFLHD' : 'UAP-FlexHD',
|
||||||
|
'UHDIW' : 'UAP-IW-HD',
|
||||||
|
'UAIW6' : 'U6-IW',
|
||||||
|
'UAE6' : 'U6-Extender',
|
||||||
|
'UAL6' : 'U6-Lite',
|
||||||
|
'UAM6' : 'U6-Mesh',
|
||||||
|
'UALR6' : 'U6-LR-EA',
|
||||||
|
'UAP6' : 'U6-LR',
|
||||||
|
'UALR6v2' : 'U6-LR',
|
||||||
|
'UALR6v3' : 'U6-LR',
|
||||||
|
'UCXG' : 'UAP-XG',
|
||||||
|
'UXSDM' : 'UWB-XG',
|
||||||
|
'UXBSDM' : 'UWB-XG-BK',
|
||||||
|
'UCMSH' : 'UAP-XG-Mesh',
|
||||||
|
'U7IW' : 'UAP-AC-IW',
|
||||||
|
'U7IWP' : 'UAP-AC-IW-Pro',
|
||||||
|
'U7MP' : 'UAP-AC-M-Pro',
|
||||||
|
'U7LR' : 'UAP-AC-LR',
|
||||||
|
'U7LT' : 'UAP-AC-Lite',
|
||||||
|
'U7O' : 'UAP-AC-Outdoor',
|
||||||
|
'U7P' : 'UAP-Pro',
|
||||||
|
'U7MSH' : 'UAP-AC-M',
|
||||||
|
'U7PG2' : 'UAP-AC-Pro',
|
||||||
|
'p2N' : 'PICOM2HP',
|
||||||
|
'UDMB' : 'UAP-BeaconHD',
|
||||||
|
'USF5P' : 'USW-Flex',
|
||||||
|
'US8' : 'US-8',
|
||||||
|
'US8P60' : 'US-8-60W',
|
||||||
|
'US8P150' : 'US-8-150W',
|
||||||
|
'S28150' : 'US-8-150W',
|
||||||
|
'USC8' : 'US-8',
|
||||||
|
'USC8P60' : 'US-8-60W',
|
||||||
|
'USC8P150' : 'US-8-150W',
|
||||||
|
'US16P150' : 'US-16-150W',
|
||||||
|
'S216150' : 'US-16-150W',
|
||||||
|
'US24' : 'US-24-G1',
|
||||||
|
'US24PRO' : 'USW-Pro-24-PoE',
|
||||||
|
'US24PRO2' : 'USW-Pro-24',
|
||||||
|
'US24P250' : 'US-24-250W',
|
||||||
|
'US24PL2' : 'US-L2-24-PoE',
|
||||||
|
'US24P500' : 'US-24-500W',
|
||||||
|
'S224250' : 'US-24-250W',
|
||||||
|
'S224500' : 'US-24-500W',
|
||||||
|
'US48' : 'US-48-G1',
|
||||||
|
'US48PRO' : 'USW-Pro-48-PoE',
|
||||||
|
'US48PRO2' : 'USW-Pro-48',
|
||||||
|
'US48P500' : 'US-48-500W',
|
||||||
|
'US48PL2' : 'US-L2-48-PoE',
|
||||||
|
'US48P750' : 'US-48-750W',
|
||||||
|
'S248500' : 'US-48-500W',
|
||||||
|
'S248750' : 'US-48-750W',
|
||||||
|
'US6XG150' : 'US-XG-6PoE',
|
||||||
|
'USMINI' : 'USW-Flex-Mini',
|
||||||
|
'USXG' : 'US-16-XG',
|
||||||
|
'USC8P450' : 'USW-Industrial',
|
||||||
|
'UDC48X6' : 'USW-Leaf',
|
||||||
|
'USL8A' : 'UniFi Switch Aggregation',
|
||||||
|
'USAGGPRO' : 'UniFi Switch Aggregation Pro',
|
||||||
|
'USL8LP' : 'USW-Lite-8-PoE',
|
||||||
|
'USL8MP' : 'USW-Mission-Critical',
|
||||||
|
'USL16P' : 'USW-16-PoE',
|
||||||
|
'USL16LP' : 'USW-Lite-16-PoE',
|
||||||
|
'USL24' : 'USW-24-G2',
|
||||||
|
'USL48' : 'USW-48-G2',
|
||||||
|
'USL24P' : 'USW-24-PoE',
|
||||||
|
'USL48P' : 'USW-48-PoE',
|
||||||
|
'UGW3' : 'USG-3P',
|
||||||
|
'UGW4' : 'USG-Pro-4',
|
||||||
|
'UGWHD4' : 'USG',
|
||||||
|
'UGWXG' : 'USG-XG-8',
|
||||||
|
'UDM' : 'UDM',
|
||||||
|
'UDMSE' : 'UDM-SE',
|
||||||
|
'UDMPRO' : 'UDM-Pro',
|
||||||
|
'UP4' : 'UVP-X',
|
||||||
|
'UP5' : 'UVP',
|
||||||
|
'UP5t' : 'UVP-Pro',
|
||||||
|
'UP7' : 'UVP-Executive',
|
||||||
|
'UP5c' : 'UVP',
|
||||||
|
'UP5tc' : 'UVP-Pro',
|
||||||
|
'UP7c' : 'UVP-Executive',
|
||||||
|
'UCK' : 'UCK',
|
||||||
|
'UCK-v2' : 'UCK',
|
||||||
|
'UCK-v3' : 'UCK',
|
||||||
|
'UCKG2' : 'UCK-G2',
|
||||||
|
'UCKP' : 'UCK-G2-Plus',
|
||||||
|
'UASXG' : 'UAS-XG',
|
||||||
|
'ULTE' : 'U-LTE',
|
||||||
|
'ULTEPUS' : 'U-LTE-Pro',
|
||||||
|
'ULTEPEU' : 'U-LTE-Pro',
|
||||||
|
'UP1' : 'USP-Plug',
|
||||||
|
'UP6' : 'USP-Strip',
|
||||||
|
'USPPDUP' : 'USP - Power Distribution Unit Pro',
|
||||||
|
'USPRPS' : 'USP-RPS',
|
||||||
|
'US624P' : 'UniFi6 Switch 24',
|
||||||
|
'UBB' : 'UBB',
|
||||||
|
'UXGPRO' : 'UniFi NeXt-Gen Gateway PRO'
|
||||||
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from cmk.special_agents.utils.argument_parsing import create_default_argument_parser
|
from cmk.special_agents.utils.argument_parsing import create_default_argument_parser
|
||||||
@ -40,6 +181,9 @@ class unifi_object(object):
|
|||||||
if hasattr(self,"_init"):
|
if hasattr(self,"_init"):
|
||||||
self._init()
|
self._init()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return repr([(_k,_v) for _k,_v in self.__dict__.items() if type(_v) in (int,str)])
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
######
|
######
|
||||||
###### S S I D
|
###### S S I D
|
||||||
@ -51,9 +195,17 @@ class unifi_network_ssid(unifi_object):
|
|||||||
self._UNIFI_SITE = self._PARENT._PARENT
|
self._UNIFI_SITE = self._PARENT._PARENT
|
||||||
for _k,_v in getattr(self,"reasons_bar_chart_now",{}).items():
|
for _k,_v in getattr(self,"reasons_bar_chart_now",{}).items():
|
||||||
setattr(self,_k,_v)
|
setattr(self,_k,_v)
|
||||||
|
setattr(self,f"{self.radio}_num_sta",self.num_sta)
|
||||||
|
setattr(self,f"{self.radio}_tcp_packet_loss",self.tcp_packet_loss)
|
||||||
|
setattr(self,f"{self.radio}_wifi_retries",self.wifi_retries)
|
||||||
|
setattr(self,f"{self.radio}_wifi_latency",self.wifi_latency)
|
||||||
|
setattr(self,f"{self.radio}_avg_client_signal",self.avg_client_signal)
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
_ret = []
|
_ret = []
|
||||||
_unwanted = ["essid","radio","id","t","name","radio_name","wlanconf_id","is_wep","up","site_id","ap_mac","state"]
|
_unwanted = ["essid","radio","id","t","name","radio_name","wlanconf_id","is_wep","up","site_id","ap_mac","state",
|
||||||
|
"na_num_sta","ng_num_sta","ng_tcp_packet_loss","na_tcp_packet_loss","na_wifi_retries","ng_wifi_retries",
|
||||||
|
"na_wifi_latency","ng_wifi_latency","na_avg_client_signal","ng_avg_client_signal"
|
||||||
|
]
|
||||||
for _k,_v in self.__dict__.items():
|
for _k,_v in self.__dict__.items():
|
||||||
if _k.startswith("_") or _k in _unwanted or type(_v) not in (str,int,float):
|
if _k.startswith("_") or _k in _unwanted or type(_v) not in (str,int,float):
|
||||||
continue
|
continue
|
||||||
@ -101,6 +253,9 @@ class unifi_network_port(unifi_object):
|
|||||||
self.name = self.ifname
|
self.name = self.ifname
|
||||||
if not hasattr(self,"port_idx") and hasattr(self,"ifname"):
|
if not hasattr(self,"port_idx") and hasattr(self,"ifname"):
|
||||||
self.port_idx = int(self.ifname[-1])+1 ## ethX
|
self.port_idx = int(self.ifname[-1])+1 ## ethX
|
||||||
|
|
||||||
|
self.portconf = self._PARENT._PARENT._PORTCONFIGS.get(getattr(self,"portconf_id",None))
|
||||||
|
|
||||||
|
|
||||||
def _get_state(self,state):
|
def _get_state(self,state):
|
||||||
return {
|
return {
|
||||||
@ -135,6 +290,7 @@ class unifi_device(unifi_object):
|
|||||||
for _k,_v in getattr(self,"sys_stats",{}).items():
|
for _k,_v in getattr(self,"sys_stats",{}).items():
|
||||||
_k = _k.replace("-","_")
|
_k = _k.replace("-","_")
|
||||||
setattr(self,_k,_v)
|
setattr(self,_k,_v)
|
||||||
|
self.model_name = UNIFI_DEVICE_TABLE.get(self.model)
|
||||||
if self.type in ("ugw","udm"):
|
if self.type in ("ugw","udm"):
|
||||||
## change ip to local ip
|
## change ip to local ip
|
||||||
self.wan_ip = self.ip
|
self.wan_ip = self.ip
|
||||||
@ -172,7 +328,7 @@ class unifi_device(unifi_object):
|
|||||||
|
|
||||||
def _get_short_info(self):
|
def _get_short_info(self):
|
||||||
_ret = []
|
_ret = []
|
||||||
_wanted = ["version","ip","mac","serial","model","uptime","upgradeable","num_sta"]
|
_wanted = ["version","ip","mac","serial","model","model_name","uptime","upgradeable","num_sta","adopted","state"]
|
||||||
for _k,_v in self.__dict__.items():
|
for _k,_v in self.__dict__.items():
|
||||||
if _k.startswith("_") or _k not in _wanted or type(_v) not in (str,int,float):
|
if _k.startswith("_") or _k not in _wanted or type(_v) not in (str,int,float):
|
||||||
continue
|
continue
|
||||||
@ -234,6 +390,8 @@ class unifi_site(unifi_object):
|
|||||||
|
|
||||||
##pprint(_api.get_data("/stat/rogueap"))
|
##pprint(_api.get_data("/stat/rogueap"))
|
||||||
self._SITE_DEVICES = []
|
self._SITE_DEVICES = []
|
||||||
|
self._PORTCONFIGS = {}
|
||||||
|
self._get_portconfig()
|
||||||
self._get_devices()
|
self._get_devices()
|
||||||
_satisfaction = list(filter(
|
_satisfaction = list(filter(
|
||||||
lambda x: x != None,map(
|
lambda x: x != None,map(
|
||||||
@ -242,6 +400,10 @@ class unifi_site(unifi_object):
|
|||||||
))
|
))
|
||||||
self.satisfaction = max(0,int(mean(_satisfaction)) if _satisfaction else 0)
|
self.satisfaction = max(0,int(mean(_satisfaction)) if _satisfaction else 0)
|
||||||
|
|
||||||
|
def _get_portconfig(self):
|
||||||
|
_data = self._API.get_portconfig(site=self.name)
|
||||||
|
for _config in _data:
|
||||||
|
self._PORTCONFIGS[_config["_id"]] = _config.get("name")
|
||||||
|
|
||||||
def _get_devices(self):
|
def _get_devices(self):
|
||||||
_data = self._API.get_devices(site=self.name)
|
_data = self._API.get_devices(site=self.name)
|
||||||
@ -308,7 +470,11 @@ class unifi_controller(unifi_object):
|
|||||||
|
|
||||||
_ret = []
|
_ret = []
|
||||||
for _ssid,_obj in _dict.items():
|
for _ssid,_obj in _dict.items():
|
||||||
_ret.append("|".join([_ssid,"num_sta",str(sum(map(lambda x: getattr(x,"num_sta",0),_obj)))]))
|
pprint(_obj)
|
||||||
|
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"):
|
||||||
|
_ret.append("|".join([_ssid,_key,str(sum(map(lambda x: getattr(x,_key,0),_obj)))]))
|
||||||
|
_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))))]))
|
||||||
|
_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))))]))
|
||||||
_ret.append("|".join([_ssid,"channels",",".join(
|
_ret.append("|".join([_ssid,"channels",",".join(
|
||||||
sorted(
|
sorted(
|
||||||
set(map(lambda x: str(getattr(x,"channel","0")),_obj))
|
set(map(lambda x: str(getattr(x,"channel","0")),_obj))
|
||||||
@ -338,7 +504,7 @@ class unifi_controller(unifi_object):
|
|||||||
for _site in self._UNIFI_SITES:
|
for _site in self._UNIFI_SITES:
|
||||||
_ret.append(str(_site))
|
_ret.append(str(_site))
|
||||||
|
|
||||||
_ret.append("<<<unifi_device_shortlist>>>")
|
_ret.append("<<<unifi_device_shortlist:sep(124)>>>")
|
||||||
for _device in self._UNIFI_DEVICES:
|
for _device in self._UNIFI_DEVICES:
|
||||||
if _device._piggy_back:
|
if _device._piggy_back:
|
||||||
_ret.append(_device._get_short_info())
|
_ret.append(_device._get_short_info())
|
||||||
@ -351,7 +517,7 @@ class unifi_controller(unifi_object):
|
|||||||
if self._API.PIGGYBACK_ATTRIBUT.lower() != "none":
|
if self._API.PIGGYBACK_ATTRIBUT.lower() != "none":
|
||||||
## PIGGYBACK DEVICES ##
|
## PIGGYBACK DEVICES ##
|
||||||
for _device in self._UNIFI_DEVICES:
|
for _device in self._UNIFI_DEVICES:
|
||||||
if _device._piggy_back:
|
if _device._piggy_back and _device.adopted:
|
||||||
_ret.append(str(_device))
|
_ret.append(str(_device))
|
||||||
return "\n".join(_ret)
|
return "\n".join(_ret)
|
||||||
|
|
||||||
@ -388,6 +554,9 @@ class unifi_controller_api(object):
|
|||||||
def get_sites(self):
|
def get_sites(self):
|
||||||
return self.get_data("/stat/sites",site=None)
|
return self.get_data("/stat/sites",site=None)
|
||||||
|
|
||||||
|
def get_portconfig(self,site):
|
||||||
|
return self.get_data("/rest/portconf",site=site)
|
||||||
|
|
||||||
def get_devices(self,site):
|
def get_devices(self,site):
|
||||||
return self.get_data("/stat/device",site=site)
|
return self.get_data("/stat/device",site=site)
|
||||||
|
|
||||||
@ -409,8 +578,8 @@ class unifi_controller_api(object):
|
|||||||
return
|
return
|
||||||
raise unifi_api_exception("Login failed")
|
raise unifi_api_exception("Login failed")
|
||||||
|
|
||||||
def get_data(self,path,site="default",method="GET"):
|
def get_data(self,path,site="default",method="GET",**kwargs):
|
||||||
_json = self.request(method=method,path=path,site=site).json()
|
_json = self.request(method=method,path=path,site=site,**kwargs).json()
|
||||||
_meta = _json.get("meta",{})
|
_meta = _json.get("meta",{})
|
||||||
if _meta.get("rc") == "ok":
|
if _meta.get("rc") == "ok":
|
||||||
return _json.get("data",[])
|
return _json.get("data",[])
|
||||||
@ -470,11 +639,10 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
if _api.is_unifios:
|
if _api.is_unifios:
|
||||||
print("AgentOS: UnifiOS")
|
print("AgentOS: UnifiOS")
|
||||||
#pprint(_api.get_data("rest/portconf",site="default",method="GET"))
|
##pprint(_api.get_data("/stat/rogueap?within=4"))
|
||||||
##pprint(_api.get_data("/stat/rogueap"))
|
|
||||||
##pprint(_api.get_data("/rest/user",site="default",method="GET"))
|
##pprint(_api.get_data("/rest/user",site="default",method="GET"))
|
||||||
##pprint(_api.get_data("/stat/sta",site="default",method="GET"))
|
##pprint(_api.get_data("/stat/sta",site="default",method="GET"))
|
||||||
#sys.exit(0)
|
##sys.exit(0)
|
||||||
_controller = unifi_controller(_API=_api)
|
_controller = unifi_controller(_API=_api)
|
||||||
if args.rawapi == False:
|
if args.rawapi == False:
|
||||||
print(_controller)
|
print(_controller)
|
||||||
|
13
share/check_mk/checkman/unifi_controller
Normal file
13
share/check_mk/checkman/unifi_controller
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
title: Unifi Controller
|
||||||
|
agents: unifi_controller
|
||||||
|
catalog: networking
|
||||||
|
licence: MIT
|
||||||
|
description:
|
||||||
|
plz fill me
|
||||||
|
|
||||||
|
item:
|
||||||
|
The name of the device
|
||||||
|
|
||||||
|
inventory:
|
||||||
|
One Service for each device
|
||||||
|
|
13
share/check_mk/checkman/unifi_device
Normal file
13
share/check_mk/checkman/unifi_device
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
title: Unifi Device
|
||||||
|
agents: unifi_controller
|
||||||
|
catalog: networking
|
||||||
|
licence: MIT
|
||||||
|
description:
|
||||||
|
plz fill me
|
||||||
|
|
||||||
|
item:
|
||||||
|
The name of the device
|
||||||
|
|
||||||
|
inventory:
|
||||||
|
One Service for each device
|
||||||
|
|
13
share/check_mk/checkman/unifi_device_shortlist
Normal file
13
share/check_mk/checkman/unifi_device_shortlist
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
title: Unifi Devicelist
|
||||||
|
catalog: networking
|
||||||
|
agents: unifi_controller
|
||||||
|
licence: MIT
|
||||||
|
description:
|
||||||
|
plz fill me
|
||||||
|
|
||||||
|
item:
|
||||||
|
The name of the device
|
||||||
|
|
||||||
|
inventory:
|
||||||
|
One Service for each device
|
||||||
|
|
13
share/check_mk/checkman/unifi_network_ports_if
Normal file
13
share/check_mk/checkman/unifi_network_ports_if
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
title: Unifi Network Port
|
||||||
|
agents: unifi_controller
|
||||||
|
catalog: networking
|
||||||
|
licence: MIT
|
||||||
|
description:
|
||||||
|
plz fill me
|
||||||
|
|
||||||
|
item:
|
||||||
|
The name of the Port
|
||||||
|
|
||||||
|
inventory:
|
||||||
|
One Service for each Port
|
||||||
|
|
13
share/check_mk/checkman/unifi_network_radios
Normal file
13
share/check_mk/checkman/unifi_network_radios
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
title: Unifi WLAN Radio
|
||||||
|
agents: unifi_controller
|
||||||
|
catalog: networking
|
||||||
|
licence: MIT
|
||||||
|
description:
|
||||||
|
plz fill me
|
||||||
|
|
||||||
|
item:
|
||||||
|
The name of the Radio
|
||||||
|
|
||||||
|
inventory:
|
||||||
|
One Service for each Radio
|
||||||
|
|
13
share/check_mk/checkman/unifi_network_ssids
Normal file
13
share/check_mk/checkman/unifi_network_ssids
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
title: Unifi SSID
|
||||||
|
agents: unifi_controller
|
||||||
|
catalog: networking
|
||||||
|
licence: MIT
|
||||||
|
description:
|
||||||
|
plz fill me
|
||||||
|
|
||||||
|
item:
|
||||||
|
The name of the SSID
|
||||||
|
|
||||||
|
inventory:
|
||||||
|
One Service for each SSID
|
||||||
|
|
13
share/check_mk/checkman/unifi_sites
Normal file
13
share/check_mk/checkman/unifi_sites
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
title: Unifi Site
|
||||||
|
agents: unifi_controller
|
||||||
|
catalog: networking
|
||||||
|
licence: MIT
|
||||||
|
description:
|
||||||
|
plz fill me
|
||||||
|
|
||||||
|
item:
|
||||||
|
The name of the Site
|
||||||
|
|
||||||
|
inventory:
|
||||||
|
One Service for each Site
|
||||||
|
|
13
share/check_mk/checkman/unifi_ssid_list
Normal file
13
share/check_mk/checkman/unifi_ssid_list
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
title: Unifi Devicelist
|
||||||
|
catalog: networking
|
||||||
|
agents: unifi_controller
|
||||||
|
licence: MIT
|
||||||
|
description:
|
||||||
|
plz fill me
|
||||||
|
|
||||||
|
item:
|
||||||
|
The name of the device
|
||||||
|
|
||||||
|
inventory:
|
||||||
|
One Service for each device
|
||||||
|
|
@ -1,5 +1,26 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||||
|
## MIT License
|
||||||
|
##
|
||||||
|
## Copyright (c) 2021 Bash Club
|
||||||
|
##
|
||||||
|
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
## of this software and associated documentation files (the "Software"), to deal
|
||||||
|
## in the Software without restriction, including without limitation the rights
|
||||||
|
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
## copies of the Software, and to permit persons to whom the Software is
|
||||||
|
## furnished to do so, subject to the following conditions:
|
||||||
|
##
|
||||||
|
## The above copyright notice and this permission notice shall be included in all
|
||||||
|
## copies or substantial portions of the Software.
|
||||||
|
##
|
||||||
|
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
## SOFTWARE.
|
||||||
|
|
||||||
#Function get params (in this case is port, passed via WATO agent rule cunfiguration, hostname and ip addres of host,
|
#Function get params (in this case is port, passed via WATO agent rule cunfiguration, hostname and ip addres of host,
|
||||||
#for which agent will be invoked
|
#for which agent will be invoked
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||||
|
## MIT License
|
||||||
|
##
|
||||||
|
## Copyright (c) 2021 Bash Club
|
||||||
|
##
|
||||||
|
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
## of this software and associated documentation files (the "Software"), to deal
|
||||||
|
## in the Software without restriction, including without limitation the rights
|
||||||
|
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
## copies of the Software, and to permit persons to whom the Software is
|
||||||
|
## furnished to do so, subject to the following conditions:
|
||||||
|
##
|
||||||
|
## The above copyright notice and this permission notice shall be included in all
|
||||||
|
## copies or substantial portions of the Software.
|
||||||
|
##
|
||||||
|
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
## SOFTWARE.
|
||||||
|
|
||||||
from cmk.gui.i18n import _
|
from cmk.gui.i18n import _
|
||||||
from cmk.gui.plugins.metrics import (
|
from cmk.gui.plugins.metrics import (
|
||||||
metric_info,
|
metric_info,
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||||
|
|
||||||
|
## MIT License
|
||||||
|
##
|
||||||
|
## Copyright (c) 2021 Bash Club
|
||||||
|
##
|
||||||
|
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
## of this software and associated documentation files (the "Software"), to deal
|
||||||
|
## in the Software without restriction, including without limitation the rights
|
||||||
|
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
## copies of the Software, and to permit persons to whom the Software is
|
||||||
|
## furnished to do so, subject to the following conditions:
|
||||||
|
##
|
||||||
|
## The above copyright notice and this permission notice shall be included in all
|
||||||
|
## copies or substantial portions of the Software.
|
||||||
|
##
|
||||||
|
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
## SOFTWARE.
|
||||||
|
|
||||||
from cmk.gui.plugins.metrics import perfometer_info
|
from cmk.gui.plugins.metrics import perfometer_info
|
||||||
|
|
||||||
perfometer_info.append({
|
perfometer_info.append({
|
||||||
|
@ -1,5 +1,26 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||||||
|
## MIT License
|
||||||
|
##
|
||||||
|
## Copyright (c) 2021 Bash Club
|
||||||
|
##
|
||||||
|
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
## of this software and associated documentation files (the "Software"), to deal
|
||||||
|
## in the Software without restriction, including without limitation the rights
|
||||||
|
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
## copies of the Software, and to permit persons to whom the Software is
|
||||||
|
## furnished to do so, subject to the following conditions:
|
||||||
|
##
|
||||||
|
## The above copyright notice and this permission notice shall be included in all
|
||||||
|
## copies or substantial portions of the Software.
|
||||||
|
##
|
||||||
|
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
## SOFTWARE.
|
||||||
|
|
||||||
from cmk.gui.i18n import _
|
from cmk.gui.i18n import _
|
||||||
from cmk.gui.plugins.wato import (
|
from cmk.gui.plugins.wato import (
|
||||||
@ -50,3 +71,4 @@ rulespec_registry.register(
|
|||||||
name='special_agents:unifi_controller',
|
name='special_agents:unifi_controller',
|
||||||
valuespec=_valuespec_special_agent_unifi_controller,
|
valuespec=_valuespec_special_agent_unifi_controller,
|
||||||
))
|
))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user