From 52b4e8174d989035c3dd5f00336baab223168702 Mon Sep 17 00:00:00 2001
From: "th.l" <thl-cmk@outlook.com>
Date: Wed, 7 Jun 2023 10:04:05 +0200
Subject: [PATCH] update project

---
 check_ntp-0.0.3-20230607.mkp | Bin 0 -> 6344 bytes
 check_ntp.mkp                | Bin 6311 -> 6344 bytes
 gui/metrics/check_ntp.py     |  88 +++++++++++++++++
 gui/wato/check_ntp.py        | 184 +++++++++++++++++++++++++++++++++++
 lib/nagios/plugins/check_ntp |  12 ++-
 packages/check_ntp           |  12 +--
 6 files changed, 284 insertions(+), 12 deletions(-)
 create mode 100644 check_ntp-0.0.3-20230607.mkp
 create mode 100644 gui/metrics/check_ntp.py
 create mode 100644 gui/wato/check_ntp.py

diff --git a/check_ntp-0.0.3-20230607.mkp b/check_ntp-0.0.3-20230607.mkp
new file mode 100644
index 0000000000000000000000000000000000000000..4cddd50e3cc3fb0c308d81ffd765d4817a52f81f
GIT binary patch
literal 6344
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

literal 0
HcmV?d00001

diff --git a/check_ntp.mkp b/check_ntp.mkp
index 918b8d4c8e196d2a8f14a4c369d82d4af49d2542..4cddd50e3cc3fb0c308d81ffd765d4817a52f81f 100644
GIT binary patch
literal 6344
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

literal 6311
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
NF+vvNj&Os3@PBLTVF~~M

diff --git a/gui/metrics/check_ntp.py b/gui/metrics/check_ntp.py
new file mode 100644
index 0000000..3456514
--- /dev/null
+++ b/gui/metrics/check_ntp.py
@@ -0,0 +1,88 @@
+#!/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  : 2022-10-06
+# File  : metrics/check_ntp.py
+#
+#
+
+from cmk.gui.i18n import _
+
+from cmk.gui.plugins.metrics.utils import (
+    metric_info,
+    graph_info,
+    perfometer_info
+)
+
+metric_info['ntp_offset'] = {
+    'title': _('Offset'),
+    'unit': 's',
+    'color': '#9a52bf',
+}
+
+
+metric_info['ntp_delay'] = {
+    'title': _('Delay'),
+    'help': _(''),
+    'unit': 's',
+    'color': '26/a',
+}
+
+metric_info['ntp_root_dispersion'] = {
+    'title': _('Root dispersion'),
+    'help': _(''),
+    'unit': 's',
+    'color': '32/a',
+}
+
+
+graph_info['check_ntp_offset'] = {
+    'title': _('Time offset'),
+    'metrics': [
+        ('ntp_offset', 'area'),
+    ],
+    'scalars': [
+        ('ntp_offset:crit', _('Upper critical level')),
+        ('ntp_offset:warn', _('Upper warning level')),
+        ('0,ntp_offset:warn,-', _('Lower warning level')),
+        ('0,ntp_offset:crit,-', _('Lower critical level')),
+    ],
+    'range': ('0,ntp_offset:crit,-', 'ntp_offset:crit'),
+}
+
+graph_info['check_ntp_delay'] = {
+    'title': _('Delay'),
+    'metrics': [
+        ('ntp_delay', 'area'),
+    ],
+    'scalars': [
+        ('ntp_delay:crit', _('Critical')),
+        ('ntp_delay:warn', _('Warning')),
+    ],
+    'range': (0, 'ntp_delay:max'),
+}
+
+
+graph_info['check_ntp_dispersion'] = {
+    'title': _('Root dispersion'),
+    'metrics': [
+        ('ntp_root_dispersion', 'area'),
+    ],
+    'scalars': [
+        ('ntp_root_dispersion:crit', _('Critical')),
+        ('ntp_root_dispersion:warn', _('Warning')),
+    ],
+    'range': (0, 'ntp_root_dispersion:max'),
+}
+
+
+perfometer_info.append({
+    'type': 'logarithmic',
+    'metric': 'ntp_offset',
+    'half_value': 1.0,
+    'exponent': 10.0,
+})
diff --git a/gui/wato/check_ntp.py b/gui/wato/check_ntp.py
new file mode 100644
index 0000000..451a293
--- /dev/null
+++ b/gui/wato/check_ntp.py
@@ -0,0 +1,184 @@
+#!/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  : 2022-10-04
+# File  : wato/active_checks_ntp.py
+#
+
+from cmk.gui.i18n import _
+from cmk.gui.valuespec import (
+    Dictionary,
+    Tuple,
+    Transform,
+    Integer,
+    TextAscii,
+    MonitoringState,
+)
+
+from cmk.gui.plugins.wato.utils import (
+    rulespec_registry,
+    HostRulespec,
+)
+
+from cmk.gui.plugins.wato.active_checks import (
+    RulespecGroupActiveChecks
+)
+
+
+def _valuespec_active_checks_ntp():
+    return Transform(
+        Dictionary(
+            title=_('Check NTP service'),
+            help=_(''),
+            elements=[
+                ('description',
+                 TextAscii(
+                     title=_('Service description'),
+                     help=_(
+                         'Must be unique for every host. The service description starts always with \"NTP server\".'),
+                     size=50,
+                 )),
+                ('server',
+                 TextAscii(
+                     title=_('Server IP-address or name'),
+                     help=_(
+                         'Hostname or IP-address to monitor. Default is the host name/IP-Address of the monitored host.'
+                     ),
+                     size=50,
+                 )),
+                ('port',
+                 Integer(
+                     title=_('NTP port'),
+                     help=_('UDP Port to use. Default is 123.'),
+                     # size=5,
+                     default_value=123,
+                     minvalue=1,
+                     maxvalue=65535,
+                 )),
+                ('version',
+                 Integer(
+                     title=_('NTP version'),
+                     help=_('NTP version for the request. Default is version 4.'),
+                     # size=1,
+                     default_value=4,
+                     minvalue=1,
+                     maxvalue=4,
+                 )),
+                ('timeout',
+                 Integer(
+                     title=_('Request timeout'),
+                     help=_('Timeoute for the request in seconds. Min: 1s, Max: 20, Default is 2 seconds.'),
+                     # size=3,
+                     default_value=2,
+                     minvalue=1,
+                     maxvalue=20,
+                 )),
+                ('state_not_synchronized',
+                 MonitoringState(
+                     title=_('Monitoring state if server is not synchronized'),
+                     help=_('Monitoring state if server is not synchronized. Default is warning.'),
+                     default_value=2,
+                 )),
+                ('state_no_response',
+                 MonitoringState(
+                     default_value=2,
+                     title=_('Monitoring state if server doesn\'t respond (timeout)'),
+                     help=_('Monitoring state if the server doesn\'t respond. Default is "CRIT"')
+                 )),
+                ('stratum_levels',
+                 Tuple(
+                     title=_('max. stratum'),
+                     elements=[
+                         Integer(
+                             title=_('Warning at'),
+                             default_value=10,
+                             maxvalue=255,
+                             minvalue=1,
+                             help=_(
+                                 'The stratum (\'distance\' to the reference clock) at which the check gets warning.'),
+                         ),
+                         Integer(
+                             title=_('Critical at'),
+                             default_value=15,
+                             maxvalue=18,
+                             help=_(
+                                 'The stratum (\'distance\' to the reference clock) at which the check gets critical.'),
+                         )
+                     ],
+                 )),
+                ('offset_levels',
+                 Tuple(
+                     title=_('max. offset in ms'),
+                     help=_('Mean offset in the times reported between this local host and the remote peer or server.'
+                            'Note: This levels will also be used as lower levels.'),
+                     elements=[
+                         Integer(
+                             title=_('Warning at'),
+                             unit='ms',
+                             default_value=200,
+                             help=_('The offset in ms at which a warning state is triggered. Default is 200ms'),
+                         ),
+                         Integer(
+                             title=_('Critical at'),
+                             unit='ms',
+                             default_value=500,
+                             help=_('The offset in ms at which a critical state is triggered. Default is 500ms'),
+                         )
+                     ],
+                 )),
+                ('delay_levels',
+                 Tuple(
+                     title=_('max. delay in ms'),
+                     help=_('Upper levels for delay in milly seconds.'),
+                     elements=[
+                         Integer(
+                             title=_('Warning at'),
+                             unit='ms',
+                             default_value=200,
+                             help=_('The delay in ms at which a warning state is triggered. Default is 200ms'),
+                         ),
+                         Integer(
+                             title=_('Critical at'),
+                             unit='ms',
+                             default_value=500,
+                             help=_('The delay in s at which a critical state is triggered. Default is 500ms'),
+                         )
+                     ],
+                 )),
+                ('dispersion_levels',
+                 Tuple(
+                     title=_('max. root dispersion in s'),
+                     help=_('Upper levels for (root) dispersion in seconds.'),
+                     elements=[
+                         Integer(
+                             title=_('Warning at'),
+                             unit='s',
+                             default_value=3,
+                             help=_('The dispersion in s at which a warning state is triggered. Default is 3s'),
+                         ),
+                         Integer(
+                             title=_('Critical at'),
+                             unit='s',
+                             default_value=5,
+                             help=_('The dispersion in s at which a critical state is triggered. Default is 5s'),
+                         )
+                     ],
+                 )),
+            ],
+        ),
+    )
+
+
+rulespec_registry.register(
+    HostRulespec(
+        group=RulespecGroupActiveChecks,
+        match_type='all',
+        name='active_checks:ntp',
+        valuespec=_valuespec_active_checks_ntp,
+    )
+)
diff --git a/lib/nagios/plugins/check_ntp b/lib/nagios/plugins/check_ntp
index 40d821f..f270473 100755
--- a/lib/nagios/plugins/check_ntp
+++ b/lib/nagios/plugins/check_ntp
@@ -14,21 +14,22 @@
 # 2022-10-13: added exception handling for ntp request
 # 2022-11-14: made state on no response configurable
 # 2022-11-15: added short options
+# 2023-06-07: moved gui files to ~/local/lib/chek_mk/gui/plugins/...
 
 from typing import Optional, Sequence, Tuple
 from ipaddress import IPv4Address
 import sys
 import argparse
 import socket
-from time import ctime, gmtime, strftime
+from time import ctime
 
 import ntplib
 
-no_ntplib=False
+no_ntplib = False
 try:
     from ntplib import NTPClient, NTPStats
 except ModuleNotFoundError:
-    no_ntplib=True
+    no_ntplib = True
 
 _ntp_leap = {
     0: 'no warning',
@@ -182,7 +183,8 @@ def parse_arguments(argv: Sequence[str]) -> argparse.Namespace:
     return args
 
 
-def get_ntp_time(server: str, port: int, timeout: int, version: int, state_no_response: int):  # -> Optional[NTPStats] # is not available if ntplib is not installed
+def get_ntp_time(server: str, port: int, timeout: int, version: int, state_no_response: int):  # -> Optional[NTPStats]
+    # NTPStats is not available if ntplib is not installed
     c = NTPClient()
     try:
         response = c.request(
@@ -226,7 +228,7 @@ def main(args=None):
     perfdata = ''
     status = 0
     # https://tutorial.eyehunts.com/python/python-strftime-function-milliseconds-examples/
-    time_format = '%Y-%m-%d %H:%M:%S'
+    # time_format = '%Y-%m-%d %H:%M:%S'
 
     text = f'Stratum: {stratum}'
     if stratum >= args.stratum[1]:
diff --git a/packages/check_ntp b/packages/check_ntp
index 764eb20..d1d9e1a 100644
--- a/packages/check_ntp
+++ b/packages/check_ntp
@@ -2,13 +2,11 @@
  'description': 'Active check to monitor NTP servers\n',
  'download_url': 'https://thl-cmk.hopto.org',
  'files': {'checks': ['check_ntp'],
-           'lib': ['nagios/plugins/check_ntp'],
-           'web': ['plugins/metrics/check_ntp.py',
-                   'plugins/wato/active_checks_ntp.py']},
+           'gui': ['metrics/check_ntp.py', 'wato/check_ntp.py'],
+           'lib': ['nagios/plugins/check_ntp']},
  'name': 'check_ntp',
- 'num_files': 4,
  'title': 'Active check NTP',
- 'version': '20221115.v.0.0.2a',
- 'version.min_required': '2.0.0',
- 'version.packaged': '2021.09.20',
+ 'version': '0.0.3-20230607',
+ 'version.min_required': '2.1.0b1',
+ 'version.packaged': '2.1.0p21',
  'version.usable_until': None}
\ No newline at end of file
-- 
GitLab