From a8fb2ec4a182859df2bc60138b1a9f80fc8447e9 Mon Sep 17 00:00:00 2001
From: "th.l" <thl-cmk@outlook.com>
Date: Wed, 22 May 2024 19:52:38 +0200
Subject: [PATCH] update project

---
 README.md                                   |   2 +-
 mkp/unbound-1.2.4-20240522.mkp              | Bin 0 -> 6382 bytes
 source/agent_based/unbound.py               |  83 ++++++------
 source/agent_based/unbound_status.py        |   2 -
 source/gui/wato/check_parameters/unbound.py | 133 ++++++++++----------
 source/packages/unbound                     |  14 ++-
 6 files changed, 126 insertions(+), 108 deletions(-)
 create mode 100644 mkp/unbound-1.2.4-20240522.mkp

diff --git a/README.md b/README.md
index 3b26bb4..8bed6bf 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
GIT binary patch
literal 6382
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
J5Z)sq{14p*eFgvk

literal 0
HcmV?d00001

diff --git a/source/agent_based/unbound.py b/source/agent_based/unbound.py
index 4f6e23f..f37ffe9 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 7ced922..3cc9941 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 6e01e01..f20bb6e 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 457cef7..77789d9 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}
-- 
GitLab