diff --git a/README.md b/README.md index a34402a0092bc9e7d242dd79d38aae0915d0985b..4fa2cabe324d8470868b945a08cfee93511a6ac3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[PACKAGE]: ../../raw/master/mkp/cisco_asyncos-0.4.1-20240418.mkp "cisco_asyncos-0.4.1-20240418.mkp" # Cisco AsyncOS (IronPort) **Note: this package is for CheckMK version 2.x. For other versions see the corresponding branch.** diff --git a/agent_based/cisco_asyncos_dns.py b/agent_based/cisco_asyncos_dns.py deleted file mode 100644 index 534f79af3811fc2a7c0728a4d3546282d6e7d6dd..0000000000000000000000000000000000000000 --- a/agent_based/cisco_asyncos_dns.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/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 : 2020-03-08 -# -# monitors status Cisco IronPort Appliances (ESA) DNS requests -# Tested with: C380, C370 -# -# 2021-03-24: rewrite for CMK 2.0 -# -# .1.3.6.1.4.1.15497.1.1.1.15.0 = Gauge32: 0 -# .1.3.6.1.4.1.15497.1.1.1.16.0 = Gauge32: 0 -# -# ASYNCOS-MAIL-MIB::outstandingDNSRequests.0 = Gauge32: 0 -# ASYNCOS-MAIL-MIB::pendingDNSRequests.0 = Gauge32: 0 -# -# -from typing import Mapping, List, NamedTuple, Optional - -from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( - DiscoveryResult, - CheckResult, - StringTable, -) - -from cmk.base.plugins.agent_based.agent_based_api.v1 import ( - register, - Service, - check_levels, - Result, - Metric, - SNMPTree, - contains, - State, -) - - -class CiscoAsyncosDns(NamedTuple): - outstandingDNSRequests: int - pendingDNSRequests: int - - -# [['0', '0']] -def parse_cisco_asyncos_dns(string_table: StringTable) -> Optional[CiscoAsyncosDns]: - try: - return CiscoAsyncosDns( - outstandingDNSRequests=int(string_table[0][0]), - pendingDNSRequests=int(string_table[0][1]), - ) - except IndexError: - return - - -def discovery_cisco_asyncos_dns(section: CiscoAsyncosDns) -> DiscoveryResult: - yield Service() - - -def check_cisco_asyncos_dns(params, section: CiscoAsyncosDns) -> CheckResult: - yield Result(state=State.OK, - summary='%s outstanding, %s pending' % ( - section.outstandingDNSRequests, section.pendingDNSRequests)) - - yield Metric(name='outstandingDNSRequests', value=section.outstandingDNSRequests) - yield Metric(name='pendingDNSRequests', value=section.pendingDNSRequests) - - -register.snmp_section( - name='cisco_asyncos_dns', - parse_function=parse_cisco_asyncos_dns, - fetch= SNMPTree( - base='.1.3.6.1.4.1.15497.1.1.1', # ASYNCOS-MAIL-MIB - oids=[ - '15', # outstandingDNSRequests - '16', # pendingDNSRequests - ] - ), - detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'), -) - -register.check_plugin( - name='cisco_asyncos_dns', - service_name='DNS requests', - discovery_function=discovery_cisco_asyncos_dns, - check_function=check_cisco_asyncos_dns, - check_default_parameters={}, -) diff --git a/agent_based/cisco_asyncos_queue.py b/agent_based/cisco_asyncos_queue.py deleted file mode 100644 index b4a7988b7fa40b412b82b19fc7d553b4b1340f8f..0000000000000000000000000000000000000000 --- a/agent_based/cisco_asyncos_queue.py +++ /dev/null @@ -1,105 +0,0 @@ -#!/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 : 2020-02-10 -# -# added wato, fixed inventory function, changed snmp scan function, changed item to 'work queue' -# -# 2021-03-24: rewrite for CMK 2.0 -# - -from typing import Mapping, List, NamedTuple, Optional - -from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( - DiscoveryResult, - CheckResult, - StringTable, -) - -from cmk.base.plugins.agent_based.agent_based_api.v1 import ( - register, - Service, - check_levels, - Result, - Metric, - SNMPTree, - contains, - State, -) - - -class CiscoAsyncosQueue(NamedTuple): - state: State - status_readable: str - workQueueMessages: int - - -def get_status_readable(st: str) -> str: - states = { - '1': 'enough', - '2': 'near full', - '3': 'full', - } - return states.get(st, st) - - -def get_cmk_state(st: str) -> State: - states = { - '1': State.OK, - '2': State.CRIT, - '3': State.WARN - } - return states.get(st, State.CRIT) - - -# [['1', '1']] -def parse_cisco_asyncos_messageage(string_table: StringTable) -> Optional[CiscoAsyncosQueue]: - try: - return CiscoAsyncosQueue( - state=get_cmk_state(string_table[0][0]), - status_readable=get_status_readable(string_table[0][0]), - workQueueMessages=int(string_table[0][1]) - ) - except IndexError: - return - - -def discovery_cisco_asyncos_queue(section: CiscoAsyncosQueue) -> DiscoveryResult: - yield Service() - - -def check_cisco_asyncos_queue(params, section: CiscoAsyncosQueue) -> CheckResult: - yield from check_levels( - value=section.workQueueMessages, - label='Messages in work queue', - levels_upper=params.get('upper', None), - metric_name='work_queue_size', - ) - yield Result(state=section.state, notice='Queue space: %s' % section.status_readable) - - -register.snmp_section( - name='cisco_asyncos_queue', - parse_function=parse_cisco_asyncos_messageage, - fetch= SNMPTree( - base='.1.3.6.1.4.1.15497.1.1.1', # ASYNCOS-MAIL-MIB - oids=[ - '5', # queueAvailabilityStatus - '11' # workQueueMessages - ] - ), - detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'), -) - -register.check_plugin( - name='cisco_asyncos_queue', - service_name='Queue', - discovery_function=discovery_cisco_asyncos_queue, - check_function=check_cisco_asyncos_queue, - check_default_parameters={'levels': (50, 100)}, - check_ruleset_name='cisco_asyncos_queue', -) diff --git a/cisco_asyncos.mkp b/cisco_asyncos.mkp deleted file mode 100644 index 60bcf605212b7552bb0db41df2d304ff042462d5..0000000000000000000000000000000000000000 Binary files a/cisco_asyncos.mkp and /dev/null differ diff --git a/doc/.gitkeep b/img/.gitkeep similarity index 100% rename from doc/.gitkeep rename to img/.gitkeep diff --git a/doc/sample_fan.png b/img/sample_fan.png similarity index 100% rename from doc/sample_fan.png rename to img/sample_fan.png diff --git a/doc/sample_license.png b/img/sample_license.png similarity index 100% rename from doc/sample_license.png rename to img/sample_license.png diff --git a/doc/sample_power.png b/img/sample_power.png similarity index 100% rename from doc/sample_power.png rename to img/sample_power.png diff --git a/doc/sample_raid.png b/img/sample_raid.png similarity index 100% rename from doc/sample_raid.png rename to img/sample_raid.png diff --git a/doc/sample_temp.png b/img/sample_temp.png similarity index 100% rename from doc/sample_temp.png rename to img/sample_temp.png diff --git a/doc/sample_updates.png b/img/sample_updates.png similarity index 100% rename from doc/sample_updates.png rename to img/sample_updates.png diff --git a/doc/sample_workqueue.png b/img/sample_workqueue.png similarity index 100% rename from doc/sample_workqueue.png rename to img/sample_workqueue.png diff --git a/mkp/cisco_asyncos-0.4.1-20240418.mkp b/mkp/cisco_asyncos-0.4.1-20240418.mkp new file mode 100644 index 0000000000000000000000000000000000000000..a794d4f34a5506ada4d5d0ed69d3d03c83785c39 Binary files /dev/null and b/mkp/cisco_asyncos-0.4.1-20240418.mkp differ diff --git a/agent_based/cisco_asyncos_bandwidth.py b/source/agent_based/cisco_asyncos_bandwidth.py similarity index 55% rename from agent_based/cisco_asyncos_bandwidth.py rename to source/agent_based/cisco_asyncos_bandwidth.py index 4d739945661637de6bec45abec10d2f3e7dc64c8..eb6a701c37f96393d37cafec680267a2b24da096 100644 --- a/agent_based/cisco_asyncos_bandwidth.py +++ b/source/agent_based/cisco_asyncos_bandwidth.py @@ -7,27 +7,27 @@ # URL : https://thl-cmk.hopto.org # Date : 2021-03-24 # -# only use full for Cisco WSA appliances +# only useful for Cisco WSA appliances # # 2023-03-06: fixed: IndexError in parse function -# +# 2024-04-18: fixed bandwidth values to bytes/s (kb/s), see MIB -from typing import Mapping, List, NamedTuple, Optional +from typing import NamedTuple from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( - DiscoveryResult, CheckResult, + DiscoveryResult, + HostLabelGenerator, StringTable, ) from cmk.base.plugins.agent_based.agent_based_api.v1 import ( - register, + HostLabel, + SNMPTree, Service, check_levels, - Result, - SNMPTree, contains, - State, + register, render, ) @@ -38,13 +38,22 @@ class CiscoAsyncosBandwidth(NamedTuple): bandwidth_day: int +def host_label_cisco_asyncos(section: int) -> HostLabelGenerator: + """Host label function + Labels: + cmk/os_family: + This label is set to "AsyncOS" for all Cisco Ironport devices + """ + yield HostLabel(name="cmk/os_family", value="AsyncOS") + + # [['0', '0', '247']] -def parse_cisco_asyncos_bandwidth(string_table: StringTable) -> Optional[CiscoAsyncosBandwidth]: +def parse_cisco_asyncos_bandwidth(string_table: StringTable) -> CiscoAsyncosBandwidth | None: try: return CiscoAsyncosBandwidth( - bandwidth_now=int(string_table[0][0]), - bandwidth_hour=int(string_table[0][1]), - bandwidth_day = int(string_table[0][2]), + bandwidth_now=int(string_table[0][0]) * 1000 / 8, # kbits/s -> bytes/s + bandwidth_hour=int(string_table[0][1]) * 1000 / 8, + bandwidth_day=int(string_table[0][2]) * 1000 / 8, ) except IndexError: return @@ -56,44 +65,36 @@ def discovery_cisco_asyncos_bandwidth(section: CiscoAsyncosBandwidth) -> Discove def check_cisco_asyncos_bandwidth(params, section: CiscoAsyncosBandwidth) -> CheckResult: yield from check_levels( - section.bandwidth_now * 8, + value=section.bandwidth_now, label='Current bandwidth', - levels_upper=params.get('upper', None), - levels_lower=params.get('lower', None), - metric_name='bandwith_now', + # levels_upper=params.get('upper', None), # not implemented + # levels_lower=params.get('lower', None), # not implemented + metric_name='bandwidth_now', render_func=render.networkbandwidth, - # unit='bits/s' ) yield from check_levels( - section.bandwidth_hour * 8, - label='last hour', - # levels_upper=params.get('upper', None), - # levels_lower=params.get('lower', None), - # metric_name='bandwith_now', + value=section.bandwidth_hour, + label='Last hour', render_func=render.networkbandwidth ) yield from check_levels( - section.bandwidth_day * 8, - label='last day', - #levels_upper=params.get('upper', None), - #levels_lower=params.get('lower', None), - #metric_name='bandwith_now', + value=section.bandwidth_day, + label='Last day', render_func=render.networkbandwidth ) - # yield Result(state=State.OK, summary='last hour: %s, last day: %s' % (section.bandwidth_hour, section.bandwidth_day)) - register.snmp_section( name='cisco_asyncos_bandwidth', parse_function=parse_cisco_asyncos_bandwidth, - fetch= SNMPTree( - base='.1.3.6.1.4.1.15497.1.2.3.7.4', # ASYNCOSWEBSECURITYAPPLIANCE-MIB::proxyRecentBandWTotPerf - oids=[ - '1', # cacheBwidthTotalNow - '3', # cacheBwidthTotal1hrMean - '5', # cacheBwidthTotal1dayMean - ] + host_label_function=host_label_cisco_asyncos, + fetch=SNMPTree( + base='.1.3.6.1.4.1.15497.1.2.3.7.4', # ASYNCOSWEBSECURITYAPPLIANCE-MIB::proxyRecentBandWTotPerf + oids=[ + '1', # cacheBwidthTotalNow (kb/s -> 1000 bits/s) + '3', # cacheBwidthTotal1hrMean (kb/s) + '5', # cacheBwidthTotal1dayMean (kb/s) + ] ), detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'), ) diff --git a/agent_based/cisco_asyncos_cache.py b/source/agent_based/cisco_asyncos_cache.py similarity index 53% rename from agent_based/cisco_asyncos_cache.py rename to source/agent_based/cisco_asyncos_cache.py index bf535717efeeeb0d4f265621c5b4bb5f07de8fe1..54dac162d1be3e5de2f063fcd7cd62baebd972b7 100644 --- a/agent_based/cisco_asyncos_cache.py +++ b/source/agent_based/cisco_asyncos_cache.py @@ -7,26 +7,27 @@ # URL : https://thl-cmk.hopto.org # Date : 2021-03-24 # -# only use full for Cisco WSA appliances +# only useful for Cisco WSA appliances # -from typing import Mapping, List, NamedTuple, Optional +from typing import NamedTuple from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( - DiscoveryResult, CheckResult, + DiscoveryResult, + HostLabelGenerator, StringTable, ) from cmk.base.plugins.agent_based.agent_based_api.v1 import ( - register, - Service, - check_levels, - Result, + HostLabel, Metric, + Result, SNMPTree, - contains, + Service, State, + contains, + register, ) @@ -38,15 +39,24 @@ class CiscoAsyncosCache(NamedTuple): cache_total_resptime: int +def host_label_cisco_asyncos(section: int) -> HostLabelGenerator: + """Host label function + Labels: + cmk/os_family: + This label is set to "AsyncOS" for all Cisco Ironport devices + """ + yield HostLabel(name="cmk/os_family", value="AsyncOS") + + # [['0', '0', '0', '0', '0']] -def parse_cisco_asyncos_cache(string_table: StringTable) -> Optional[CiscoAsyncosCache]: +def parse_cisco_asyncos_cache(string_table: StringTable) -> CiscoAsyncosCache | None: try: return CiscoAsyncosCache( - cache_hits_now=int(string_table[0][0]), - cache_misses_now=int(string_table[0][1]), - cache_hit_resptime_now=int(string_table[0][2]), - cache_miss_resptime_now=int(string_table[0][3]), - cache_total_resptime=int(string_table[0][4]), + cache_hits_now=int(string_table[0][0]), + cache_misses_now=int(string_table[0][1]), + cache_hit_resptime_now=int(string_table[0][2]), + cache_miss_resptime_now=int(string_table[0][3]), + cache_total_resptime=int(string_table[0][4]), ) except IndexError: return @@ -57,10 +67,14 @@ def discovery_cisco_asyncos_cache(section: CiscoAsyncosCache) -> DiscoveryResult def check_cisco_asyncos_cache(params, section: CiscoAsyncosCache) -> CheckResult: - yield Result(state=State.OK, - summary='Cache Stats current %s Hits (%sms response time), %s Misses (%sms response time) and %sms total response time' % ( - section.cache_hits_now, section.cache_hit_resptime_now, section.cache_misses_now, - section.cache_miss_resptime_now, section.cache_total_resptime)) + yield Result( + state=State.OK, + summary=f'Cache Stats current {section.cache_hits_now} Hits ' + f'({section.cache_hit_resptime_now}ms response time), ' + f'{section.cache_misses_now} Misses ' + f'({section.cache_miss_resptime_now}ms response time) and ' + f'{section.cache_total_resptime}ms total response time' + ) yield Metric(name='cache_hits_now', value=section.cache_hits_now) yield Metric(name='cache_misses_now', value=section.cache_misses_now) @@ -68,19 +82,21 @@ def check_cisco_asyncos_cache(params, section: CiscoAsyncosCache) -> CheckResult yield Metric(name='cache_miss_resptime_now', value=section.cache_miss_resptime_now) yield Metric(name='cache_total_resptime', value=section.cache_total_resptime) + register.snmp_section( name='cisco_asyncos_cache', parse_function=parse_cisco_asyncos_cache, - fetch= SNMPTree( - base='.1.3.6.1.4.1.15497.1.2.3.7', # ASYNCOSWEBSECURITYAPPLIANCE-MIB::proxyRecentPerf - oids=[ - '5.1', # cacheHitsNow - '6.1', # cacheMissesNow - '7.1', # cacheHitRespTimeNow - '8.1', # cacheMissRespTimeNow - '9.1', # cacheTotalRespTimeNow - ] - ), + host_label_function=host_label_cisco_asyncos, + fetch=SNMPTree( + base='.1.3.6.1.4.1.15497.1.2.3.7', # ASYNCOSWEBSECURITYAPPLIANCE-MIB::proxyRecentPerf + oids=[ + '5.1', # cacheHitsNow + '6.1', # cacheMissesNow + '7.1', # cacheHitRespTimeNow + '8.1', # cacheMissRespTimeNow + '9.1', # cacheTotalRespTimeNow + ] + ), detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'), ) diff --git a/agent_based/cisco_asyncos_conn.py b/source/agent_based/cisco_asyncos_conn.py similarity index 50% rename from agent_based/cisco_asyncos_conn.py rename to source/agent_based/cisco_asyncos_conn.py index f5436cd60e0fb13855a5fec62ebb3f44005c09e9..c7e598667f7ba7d45ba628feb2441a90fde9d6f3 100644 --- a/agent_based/cisco_asyncos_conn.py +++ b/source/agent_based/cisco_asyncos_conn.py @@ -9,42 +9,52 @@ # # only use full for Cisco WSA appliances # -from typing import Mapping, List, NamedTuple, Optional +from typing import NamedTuple from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( - DiscoveryResult, CheckResult, + DiscoveryResult, + HostLabelGenerator, StringTable, ) from cmk.base.plugins.agent_based.agent_based_api.v1 import ( - register, - Service, - check_levels, - Result, + HostLabel, Metric, + Result, SNMPTree, - contains, + Service, State, + contains, + register, ) class CiscoAsyncosConn(NamedTuple): - cacheClientIdleConns: int - cacheClientTotalConns: int - cacheClientMaxConns: int + cache_client_idle_conns: int + cache_client_total_conns: int + cache_client_max_conns: int + + +def host_label_cisco_asyncos(section: int) -> HostLabelGenerator: + """Host label function + Labels: + cmk/os_family: + This label is set to "AsyncOS" for all Cisco Ironport devices + """ + yield HostLabel(name="cmk/os_family", value="AsyncOS") # [['0', '5', '66277']] -def parse_cisco_asyncos_conn(string_table: StringTable) -> Optional[CiscoAsyncosConn]: +def parse_cisco_asyncos_conn(string_table: StringTable) -> CiscoAsyncosConn | None: try: return CiscoAsyncosConn( - cacheClientIdleConns=int(string_table[0][0]), - cacheClientTotalConns=int(string_table[0][1]), - cacheClientMaxConns=int(string_table[0][2]), + cache_client_idle_conns=int(string_table[0][0]), + cache_client_total_conns=int(string_table[0][1]), + cache_client_max_conns=int(string_table[0][2]), ) except IndexError: - return + return def discovery_cisco_asyncos_conn(section: CiscoAsyncosConn) -> DiscoveryResult: @@ -52,26 +62,30 @@ def discovery_cisco_asyncos_conn(section: CiscoAsyncosConn) -> DiscoveryResult: def check_cisco_asyncos_conn(params, section: CiscoAsyncosConn) -> CheckResult: - yield Result(state=State.OK, - summary='%s Active Connections - %s Idle Connections - Maximum Connections was %s' % ( - section.cacheClientTotalConns, section.cacheClientIdleConns, section.cacheClientMaxConns)) + yield Result( + state=State.OK, + summary=f'{section.cache_client_total_conns} Active Connections - ' + f'{section.cache_client_idle_conns} Idle Connections - Maximum Connections was ' + f'{section.cache_client_max_conns}' + ) - yield Metric(name='cacheClientIdleConns', value=section.cacheClientIdleConns) - yield Metric(name='cacheClientTotalConns', value=section.cacheClientTotalConns) - yield Metric(name='cacheClientMaxConns', value=section.cacheClientMaxConns) + yield Metric(name='cacheClientIdleConns', value=section.cache_client_idle_conns) + yield Metric(name='cacheClientTotalConns', value=section.cache_client_total_conns) + yield Metric(name='cacheClientMaxConns', value=section.cache_client_max_conns) register.snmp_section( name='cisco_asyncos_conn', parse_function=parse_cisco_asyncos_conn, - fetch= SNMPTree( - base='.1.3.6.1.4.1.15497.1.2.3.2', # ASYNCOSWEBSECURITYAPPLIANCE-MIB::proxyClientSidePerf - oids=[ - '7', # cacheClientIdleConns - '8', # cacheClientTotalConns - '9', # cacheClientMaxConns - ] - ), + host_label_function=host_label_cisco_asyncos, + fetch=SNMPTree( + base='.1.3.6.1.4.1.15497.1.2.3.2', # ASYNCOSWEBSECURITYAPPLIANCE-MIB::proxyClientSidePerf + oids=[ + '7', # cacheClientIdleConns + '8', # cacheClientTotalConns + '9', # cacheClientMaxConns + ] + ), detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'), ) diff --git a/agent_based/cisco_asyncos_cpu.py b/source/agent_based/cisco_asyncos_cpu.py similarity index 73% rename from agent_based/cisco_asyncos_cpu.py rename to source/agent_based/cisco_asyncos_cpu.py index 51235007ffd2f3228fef560caa3fc45d63db9b97..bb00f79e5ec5d9f9fa146c21e5aa2733c9f002e8 100644 --- a/agent_based/cisco_asyncos_cpu.py +++ b/source/agent_based/cisco_asyncos_cpu.py @@ -7,28 +7,41 @@ # URL : https://thl-cmk.hopto.org # Date : 2021-03-21 -from typing import Mapping, Dict, List, Tuple, NamedTuple +# 2024-04-18: added host label cmk/os_family:AsyncOS + +from typing import List from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( - DiscoveryResult, CheckResult, + DiscoveryResult, + HostLabelGenerator, StringTable, ) from cmk.base.plugins.agent_based.agent_based_api.v1 import ( - register, + HostLabel, + SNMPTree, Service, check_levels, - SNMPTree, contains, + register, ) +def host_label_cisco_asyncos(section: int) -> HostLabelGenerator: + """Host label function + Labels: + cmk/os_family: + This label is set to "AsyncOS" for all Cisco Ironport devices + """ + yield HostLabel(name="cmk/os_family", value="AsyncOS") + + # # sample string_table # [[['41']]] # -def parse_cisco_asyncos_cpu(string_table: List[StringTable]) -> int: +def parse_cisco_asyncos_cpu(string_table: List[StringTable]) -> int | None: try: return int(string_table[0][0][0]) except KeyError: @@ -55,11 +68,12 @@ def check_cisco_asyncos_cpu(params, section: int) -> CheckResult: register.snmp_section( name='cisco_asyncos_cpu', parse_function=parse_cisco_asyncos_cpu, + host_label_function=host_label_cisco_asyncos, fetch=[ SNMPTree( - base='.1.3.6.1.4.1.15497.1.1.1', + base='.1.3.6.1.4.1.15497.1.1.1', # ASYNCOS-MAIL-MIB::asyncOSMailObjects oids=[ - '2' # ASYNCOS-MAIL-MIB::perCentCPUUtilization + '2' # perCentCPUUtilization ] ), ], diff --git a/source/agent_based/cisco_asyncos_dns.py b/source/agent_based/cisco_asyncos_dns.py new file mode 100644 index 0000000000000000000000000000000000000000..dc25ff95cc345b3e8773af2fbdde9e90accfae1e --- /dev/null +++ b/source/agent_based/cisco_asyncos_dns.py @@ -0,0 +1,112 @@ +#!/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 : 2020-03-08 +# +# monitors status Cisco IronPort Appliances (ESA) DNS requests +# Tested with: C380, C370 +# +# 2021-03-24: rewrite for CMK 2.0 +# 2024-04-18: changed to check_levels +# added upper levels +# added metrics definition + +# +# .1.3.6.1.4.1.15497.1.1.1.15.0 = Gauge32: 0 +# .1.3.6.1.4.1.15497.1.1.1.16.0 = Gauge32: 0 +# +# ASYNCOS-MAIL-MIB::outstandingDNSRequests.0 = Gauge32: 0 +# ASYNCOS-MAIL-MIB::pendingDNSRequests.0 = Gauge32: 0 +# +# +from typing import NamedTuple + +from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( + CheckResult, + DiscoveryResult, + HostLabelGenerator, + StringTable, +) + +from cmk.base.plugins.agent_based.agent_based_api.v1 import ( + HostLabel, + SNMPTree, + Service, + check_levels, + contains, + register, +) + + +class CiscoAsyncosDns(NamedTuple): + outstanding_dns_requests: int + pending_dns_requests: int + + +def host_label_cisco_asyncos(section: int) -> HostLabelGenerator: + """Host label function + Labels: + cmk/os_family: + This label is set to "AsyncOS" for all Cisco Ironport devices + """ + yield HostLabel(name="cmk/os_family", value="AsyncOS") + + +# [['0', '0']] +def parse_cisco_asyncos_dns(string_table: StringTable) -> CiscoAsyncosDns | None: + try: + return CiscoAsyncosDns( + outstanding_dns_requests=int(string_table[0][0]), + pending_dns_requests=int(string_table[0][1]), + ) + except IndexError: + return + + +def discovery_cisco_asyncos_dns(section: CiscoAsyncosDns) -> DiscoveryResult: + yield Service() + + +def check_cisco_asyncos_dns(params, section: CiscoAsyncosDns) -> CheckResult: + yield from check_levels( + value=section.outstanding_dns_requests, + label='Outstanding requests', + metric_name='outstandingDNSRequests', + render_func=lambda v: f'{v}', + levels_upper=params.get('levels_outstanding') + ) + yield from check_levels( + value=section.pending_dns_requests, + label='Pending requests', + metric_name='pendingDNSRequests', + render_func=lambda v: f'{v}', + levels_upper=params.get('levels_pending') + ) + + +register.snmp_section( + name='cisco_asyncos_dns', + parse_function=parse_cisco_asyncos_dns, + host_label_function=host_label_cisco_asyncos, + fetch=SNMPTree( + base='.1.3.6.1.4.1.15497.1.1.1', # ASYNCOS-MAIL-MIB + oids=[ + '15', # outstandingDNSRequests + '16', # pendingDNSRequests + ] + ), + detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'), +) + +register.check_plugin( + name='cisco_asyncos_dns', + service_name='DNS requests', + discovery_function=discovery_cisco_asyncos_dns, + check_function=check_cisco_asyncos_dns, + check_default_parameters={}, + check_ruleset_name='cisco_asyncos_dns' +) diff --git a/agent_based/cisco_asyncos_fan.py b/source/agent_based/cisco_asyncos_fan.py similarity index 82% rename from agent_based/cisco_asyncos_fan.py rename to source/agent_based/cisco_asyncos_fan.py index 13e66181c0158755cc76f32de4cc55a853564f85..5e6995011e6b4ce700c6a8525424d64695be022e 100644 --- a/agent_based/cisco_asyncos_fan.py +++ b/source/agent_based/cisco_asyncos_fan.py @@ -44,25 +44,36 @@ from typing import Dict, List from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( - DiscoveryResult, CheckResult, + DiscoveryResult, + HostLabelGenerator, StringTable, ) from cmk.base.plugins.agent_based.agent_based_api.v1 import ( - register, + HostLabel, + SNMPTree, Service, check_levels, - State, - SNMPTree, contains, + register, ) + +def host_label_cisco_asyncos(section: int) -> HostLabelGenerator: + """Host label function + Labels: + cmk/os_family: + This label is set to "AsyncOS" for all Cisco Ironport devices + """ + yield HostLabel(name="cmk/os_family", value="AsyncOS") + + # # [[['6400', 'FAN 1'], ['6300', 'FAN 2'], ['6400', 'FAN 3'], ['6400', 'FAN 4'], ['6400', 'FAN 5'], ['6800', 'FAN 6']]] # -def parse_cisco_asyncos_fan(string_table: List[StringTable]) -> dict: +def parse_cisco_asyncos_fan(string_table: List[StringTable]) -> Dict: sensors = {} for sensor in string_table[0]: try: @@ -83,23 +94,23 @@ def discovery_cisco_asyncos_fan(section: Dict) -> DiscoveryResult: def check_cisco_asyncos_fan(item, params, section) -> CheckResult: try: value = section[item] - - yield from check_levels( - value, - label='Speed', - levels_lower=params.get('lower', None), - levels_upper=params.get('upper', None), - metric_name='fan' if params.get('output_metrics') else None, - render_func=lambda v: '%s RPM' % str(v), - ) - except KeyError: - pass + return + + yield from check_levels( + value=value, + label='Speed', + levels_lower=params.get('lower', None), + levels_upper=params.get('upper', None), + metric_name='fan' if params.get('output_metrics') else None, + render_func=lambda v: f'{str(v)} RPM', + ) register.snmp_section( name='cisco_asyncos_fan', parse_function=parse_cisco_asyncos_fan, + host_label_function=host_label_cisco_asyncos, fetch=[ SNMPTree( base='.1.3.6.1.4.1.15497.1.1.1.10.1', # ASYNCOS-MAIL-MIB::fanEntry diff --git a/agent_based/cisco_asyncos_feature_keys.py b/source/agent_based/cisco_asyncos_feature_keys.py similarity index 84% rename from agent_based/cisco_asyncos_feature_keys.py rename to source/agent_based/cisco_asyncos_feature_keys.py index 4d75a73b4a4b1c43c9d46b653f2dac022255f279..37b078b1ca48f2303e884d5d80e83102582c2461 100644 --- a/agent_based/cisco_asyncos_feature_keys.py +++ b/source/agent_based/cisco_asyncos_feature_keys.py @@ -111,36 +111,45 @@ import time from typing import Mapping, List, NamedTuple from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( - DiscoveryResult, CheckResult, + DiscoveryResult, + HostLabelGenerator, StringTable, ) from cmk.base.plugins.agent_based.agent_based_api.v1 import ( - register, - Service, - check_levels, + HostLabel, Result, SNMPTree, - contains, + Service, State, - render, + contains, + register, ) -def get_isperpetual(isperpetual): +def get_is_perpetual(is_perpetual): s_status = { '1': True, '2': False } - return s_status.get(isperpetual, False) + return s_status.get(is_perpetual, False) class CiscoAsyncosLicense(NamedTuple): perpetual: bool - secondsuntilexpire: int - daysuntilexpire: int - expiredate: str + seconds_until_expire: int + days_until_expire: int + expire_date: str + + +def host_label_cisco_asyncos(section: int) -> HostLabelGenerator: + """Host label function + Labels: + cmk/os_family: + This label is set to "AsyncOS" for all Cisco Ironport devices + """ + yield HostLabel(name="cmk/os_family", value="AsyncOS") # [[ @@ -158,12 +167,12 @@ class CiscoAsyncosLicense(NamedTuple): # ]] def parse_cisco_asyncos_feature_keys(string_table: List[StringTable]) -> Mapping[str, CiscoAsyncosLicense]: licenses = {} - for license, isperpetual, secondsuntilexpire in string_table[0]: + for license, is_perpetual, seconds_until_expire in string_table[0]: licenses.update({license: CiscoAsyncosLicense( - perpetual=get_isperpetual(isperpetual), - secondsuntilexpire=int(secondsuntilexpire), - daysuntilexpire=int(secondsuntilexpire) // 3600 // 24, - expiredate=time.strftime("%d %b %Y", time.localtime(time.time() + int(secondsuntilexpire))) + perpetual=get_is_perpetual(is_perpetual), + seconds_until_expire=int(seconds_until_expire), + days_until_expire=int(seconds_until_expire) // 3600 // 24, + expire_date=time.strftime("%d %b %Y", time.localtime(time.time() + int(seconds_until_expire))) )}) return licenses @@ -193,30 +202,37 @@ def check_cisco_asyncos_feature_keys(params, section: Mapping[str, CiscoAsyncosL ignore_count = 0 for license in section.keys(): if section[license].perpetual: - yield Result(state=State.OK, notice='%s is perpetual (will not expire)' % license) + yield Result(state=State.OK, notice=f'{license} is perpetual (will not expire)') elif license in features_ignore: - yield Result(state=State.OK, notice='%s will expire at %s (%s days). Feature ignored!' % ( - license, section[license].expiredate, section[license].daysuntilexpire)) + yield Result( + state=State.OK, + notice=f'{license} will expire at {section[license].expire_date} ' + f'({section[license].days_until_expire} days). Feature ignored!' + ) ignore_count += 1 - elif section[license].secondsuntilexpire == 0: - yield Result(state=State.CRIT, notice='%s has expired or is not licensed' % license) + elif section[license].seconds_until_expire == 0: + yield Result(state=State.CRIT, notice=f'{license} has expired or is not licensed') else: - if section[license].daysuntilexpire < crit: + if section[license].days_until_expire < crit: state = State.CRIT - elif section[license].daysuntilexpire < warn: + elif section[license].days_until_expire < warn: state = State.WARN else: state = State.OK - yield Result(state=state, notice='%s will expire at %s (%s days)' % ( - license, section[license].expiredate, section[license].daysuntilexpire)) + yield Result( + state=state, + notice=f'{license} will expire at {section[license].expire_date} ' + f'({section[license].days_until_expire} days)' + ) - yield Result(state=State.OK, summary='%d/%d Features found/ignored' % (len(section.keys()), ignore_count)) + yield Result(state=State.OK, summary=f'{len(section.keys())}/{ignore_count} Features found/ignored') register.snmp_section( name='cisco_asyncos_feature_keys', parse_function=parse_cisco_asyncos_feature_keys, + host_label_function=host_label_cisco_asyncos, fetch=[ SNMPTree( base='.1.3.6.1.4.1.15497.1.1.1.12.1', # ASYNCOS-MAIL-MIB::keyExpirationEntry diff --git a/agent_based/cisco_asyncos_mem.py b/source/agent_based/cisco_asyncos_mem.py similarity index 75% rename from agent_based/cisco_asyncos_mem.py rename to source/agent_based/cisco_asyncos_mem.py index f50d747dd751ecec25e4f6eba6d6964a578da2ad..237e57fc29cf0f557a5e93367df4e1093f82af28 100644 --- a/agent_based/cisco_asyncos_mem.py +++ b/source/agent_based/cisco_asyncos_mem.py @@ -7,6 +7,8 @@ # URL : https://thl-cmk.hopto.org # Date : 2021-03-21 # +# 2024-04-18: fixed params for levels_upper (ThX to alexander[dot]laengle[at]lgt[dot]com) +# # .1.3.6.1.4.1.15497.1.1.1.1.0 = INTEGER: 0 # .1.3.6.1.4.1.15497.1.1.1.7.0 = INTEGER: 1 # @@ -17,31 +19,38 @@ # [[u'0', u'1']] # -from typing import Mapping, Dict, List, Tuple, NamedTuple +from typing import List from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( - DiscoveryResult, CheckResult, + DiscoveryResult, + HostLabelGenerator, StringTable, ) from cmk.base.plugins.agent_based.agent_based_api.v1 import ( - register, + HostLabel, + SNMPTree, Service, check_levels, - SNMPTree, contains, + register, ) -# factory_settings['cisco_asyncos_mem_default_levels'] = { -# 'levels':(80.0, 90.0), -# } +def host_label_cisco_asyncos(section: int) -> HostLabelGenerator: + """Host label function + Labels: + cmk/os_family: + This label is set to "AsyncOS" for all Cisco Ironport devices + """ + yield HostLabel(name="cmk/os_family", value="AsyncOS") + # # [[['48']] # -def parse_cisco_asyncos_mem(string_table: List[StringTable]) -> int: +def parse_cisco_asyncos_mem(string_table: List[StringTable]) -> int | None: try: return int(string_table[0][0][0]) except KeyError: @@ -53,21 +62,19 @@ def discovery_cisco_asyncos_mem(section: int) -> DiscoveryResult: def check_cisco_asyncos_mem(params, section: int) -> CheckResult: - def render_percent(value) -> str: - return '%s%%' % value - yield from check_levels( section, label='Memory utilization', - levels_upper=params.get('util', None), + levels_upper=params.get('levels', None), metric_name='util', - render_func=render_percent, + render_func=lambda v: f'{v}%', ) register.snmp_section( name='cisco_asyncos_mem', parse_function=parse_cisco_asyncos_mem, + host_label_function=host_label_cisco_asyncos, fetch=[ SNMPTree( base='.1.3.6.1.4.1.15497.1.1.1', diff --git a/agent_based/cisco_asyncos_messageage.py b/source/agent_based/cisco_asyncos_messageage.py similarity index 72% rename from agent_based/cisco_asyncos_messageage.py rename to source/agent_based/cisco_asyncos_messageage.py index 91383d7bf948143636414608c6dd257ac5f28606..9b6b7a81f9739b5e8627417bda329b9ec7921ee2 100644 --- a/agent_based/cisco_asyncos_messageage.py +++ b/source/agent_based/cisco_asyncos_messageage.py @@ -17,35 +17,44 @@ # ASYNCOS-MAIL-MIB::oldestMessageAge.0 = Gauge32: 259706 # -from typing import Mapping, List, NamedTuple, Optional +from typing import NamedTuple from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( - DiscoveryResult, CheckResult, + DiscoveryResult, + HostLabelGenerator, StringTable, ) from cmk.base.plugins.agent_based.agent_based_api.v1 import ( - register, + HostLabel, + SNMPTree, Service, check_levels, - Result, - Metric, - SNMPTree, contains, - State, + register, render, ) class CiscoAsyncosMessageage(NamedTuple): - messageage: int + message: int + + +def host_label_cisco_asyncos(section: int) -> HostLabelGenerator: + """Host label function + Labels: + cmk/os_family: + This label is set to "AsyncOS" for all Cisco Ironport devices + """ + yield HostLabel(name="cmk/os_family", value="AsyncOS") + # [['259297']] -def parse_cisco_asyncos_messageage(string_table: StringTable) -> Optional[CiscoAsyncosMessageage]: +def parse_cisco_asyncos_messageage(string_table: StringTable) -> CiscoAsyncosMessageage | None: try: return CiscoAsyncosMessageage( - messageage=int(string_table[0][0]), + message=int(string_table[0][0]), ) except IndexError: return @@ -57,7 +66,7 @@ def discovery_cisco_asyncos_messageage(section: CiscoAsyncosMessageage) -> Disco def check_cisco_asyncos_messageage(params, section: CiscoAsyncosMessageage) -> CheckResult: yield from check_levels( - value=section.messageage, + value=section.message, label='Oldest messages', metric_name='message_age', levels_upper=params.get('upper', None), @@ -68,12 +77,13 @@ def check_cisco_asyncos_messageage(params, section: CiscoAsyncosMessageage) -> C register.snmp_section( name='cisco_asyncos_messageage', parse_function=parse_cisco_asyncos_messageage, - fetch= SNMPTree( - base='.1.3.6.1.4.1.15497.1.1.1', # ASYNCOS-MAIL-MIB - oids=[ - '14', # oldestMessageAge - ] - ), + host_label_function=host_label_cisco_asyncos, + fetch=SNMPTree( + base='.1.3.6.1.4.1.15497.1.1.1', # ASYNCOS-MAIL-MIB + oids=[ + '14', # oldestMessageAge + ] + ), detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'), ) diff --git a/agent_based/cisco_asyncos_power.py b/source/agent_based/cisco_asyncos_power.py similarity index 88% rename from agent_based/cisco_asyncos_power.py rename to source/agent_based/cisco_asyncos_power.py index 2ea635ef64099d743702862c95cbc8b86ee8a8ad..ee043d195dd40b7073e84d653ef956b8e8b458f4 100644 --- a/agent_based/cisco_asyncos_power.py +++ b/source/agent_based/cisco_asyncos_power.py @@ -35,28 +35,39 @@ from typing import Dict, List, NamedTuple from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( - DiscoveryResult, CheckResult, + DiscoveryResult, + HostLabelGenerator, StringTable, ) from cmk.base.plugins.agent_based.agent_based_api.v1 import ( - register, - Service, + HostLabel, Result, - State, SNMPTree, + Service, + State, contains, + register, ) class CiscoAsyncosPowersupply(NamedTuple): redundancy: State - state: State redundancy_readable: str + state: State state_readable: str +def host_label_cisco_asyncos(section: int) -> HostLabelGenerator: + """Host label function + Labels: + cmk/os_family: + This label is set to "AsyncOS" for all Cisco Ironport devices + """ + yield HostLabel(name="cmk/os_family", value="AsyncOS") + + # # [[['2', '1', 'PS 1'], ['2', '1', 'PS 2']]] # @@ -89,10 +100,10 @@ def parse_cisco_asyncos_power(string_table: List[StringTable]) -> dict: redundancy, redundancy_readable = get_ps_redundancy(redundancy) sensors.update({item: CiscoAsyncosPowersupply( - state=state, - state_readable=state_readable, redundancy=redundancy, redundancy_readable=redundancy_readable, + state=state, + state_readable=state_readable, )}) except (ValueError, IndexError): pass @@ -115,8 +126,8 @@ def check_cisco_asyncos_power(item, section) -> CheckResult: try: sensor = section[item] - yield Result(state=sensor.state, summary='Status: %s' % sensor.state_readable) - yield Result(state=sensor.redundancy, summary='Redundancy: %s' % sensor.redundancy_readable) + yield Result(state=sensor.state, summary=f'Status: {sensor.state_readable}') + yield Result(state=sensor.redundancy, summary=f'Redundancy: {sensor.redundancy_readable}') except KeyError: pass @@ -125,6 +136,7 @@ def check_cisco_asyncos_power(item, section) -> CheckResult: register.snmp_section( name='cisco_asyncos_power', parse_function=parse_cisco_asyncos_power, + host_label_function=host_label_cisco_asyncos, fetch=[ SNMPTree( base='.1.3.6.1.4.1.15497.1.1.1.8.1', # ASYNCOS-MAIL-MIB::powerSupplyEntry diff --git a/source/agent_based/cisco_asyncos_queue.py b/source/agent_based/cisco_asyncos_queue.py new file mode 100644 index 0000000000000000000000000000000000000000..9792927695e5231c4bf344336403eb6384a062b0 --- /dev/null +++ b/source/agent_based/cisco_asyncos_queue.py @@ -0,0 +1,121 @@ +#!/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 : 2020-02-10 +# +# added wato, fixed inventory function, changed snmp scan function, changed item to 'work queue' +# +# 2021-03-24: rewrite for CMK 2.0 +# 2024-04-18: fixed wrong queue states (ThX to alexander[dot]laengle[at]lgt[dot]com) +# fixed levels for queue full not working (ThX to alexander[dot]laengle[at]lgt[dot]com) +# changed state for not defined state from CRIT to UNKNOWN +# a bit of clean up + +from typing import NamedTuple + +from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( + CheckResult, + DiscoveryResult, + HostLabelGenerator, + StringTable, +) + +from cmk.base.plugins.agent_based.agent_based_api.v1 import ( + HostLabel, + Result, + SNMPTree, + Service, + State, + check_levels, + contains, + register, +) + + +class CiscoAsyncosQueue(NamedTuple): + state: State + state_readable: str + work_queue_messages: int | None + + +def get_state_readable(st: str) -> str: + states = { + '1': 'enough', + '2': 'near full', + '3': 'full', + } + return states.get(st, st) + + +def get_cmk_state(st: str) -> State: + states = { + '1': State.OK, + '2': State.WARN, + '3': State.CRIT + } + return states.get(st, State.UNKNOWN) + + +def host_label_cisco_asyncos(section: int) -> HostLabelGenerator: + """Host label function + Labels: + cmk/os_family: + This label is set to "AsyncOS" for all Cisco Ironport devices + """ + yield HostLabel(name="cmk/os_family", value="AsyncOS") + + +# [['1', '3451']] +def parse_cisco_asyncos_queue(string_table: StringTable) -> CiscoAsyncosQueue | None: + try: + queue_availability_status, work_queue_messages = string_table[0] + except IndexError: + return + + return CiscoAsyncosQueue( + state=get_cmk_state(queue_availability_status), + state_readable=get_state_readable(queue_availability_status), + work_queue_messages=int(work_queue_messages) if work_queue_messages.isdigit() else None + ) + + +def discovery_cisco_asyncos_queue(section: CiscoAsyncosQueue) -> DiscoveryResult: + yield Service() + + +def check_cisco_asyncos_queue(params, section: CiscoAsyncosQueue) -> CheckResult: + yield from check_levels( + value=section.work_queue_messages, + label='Messages in work queue', + levels_upper=params.get('levels', None), + metric_name='work_queue_size', + ) + yield Result(state=section.state, notice=f'Queue space: {section.state_readable}') + + +register.snmp_section( + name='cisco_asyncos_queue', + parse_function=parse_cisco_asyncos_queue, + host_label_function=host_label_cisco_asyncos, + fetch=SNMPTree( + base='.1.3.6.1.4.1.15497.1.1.1', # ASYNCOS-MAIL-MIB::asyncOSMailObjects + oids=[ + '5', # queueAvailabilityStatus + '11' # workQueueMessages + ] + ), + detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'), +) + +register.check_plugin( + name='cisco_asyncos_queue', + service_name='Queue', + discovery_function=discovery_cisco_asyncos_queue, + check_function=check_cisco_asyncos_queue, + check_default_parameters={'levels': (50, 100)}, + check_ruleset_name='cisco_asyncos_queue', +) diff --git a/agent_based/cisco_asyncos_raid.py b/source/agent_based/cisco_asyncos_raid.py similarity index 81% rename from agent_based/cisco_asyncos_raid.py rename to source/agent_based/cisco_asyncos_raid.py index be917e5472a162c67580781ac9dfae1ac2014886..70d48a0b22775d5610b0f5a982e39ebef0f46507 100644 --- a/agent_based/cisco_asyncos_raid.py +++ b/source/agent_based/cisco_asyncos_raid.py @@ -36,25 +36,27 @@ from typing import Mapping, List, NamedTuple from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( - DiscoveryResult, CheckResult, + DiscoveryResult, + HostLabelGenerator, StringTable, ) from cmk.base.plugins.agent_based.agent_based_api.v1 import ( - register, - Service, + HostLabel, Result, SNMPTree, - contains, + Service, State, + contains, + register, ) class CiscoAsyncosRaid(NamedTuple): state: State - status_readable: str - lasterror: str + state_readable: str + last_error: str def get_cmk_state(st: str) -> State: @@ -66,7 +68,7 @@ def get_cmk_state(st: str) -> State: return states.get(st, State.CRIT) -def get_status_readable(st: str) -> str: +def get_state_readable(st: str) -> str: states = { '1': 'healthy', '2': 'failure', @@ -75,6 +77,15 @@ def get_status_readable(st: str) -> str: return states.get(st, st) +def host_label_cisco_asyncos(section: int) -> HostLabelGenerator: + """Host label function + Labels: + cmk/os_family: + This label is set to "AsyncOS" for all Cisco Ironport devices + """ + yield HostLabel(name="cmk/os_family", value="AsyncOS") + + # [[ # ['1', 'Drive 0', 'No Errors'], # ['2', 'Drive 1', 'UNKNOWN'], @@ -85,11 +96,11 @@ def get_status_readable(st: str) -> str: # ]] def parse_cisco_asyncos_raid(string_table: List[StringTable]) -> Mapping[str, CiscoAsyncosRaid]: arrays = {} - for raidStatus, raidID, raidLastError in string_table[0]: - arrays.update({raidID: CiscoAsyncosRaid( - state=get_cmk_state(raidStatus), - status_readable=get_status_readable(raidStatus), - lasterror=raidLastError + for raid_status, raid_id, raid_last_error in string_table[0]: + arrays.update({raid_id: CiscoAsyncosRaid( + state=get_cmk_state(raid_status), + state_readable=get_state_readable(raid_status), + last_error=raid_last_error )}) return arrays @@ -109,9 +120,10 @@ def discovery_cisco_asyncos_raid(section: Mapping[str, CiscoAsyncosRaid]) -> Dis def check_cisco_asyncos_raid(item, section: Mapping[str, CiscoAsyncosRaid]) -> CheckResult: try: - yield Result(state=section[item].state, - summary='RAID status: %s, last error: %s' % (section[item].state, section[item].lasterror), - ) + yield Result( + state=section[item].state, + summary=f'RAID status: {section[item].state}, last error: {section[item].last_error}', + ) except KeyError: pass @@ -119,6 +131,7 @@ def check_cisco_asyncos_raid(item, section: Mapping[str, CiscoAsyncosRaid]) -> C register.snmp_section( name='cisco_asyncos_raid', parse_function=parse_cisco_asyncos_raid, + host_label_function=host_label_cisco_asyncos, fetch=[ SNMPTree( base='.1.3.6.1.4.1.15497.1.1.1.18.1', # ASYNCOS-MAIL-MIB::raidEntry diff --git a/agent_based/cisco_asyncos_resources.py b/source/agent_based/cisco_asyncos_resources.py similarity index 70% rename from agent_based/cisco_asyncos_resources.py rename to source/agent_based/cisco_asyncos_resources.py index c6041a2d3abe8d0428103623c079085ade426925..a771e9b3d0d14b6e1b161f774fd50398773d3888 100644 --- a/agent_based/cisco_asyncos_resources.py +++ b/source/agent_based/cisco_asyncos_resources.py @@ -17,27 +17,27 @@ # ASYNCOS-MAIL-MIB::resourceConservationReason.0 = INTEGER: noResourceConservation(1) # # -from typing import Mapping, List, NamedTuple, Optional +from typing import NamedTuple from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( - DiscoveryResult, CheckResult, + DiscoveryResult, + HostLabelGenerator, StringTable, ) from cmk.base.plugins.agent_based.agent_based_api.v1 import ( - register, - Service, - check_levels, + HostLabel, Result, SNMPTree, - contains, + Service, State, - render, + contains, + register, ) -def get_status_readable(st: str) -> str: +def get_state_readable(st: str) -> str: states = { '1': 'none', '2': 'memory shortage', @@ -59,14 +59,23 @@ def get_cmk_state(st: str) -> State: class CiscoAsyncosResources(NamedTuple): state: State - status_readable: str + state_readable: str + + +def host_label_cisco_asyncos(section: int) -> HostLabelGenerator: + """Host label function + Labels: + cmk/os_family: + This label is set to "AsyncOS" for all Cisco Ironport devices + """ + yield HostLabel(name="cmk/os_family", value="AsyncOS") -def parse_cisco_asyncos_bandwidth(string_table: StringTable) -> Optional[CiscoAsyncosResources]: +def parse_cisco_asyncos_bandwidth(string_table: StringTable) -> CiscoAsyncosResources | None: try: return CiscoAsyncosResources( state=get_cmk_state(string_table[0][0]), - status_readable=get_status_readable(string_table[0][0]) + state_readable=get_state_readable(string_table[0][0]) ) except IndexError: return @@ -77,18 +86,19 @@ def discovery_cisco_asyncos_resources(section: CiscoAsyncosResources) -> Discove def check_cisco_asyncos_resources(section: CiscoAsyncosResources) -> CheckResult: - yield Result(state=section.state, notice='Resource conservation %s' % section.status_readable) + yield Result(state=section.state, notice=f'Resource conservation {section.state_readable}') register.snmp_section( name='cisco_asyncos_resources', parse_function=parse_cisco_asyncos_bandwidth, - fetch= SNMPTree( - base='.1.3.6.1.4.1.15497.1.1.1', # ASYNCOS-MAIL-MIB - oids=[ - '6', # resourceConservationReason - ] - ), + host_label_function=host_label_cisco_asyncos, + fetch=SNMPTree( + base='.1.3.6.1.4.1.15497.1.1.1', # ASYNCOS-MAIL-MIB + oids=[ + '6', # resourceConservationReason + ] + ), detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'), ) diff --git a/agent_based/cisco_asyncos_temp.py b/source/agent_based/cisco_asyncos_temp.py similarity index 75% rename from agent_based/cisco_asyncos_temp.py rename to source/agent_based/cisco_asyncos_temp.py index bb38d10d341d2a051c2e0d097f6ea39eccb6efa5..4782bb6644ae4b2dc6f51b6297565ec480785921 100644 --- a/agent_based/cisco_asyncos_temp.py +++ b/source/agent_based/cisco_asyncos_temp.py @@ -22,33 +22,43 @@ # ASYNCOS-MAIL-MIB::temperatureName.1 = STRING: Ambient # -from typing import Mapping, Dict, List, Tuple, NamedTuple +from typing import Dict from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( - DiscoveryResult, CheckResult, + DiscoveryResult, + HostLabelGenerator, StringTable, ) from cmk.base.plugins.agent_based.agent_based_api.v1 import ( - register, - Service, - check_levels, + HostLabel, SNMPTree, + Service, contains, get_value_store, + register, ) from cmk.base.plugins.agent_based.utils.temperature import ( - check_temperature, TempParamType, + check_temperature, ) +def host_label_cisco_asyncos(section: int) -> HostLabelGenerator: + """Host label function + Labels: + cmk/os_family: + This label is set to "AsyncOS" for all Cisco Ironport devices + """ + yield HostLabel(name="cmk/os_family", value="AsyncOS") + + # # [['22', 'FP_TEMP_SENSOR']] # -def parse_cisco_asyncos_temp(string_table: StringTable) -> dict: +def parse_cisco_asyncos_temp(string_table: StringTable) -> Dict: sensors = {} for sensor in string_table: try: @@ -70,7 +80,7 @@ def check_cisco_asyncos_temp(item, params: TempParamType, section) -> CheckResul yield from check_temperature( section[item], params=params, - unique_name='check_cisco_asyncos_temp.%s' % item, + unique_name=f'check_cisco_asyncos_temp.{item}', value_store=get_value_store(), ) except KeyError: @@ -80,13 +90,14 @@ def check_cisco_asyncos_temp(item, params: TempParamType, section) -> CheckResul register.snmp_section( name='cisco_asyncos_temp', parse_function=parse_cisco_asyncos_temp, - fetch= SNMPTree( - base='.1.3.6.1.4.1.15497.1.1.1.9.1', # ASYNCOS-MAIL-MIB::temperatureEntry - oids=[ - '2', # degreesCelsius - '3', # temperatureName - ] - ), + host_label_function=host_label_cisco_asyncos, + fetch=SNMPTree( + base='.1.3.6.1.4.1.15497.1.1.1.9.1', # ASYNCOS-MAIL-MIB::temperatureEntry + oids=[ + '2', # degreesCelsius + '3', # temperatureName + ] + ), detect=contains('.1.3.6.1.2.1.1.1.0', 'AsyncOS'), ) diff --git a/agent_based/cisco_asyncos_updates.py b/source/agent_based/cisco_asyncos_updates.py similarity index 82% rename from agent_based/cisco_asyncos_updates.py rename to source/agent_based/cisco_asyncos_updates.py index db567ceb11480cd6540e79e69f7d821881f58aad..f6c8bf51690a14b5bfa12a882b549a8a8b60ca6a 100644 --- a/agent_based/cisco_asyncos_updates.py +++ b/source/agent_based/cisco_asyncos_updates.py @@ -137,22 +137,24 @@ # ASYNCOS-MAIL-MIB::updateFailures.14 = Counter32: 0 # ASYNCOS-MAIL-MIB::updateFailures.15 = Counter32: 0 # -from typing import Mapping, List, NamedTuple +from typing import List, Mapping, NamedTuple from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( - DiscoveryResult, CheckResult, + DiscoveryResult, + HostLabelGenerator, StringTable, ) from cmk.base.plugins.agent_based.agent_based_api.v1 import ( - register, - Service, + HostLabel, + Metric, Result, SNMPTree, - contains, + Service, State, - Metric, + contains, + register, ) from cmk.base.item_state import ( @@ -160,9 +162,20 @@ from cmk.base.item_state import ( set_item_state, ) + class CiscoAsyncosUpdate(NamedTuple): updates: int - updatefailures: int + update_failures: int + + +def host_label_cisco_asyncos(section: int) -> HostLabelGenerator: + """Host label function + Labels: + cmk/os_family: + This label is set to "AsyncOS" for all Cisco Ironport devices + """ + yield HostLabel(name="cmk/os_family", value="AsyncOS") + # [[ # ['File Reputation', '6', '38'], @@ -186,10 +199,11 @@ def parse_cisco_asyncos_updates(string_table: List[StringTable]) -> Mapping[str, for feature, updates, update_failures in string_table[0]: features.update({feature: CiscoAsyncosUpdate( updates=int(updates), - updatefailures=int(update_failures) - ) }) + update_failures=int(update_failures) + )}) return features + # { # 'File Reputation': CiscoAsyncosUpdate(updates=6, updatefailures=38), # 'IronPort Anti-Spam': CiscoAsyncosUpdate(updates=12, updatefailures=9), @@ -207,25 +221,24 @@ def parse_cisco_asyncos_updates(string_table: List[StringTable]) -> Mapping[str, # 'support_request': CiscoAsyncosUpdate(updates=1, updatefailures=0), # 'timezones': CiscoAsyncosUpdate(updates=1, updatefailures=0) # } -def discovery_cisco_asyncos_updates(section:Mapping[str, CiscoAsyncosUpdate])-> DiscoveryResult: +def discovery_cisco_asyncos_updates(section: Mapping[str, CiscoAsyncosUpdate]) -> DiscoveryResult: yield Service() -def check_cisco_asyncos_updates(params, section:Mapping[str, CiscoAsyncosUpdate]) -> CheckResult: + +def check_cisco_asyncos_updates(params, section: Mapping[str, CiscoAsyncosUpdate]) -> CheckResult: features_ignore = params.get('features_ignore', []) warn, crit = params.get('failedLevel') ignore_count = 0 for feature in section.keys(): - failed = section[feature].updatefailures + failed = section[feature].update_failures passed = section[feature].updates # read counters - passedLast = get_item_state('cisco_asyncos_updates_%s_passedLast' % feature) - failedLast = get_item_state('cisco_asyncos_updates_%s_failedLast' % feature) - failedAttempts = get_item_state('cisco_asyncos_updates_%s_failedAttempts' % feature) + passed_last = get_item_state('cisco_asyncos_updates_%s_passedLast' % feature) + failed_last = get_item_state('cisco_asyncos_updates_%s_failedLast' % feature) + failed_attempts = get_item_state('cisco_asyncos_updates_%s_failedAttempts' % feature) - # print('Feature %s, passed: %s/%s failed: %s/%s, Attempts: %s' % (feature, passed,passedLast, failed,failedLast, failedAttempts)) - - if (passedLast == None) or (failedLast == None) or (failedAttempts == None): # or (lastState == None): + if (passed_last is None) or (failed_last is None) or (failed_attempts is None): # or (lastState is None): # init counters set_item_state('cisco_asyncos_updates_%s_passedLast' % feature, passed) set_item_state('cisco_asyncos_updates_%s_failedLast' % feature, failed) @@ -233,50 +246,52 @@ def check_cisco_asyncos_updates(params, section:Mapping[str, CiscoAsyncosUpdate] else: set_item_state('cisco_asyncos_updates_%s_passedLast' % feature, passed) set_item_state('cisco_asyncos_updates_%s_failedLast' % feature, failed) - passedLast = int(passedLast) - failedLast = int(failedLast) - failedAttempts = int(failedAttempts) + passed_last = int(passed_last) + failed_last = int(failed_last) + failed_attempts = int(failed_attempts) # reset counter if overrun - if failed < failedLast: + if failed < failed_last: set_item_state('cisco_asyncos_updates_%s_failedLast' % feature, failed) - failedLast = failed - if passed < passedLast: + failed_last = failed + if passed < passed_last: set_item_state('cisco_asyncos_updates_%s_passedLast' % feature, passed) - passedLast = passed + passed_last = passed - if passed > passedLast: + if passed > passed_last: # reset error counter after passed update attempt set_item_state('cisco_asyncos_updates_%s_failedAttempts' % feature, 0) else: - failedAttempts = failedAttempts + failed - failedLast - set_item_state('cisco_asyncos_updates_%s_failedAttempts' % feature, failedAttempts) + failed_attempts = failed_attempts + failed - failed_last + set_item_state('cisco_asyncos_updates_%s_failedAttempts' % feature, failed_attempts) + base_message = f'{feature}: {passed}/{failed}' if feature in features_ignore: - yield Result(state=State.OK, notice='%s: %d/%d updates/update failures. Feature ignored!' % (feature, passed, failed)) + yield Result(state=State.OK, notice=f'{base_message} updates/update failures. Feature ignored!') ignore_count += 1 else: - if failedAttempts >= crit: - yield Result(state=State.CRIT, notice='%s: %d/%d passed/failed.' % (feature, passed, failed)) - lastState=-1 - elif failedAttempts >= warn: - yield Result(state=State.WARN, notice='%s: %d/%d passed/failed.' % (feature, passed, failed)) - lastState=-1 + if failed_attempts >= crit: + yield Result(state=State.CRIT, notice=f'{base_message} passed/failed.') + last_state = -1 + elif failed_attempts >= warn: + yield Result(state=State.WARN, notice=f'{base_message} passed/failed.') + last_state = -1 else: - yield Result(state=State.OK, notice='%s: %d/%d passed/failed.' % (feature, passed, failed)) - lastState=1 + yield Result(state=State.OK, notice=f'{base_message} passed/failed.') + last_state = 1 yield Metric( name=feature.replace(' ', '_'), - value=lastState, - boundaries=(2,-2) + value=last_state, + boundaries=(2, -2) ) - yield Result(state=State.OK, summary='%d/%d Features found/ignored' % (len(section.keys()), ignore_count)) + yield Result(state=State.OK, summary=f'{len(section.keys())}/{ignore_count} Features found/ignored') register.snmp_section( name='cisco_asyncos_updates', parse_function=parse_cisco_asyncos_updates, + host_label_function=host_label_cisco_asyncos, fetch=[ SNMPTree( base='.1.3.6.1.4.1.15497.1.1.1.13.1', # ASYNCOS-MAIL-MIB::updateEntry @@ -298,4 +313,3 @@ register.check_plugin( check_default_parameters={'failedLevel': (5, 10)}, check_ruleset_name='cisco_asyncos_updates', ) - diff --git a/source/gui/metrics/cisco_asyncos.py b/source/gui/metrics/cisco_asyncos.py new file mode 100644 index 0000000000000000000000000000000000000000..68350c8c2f797eb7ff42490a5d5b03a707319739 --- /dev/null +++ b/source/gui/metrics/cisco_asyncos.py @@ -0,0 +1,100 @@ +#!/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 : 2024-04-18 +# File : cisco_asyncos.py (metrics) +# + +from cmk.gui.i18n import _ + +from cmk.gui.plugins.metrics.utils import ( + metric_info, + graph_info, + perfometer_info +) + +# +# asyncos bandwidth +# + +metric_info['bandwidth_now'] = { + 'title': _('Current bandwidth'), + 'unit': 'bytes/s', + 'color': '31/a', +} + +graph_info['cisco_asyncos.bandwidth_now'] = { + 'title': _('Cisco AsyncOS current bandwidth'), + 'metrics': [ + ('bandwidth_now', 'area'), + ], +} + +perfometer_info.append({ + 'type': 'logarithmic', + 'metric': 'bandwidth_now', + 'half_value': 1073741824, # 1GByte + 'exponent': 2, +}) + +# +# asyncos dns +# + +metric_info['outstandingDNSRequests'] = { + 'title': _('Outstanding DNS requests'), + 'unit': 'count', + 'color': '31/a', +} +metric_info['pendingDNSRequests'] = { + 'title': _('Pending DNS requests'), + 'unit': 'count', + 'color': '21/a', +} +graph_info['cisco_asyncos.dns'] = { + 'title': _('Cisco AsyncOS DNS requests'), + 'metrics': [ + ('outstandingDNSRequests', 'area'), + ('pendingDNSRequests', '-area'), + ], +} +perfometer_info.append(('stacked', [ + { + 'type': 'logarithmic', + 'metric': 'outstandingDNSRequests', + 'half_value': 100, + 'exponent': 2, + }, + { + 'type': 'logarithmic', + 'metric': 'pendingDNSRequests', + 'half_value': 100, + 'exponent': 2, + } +])) + +# +# asyncos message queue +# + +metric_info['work_queue_size'] = { + 'title': _('Work queue size'), + 'unit': 'count', + 'color': '11/a', +} + +graph_info['cisco_asyncos.queue'] = { + 'title': _('Cisco AsyncOS work queue'), + 'metrics': [ + ('work_queue_size', 'area'), + ], +} +perfometer_info.append({ + 'type': 'logarithmic', + 'metric': 'work_queue_size', + 'half_value': 100, + 'exponent': 2, +}) diff --git a/source/gui/wato/cisco_asyncos_dns.py b/source/gui/wato/cisco_asyncos_dns.py new file mode 100644 index 0000000000000000000000000000000000000000..02b399bc4cb72f2b3b1a4cd2baf2e1c07020e364 --- /dev/null +++ b/source/gui/wato/cisco_asyncos_dns.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# +from cmk.gui.i18n import _ +from cmk.gui.valuespec import ( + Dictionary, + Integer, + TextAscii, + Tuple, +) + +from cmk.gui.plugins.wato.utils import ( + CheckParameterRulespecWithItem, + RulespecGroupCheckParametersNetworking, + rulespec_registry, +) + + +def _parameter_valuespec_cisco_asyncos_dns(): + return Dictionary(elements=[ + ('levels_outstanding', + Tuple( + title=_('Upper levels for outstanding DNS requests'), + help=_('Number of DNS requests that have been sent but for which no reply has been received.'), + elements=[ + Integer(title=_('Warning at'), unit=_('# of requests')), + Integer(title=_('Critical at'), unit=_('# of requests')), + ]) + ), + ('levels_pending', + Tuple( + title=_('Upper levels for pending DNS requests'), + help=_('Number of DNS requests waiting to be sent.'), + elements=[ + Integer(title=_('Warning'), unit=_('# of requests')), + Integer(title=_('Critical'), unit=_('# of requests')), + ]) + ), + ]) + + +rulespec_registry.register( + CheckParameterRulespecWithItem( + check_group_name='cisco_asyncos_dns', + group=RulespecGroupCheckParametersNetworking, + item_spec=lambda: TextAscii(title=_('Cisco AsyncOS DNS'), ), + match_type='dict', + parameter_valuespec=_parameter_valuespec_cisco_asyncos_dns, + title=lambda: _('Cisco AsyncOS DNS'), + )) diff --git a/gui/wato/cisco_asyncos_feature_keys.py b/source/gui/wato/cisco_asyncos_feature_keys.py similarity index 87% rename from gui/wato/cisco_asyncos_feature_keys.py rename to source/gui/wato/cisco_asyncos_feature_keys.py index 8b38a99ae5511dee47bc8a2adc4ed95a8b5d9df1..a42936026b662cddc7c8015b255bb587ccacb0ec 100644 --- a/gui/wato/cisco_asyncos_feature_keys.py +++ b/source/gui/wato/cisco_asyncos_feature_keys.py @@ -6,15 +6,15 @@ from cmk.gui.i18n import _ from cmk.gui.valuespec import ( Dictionary, Integer, - TextAscii, ListOfStrings, + TextAscii, Tuple, ) from cmk.gui.plugins.wato.utils import ( CheckParameterRulespecWithItem, - rulespec_registry, RulespecGroupCheckParametersNetworking, + rulespec_registry, ) @@ -33,8 +33,8 @@ def _parameter_valuespec_cisco_asyncos_feature_keys(): Tuple( title=_('Levels for feature key expiration in days'), elements=[ - Integer(title=_('Warning'), default_value=30, unit=_('days before expiration')), - Integer(title=_('Critical'), default_value=7, unit=_('days before expiration')), + Integer(title=_('Warning at'), default_value=30, unit=_('days before expiration')), + Integer(title=_('Critical at'), default_value=7, unit=_('days before expiration')), ])), ]) diff --git a/gui/wato/cisco_asyncos_license.py b/source/gui/wato/cisco_asyncos_license.py similarity index 87% rename from gui/wato/cisco_asyncos_license.py rename to source/gui/wato/cisco_asyncos_license.py index fb7cbcafd99b6ca5d8484d8aa96f7277a1bf053b..31c4a612ad166fa406a7ed9ae516feb832c8b65c 100644 --- a/gui/wato/cisco_asyncos_license.py +++ b/source/gui/wato/cisco_asyncos_license.py @@ -6,15 +6,15 @@ from cmk.gui.i18n import _ from cmk.gui.valuespec import ( Dictionary, Integer, - TextAscii, ListOfStrings, + TextAscii, Tuple, ) from cmk.gui.plugins.wato.utils import ( CheckParameterRulespecWithItem, - rulespec_registry, RulespecGroupCheckParametersNetworking, + rulespec_registry, ) @@ -34,8 +34,8 @@ def _parameter_valuespec_cisco_asyncos_license(): Tuple( title=_('Levels for licence expiration in days'), elements=[ - Integer(title=_('Warning'), default_value=30, unit=_('days before expiration')), - Integer(title=_('Critical'), default_value=7, unit=_('days before expiration')), + Integer(title=_('Warning at'), default_value=30, unit=_('days before expiration')), + Integer(title=_('Critical at'), default_value=7, unit=_('days before expiration')), ])), ]) diff --git a/gui/wato/cisco_asyncos_queue.py b/source/gui/wato/cisco_asyncos_queue.py similarity index 82% rename from gui/wato/cisco_asyncos_queue.py rename to source/gui/wato/cisco_asyncos_queue.py index 66d0258affe07442c455d6cf439b270d22551ba3..403a5e5d4dd0d35315a9173e664469b0b0d64ab9 100644 --- a/gui/wato/cisco_asyncos_queue.py +++ b/source/gui/wato/cisco_asyncos_queue.py @@ -7,14 +7,13 @@ from cmk.gui.valuespec import ( Dictionary, Integer, TextAscii, - ListOfStrings, Tuple, ) from cmk.gui.plugins.wato.utils import ( CheckParameterRulespecWithItem, - rulespec_registry, RulespecGroupCheckParametersNetworking, + rulespec_registry, ) @@ -24,8 +23,8 @@ def _parameter_valuespec_cisco_asyncos_queue(): Tuple( title=_('Levels for nuber of messages in work queue'), elements=[ - Integer(title=_('Warning'), default_value=50, unit=_('# of messages')), - Integer(title=_('Critical'), default_value=100, unit=_('# of messages')), + Integer(title=_('Warning at'), default_value=50, unit=_('# of messages')), + Integer(title=_('Critical at'), default_value=100, unit=_('# of messages')), ])), ]) diff --git a/gui/wato/cisco_asyncos_updates.py b/source/gui/wato/cisco_asyncos_updates.py similarity index 86% rename from gui/wato/cisco_asyncos_updates.py rename to source/gui/wato/cisco_asyncos_updates.py index 4f25b4d3fd07d5edbaf559acbabcca4d62844867..5f1061e5f9d32dcf576fefe0a9821958143b0ce9 100644 --- a/gui/wato/cisco_asyncos_updates.py +++ b/source/gui/wato/cisco_asyncos_updates.py @@ -6,15 +6,15 @@ from cmk.gui.i18n import _ from cmk.gui.valuespec import ( Dictionary, Integer, - TextAscii, ListOfStrings, + TextAscii, Tuple, ) from cmk.gui.plugins.wato.utils import ( CheckParameterRulespecWithItem, - rulespec_registry, RulespecGroupCheckParametersNetworking, + rulespec_registry, ) @@ -32,8 +32,8 @@ def _parameter_valuespec_cisco_asyncos_updates(): Tuple( title=_('Levels for failed attempts'), elements=[ - Integer(title=_('Warning'), default_value=5, unit=_('# of failed attempts')), - Integer(title=_('Critical'), default_value=10, unit=_('# of failed attempts')), + Integer(title=_('Warning at'), default_value=5, unit=_('# of failed attempts')), + Integer(title=_('Critical at'), default_value=10, unit=_('# of failed attempts')), ])), ]) diff --git a/packages/cisco_asyncos b/source/packages/cisco_asyncos similarity index 89% rename from packages/cisco_asyncos rename to source/packages/cisco_asyncos index 40f791060a0f63ebc586317b40b1f7a2866f7bb9..bd98f08687d2038ec1c6b05dcb8d42f43b27a472 100644 --- a/packages/cisco_asyncos +++ b/source/packages/cisco_asyncos @@ -42,10 +42,12 @@ 'gui': ['wato/cisco_asyncos_feature_keys.py', 'wato/cisco_asyncos_license.py', 'wato/cisco_asyncos_queue.py', - 'wato/cisco_asyncos_updates.py']}, + 'wato/cisco_asyncos_updates.py', + 'metrics/cisco_asyncos.py', + 'wato/cisco_asyncos_dns.py']}, 'name': 'cisco_asyncos', 'title': 'Cisco AsyncOS (IronPort) checks', - 'version': '20230306.v0.3.0', - 'version.min_required': '2.1.0', - 'version.packaged': '2.1.0p22', - 'version.usable_until': None} \ No newline at end of file + 'version': '0.4.1-20240418', + 'version.min_required': '2.1.0b1', + 'version.packaged': '2.2.0p24', + 'version.usable_until': None}