diff --git a/README.md b/README.md index 3b26bb438560da8adbf16fcab85c50f2c8394c3b..8bed6bf1c8ebff4659d7f84e23a68f14ee064af6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[PACKAGE]: ../../raw/master/mkp/unbound-1.2.3-20240521.mkp "unbound-1.2.3-20240521.mkp" +[PACKAGE]: ../../raw/master/mkp/unbound-1.2.4-20240522.mkp "unbound-1.2.4-20240522.mkp" # unbound This agent plugin cheks the state of the unbound dns daemon. For more information about unbound see: https://nlnetlabs.nl/projects/unbound/about/ diff --git a/mkp/unbound-1.2.4-20240522.mkp b/mkp/unbound-1.2.4-20240522.mkp new file mode 100644 index 0000000000000000000000000000000000000000..50143806c05d843c30d2dfbb5393b0b86d6bc85f Binary files /dev/null and b/mkp/unbound-1.2.4-20240522.mkp differ diff --git a/source/agent_based/unbound.py b/source/agent_based/unbound.py index 4f6e23fc9d5008a30a2d0c9031609a2f2699e3f1..f37ffe99ea98d53aaaa79fbc2eaab1b298899faa 100644 --- a/source/agent_based/unbound.py +++ b/source/agent_based/unbound.py @@ -21,11 +21,16 @@ # changes by thl-cmk[at]outlook[dot]com # 2024-04-21: removed Union -> no need "int | float" should do # added levels_upper_NOERROR to default parameters -> show up in info line +# 2024-05-22: changed time for get_rate from section to system time +# added output in case get_rate is initialising (unknown state in discovery) +# removed default levels for unbound_answers +# added params for unwanted replies + +from time import time as now_time from typing import ( Any, Mapping, - # Union, ) from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( @@ -36,7 +41,9 @@ from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( from cmk.base.plugins.agent_based.agent_based_api.v1 import ( GetRateError, + Result, Service, + State, check_levels, get_rate, get_value_store, @@ -44,8 +51,6 @@ from cmk.base.plugins.agent_based.agent_based_api.v1 import ( render, ) - -# UnboundSection = Mapping[str, Union[int, float, "UnboundSection"]] UnboundSection = Mapping[str, int | float] @@ -64,7 +69,7 @@ def parse_unbound(string_table: StringTable) -> UnboundSection: register.agent_section( - name="unbound", + name='unbound', parse_function=parse_unbound, ) @@ -75,12 +80,12 @@ def discover_unbound_cache(section: UnboundSection) -> DiscoveryResult: def check_unbound_cache( - params: Mapping[str, Any], - section: UnboundSection, + params: Mapping[str, Any], + section: UnboundSection, ) -> CheckResult: cumulative_cache_hits = section.get('total.num.cachehits') cumulative_cache_miss = section.get('total.num.cachemiss') - now = section.get('time.now') + now = now_time() if None in (cumulative_cache_hits, cumulative_cache_miss, now): return @@ -104,8 +109,8 @@ def check_unbound_cache( yield from check_levels( value=cache_miss, - metric_name="cache_misses_rate", - levels_upper=params.get("cache_misses"), + metric_name='cache_misses_rate', + levels_upper=params.get('cache_misses'), render_func=render_qps, label='Cache Misses', notice_only=True, @@ -113,7 +118,7 @@ def check_unbound_cache( yield from check_levels( value=cache_hits, - metric_name="cache_hit_rate", + metric_name='cache_hit_rate', render_func=render_qps, label='Cache Hits', notice_only=True, @@ -121,41 +126,39 @@ def check_unbound_cache( yield from check_levels( value=hit_perc, - metric_name="cache_hit_ratio", - levels_lower=params.get("cache_hits"), + metric_name='cache_hit_ratio', + levels_lower=params.get('cache_hits'), render_func=render.percent, label='Cache Hit Ratio', ) register.check_plugin( - name="unbound_cache", - service_name="Unbound Cache", - sections=["unbound"], + name='unbound_cache', + service_name='Unbound Cache', + sections=['unbound'], discovery_function=discover_unbound_cache, check_function=check_unbound_cache, check_default_parameters={}, - check_ruleset_name="unbound_cache", + check_ruleset_name='unbound_cache', ) def discover_unbound_answers(section: UnboundSection) -> DiscoveryResult: - if 'time.now' in section and 'num.answer.rcode.SERVFAIL' in section: + if 'num.answer.rcode.SERVFAIL' in section: yield Service() def check_unbound_answers(params: Mapping, section: UnboundSection) -> CheckResult: key_prefix = 'num.answer.rcode.' - if 'time.now' not in section: - return - - now = section['time.now'] + now = now_time() total = sum( value for key, value in section.items() if key.startswith(key_prefix) ) + init_counters = False for key, value in section.items(): if not key.startswith(key_prefix): continue @@ -169,8 +172,10 @@ def check_unbound_answers(params: Mapping, section: UnboundSection) -> CheckResu value, raise_overflow=True, ) - except GetRateError: - pass + except GetRateError as e: + if not init_counters: + yield Result(state=State.OK, summary=str(e)) + init_counters = True else: levels_upper = params.get(f'levels_upper_{answer}') if levels_upper is not None and len(levels_upper) == 3: @@ -190,40 +195,40 @@ def check_unbound_answers(params: Mapping, section: UnboundSection) -> CheckResu register.check_plugin( - name="unbound_answers", - service_name="Unbound Answers", - sections=["unbound"], + name='unbound_answers', + service_name='Unbound Answers', + sections=['unbound'], discovery_function=discover_unbound_answers, check_function=check_unbound_answers, check_default_parameters={ - 'levels_upper_NOERROR': (101,101), - 'levels_upper_SERVFAIL': (10, 100), - 'levels_upper_REFUSED': (10, 100), + # 'levels_upper_NOERROR': (101, 101), + # 'levels_upper_SERVFAIL': (10, 100), + # 'levels_upper_REFUSED': (10, 100), }, - check_ruleset_name="unbound_answers", + check_ruleset_name='unbound_answers', ) def discover_unbound_unwanted_replies(section: UnboundSection) -> DiscoveryResult: - if 'time.now' in section and 'unwanted.replies' in section: + if 'unwanted.replies' in section: yield Service() -def check_unbound_unwanted_replies(section: UnboundSection) -> CheckResult: - if 'time.now' not in section or 'unwanted.replies' not in section: +def check_unbound_unwanted_replies(params, section: UnboundSection) -> CheckResult: + if 'unwanted.replies' not in section: return rate = get_rate( get_value_store(), 'unbound_unwanted_replies', - section['time.now'], + now_time(), section['unwanted.replies'], raise_overflow=True, ) yield from check_levels( value=rate, - levels_upper=(10, 100), + levels_upper=params.get('unwanted_replies'), metric_name='unbound_unwanted_replies', render_func=render_qps, label='Unwanted Replies', @@ -231,9 +236,11 @@ def check_unbound_unwanted_replies(section: UnboundSection) -> CheckResult: register.check_plugin( - name="unbound_unwanted_replies", - service_name="Unbound Unwanted Replies", - sections=["unbound"], + name='unbound_unwanted_replies', + service_name='Unbound Unwanted Replies', + sections=['unbound'], discovery_function=discover_unbound_unwanted_replies, check_function=check_unbound_unwanted_replies, + check_default_parameters={}, + check_ruleset_name='unbound_replies', ) diff --git a/source/agent_based/unbound_status.py b/source/agent_based/unbound_status.py index 7ced922daba226ab6a4750bf2a8991c639a9092d..3cc99411c5bb5998be6010e5d18c45ee2326067b 100644 --- a/source/agent_based/unbound_status.py +++ b/source/agent_based/unbound_status.py @@ -132,5 +132,3 @@ register.check_plugin( check_default_parameters={}, check_ruleset_name="unbound_status", ) - - diff --git a/source/gui/wato/check_parameters/unbound.py b/source/gui/wato/check_parameters/unbound.py index 6e01e01560041449c08e1f21f3a27dfd93dba4bb..f20bb6e60c204a7c1ce94bccc3ff765e1436b5bd 100644 --- a/source/gui/wato/check_parameters/unbound.py +++ b/source/gui/wato/check_parameters/unbound.py @@ -25,7 +25,7 @@ # renamed to unbound.py (from unbound_parameters.py) # moved to ~/local/lib/check_mk/gui/plugins/wato/check_parameters (from local/share/check_mk/web/plugins/wato) # 2024-05-14: separated WATO for bakery and check in two files - +# 2024-05-22: added ruleset for unwanted replies from cmk.gui.i18n import _ from cmk.gui.plugins.wato.utils import ( @@ -34,7 +34,6 @@ from cmk.gui.plugins.wato.utils import ( rulespec_registry, ) - from cmk.gui.valuespec import ( Alternative, Dictionary, @@ -47,78 +46,61 @@ from cmk.gui.valuespec import ( def _parameter_valuespec_unbound_cache(): return Dictionary( - title=_("Unbound: Cache"), + title=_('Unbound: Cache'), elements=[ - ( - "cache_misses", - Tuple( - title="Levels on cache misses per second", - elements=[ - Float( - title="warn", - ), - Float( - title="crit", - ), - ], - ), - ), - ( - "cache_hits", - Tuple( - title="Lower levels for hits in %", - elements=[ - Percentage( - title="warn", - ), - Percentage( - title="crit", - ), - ], - ), - ), - ], - ) + ('cache_misses', + Tuple( + title='Levels on cache misses per second', + elements=[ + Float(title='warn', ), + Float(title='crit', ), + ])), + ('cache_hits', + Tuple( + title='Lower levels for hits in %', + elements=[ + Percentage(title='warn', ), + Percentage(title='crit', ), + ])), + ]) rulespec_registry.register( CheckParameterRulespecWithoutItem( - check_group_name="unbound_cache", + check_group_name='unbound_cache', group=RulespecGroupCheckParametersApplications, - match_type="dict", + match_type='dict', parameter_valuespec=_parameter_valuespec_unbound_cache, - title=lambda: _("Unbound Cache"), + title=lambda: _('Unbound Cache'), ) ) def _parameter_valuespec_unbound_answers(): return Dictionary( + title=_('Unbound answers'), elements=[ - ( - f"levels_upper_{answer}", - Alternative( - title=f'Upper levels for {answer} answers', - show_alternative_title=True, - elements=[ - Tuple( - elements=[ - Float(title=_("Warning at"), unit=_("qps")), - Float(title=_("Critical at"), unit=_("qps")), - ], - title=f'Upper levels in qps', - ), - Tuple( - elements=[ - Percentage(title=_("Warning at"), unit=_("%")), - Percentage(title=_("Critical at"), unit=_("%")), - FixedValue(value="%", totext=""), # need to decide between both variants - ], - title=f'Upper levels in %', - ), - ] - ) - ) + (f'levels_upper_{answer}', + Alternative( + title=f'Upper levels for {answer} answers', + show_alternative_title=True, + elements=[ + Tuple( + elements=[ + Float(title=_('Warning at'), unit=_('qps')), + Float(title=_('Critical at'), unit=_('qps')), + ], + title=_('Upper levels in qps'), + ), + Tuple( + elements=[ + Percentage(title=_('Warning at'), unit=_('%')), + Percentage(title=_('Critical at'), unit=_('%')), + FixedValue(value='%', totext=''), # needed to decide between both variants + ], + title=_('Upper levels in %'), + ), + ])) for answer in ( 'NOERROR', 'FORMERR', @@ -134,10 +116,35 @@ def _parameter_valuespec_unbound_answers(): rulespec_registry.register( CheckParameterRulespecWithoutItem( - check_group_name="unbound_answers", + check_group_name='unbound_answers', group=RulespecGroupCheckParametersApplications, - match_type="dict", + match_type='dict', parameter_valuespec=_parameter_valuespec_unbound_answers, - title=lambda: _("Unbound Answers"), + title=lambda: _('Unbound Answers'), + ) +) + + +def _parameter_valuespec_unbound_replies(): + return Dictionary( + title=_('Unbound: Replies'), + elements=[ + ('unwanted_replies', + Tuple( + title='Levels on unwanted replies per second', + elements=[ + Float(title='warn', ), + Float(title='crit', ), + ])), + ]) + + +rulespec_registry.register( + CheckParameterRulespecWithoutItem( + check_group_name='unbound_replies', + group=RulespecGroupCheckParametersApplications, + match_type='dict', + parameter_valuespec=_parameter_valuespec_unbound_replies, + title=lambda: _('Unbound Replies'), ) ) diff --git a/source/packages/unbound b/source/packages/unbound index 457cef7311df1d0161772c3aba5c08d240fe5887..77789d9c90d7e4c9a1577d191e627de329eba2a7 100644 --- a/source/packages/unbound +++ b/source/packages/unbound @@ -1,12 +1,18 @@ -{'author': 'Jan-Philipp Litza <jpl@plutex.de>', +{'author': 'Th.L. (thl-cmk[at]outlook[dot]com)', 'description': 'Plugin to gather statistics from unbound caching DNS resolver ' 'via agent plugin. It monitors answer types, cache hit ratio ' 'and miss rate as well as unwanted reply rate.\n' '\n' 'needs in server config:\n' ' server:\n' - ' extended-statistics: yes\n', - 'download_url': 'https://github.com/PLUTEX/checkmk-unbound/', + ' extended-statistics: yes\n' + '\n' + 'Acnowlegement\n' + 'This plugin is based on the work of Jan-Philipp Litza ' + '(PLUTEX) jpl[at]plutex[dor]de.\n' + 'See: https://exchange.checkmk.com/p/unbound for more ' + 'details.\n', + 'download_url': 'https://thl-cmk.hopto.org', 'files': {'agent_based': ['unbound.py', 'unbound_status.py'], 'agents': ['plugins/unbound'], 'gui': ['metrics/unbound.py', @@ -15,7 +21,7 @@ 'lib': ['python3/cmk/base/cee/plugins/bakery/unbound.py']}, 'name': 'unbound', 'title': 'Unbound', - 'version': '1.2.3-20240521', + 'version': '1.2.4-20240522', 'version.min_required': '2.2.0b1', 'version.packaged': '2.2.0p24', 'version.usable_until': None}