diff --git a/agent_based/cisco_cellular_lte.py b/agent_based/cisco_cellular_lte.py new file mode 100644 index 0000000000000000000000000000000000000000..d4be481c7ef8404e046f20815a787ea8e884dfa1 --- /dev/null +++ b/agent_based/cisco_cellular_lte.py @@ -0,0 +1,472 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# License: GNU General Public License v2 +# +# Author: thl-cmk[at]outlook[dot]com +# URL : https://thl-cmk.hopto.org +# Date : 2022-09-17 +# +# Monitor status of Cisco cellular modems/connections/interfaces +# +# 2022-09-20: added WATO options +# +# snmpwalk sample +# + +# +# sample info +# + +# +# sample section +# + +# IMSI -> International Mobile Subscriber Identifier +# IMEI -> International Mobile Equipment Identifier +# ICCID -> Integrated Circuit Card ID +# MSISDN -> Mobile Subscriber Integrated Services Digital Network Number +# RSSI -> Received Signal Strength Indicator +# RSRP -> Reference Signal Received Power +# RSRQ -> Reference Signal Received Quality +# SNR -> Signal to Noise Ratio +# +# for Values https://usatcorp.com/faqs/understanding-lte-signal-strength-values/ +# + +import time +from dataclasses import dataclass +from typing import Optional, Dict, List +from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( + DiscoveryResult, + CheckResult, + StringByteTable, +) + +from cmk.base.plugins.agent_based.agent_based_api.v1 import ( + register, + Service, + SNMPTree, + contains, + check_levels, + OIDEnd, + OIDBytes, + Result, + render, + State, + all_of, + exists, + get_rate, + GetRateError, + get_value_store, + IgnoreResultsError, +) + + +########################################################################### +# +# DATA Parser function +# +########################################################################### + +@dataclass +class CiscoCellular3g: + modem_state: str + service_type: str + roaming_status: str + current_system_time: str + connection_status: str + total_bytes_tx: int + total_bytes_rx: int + modem_status: str + network: str + channel: int + rssi: int + band: str + + +@dataclass +class CiscoCellularRadio: + lte_rsrp: int + lte_rsrq: int + + +@dataclass +class CiscoCellularProfile: + apn_type: str + apn: str + radio_index: str + + +@dataclass +class CiscoCellularInterface: + conn_status: str + pdn_type: str + ipv4_addr: str + ipv6_addr: str + profile: Optional[CiscoCellularProfile] + radio: Optional[CiscoCellularRadio] + modem: Optional[CiscoCellular3g] + + +_cisco_gsm_modem_state = { + '1': 'Unknown', + '2': 'Up', + '3': 'Down', +} + +_cisco_gsm_modem_status = { + '1': 'unknown', + '2': 'Offline', + '3': 'Online', + '4': 'low Power Mode', +} + +_cisco_gsm_service_type = { + '0': '1xRTT', + '1': 'EVDO Revision 0', + '2': 'EVDO Revision A', + '3': 'EVDO Revision B', + '4': 'GPRS', + '5': 'EDGE', + '6': 'UMTS/WCDMA', + '7': 'HSDPA', + '8': 'HSUPA', + '9': 'HSPA', + '10': 'HSPA Plus', + '11': 'LTE TDD', + '12': 'LTE FDD', +} + +_cisco_gsm_band = { + '1': 'unknown', + '2': 'invalid', + '3': 'none', + '4': 'GSM-850', + '5': 'GSM-900', + '6': 'GSM-1800', + '7': 'GSM-1900', + '8': 'WCDMA-800', + '9': 'WCDMA-850', + '10': 'WCDMA-1900', + '11': 'WCDMA-2100', + '12': 'LTE Band', +} + +_cisco_roaming_status = { + '1': 'Unknown', + '2': 'Yes', + '3': 'No', +} + +_cisco_gsm_connection_status = { + '1': 'unknown', + '2': 'error', + '3': 'connecting', + '4': 'dormant', + '5': 'connected', + '6': 'disconnected', + '7': 'idle', + '8': 'active', + '9': 'inactive', +} + +_cisco_wan_cell_ext_protocol_type = { + '1': 'unknown', + '2': 'IPv4', + '3': 'PPP', + '4': 'IPv6', + '5': 'IPv4v6', +} + +_cisco_gsm_pdp_status = { + '1': 'unknown', + '2': 'active', + '3': 'inactive', +} + + +def parse_cisco_cellular_lte(string_table: List[StringByteTable]) -> Optional[Dict[str, CiscoCellularInterface]]: + section = {} + radios = {} + profiles = {} + modems = {} + interfaces = {} + modem_table, radio_table, profile_table, pdn_table, interface_table = string_table + + for radio_oid_end, current_rsrp, current_rsrq in radio_table: + radios[radio_oid_end] = CiscoCellularRadio( + lte_rsrp=int(current_rsrp), + lte_rsrq=int(current_rsrq) // 10, # See Cisco bug ID CSCvt55347 + ) + + for profile_oid_end, apn_type, apn in profile_table: + radio_index, profile_index = profile_oid_end.split('.') + profiles[profile_index] = CiscoCellularProfile( + radio_index=radio_index, + apn=apn, + apn_type=apn_type + ) + + for modem_oid_end, modem_state, service_type, roaming_status, modem_time, conn_status,\ + modem_status, network, totyl_bytes_tx, total_bytes_rx, rssi, channel, band in modem_table: + + modems[modem_oid_end] = CiscoCellular3g( + modem_state=modem_state, + service_type=str(service_type[0]*256 + service_type[1]), + roaming_status=roaming_status, + current_system_time=modem_time, + connection_status=conn_status, + total_bytes_tx=int(totyl_bytes_tx), + total_bytes_rx=int(total_bytes_rx), + modem_status=modem_status, + network=network, + rssi=int(rssi), + channel=int(channel), + band=band, + ) + + for index, name in interface_table: + interfaces[index] = name + + for if_index, pdn_profile_used, pdn_conn_status, pdn_type, pdn_ipv4_addr, pdn_ipv6_addr in pdn_table: + if interfaces.get(if_index): + profile = profiles.get(pdn_profile_used) + if profile: + radio_index = profile.radio_index + radio = radios.get(radio_index) + modem = modems.get(radio_index) + else: + radio = None + modem = None + + section[interfaces.get(if_index)] = CiscoCellularInterface( + conn_status=pdn_conn_status, + pdn_type=pdn_type, + ipv4_addr=pdn_ipv4_addr, + ipv6_addr=pdn_ipv6_addr, + profile=profile, + radio=radio, + modem=modem, + ) + + return section + + +########################################################################### +# +# INVENTORY function +# +########################################################################### + + +def discovery_cisco_cellular_lte(params, section: Dict[str, CiscoCellularInterface]) -> DiscoveryResult: + for item, interface in section.items(): + if interface.profile is not None or params['not_configured']: + yield Service(item=item) + +########################################################################### +# +# CHECK function +# +########################################################################### + + +def check_cisco_cellular_lte(item, params, section: Dict[str, CiscoCellularInterface]) -> Optional[CheckResult]: + + try: + interface = section[item] + except KeyError: + # yield Result(state=State.UNKNOWN, notice='Item not found.') + return + + if interface.profile is None: + yield Result(state=State(params['no_profile_state']), summary='No GSM/LTE profile configured') + return + + metric_prefix = 'cisco_cellular_' + + text = f'Status: {_cisco_gsm_pdp_status.get(interface.conn_status)}' + if interface.conn_status == '2': # active + yield Result(state=State.OK, summary=text) + else: + yield Result(state=State(params['connection_state']), summary=text) + + text = f'Modem state: {_cisco_gsm_modem_state.get(interface.modem.modem_state)}' + if interface.modem.modem_state == '2': # UP + yield Result(state=State.OK, notice=text) + else: + yield Result(state=State(params['modem_not_up_state']), notice=text) + + text = f'Modem status: {_cisco_gsm_modem_status.get(interface.modem.modem_status)}' + if interface.modem.modem_status == '3': # online + yield Result(state=State.OK, notice=text) + else: + yield Result(state=State(params['modem_not_online_state']), notice=text) + + yield Result( + state=State.OK, + notice=f'Connection status: {_cisco_gsm_connection_status.get(interface.modem.connection_status)}' + ) + + text = f'Roaming: {_cisco_roaming_status.get(interface.modem.roaming_status)}' + if interface.modem.roaming_status == '3': # Home not roaming + yield Result(state=State.OK, notice=text) + else: + yield Result(state=State(params['roaming_state']), notice=text) + + for value, label, render_func, levels_lower, metric in [ + (interface.radio.lte_rsrp, 'RSRP', lambda v: f'{v} dBm', params['rsrp_levels_lower'], 'rsrp'), + (interface.radio.lte_rsrq, 'RSRQ', lambda v: f'{v} dB', params['rsrp_levels_lower'], 'rsrq',), + (interface.modem.rssi, 'RSSI', lambda v: f'{v} dBm', params['rssi_levels_lower'], 'rssi'), + ]: + yield from check_levels( + value=value, + label=label, + render_func=render_func, + levels_lower=levels_lower, + metric_name=f'{metric_prefix}{metric}', + ) + + now_time = time.time() + value_store = get_value_store() + + for metric, value, label in [ + ('if_in_bps', interface.modem.total_bytes_rx, 'In'), + ('if_out_bps', interface.modem.total_bytes_tx, 'Out'), + ]: + try: + value = get_rate(value_store, f'{metric}', now_time, value * 8, raise_overflow=True) + except GetRateError: + value = 0 + yield from check_levels( + value=value, + label=label, + metric_name=metric, + render_func=render.networkbandwidth, + ) + + if interface.ipv4_addr: + yield Result(state=State.OK, summary=f'IPv4 Addr: {interface.ipv4_addr}') + if interface.ipv6_addr: + yield Result(state=State.OK, summary=f'IPv6 Addr: {interface.ipv6_addr}') + + # if interface.profile.apn_type == interface.pdn_type: + # yield Result( + # state=State.OK, + # notice=f'Current APN type: {_cisco_wan_cell_ext_protocol_type.get(interface.pdn_type)}' + # ) + # else: + # yield Result( + # state=State.WARN, + # summary=f'Current APN type: {_cisco_wan_cell_ext_protocol_type.get(interface.pdn_type)} ' + # f'(expected: {_cisco_wan_cell_ext_protocol_type.get(interface.profile.apn_type)})' + # ) + + yield Result(state=State.OK, notice=f'Networkcode: {interface.modem.network}') + expected_band = params['expected_band'] + if interface.modem.band == expected_band: + yield Result(state=State.OK, summary=f'Band: {_cisco_gsm_band.get(interface.modem.band)}') + else: + yield Result( + state=State(params['state_not_expected_band']), + summary=f'Band: {_cisco_gsm_band.get(interface.modem.band)} (expected: {_cisco_gsm_band.get(expected_band)})' + ) + yield Result(state=State.OK, notice=f'Channel: {interface.modem.channel}') + yield Result(state=State.OK, notice=f'Service type: {_cisco_gsm_service_type.get(interface.modem.service_type)}') + yield Result(state=State.OK, notice=f'Provider Time: {interface.modem.current_system_time}') + + yield Result(state=State.OK, notice='\nInventory') + yield Result(state=State.OK, notice=f'APN: {interface.profile.apn}') + yield Result(state=State.OK, notice=f'Configured APN type: {_cisco_wan_cell_ext_protocol_type.get(interface.pdn_type)}') + yield Result(state=State.OK, notice=f'Current APN type: {_cisco_wan_cell_ext_protocol_type.get(interface.profile.apn_type)}') + +########################################################################### +# +# SNMP section +# +########################################################################### + + +register.snmp_section( + name='cisco_cellular_lte', + parse_function=parse_cisco_cellular_lte, + fetch=[ + SNMPTree( + base='.1.3.6.1.4.1.9.9.661.1', # CISCO-WAN-3G-MIB::ciscoWan3gMIBObjects + oids=[ + OIDEnd(), + '1.1.3', # c3gModemState + OIDBytes('1.1.5'), # c3gCurrentServiceType + '1.1.6', # c3gRoamingStatus + '1.1.7', # c3gCurrentSystemTime + '1.1.8', # c3gConnectionStatus + '3.1.1.6', # c3gModemStatus + '3.2.1.9', # c3gGsmNetwork + '3.2.1.19', # c3gGsmTotalByteTransmitted + '3.2.1.20', # c3gGsmTotalByteReceived + '3.4.1.1.1', # c3gCurrentGsmRssi + '3.4.1.1.4', # c3gGsmChannelNumber + '3.4.1.1.3', # c3gGsmCurrentBand + ]), + SNMPTree( + base='.1.3.6.1.4.1.9.9.817.1.1.1.1.1', # CISCO-WAN-CELL-EXT-MIB::cwceLteRadioEntry + oids=[ + OIDEnd(), + '1', # cwceLteCurrRsrp + '2', # cwceLteCurrRsrq + ]), + SNMPTree( + base='.1.3.6.1.4.1.9.9.817.1.1.2.3.1', # CISCO-WAN-CELL-EXT-MIB::cwceLteProfileEntry + oids=[ + OIDEnd(), + '2', # cwceLteProfileType + '5', # cwceLteProfileApn + ]), + SNMPTree( + base='.1.3.6.1.4.1.9.9.817.1.1.2.4.1', # CISCO-WAN-CELL-EXT-MIB::cwceLtePdnEntry + oids=[ + OIDEnd(), + '2', # cwceLtePdnProfileUsed + '3', # cwceLtePdnConnStatus + '4', # cwceLtePdnType + '5', # cwceLtePdnIpv4Addr + '6', # cwceLtePdnIpv6Addr + ]), + + SNMPTree( + base='.1.3.6.1.2.1.31.1.1.1', # IF-MIB::ifXEntry + oids=[ + OIDEnd(), + '1', # ifName + ] + ) + ], + detect=all_of( + contains('.1.3.6.1.2.1.1.1.0', 'cisco'), # sysDescr + exists('.1.3.6.1.4.1.9.9.661.1.3.1.1.2.*'), # CISCO-WAN-3G-MIB::c3gImei + )) + +register.check_plugin( + name='cisco_cellular_lte', + service_name='Cellular %s', + discovery_function=discovery_cisco_cellular_lte, + discovery_ruleset_name='discovery_cisco_cellular_lte', + discovery_default_parameters={ + 'not_configured': False, + }, + check_function=check_cisco_cellular_lte, + check_default_parameters={ + 'rsrp_levels_lower': (-100, -115), + 'rsrq_levels_lower': (-8, -15), + 'rssi_levels_lower': (-75, -85), + 'roaming_state': 1, + 'no_profile_state': 1, + 'connection_state': 2, + 'modem_not_up_state': 2, + 'modem_not_online_state': 2, + 'expected_band': '12', + 'state_not_expected_band': 0, + }, + check_ruleset_name='cisco_cellular_lte', +) diff --git a/agent_based/inv_cisco_cellular_lte.py b/agent_based/inv_cisco_cellular_lte.py new file mode 100644 index 0000000000000000000000000000000000000000..bd00724ffd63281f79c3b8ec0435d2a83f4fc1aa --- /dev/null +++ b/agent_based/inv_cisco_cellular_lte.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# License: GNU General Public License v2 +# +# Author: thl-cmk[at]outlook[dot]com +# URL : https://thl-cmk.hopto.org +# Date : 2022-09-26 +# File : inv_cisco_cellular_lte +# +# inventory of Cisco cellular interfaces (SIM cards) +# +# + +from typing import List +from dataclasses import dataclass +from cmk.base.plugins.agent_based.agent_based_api.v1 import ( + register, + SNMPTree, + TableRow, + OIDEnd, + OIDBytes, + all_of, + contains, + exists, +) +from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( + StringByteTable, + InventoryResult, +) + + +@dataclass +class CiscoCellularProfile: + apn_type: str + apn: str + + +_cisco_gsm_service_type = { + '0': '1xRTT', + '1': 'EVDO Revision 0', + '2': 'EVDO Revision A', + '3': 'EVDO Revision B', + '4': 'GPRS', + '5': 'EDGE', + '6': 'UMTS/WCDMA', + '7': 'HSDPA', + '8': 'HSUPA', + '9': 'HSPA', + '10': 'HSPA Plus', + '11': 'LTE TDD', + '12': 'LTE FDD', +} + + +_cisco_gsm_band = { + '1': 'unknown', + '2': 'invalid', + '3': 'none', + '4': 'GSM-850', + '5': 'GSM-900', + '6': 'GSM-1800', + '7': 'GSM-1900', + '8': 'WCDMA-800', + '9': 'WCDMA-850', + '10': 'WCDMA-1900', + '11': 'WCDMA-2100', + '12': 'LTE Band', +} + +_cisco_wan_cell_ext_protocol_type = { + '1': 'unknown', + '2': 'IPv4', + '3': 'PPP', + '4': 'IPv6', + '5': 'IPv4v6', +} + + +def parse_inv_cisco_cellular_lte(string_table: List[StringByteTable]): + section = [] + profiles = {} + + modem_table, profile_table = string_table + + for profile_oid_end, apn_type, apn in profile_table: + radio_index, profile_index = profile_oid_end.split('.') + profiles[radio_index] = CiscoCellularProfile( + apn=apn, + apn_type=apn_type + ) + + for oid_end, service_type, imsi, imei, iccid, msisdn, country, network, current_band in modem_table: + entry = { + 'key_columns': { + 'iccid': iccid, + 'imei': imei, + }, + 'inventory_columns': { + 'imsi': imsi if imsi else None, + 'msisdn': msisdn if msisdn else None, + 'country': country if country else None, + 'network': network if network else None, + 'current_band': _cisco_gsm_band.get(current_band, f'Unknown {current_band}'), + 'apn': profiles[oid_end].apn if profiles.get(oid_end) else None, + 'apn_type': _cisco_wan_cell_ext_protocol_type.get(profiles[oid_end].apn_type) if profiles.get(oid_end) else None, + 'service_type': _cisco_gsm_service_type.get(str(service_type[0]*256 + service_type[1])) + }, + 'status_columns': { + + } + } + + keys = list(entry['inventory_columns'].keys()) + for key in keys: + if not entry['inventory_columns'][key]: + entry['inventory_columns'].pop(key) + + section.append(entry) + + return section + + +def inventory_cisco_cellular_lte(params, section) -> InventoryResult: + path = ['networking', 'cellular'] + + for entry in section: + yield TableRow( + path=path, + key_columns=entry['key_columns'], + inventory_columns=entry['inventory_columns'], + status_columns=entry['status_columns'] + ) + + +register.snmp_section( + name='inv_cisco_cellular_lte', + parse_function=parse_inv_cisco_cellular_lte, + fetch=[SNMPTree( + base='.1.3.6.1.4.1.9.9.661.1', # CISCO-WAN-3G-MIB::ciscoWan3gMIBObjects + oids=[ + OIDEnd(), + OIDBytes('1.1.5'), # c3gCurrentServiceType + '3.1.1.1', # c3gImsi + '3.1.1.2', # c3gImei + '3.1.1.3', # c3gIccId + '3.1.1.4', # c3gMsisdn + '3.2.1.8', # c3gGsmCountry + '3.2.1.9', # c3gGsmNetwork + '3.4.1.1.3', # c3gGsmCurrentBand + ]), + SNMPTree( + base='.1.3.6.1.4.1.9.9.817.1.1.2.3.1', # CISCO-WAN-CELL-EXT-MIB::cwceLteProfileEntry + oids=[ + OIDEnd(), + '2', # cwceLteProfileType + '5', # cwceLteProfileApn + ])], + detect=all_of( + contains('.1.3.6.1.2.1.1.1.0', 'cisco'), # sysDescr + exists('.1.3.6.1.4.1.9.9.661.1.3.1.1.2.*'), # CISCO-WAN-3G-MIB::c3gImei + )) + +register.inventory_plugin( + name='inv_cisco_cellular_lte', + inventory_function=inventory_cisco_cellular_lte, + inventory_default_parameters={ + }, + inventory_ruleset_name='inv_cisco_cellular_lte', +) diff --git a/cisco_cellular_lte.mkp b/cisco_cellular_lte.mkp index cd03f1fa6160413f51b2b3ffb6dcc9c09e074697..243b86fe520023343700c1550021e122636e3146 100644 Binary files a/cisco_cellular_lte.mkp and b/cisco_cellular_lte.mkp differ diff --git a/packages/cisco_cellular_lte b/packages/cisco_cellular_lte new file mode 100644 index 0000000000000000000000000000000000000000..e1783f5594d106f40814763e7687c3dec0ef523d --- /dev/null +++ b/packages/cisco_cellular_lte @@ -0,0 +1,16 @@ +{'author': 'Th.L. (thl-cmk[at]outlook[dot]com)', + 'description': 'Monitors Cisco cellular interfaces/modems/radios (LTE ' + 'connections)\n', + 'download_url': 'https://thl-cmk.hopto.org', + 'files': {'agent_based': ['cisco_cellular_lte.py', + 'inv_cisco_cellular_lte.py'], + 'web': ['plugins/wato/cisco_cellular_lte.py', + 'plugins/metrics/cisco_cellular_lte.py', + 'plugins/views/inv_cisco_cellular_lte.py']}, + 'name': 'cisco_cellular_lte', + 'num_files': 5, + 'title': 'Cisco cellular LTE', + 'version': '20220920.v0.0.1', + 'version.min_required': '2.0.0', + 'version.packaged': '2021.09.20', + 'version.usable_until': None} \ No newline at end of file diff --git a/web/plugins/metrics/cisco_cellular_lte.py b/web/plugins/metrics/cisco_cellular_lte.py new file mode 100644 index 0000000000000000000000000000000000000000..ebef8307f51a4aaa66134d0dc19fefda7d813a59 --- /dev/null +++ b/web/plugins/metrics/cisco_cellular_lte.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# License: GNU General Public License v2 +# +# Author: thl-cmk[at]outlook[dot]com +# URL : https://thl-cmk.hopto.org +# Date : 2022-09-26 +# +# Cisco Cellular Lte metrics plugin +# +# +from cmk.gui.i18n import _ + +from cmk.gui.plugins.metrics import ( + metric_info, + graph_info, + perfometer_info +) + + +metric_info['cisco_cellular_rsrp'] = { + 'title': _('RSRP'), + 'unit': 'dbm', + 'color': '22/a', +} +metric_info['cisco_cellular_rsrq'] = { + 'title': _('RSRQ'), + 'unit': 'db', + 'color': '32/a', +} +metric_info['cisco_cellular_rssi'] = { + 'title': _('RSSI'), + 'unit': 'dbm', + 'color': '42/a', +} + +###################################################################################################################### +# +# how to graph perdata for bgp peer +# +###################################################################################################################### + +graph_info['cisco_cellular.rsrp'] = { + 'title': _('Reference Signal Received Power'), + 'metrics': [ + ('cisco_cellular_rsrp', 'area'), + ], + 'range': (0, 'cisco_cellular_rsrp:max'), +} + +graph_info['cisco_cellular.rsrq'] = { + 'title': _('Reference Signal Received Quality'), + 'metrics': [ + ('cisco_cellular_rsrq', 'area'), + ], + 'scalars': [ + ('cisco_cellular_rsrq:crit', _('crit')), + ('cisco_cellular_rsrq:warn', _('warn')), + ], + 'range': (0, 'cisco_cellular_rsrq:max'), +} + +graph_info['cisco_cellular.rssi'] = { + 'title': _('Received Signal Strength Indicator'), + 'metrics': [ + ('cisco_cellular_rssi', 'area'), + ], +} + + +# perfometer_info.append(('stacked', [ +# { +# 'type': 'logarithmic', +# 'metric': 'bgp_peer_fsmestablishedtime', +# 'half_value': 2592000.0, # ome month +# 'exponent': 2, +# }, +# { +# 'type': 'logarithmic', +# 'metric': 'bgp_peer_acceptedprefixes', +# 'half_value': 500000.0, +# 'exponent': 2, +# } +# ])) +# +# perfometer_info.append({ +# 'type': 'logarithmic', +# 'metric': 'bgp_peer_fsmestablishedtime', +# 'half_value': 2592000.0, # ome month +# 'exponent': 2, +# }) \ No newline at end of file diff --git a/web/plugins/views/inv_cisco_cellular_lte.py b/web/plugins/views/inv_cisco_cellular_lte.py new file mode 100644 index 0000000000000000000000000000000000000000..7554aaf86b232c6ff9774b682a5fc09cbf22e3cb --- /dev/null +++ b/web/plugins/views/inv_cisco_cellular_lte.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# License: GNU General Public License v2 +# +# Author: thl-cmk[at]outlook[dot]com +# URL : https://thl-cmk.hopto.org +# Date : 2022-09-26 +# File : view/inv_cisco_cellular_lte +# + +from cmk.gui.i18n import _ +from cmk.gui.plugins.views import ( + inventory_displayhints, +) + +from cmk.gui.plugins.views.inventory import declare_invtable_view + +inventory_displayhints.update({ + '.networking.cellular:': { + 'title': _('Cellular (LTE)'), + 'keyorder': [ + 'imei', + 'iccid', + 'imsi', + 'network', + 'apn', + 'apn_type', + 'service_type' + ], + 'view': 'invcellularlte_of_host', + }, + '.networking.cellular:*.iccid': {'short': _('ICC ID'), 'title': _('Integrated Circuit Card ID (ICC ID)')}, + '.networking.cellular:*.imei': {'short': _('IMEI'), 'title': _('International Mobile Equipment Identifier (IMEI)')}, + '.networking.cellular:*.imsi': {'short': _('IMSI'), + 'title': _('International Mobile Subscriber Identifier (IMSI)')}, + '.networking.cellular:*.msisdn': { + 'short': _('MSISDN'), + 'title': _('Mobile Subscriber Integrated Services Digital Network Number (MSISDN') + }, + '.networking.cellular:*.country': {'title': _('Country'), }, + '.networking.cellular:*.network': {'title': _('Network'), }, + '.networking.cellular:*.current_band': {'title': _('Current band'), }, + '.networking.cellular:*.apn': {'short': _('APN'), 'title': _('Access Point Name (APN)')}, + '.networking.cellular:*.apn_type': {'title': _('APN type'), }, + '.networking.cellular:*.service_type': {'title': _('Service type'), }, +}) + +declare_invtable_view('invcellularlte', '.networking.cellular:', _('Cellular (LTE)'), _('Cellular (LTE)')) diff --git a/web/plugins/wato/cisco_cellular_lte.py b/web/plugins/wato/cisco_cellular_lte.py new file mode 100644 index 0000000000000000000000000000000000000000..a5c77851aa5b37f4780513a444c18db6da061551 --- /dev/null +++ b/web/plugins/wato/cisco_cellular_lte.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# License: GNU General Public License v2 +# +# Author: thl-cmk[at]outlook[dot]com +# URL : https://thl-cmk.hopto.org +# Date : 2022-09-20 +# File : wato/cisco_cellular_lte +# + +from cmk.gui.i18n import _ +from cmk.gui.valuespec import ( + Dictionary, + TextAscii, + MonitoringState, + FixedValue, + ListOfStrings, + ListOf, + Integer, + Tuple, + DropdownChoice, +) + +from cmk.gui.plugins.wato import ( + CheckParameterRulespecWithItem, + rulespec_registry, + RulespecGroupCheckParametersNetworking, + RulespecGroupCheckParametersDiscovery, + HostRulespec, +) + + +def _parameter_valuespec_cisco_cellular_lte(): + return Dictionary( + elements=[ + ('rsrp_levels_lower', + Tuple( + title=_('Lower levels for RSRP'), + help=_('Lower levels for RSRP (Reference Signal Received Power) in dBm'), + elements=[ + Integer(title=_('Warning below'), default_value=-100, unit=_('dBm')), + Integer(title=_('Critical below'), default_value=-115, unit=_('dBm')), + ])), + ('rsrq_levels_lower', + Tuple( + title=_('Lower levels for RSRQ'), + help=_('Lower levels for RSRQ (Reference Signal Received Quality) in dB'), + elements=[ + Integer(title=_('Warning below'), default_value=-8, unit=_('dB')), + Integer(title=_('Critical below'), default_value=-15, unit=_('dB')), + ])), + ('rssi_levels_lower', + Tuple( + title=_('Lower levels for RSSI'), + help=_('Lower levels for RSSI (Received Signal Strength Indicator) in dBm'), + elements=[ + Integer(title=_('Warning below'), default_value=-75, unit=_('dBm')), + Integer(title=_('Critical below'), default_value=-85, unit=_('dBm')), + ])), + ('roaming_state', + MonitoringState( + title=_('Monitoring state if the device is roaming'), + help=_('Monitoring state if the device is roaming. Default is WARN.'), + default_value=1, + )), + ('no_profile_state', + MonitoringState( + title=_('Monitoring state if no GSM/LTE profile configured'), + help=_('Monitoring state if no GSM/LTE profile is configured. Default is WARN.'), + default_value=1, + )), + ('connection_state', + MonitoringState( + title=_('Monitoring state if the device is not connected'), + help=_('Monitoring state if the device is not connected. Default is CRIT.'), + default_value=1, + )), + ('modem_not_up_state', + MonitoringState( + title=_('Monitoring state if the modem is not up'), + help=_('Monitoring state if the the modem is not up. Default is CRIT.'), + default_value=1, + )), + ('modem_not_online_state', + MonitoringState( + title=_('Monitoring state if the modem is not online'), + help=_('Monitoring state if the the modem is not online. Default is CRIT.'), + default_value=1, + )), + ], + ) + + +rulespec_registry.register( + CheckParameterRulespecWithItem( + check_group_name='cisco_cellular_lte', + group=RulespecGroupCheckParametersNetworking, + match_type='dict', + parameter_valuespec=_parameter_valuespec_cisco_cellular_lte, + title=lambda: _('Cisco cellular LTE'), + item_spec=lambda: TextAscii(title=_('Item'), ), + )) + + +def _valuespec_discovery_cisco_cellular_lte(): + return Dictionary( + title=_('Cisco cellular LTE'), + elements=[ + ('not_configured', + FixedValue( + True, + title=_('Discover not configured interfaces'), + help=_('If enabled the plugin will also discover cellular interfaces without a profile attached.'), + totext=_('') + )), + ], + ) + + +rulespec_registry.register( + HostRulespec( + group=RulespecGroupCheckParametersDiscovery, + match_type='dict', + name='discovery_cisco_cellular_lte', + valuespec=_valuespec_discovery_cisco_cellular_lte, + ))