diff --git a/README.md b/README.md index d724da6c0c16f40995985d4dec9e59f6cffc5791..e744c03f8cceec4a831bc45d065e38b46551fc44 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[PACKAGE]: ../../raw/master/juniper_craft_alarm-0.0.2-20230901.mkp "juniper_craft_alarm-0.0.2-20230901.mkp" # Juniper Chassis Alarm Monitors the status of the Juniper Chassis alarm using the JUNIPER-ALARM-MIB. diff --git a/agent_based/juniper_craft_alarm.py b/agent_based/juniper_craft_alarm.py index a096c9036ce71916fbc130a9cf7f1129aebec584..36dc752adb87d2b8897c9ee4a2cc875346e5988c 100644 --- a/agent_based/juniper_craft_alarm.py +++ b/agent_based/juniper_craft_alarm.py @@ -5,10 +5,15 @@ # # Author: thl-cmk[at]outlook[dot]com # URL : https://thl-cmk.hopto.org -# Date : 2016-08-01 +# Date : 2022-06-07 # # monitor Juniper Networks craft alarms # +# 2023-09-01: fixed empty string_table +# added WATO rule +# added alarm state +# added last change (notice only) +# # sample snmpwalk # .1.3.6.1.4.1.2636.3.4.2.1.0 = INTEGER: 2 # .1.3.6.1.4.1.2636.3.4.2.2.1.0 = INTEGER: 2 @@ -19,7 +24,7 @@ # .1.3.6.1.4.1.2636.3.4.2.3.3.0 = 0 # # sample string_table -# [[['2']], [['2', '0', '0', '2', '0', '0']]] +# [[['2']], [['2', '0', '0']], [['2', '0', '0']]] # # sample section # JuniperAlarms( @@ -28,8 +33,6 @@ # red_alarm=JuniperAlarm(state=2, count=0, last_change=0) # ) # -# ToDo: create WATO for params -# from dataclasses import dataclass from typing import Optional, List @@ -41,6 +44,7 @@ from cmk.base.plugins.agent_based.agent_based_api.v1 import ( State, SNMPTree, startswith, + check_levels, ) from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( DiscoveryResult, @@ -51,9 +55,9 @@ from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( @dataclass class JuniperAlarm: - # state: int + state: int count: int - # last_change: int + last_change: int @dataclass @@ -77,20 +81,37 @@ _juniper_alarm_state = { def parse_juniper_craft_alarms(string_table: List[StringTable]) -> Optional[JuniperAlarms]: - alarm_relay_mode, alarms = string_table - yellow_count, red_count = alarms[0] + try: + alarm_relay_mode, yellow_alarm, red_alarm = string_table + except IndexError: + return + + try: + alarm_relay_mode = alarm_relay_mode[0][0] + except IndexError: + return + + try: + yellow_state, yellow_count, yellow_last_change = yellow_alarm[0] + except IndexError: + return + + try: + red_state, red_count, red_last_change = red_alarm[0] + except IndexError: + return return JuniperAlarms( - alarm_relay_mode=int(alarm_relay_mode[0][0]), + alarm_relay_mode=int(alarm_relay_mode), yellow_alarm=JuniperAlarm( - # state=int(yellow_state), + state=int(yellow_state), count=int(yellow_count), - # last_change=int(yellow_last_change) + last_change=int(yellow_last_change) ), red_alarm=JuniperAlarm( - # state=int(red_state), + state=int(red_state), count=int(red_count), - # last_change=int(red_last_change) + last_change=int(red_last_change) ) ) @@ -100,24 +121,42 @@ def discovery_juniper_craft_alarms(section: JuniperAlarms) -> DiscoveryResult: def check_juniper_craft_alarms(params, section: JuniperAlarms) -> CheckResult: - if section.alarm_relay_mode != 2 and params['warn_not_pass_om']: - yield Result( - state=State.WARN, - summary=f'Alarm relay mode: {_juniper_alarm_relay_mode.get(section.alarm_relay_mode)}') + message = f'Alarm relay mode: {_juniper_alarm_relay_mode.get(section.alarm_relay_mode, section.alarm_relay_mode )}' + if section.alarm_relay_mode != 2: # pass on + yield Result(state=State(params['state_not_pass_om']), summary=message) else: - yield Result( - state=State.OK, - summary=f'Alarm relay mode: {_juniper_alarm_relay_mode.get(section.alarm_relay_mode)}') + yield Result(state=State.OK, summary=message) - if section.yellow_alarm.count > params['count_yellow']: - yield Result(state=State.WARN, notice=f'Yellow alarm count: {section.yellow_alarm.count}') + message = f'Yellow alarm state: {_juniper_alarm_state.get(section.yellow_alarm.state, section.yellow_alarm.state)}' + if section.yellow_alarm.state != 2: # off + yield Result(state=State(params['state_yellow_not_off']), summary=message) else: - yield Result(state=State.OK, summary=f'Yellow alarm count: {section.yellow_alarm.count}') + yield Result(state=State.OK, summary=message) - if section.red_alarm.count > params['count_red']: - yield Result(state=State.CRIT, notice=f'Red alarm count: {section.red_alarm.count}') + message = f'Red alarm state: {_juniper_alarm_state.get(section.red_alarm.state, section.red_alarm.state)}' + if section.red_alarm.state != 2: # off + yield Result(state=State(params['state_red_not_off']), summary=message) else: - yield Result(state=State.OK, summary=f'Red alarm count: {section.red_alarm.count}') + yield Result(state=State.OK, summary=message) + + yield from check_levels( + value=section.yellow_alarm.count, + label='Yellow alarm count', + levels_upper=params.get('count_yellow'), + render_func=lambda v: f'{v:.0f}', + notice_only=True, + ) + + yield from check_levels( + value=section.red_alarm.count, + label='Red alarm count', + levels_upper=params.get('count_red'), + render_func=lambda v: f'{v:.0f}', + notice_only=True, + ) + + yield Result(state=State.OK, notice=f'Yellow alarm last change: {section.yellow_alarm.last_change}') + yield Result(state=State.OK, notice=f'Red alarm last change: {section.red_alarm.last_change}') register.snmp_section( @@ -131,16 +170,21 @@ register.snmp_section( ] ), SNMPTree( - base='.1.3.6.1.4.1.2636.3.4.2', # JUNIPER-ALARM-MIB::jnxCraftAlarms + base='.1.3.6.1.4.1.2636.3.4.2.2', # JUNIPER-ALARM-MIB::jnxCraftAlarms oids=[ - # '2.1', # jnxYellowAlarmState - '2.2', # jnxYellowAlarmCount - # '2.3', # jnxYellowAlarmLastChange - # '3.1', # jnxRedAlarmState - '3.2', # jnxRedAlarmCount - # '3.3', # jnxRedAlarmLastChange + '1', # jnxYellowAlarmState + '2', # jnxYellowAlarmCount + '3', # jnxYellowAlarmLastChange ] - ) + ), + SNMPTree( + base='.1.3.6.1.4.1.2636.3.4.2.3', # JUNIPER-ALARM-MIB::jnxCraftAlarms + oids=[ + '1', # jnxRedAlarmState + '2', # jnxRedAlarmCount + '3', # jnxRedAlarmLastChange + ] + ), ], detect=startswith('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.2636.1.1.1'), ) @@ -152,8 +196,8 @@ register.check_plugin( check_function=check_juniper_craft_alarms, check_ruleset_name='juniper_craft_alarms', check_default_parameters={ - 'count_yellow': 0, - 'count_red': 0, - 'warn_not_pass_om': True, + 'state_not_pass_om': 1, + 'state_yellow_not_off': 1, + 'state_red_not_off': 2, } ) diff --git a/gui/wato/check_parameters/juniper_craft_alarm.py b/gui/wato/check_parameters/juniper_craft_alarm.py new file mode 100644 index 0000000000000000000000000000000000000000..6c84e1abe4a7df581f8de514626a7938009bd874 --- /dev/null +++ b/gui/wato/check_parameters/juniper_craft_alarm.py @@ -0,0 +1,73 @@ +#!/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 : 2023-09-01 +# File : juniper_craft_alarm.py +# +# 2023-09-01: initial release + +from cmk.gui.i18n import _ +from cmk.gui.valuespec import ( + Dictionary, + MonitoringState, + Tuple, + Integer, +) + +from cmk.gui.plugins.wato.utils import ( + rulespec_registry, + CheckParameterRulespecWithoutItem, + RulespecGroupCheckParametersHardware, +) + + +def _parameter_valuespec_vzlogger(): + return Dictionary( + title=_('Juniper Chassis Alarm'), + elements=[ + ('state_not_pass_om', + MonitoringState( + title=_('State if Alarm relay mode not "pass on"'), + default_value=1, + )), + ('state_yellow_not_off', + MonitoringState( + title=_('State if Yellow alarm is not "off"'), + default_value=1, + )), + ('state_red_not_off', + MonitoringState( + title=_('State if Red alarm is not "off"'), + default_value=2, + )), + ('count_yellow', + Tuple( + title=_('Levels Yellow Alarm'), + help=_(''), + elements=[ + Integer(title=_('Warning at'), minvalue=0, unit=_('')), + Integer(title=_('Critical at'), minvalue=0, unit=_('')), + ])), + ('count_red', + Tuple( + title=_('Levels Red Alarm'), + help=_(''), + elements=[ + Integer(title=_('Warning at'), minvalue=0, unit=_('')), + Integer(title=_('Critical at'), minvalue=0, unit=_('')), + ])) + + ], + ) + + +rulespec_registry.register( + CheckParameterRulespecWithoutItem( + check_group_name="juniper_craft_alarms", + group=RulespecGroupCheckParametersHardware, + parameter_valuespec=_parameter_valuespec_vzlogger, + )) diff --git a/juniper_craft_alarm-0.0.2-20230901.mkp b/juniper_craft_alarm-0.0.2-20230901.mkp new file mode 100644 index 0000000000000000000000000000000000000000..63d047f86c5edf76174671d72400ec4ff75d6839 Binary files /dev/null and b/juniper_craft_alarm-0.0.2-20230901.mkp differ diff --git a/packages/juniper_craft_alarm b/packages/juniper_craft_alarm index 431abd9bf4c1e82c55c12f08d06468fb1770a681..0092ba1404e143b57a580a7b357017b048ca5dd6 100644 --- a/packages/juniper_craft_alarm +++ b/packages/juniper_craft_alarm @@ -3,14 +3,15 @@ '\n' 'The check is based on the JUNIPER-ALARM-MIB\n' '\n' - 'WARN: if # of yellow alerts > 0\n' - 'CRIT: if # of red alerts > 0\n' - 'WARN: if alarm relay mode not pass om\n', + 'WARN: if alarm relay mode not pass om\n' + 'WARN if Yellow Alarm is not off\n' + 'CRIT if Red Alarm is not off\n', 'download_url': 'https://thl-cmk.hopto.org', - 'files': {'agent_based': ['juniper_craft_alarm.py']}, + 'files': {'agent_based': ['juniper_craft_alarm.py'], + 'gui': ['wato/check_parameters/juniper_craft_alarm.py']}, 'name': 'juniper_craft_alarm', 'title': 'Juniper (Craft) alarm', - 'version': '0.0.1-20230603', - 'version.min_required': '2.0.0b1', - 'version.packaged': '2.1.0p21', - 'version.usable_until': None} \ No newline at end of file + 'version': '0.0.2-20230901', + 'version.min_required': '2.2.0b1', + 'version.packaged': '2.2.0p7', + 'version.usable_until': None}