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 Binary files /dev/null and b/check_ntp-0.0.3-20230607.mkp differ diff --git a/check_ntp.mkp b/check_ntp.mkp index 918b8d4c8e196d2a8f14a4c369d82d4af49d2542..4cddd50e3cc3fb0c308d81ffd765d4817a52f81f 100644 Binary files a/check_ntp.mkp and b/check_ntp.mkp differ diff --git a/gui/metrics/check_ntp.py b/gui/metrics/check_ntp.py new file mode 100644 index 0000000000000000000000000000000000000000..3456514550f450e253cd2a3f848f30dfa9a3d8ea --- /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 0000000000000000000000000000000000000000..451a293db59736f8aaf9a78e683fa849c02f13da --- /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 40d821f05f572a7fea59c3c8bb5b9fc8986f26c0..f270473b5fb7873bb996ddd51aab0aa69cbde28d 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 764eb202f2b5c7adf29dd5c6d016db90780ea256..d1d9e1a1bd54898a462585a2fd67d2ff75044776 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