diff --git a/agent_based/cisco_fw_nat_translations.py b/agent_based/cisco_fw_nat_translations.py new file mode 100644 index 0000000000000000000000000000000000000000..d37bd9dc1ac82a65fa4c47d5066fe5789c563dff --- /dev/null +++ b/agent_based/cisco_fw_nat_translations.py @@ -0,0 +1,117 @@ +#!/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-03-09 +# +# Monitors Cisco Firewall NAT Translations +# +# +# sample snmp walk +# +# .1.3.6.1.4.1.9.9.532.1.1.1.1.1 = Gauge32: 2 +# .1.3.6.1.4.1.9.9.532.1.1.1.2.1 = Gauge32: 2 +# +# CISCO-NAT-EXT-MIB::cneAddrTranslationNumActive.1 = Gauge32: 2 Number of address translation entries +# CISCO-NAT-EXT-MIB::cneAddrTranslationNumPeak.1 = Gauge32: 2 Number of address translation entries +# +# + +from typing import 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, + check_levels_predictive, + SNMPTree, + startswith, + contains, + any_of, +) + + +class CiscoFwNatTranslations(NamedTuple): + active: int + peak: int + + +# [['1102', '2290']] +def parse_cisco_fw_nat_translations(string_table: StringTable) -> Optional[CiscoFwNatTranslations]: + try: + return CiscoFwNatTranslations( + active=int(string_table[0][0]), + peak=int(string_table[0][1]) + ) + except IndexError: + return + + +# CiscoFwNatTranslations(active=1102, peak=2290) +def discovery_cisco_fw_nat_translations(section: CiscoFwNatTranslations) -> DiscoveryResult: + yield Service() + + +def check_cisco_fw_nat_translations(params, section: CiscoFwNatTranslations) -> CheckResult: + levels_upper = params.get('levels_upper', None) + levels_lower = params.get('levels_lower', None) + yield from check_levels_predictive( + value=section.active, + label='Active', + metric_name='fw_nat_active', + render_func=lambda v: str(v), + levels=levels_upper, + boundaries=(0, None), + ) if isinstance(levels_upper, dict) else check_levels( + value=section.active, + label='Active', + levels_lower=levels_lower, + levels_upper=levels_upper, + metric_name='fw_nat_active', + render_func=lambda v: str(v), + ) + + yield from check_levels( + value=section.peak, + label='Peak (since system startup)', + metric_name='fw_nat_peak', + render_func=lambda v: '%s' % str(v), + ) + + +register.snmp_section( + name='cisco_fw_nat_translations', + parse_function=parse_cisco_fw_nat_translations, + fetch=SNMPTree( + # CISCO-NAT-EXT-MIB::cneAddrTranslationStatsEntry + base='.1.3.6.1.4.1.9.9.532.1.1.1', + oids=[ + '1', # cneAddrTranslationNumActive + '2', # cneAddrTranslationNumPeak + ] + ), + detect=any_of( + # startswith('.1.3.6.1.2.1.1.1.0', 'cisco adaptive security'), + startswith('.1.3.6.1.2.1.1.1.0', 'cisco firepower threat defense'), + startswith('.1.3.6.1.2.1.1.1.0', 'cisco firewall services'), + # contains('.1.3.6.1.2.1.1.1.0', 'cisco pix security'), + ) +) + +register.check_plugin( + name='cisco_fw_nat_translations', + service_name='Firewall NAT translations', + discovery_function=discovery_cisco_fw_nat_translations, + check_function=check_cisco_fw_nat_translations, + check_default_parameters={}, + check_ruleset_name='cisco_fw_nat_translations' +) \ No newline at end of file diff --git a/cisco_fw_nat_translations.mkp b/cisco_fw_nat_translations.mkp new file mode 100644 index 0000000000000000000000000000000000000000..cb1c447e9fc83435a878274ec21a5e84bfce61ed Binary files /dev/null and b/cisco_fw_nat_translations.mkp differ diff --git a/packages/cisco_fw_nat_translations b/packages/cisco_fw_nat_translations new file mode 100644 index 0000000000000000000000000000000000000000..0346694c36e425f6a6a73afedd763938c91e8b87 --- /dev/null +++ b/packages/cisco_fw_nat_translations @@ -0,0 +1,12 @@ +{'author': 'Th.L. (thl-cmk[at]outlook[dot]com)', + 'description': 'Monitor Cisco Firewall NAT translations\n', + 'download_url': 'https://thl-cmk.hopto.org', + 'files': {'agent_based': ['cisco_fw_nat_translations.py'], + 'web': ['plugins/metrics/cisco_fw_nat_translations.py', + 'plugins/wato/cisco_fw_nat_translations.py']}, + 'name': 'cisco_fw_nat_translations', + 'title': 'Cisco Firewall NAT Translations', + 'version': '20230309.v0.0.1', + 'version.min_required': '2.0.0', + 'version.packaged': '2.1.0p22', + 'version.usable_until': None} \ No newline at end of file diff --git a/web/plugins/metrics/cisco_fw_nat_translations.py b/web/plugins/metrics/cisco_fw_nat_translations.py new file mode 100644 index 0000000000000000000000000000000000000000..272eeb9c0c02355d7e820fad0e11b749824e00b7 --- /dev/null +++ b/web/plugins/metrics/cisco_fw_nat_translations.py @@ -0,0 +1,69 @@ +#!/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-03-09 +# +# Cisco Firewall NAT translations metrics plugin +# + +from cmk.gui.i18n import _ + +from cmk.gui.plugins.metrics import ( + metric_info, + graph_info, + check_metrics, + perfometer_info, +) + +# for predictive monitoring +check_metrics["check_mk-cisco_fw_nat_translations"] = { + "predict_fw_nat_active": {"auto_graph": False}, +} +metric_info['predict_fw_nat_active'] = { + 'title': _('_Predicted NAT translations'), + 'unit': 'count', + 'color': '26/b', +} +# + +metric_info['fw_nat_active'] = { + 'title': _('Active'), + 'unit': 'count', + 'color': '26/a', +} + +metric_info['fw_nat_peak'] = { + 'title': _('Peak'), + 'unit': 'count', + 'color': '16/a', +} + +graph_info['cisco_fw_nat_translations'] = { + 'title': _('NAT translatins'), + 'metrics': [ + ('predict_fw_nat_active', 'line'), + ('fw_nat_peak', 'line'), + ('fw_nat_active', 'area'), + ], + 'scalars': [ + ('fw_nat_active:crit'), # , _('CRIT') + ('fw_nat_active:warn'), # , _('WARN') + ], + 'optional_metrics': [ + 'predict_fw_nat_active', + ], + +} + +perfometer_info.append( + { + 'type': 'logarithmic', + 'metric': 'fw_nat_active', + 'half_value': 100000.0, + 'exponent': 2, + } +) diff --git a/web/plugins/wato/cisco_fw_nat_translations.py b/web/plugins/wato/cisco_fw_nat_translations.py new file mode 100644 index 0000000000000000000000000000000000000000..a1e77faef00c6b48e0fa3d86e893786f4e6cea3e --- /dev/null +++ b/web/plugins/wato/cisco_fw_nat_translations.py @@ -0,0 +1,55 @@ +#!/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-03-09 +# +# Cisco Firewall NAT translations WATO plugin +# + +from cmk.gui.i18n import _ +from cmk.gui.valuespec import ( + Dictionary, + Integer, + Tuple, +) + +from cmk.gui.plugins.wato import ( + CheckParameterRulespecWithoutItem, + rulespec_registry, + RulespecGroupCheckParametersApplications, + Levels, +) + + +def _parameter_valuespec_cisco_fw_nat_translations(): + return Dictionary(elements=[ + ('levels_upper', + Levels( + title=_('NAT translations'), + unit=_('Translations'), + )), + ('levels_lower', + Tuple( + help=_('This rule sets lower levels to the active number of NAT translations through the firewall. ' + 'Will only be used if NAT translations is not predictive levels.'), + title=_('NAT translations lower levels'), + elements=[ + Integer(title=_('Warning if below'), unit='Translations'), + Integer(title=_('Critical if below'), unit='Translations'), + ], + )), + ],) + + +rulespec_registry.register( + CheckParameterRulespecWithoutItem( + check_group_name='cisco_fw_nat_translations', + group=RulespecGroupCheckParametersApplications, + match_type='dict', + parameter_valuespec=_parameter_valuespec_cisco_fw_nat_translations, + title=lambda: _('Firewall NAT translatins'), + ))