From 9c3cfc9d89ed7e186dd05fbc6f241e2e26495ff6 Mon Sep 17 00:00:00 2001 From: "Th.L" <thl-cmk@outlook.com> Date: Thu, 18 Mar 2021 17:27:59 +0100 Subject: [PATCH] update project --- agent_based/cisco_asa_sensors.py | 110 ++++++++++++++++++++++++++++--- cisco_asa_sensors.mkp | Bin 2300 -> 2941 bytes 2 files changed, 100 insertions(+), 10 deletions(-) diff --git a/agent_based/cisco_asa_sensors.py b/agent_based/cisco_asa_sensors.py index 5941c7c..f50cbd0 100644 --- a/agent_based/cisco_asa_sensors.py +++ b/agent_based/cisco_asa_sensors.py @@ -9,17 +9,110 @@ # # Monitor Cisco ASA temperature sensors # -# this check is based on the cmk 2.0 checkpoint_temp check -# # 2021-02-25: rewrite for CMK 2.x # # sample snmpwalk +# .1.3.6.1.2.1.47.1.1.1.1.7.1 = STRING: "Chassis" +# .1.3.6.1.2.1.47.1.1.1.1.7.2 = STRING: "Processor 0/0" +# .1.3.6.1.2.1.47.1.1.1.1.7.3 = STRING: "Processor 0/1" +# .1.3.6.1.2.1.47.1.1.1.1.7.4 = STRING: "Processor 0/2" +# .1.3.6.1.2.1.47.1.1.1.1.7.5 = STRING: "ASA5515 Slot for Removable Drive 0" +# .1.3.6.1.2.1.47.1.1.1.1.7.6 = STRING: "Micron_M550_MTFDDAK128MAY Removable Drive in Slot 0" +# .1.3.6.1.2.1.47.1.1.1.1.7.7 = STRING: "Chassis Cooling Fan 1" +# .1.3.6.1.2.1.47.1.1.1.1.7.8 = STRING: "Chassis Fan Sensor 1" +# .1.3.6.1.2.1.47.1.1.1.1.7.9 = STRING: "Chassis Cooling Fan 2" +# .1.3.6.1.2.1.47.1.1.1.1.7.10 = STRING: "Chassis Fan Sensor 2" +# .1.3.6.1.2.1.47.1.1.1.1.7.11 = STRING: "Chassis Cooling Fan 3" +# .1.3.6.1.2.1.47.1.1.1.1.7.12 = STRING: "Chassis Fan Sensor 3" +# .1.3.6.1.2.1.47.1.1.1.1.7.13 = STRING: "CPU Temperature Sensor 0/0" +# .1.3.6.1.2.1.47.1.1.1.1.7.14 = STRING: "Chassis Ambient Temperature Sensor 1" +# .1.3.6.1.2.1.47.1.1.1.1.7.15 = STRING: "Chassis Ambient Temperature Sensor 2" +# .1.3.6.1.2.1.47.1.1.1.1.7.16 = STRING: "Chassis Ambient Temperature Sensor 3" +# .1.3.6.1.2.1.47.1.1.1.1.7.17 = STRING: "Gi0/0" +# .1.3.6.1.2.1.47.1.1.1.1.7.18 = STRING: "Gi0/1" +# .1.3.6.1.2.1.47.1.1.1.1.7.19 = STRING: "Gi0/2" +# .1.3.6.1.2.1.47.1.1.1.1.7.20 = STRING: "Gi0/3" +# .1.3.6.1.2.1.47.1.1.1.1.7.21 = STRING: "Gi0/4" +# .1.3.6.1.2.1.47.1.1.1.1.7.22 = STRING: "Gi0/5" +# .1.3.6.1.2.1.47.1.1.1.1.7.23 = STRING: "In0/0" +# .1.3.6.1.2.1.47.1.1.1.1.7.24 = STRING: "In0/1" +# .1.3.6.1.2.1.47.1.1.1.1.7.25 = STRING: "Ma0/0" +# .1.3.6.1.2.1.47.1.1.1.1.7.26 = STRING: "Po1" +# +# .1.3.6.1.2.1.99.1.1.1.1.8 = INTEGER: 10 +# .1.3.6.1.2.1.99.1.1.1.1.10 = INTEGER: 10 +# .1.3.6.1.2.1.99.1.1.1.1.12 = INTEGER: 10 +# .1.3.6.1.2.1.99.1.1.1.1.13 = INTEGER: 8 +# .1.3.6.1.2.1.99.1.1.1.1.14 = INTEGER: 8 +# .1.3.6.1.2.1.99.1.1.1.1.15 = INTEGER: 8 +# .1.3.6.1.2.1.99.1.1.1.1.16 = INTEGER: 8 +# .1.3.6.1.2.1.99.1.1.1.4.8 = INTEGER: 7680 +# .1.3.6.1.2.1.99.1.1.1.4.10 = INTEGER: 7936 +# .1.3.6.1.2.1.99.1.1.1.4.12 = INTEGER: 7680 +# .1.3.6.1.2.1.99.1.1.1.4.13 = INTEGER: 34 +# .1.3.6.1.2.1.99.1.1.1.4.14 = INTEGER: 32 +# .1.3.6.1.2.1.99.1.1.1.4.15 = INTEGER: 30 +# .1.3.6.1.2.1.99.1.1.1.4.16 = INTEGER: 33 +# .1.3.6.1.2.1.99.1.1.1.5.8 = INTEGER: 1 +# .1.3.6.1.2.1.99.1.1.1.5.10 = INTEGER: 1 +# .1.3.6.1.2.1.99.1.1.1.5.12 = INTEGER: 1 +# .1.3.6.1.2.1.99.1.1.1.5.13 = INTEGER: 1 +# .1.3.6.1.2.1.99.1.1.1.5.14 = INTEGER: 1 +# .1.3.6.1.2.1.99.1.1.1.5.15 = INTEGER: 1 +# .1.3.6.1.2.1.99.1.1.1.5.16 = INTEGER: 1 +# .1.3.6.1.2.1.99.1.1.1.6.8 = STRING: "rpm" +# .1.3.6.1.2.1.99.1.1.1.6.10 = STRING: "rpm" +# .1.3.6.1.2.1.99.1.1.1.6.12 = STRING: "rpm" +# .1.3.6.1.2.1.99.1.1.1.6.13 = STRING: "celsius" +# .1.3.6.1.2.1.99.1.1.1.6.14 = STRING: "celsius" +# .1.3.6.1.2.1.99.1.1.1.6.15 = STRING: "celsius" +# .1.3.6.1.2.1.99.1.1.1.6.16 = STRING: "celsius" + +# +# sample string_table +# [ +# [ +# ['Chassis', '', '', '', ''], +# ['Processor 0/0', '', '', '', ''], +# ['Processor 0/1', '', '', '', ''], +# ['Processor 0/2', '', '', '', ''], +# ['ASA5515 Slot for Removable Drive 0', '', '', '', ''], +# ['Micron_M550_MTFDDAK128MAY Removable Drive in Slot 0', '', '', '', ''], +# ['Chassis Cooling Fan 1', '', '', '', ''], +# ['Chassis Fan Sensor 1', '10', '7680', '1', 'rpm'], +# ['Chassis Cooling Fan 2', '', '', '', ''], +# ['Chassis Fan Sensor 2', '10', '7936', '1', 'rpm'], +# ['Chassis Cooling Fan 3', '', '', '', ''], +# ['Chassis Fan Sensor 3', '10', '7680', '1', 'rpm'], +# ['CPU Temperature Sensor 0/0', '8', '34', '1', 'celsius'], +# ['Chassis Ambient Temperature Sensor 1', '8', '32', '1', 'celsius'], +# ['Chassis Ambient Temperature Sensor 2', '8', '30', '1', 'celsius'], +# ['Chassis Ambient Temperature Sensor 3', '8', '33', '1', 'celsius'], +# ['Gi0/0', '', '', '', ''], +# ['Gi0/1', '', '', '', ''], +# ['Gi0/2', '', '', '', ''], +# ['Gi0/3', '', '', '', ''], +# ['Gi0/4', '', '', '', ''], +# ['Gi0/5', '', '', '', ''], +# ['In0/0', '', '', '', ''], +# ['In0/1', '', '', '', ''], +# ['Ma0/0', '', '', '', ''], +# ['Po1', '', '', '', ''] +# ] +# ] # # sample section -# +# {'fan': {'Chassis Sensor 1': CiscoAsaSensor(value=7680, status=<State.OK: 0>, state_readable='Ok', unit='rpm'), +# 'Chassis Sensor 2': CiscoAsaSensor(value=7936, status=<State.OK: 0>, state_readable='Ok', unit='rpm'), +# 'Chassis Sensor 3': CiscoAsaSensor(value=7680, status=<State.OK: 0>, state_readable='Ok', unit='rpm')}, +# 'temp': {'CPU Sensor 0/0': CiscoAsaSensor(value=34.0, status=<State.OK: 0>, state_readable='Ok', unit='celsius'), +# 'Chassis Ambient Sensor 1': CiscoAsaSensor(value=32.0, status=<State.OK: 0>, state_readable='Ok', unit='celsius'), +# 'Chassis Ambient Sensor 2': CiscoAsaSensor(value=30.0, status=<State.OK: 0>, state_readable='Ok', unit='celsius'), +# 'Chassis Ambient Sensor 3': CiscoAsaSensor(value=33.0, status=<State.OK: 0>, state_readable='Ok', unit='celsius')}, +# 'power': {}} # -from typing import Mapping, Dict, List, Tuple, NamedTuple +from typing import Dict, List, NamedTuple from .agent_based_api.v1.type_defs import ( DiscoveryResult, @@ -30,14 +123,11 @@ from .agent_based_api.v1.type_defs import ( from .agent_based_api.v1 import ( register, Service, - equals, Result, check_levels, State, SNMPTree, startswith, - all_of, - any_of, ) @@ -147,7 +237,7 @@ from .utils.temperature import ( def discovery_cisco_asa_temp(section: Dict) -> DiscoveryResult: for key in section['temp']: - yield Service(item=key) # , parameters={'asgNetIfSpeed': section[item].asgNetIfSpeed}) + yield Service(item=key) def check_cisco_asa_temp(item, params: TempParamType, section) -> CheckResult: @@ -191,7 +281,7 @@ def render_rpm(value) -> str: def discovery_cisco_asa_fan(section: Dict) -> DiscoveryResult: for key in section['fan']: - yield Service(item=key) # , parameters={'asgNetIfSpeed': section[item].asgNetIfSpeed}) + yield Service(item=key) def check_cisco_asa_fan(item, params: TempParamType, section) -> CheckResult: @@ -232,7 +322,7 @@ register.check_plugin( def discovery_cisco_asa_power(section: Dict) -> DiscoveryResult: for key in section['power']: - yield Service(item=key) # , parameters={'asgNetIfSpeed': section[item].asgNetIfSpeed}) + yield Service(item=key) def check_cisco_asa_power(item, params: TempParamType, section) -> CheckResult: diff --git a/cisco_asa_sensors.mkp b/cisco_asa_sensors.mkp index c57df0a1c356b94f1ac4775086c972014b899072..f097b69c596434aa0b758e9b0b19071f887e816c 100644 GIT binary patch delta 2929 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 IAv84q1H`zR-2eap delta 2283 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 F002gdWljJ9 -- GitLab