diff --git a/agent_based/checkpoint_asg_sg_diag.py b/agent_based/checkpoint_asg_sg_diag.py new file mode 100644 index 0000000000000000000000000000000000000000..4841c08c43307d3dd1510b56d6e54af610721f11 --- /dev/null +++ b/agent_based/checkpoint_asg_sg_diag.py @@ -0,0 +1,233 @@ +#!/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-11-03 +# +# Monitor Check Point Maestro SG Test status (asg diag verify) +# +# 2021-03-01: rewrite for CMK 2.x +# 2021-03-03: fixed date/time in parse function +# 2021-09-10: fixed duplicate detail output +# 2021-09-29: renamed checkpoint_asg_diag to checkpoint_asg_sg_diag +# +# sample snmpwalk for one passed asg test +# .1.3.6.1.4.1.2620.1.48.31.1.1.1.21.0 = Wrong Type (should be OCTET STRING): Gauge32: 21 +# .1.3.6.1.4.1.2620.1.48.31.1.1.1.21.0 = Wrong Type (should be OCTET STRING): Gauge32: 21 +# .1.3.6.1.4.1.2620.1.48.31.1.1.2.21.0 = STRING: Bond +# .1.3.6.1.4.1.2620.1.48.31.1.1.3.21.0 = STRING: 2020-10-23 01:00:02 +# .1.3.6.1.4.1.2620.1.48.31.1.1.4.21.0 = STRING: Passed +# .1.3.6.1.4.1.2620.1.48.31.1.1.5.21.0 = STRING: +# +# sample snmpwalk for one failed asg test +# .1.3.6.1.4.1.2620.1.48.31.1.1.1.28.0 = Wrong Type (should be OCTET STRING): Gauge32: 28 +# .1.3.6.1.4.1.2620.1.48.31.1.1.2.28.0 = STRING: Core Dumps +# .1.3.6.1.4.1.2620.1.48.31.1.1.3.28.0 = STRING: 2020-10-23 01:00:02 +# .1.3.6.1.4.1.2620.1.48.31.1.1.4.28.0 = STRING: Failed (!) +# .1.3.6.1.4.1.2620.1.48.31.1.1.5.28.0 = STRING: +# +# sample snmpwalk for asg test summary +# .1.3.6.1.4.1.2620.1.48.31.2.0 = STRING: On 2020-10-23, At 01:00:02, Passed: 28/30 tests. Failed tests: 11,28 +# +# sample section +# [ +# [ +# ['On 2020-10-23, At 01:00:02, Passed: 28/30 tests. Failed tests: 11,28'] +# ], +# [ +# ['1', 'System Health', '2020-10-23 01:00:02', 'Passed', ''], +# ['2', 'Resources', '2020-10-23 01:00:02', 'Passed', ''], +# ['3', 'Software Provision', '2020-10-23 01:00:02', 'Passed', ''], +# ['4', 'Media Details', '2020-10-23 01:00:02', 'Passed', ''], +# ['5', 'SSD Health', '2020-10-23 01:00:02', 'Passed', ''], +# ['6', 'Firmware Verifier', '2020-10-23 01:00:02', 'Passed', ''], +# ['7', 'Distribution Mode', '2020-10-23 01:00:02', 'Passed', ''], +# ['8', 'DXL Balance', '2020-10-23 01:00:02', 'Passed', ''], +# ['9', 'Policy', '2020-10-23 01:00:02', 'Passed', ''], +# ['10', 'AMW Policy', '2020-10-23 01:00:02', 'Passed', 'Not configured'], +# ['11', 'SWB Updates', '2020-10-23 01:00:02', 'Failed (!)', ''], +# ['12', 'Installation', '2020-10-23 01:00:02', 'Passed', ''], +# ['13', 'Security Group', '2020-10-23 01:00:02', 'Passed', ''], +# ['14', 'Cores Distribution', '2020-10-23 01:00:02', 'Passed', ''], +# ['15', 'Clock', '2020-10-23 01:00:02', 'Passed', ''], +# ['16', 'Licenses', '2020-10-23 01:00:02', 'Passed', ''], +# ['17', 'IPS Enhancement', '2020-10-23 01:00:02', 'Passed', ''], +# ['18', 'Configuration Files', '2020-10-23 01:00:02', 'Passed', ''], +# ['19', 'MAC Setting', '2020-10-23 01:00:02', 'Passed', ''], +# ['20', 'ARP Consistency', '2020-10-23 01:00:02', 'Passed', ''], +# ['21', 'Bond', '2020-10-23 01:00:02', 'Passed', ''], +# ['22', 'IPv4 Route', '2020-10-23 01:00:02', 'Passed', ''], +# ['23', 'IPv6 Route', '2020-10-23 01:00:02', 'Passed', 'Not configured'], +# ['24', 'Dynamic Routing', '2020-10-23 01:00:02', 'Passed', 'Not configured'], +# ['25', 'Local ARP', '2020-10-23 01:00:02', 'Passed', 'Not configured'], +# ['26', 'IGMP Consistency', '2020-10-23 01:00:02', 'Passed', 'Not configured'], +# ['27', 'PIM Neighbors', '2020-10-23 01:00:02', 'Passed', 'Not configured'], +# ['28', 'Core Dumps', '2020-10-23 01:00:02', 'Failed (!)', ''], +# ['29', 'Processes', '2020-10-23 01:00:02', 'Passed', ''], +# ['30', 'Performance hogs', '2020-10-23 01:00:02', 'Passed', ''] +# ] +# ] +# + +import time +from typing import List, NamedTuple + +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, + equals, + Result, + State, + SNMPTree, + startswith, + all_of, + any_of, + check_levels, +) + + +class CheckpointAsgSgDiagSummary(NamedTuple): + date: str + time: str + days_ago: int + passed: int + maxtest: int + failed: list + + +class CheckpointAsgSgDiagTest(NamedTuple): + index: str + name: str + lastrun: str + result: str + comment: str + + +class CheckpointAsgDiag(NamedTuple): + summary: CheckpointAsgSgDiagSummary + tests: List[CheckpointAsgSgDiagTest] + + +def parse_checkpoint_asg_sg_diag(string_table: List[StringTable]) -> CheckpointAsgDiag: + asgSummary, asgTests = string_table + + # sample asgSummary [['On 2020-10-23, At 01:00:02, Passed: 28/30 tests. Failed tests: 11,28']] + if len(asgSummary) != 0: + asgSummary = asgSummary[0][0] + passed, max = asgSummary[28:].split('.')[0].split(' ')[1].split('/') + return CheckpointAsgDiag( + summary=CheckpointAsgSgDiagSummary( + date=asgSummary[3:13], + time=asgSummary[18:26], + days_ago=int((time.time() - time.mktime(time.strptime(asgSummary[3:13], '%Y-%m-%d'))) / 86400), + passed=int(passed), + maxtest=int(max), + failed=list(map(int, asgSummary.split(':')[-1].strip(' ').split(','))) + ), + tests=[CheckpointAsgSgDiagTest(*test) for test in asgTests] + ) + + +def discovery_checkpoint_asg_sg_diag(section: CheckpointAsgDiag) -> DiscoveryResult: + yield Service(parameters={}) + + +def check_checkpoint_asg_sg_diag(params, section: CheckpointAsgDiag) -> CheckResult: + state = 0 + asg_diag_ignore = params['asg_diag_ignore'] + asg_diag_warning = params['asg_diag_warning'] + asg_diag_ignore.sort() + asg_diag_warning.sort() + + yield Result(state=State.OK, summary=f'Last run on: {section.summary.date} at: {section.summary.time}') + yield from check_levels( + value=section.summary.days_ago, + label='Days ago', + levels_upper=params['levels_upper_last_run'], + render_func=lambda v: str(v) + ) + + summary = f'Tests Passed {section.summary.passed}/{section.summary.maxtest},' + if len(section.summary.failed) > 0: + summary += f' Failed: {",".join(map(str, section.summary.failed))}' + if len(asg_diag_ignore) > 0: + summary += f', Ignored: {",".join(map(str, asg_diag_ignore))}' + + for test in section.summary.failed: + if test not in asg_diag_ignore: + if test in asg_diag_warning: + state = max(state, 1) + else: + state = 2 + + yield Result(state=State(state), summary=summary) + + yield Result( + state=State.OK, + notice='\nTo verify this output use the "asg diag verify" command on the Check Point SG CLI.\n' + ) + + for test in section.tests: + result = test.result + if result.lower().startswith('failed'): + if int(test.index) in asg_diag_ignore: + result = result.replace(' (!)', '') + elif int(test.index) not in asg_diag_warning: + result = result.replace(' (!)', ' (!!)') + notice = f'Index: {test.index}, Name: {test.name}, LastRun: {test.lastrun}, Restult: {result}' + if test.comment != '': + notice += f', Comment: {test.comment}' + yield Result(state=State.OK, notice=notice) + + +register.snmp_section( + name='checkpoint_asg_sg_diag', + parse_function=parse_checkpoint_asg_sg_diag, + fetch=[ + SNMPTree( + base='.1.3.6.1.4.1.2620.1.48.31', # CHECKPOINT-MIB::asgDiagnostic + oids=[ + '2', # asgDiagSummary + ] + ), + SNMPTree( + base='.1.3.6.1.4.1.2620.1.48.31.1.1', # CHECKPOINT-MIB::asgTestsResEntry + oids=[ + '1', # asgTestIndex + '2', # TestName + '3', # LastRun + '4', # Result + '5', # Comment + ] + ), + ], + detect=any_of( + startswith('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.2620'), + all_of( + equals('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.8072.3.2.10'), + equals('.1.3.6.1.4.1.2620.1.6.1.0', 'SVN Foundation'), + ) + ) +) + +register.check_plugin( + name='checkpoint_asg_sg_diag', + service_name='ASG SG Diag', + discovery_function=discovery_checkpoint_asg_sg_diag, + check_function=check_checkpoint_asg_sg_diag, + check_default_parameters={ + 'levels_upper_last_run': (3, 5), + 'asg_diag_ignore': [], + 'asg_diag_warning': [], + }, + check_ruleset_name='checkpoint_asg_sg_diag', +) diff --git a/checkpoint_asg_sg_diag.mkp b/checkpoint_asg_sg_diag.mkp new file mode 100644 index 0000000000000000000000000000000000000000..43c9abc3e99291aef06ff4b62c24787717e8b944 Binary files /dev/null and b/checkpoint_asg_sg_diag.mkp differ diff --git a/packages/checkpoint_asg_sg_diag b/packages/checkpoint_asg_sg_diag new file mode 100644 index 0000000000000000000000000000000000000000..a5cf2a5c275e3efd629004eeda582fc8c05bf109 --- /dev/null +++ b/packages/checkpoint_asg_sg_diag @@ -0,0 +1,13 @@ +{'author': 'Th.L. (thl-cmk[at]outlook[dot]com)', + 'description': 'Monitor Check Point Maestro SG Test status (asg diag verify)\n' + '\n', + 'download_url': 'http://thl-cmk.hopto.org/', + 'files': {'agent_based': ['checkpoint_asg_sg_diag.py'], + 'web': ['plugins/wato/checkpoint_asg_sg_diag.py']}, + 'name': 'checkpoint_asg_sg_diag', + 'num_files': 2, + 'title': 'Check Point Maestro SG ASG Diag', + 'version': '20210929.v0.3', + '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/wato/checkpoint_asg_sg_diag.py b/web/plugins/wato/checkpoint_asg_sg_diag.py new file mode 100644 index 0000000000000000000000000000000000000000..292cf67e9d7141b4fc74b21ee7016b0a37845bf3 --- /dev/null +++ b/web/plugins/wato/checkpoint_asg_sg_diag.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# +from cmk.gui.i18n import _ +from cmk.gui.valuespec import ( + Dictionary, + Integer, + ListOfStrings, + Tuple, +) + +from cmk.gui.plugins.wato import ( + CheckParameterRulespecWithItem, + rulespec_registry, + RulespecGroupCheckParametersNetworking, +) + + +def _parameter_valuespec_checkpoint_asg_sg_diag(): + return Dictionary(elements=[ + ('levels_upper_last_run', + Tuple( + title=_('Maximum days no run "asg diag verify"'), + elements=[ + Integer( + title=_('Warning at'), + unit='days', + default_value=3, + minvalue=1, + ), + Integer( + title=_('Critical at'), + unit='days', + default_value=5, + minvalue=1, + ) + ], + )), + ('asg_diag_ignore', + ListOfStrings( + title=_('Index list of ignored failde tests'), + orientation='horizontal', + allow_empty=False, + valuespec=Integer(minvalue=1, maxvalue=99), + help=_('This tests will be ignored if the are not "Passed". The monitoring state will stay OK'), + )), + ('asg_diag_warning', + ListOfStrings( + title=_('Indix list of WARNING only failed tests'), + orientation='horizontal', + allow_empty=False, + valuespec=Integer(minvalue=1, maxvalue=99), + help=_('For this tests the monitoring state will be WARNING if the test result is not "Passed", ' + 'all other failed tests set the monitoring state to CRITICAL.'), + )), + ]) + + +rulespec_registry.register( + CheckParameterRulespecWithItem( + check_group_name='checkpoint_asg_sg_diag', + group=RulespecGroupCheckParametersNetworking, + match_type='dict', + parameter_valuespec=_parameter_valuespec_checkpoint_asg_sg_diag, + title=lambda: _('Check Point ASG Diag'), + ))