From cb97e79ff074770cc9bed1e49405ffdfc72fa213 Mon Sep 17 00:00:00 2001 From: Markus Frei Date: Sat, 16 Sep 2023 17:01:57 +0200 Subject: [PATCH] ntp-w32tm (fix #629) --- CHANGELOG.md | 9 +- .../all-the-rest.json | 43 +++ check-plugins/ntp-w32tm/.windows | 0 check-plugins/ntp-w32tm/README.rst | 109 ++++++++ .../icingaweb2-module-director/ntp-w32tm.json | 127 +++++++++ .../icingaweb2-module-director/ntp-w32tm.yml | 7 + check-plugins/ntp-w32tm/lib | 1 + check-plugins/ntp-w32tm/ntp-w32tm | 166 ++++++++++++ check-plugins/ntp-w32tm/unit-test/run | 253 ++++++++++++++++++ .../ntp-w32tm/unit-test/stdout/EXAMPLE01 | 17 ++ .../ntp-w32tm/unit-test/stdout/EXAMPLE02 | 17 ++ .../ntp-w32tm/unit-test/stdout/EXAMPLE03 | 17 ++ .../ntp-w32tm/unit-test/stdout/EXAMPLE04 | 17 ++ .../ntp-w32tm/unit-test/stdout/EXAMPLE05 | 17 ++ .../ntp-w32tm/unit-test/stdout/EXAMPLE06 | 17 ++ .../ntp-w32tm/unit-test/stdout/EXAMPLE07 | 17 ++ .../ntp-w32tm/unit-test/stdout/EXAMPLE08 | 17 ++ .../ntp-w32tm/unit-test/stdout/EXAMPLE09 | 17 ++ .../ntp-w32tm/unit-test/stdout/EXAMPLE10 | 17 ++ 19 files changed, 881 insertions(+), 4 deletions(-) create mode 100644 check-plugins/ntp-w32tm/.windows create mode 100644 check-plugins/ntp-w32tm/README.rst create mode 100644 check-plugins/ntp-w32tm/icingaweb2-module-director/ntp-w32tm.json create mode 100644 check-plugins/ntp-w32tm/icingaweb2-module-director/ntp-w32tm.yml create mode 120000 check-plugins/ntp-w32tm/lib create mode 100755 check-plugins/ntp-w32tm/ntp-w32tm create mode 100755 check-plugins/ntp-w32tm/unit-test/run create mode 100644 check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE01 create mode 100644 check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE02 create mode 100644 check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE03 create mode 100644 check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE04 create mode 100644 check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE05 create mode 100644 check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE06 create mode 100644 check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE07 create mode 100644 check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE08 create mode 100644 check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE09 create mode 100644 check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE10 diff --git a/CHANGELOG.md b/CHANGELOG.md index f0e3a1d0a..c12401881 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ and this project does NOT adhere to [Semantic Versioning](https://semver.org/spe Monitoring Plugins: -* Notifications Plugins now generate URLs for Icinga DB Web instead of the old IcingaWeb2 Monitoring Module (fix #643) +* Notifications Plugins now generate URLs for Icinga DB Web instead of the old IcingaWeb2 Monitoring Module (fix [#643](https://github.com/Linuxfabrik/monitoring-plugins/issues/643)) ### Added @@ -33,10 +33,11 @@ Icinga Director: Monitoring Plugins: * deb-lastactivity ([PR #710](https://github.com/Linuxfabrik/monitoring-plugins/issues/710), thanks to [Yannic Schüpbach](https://github.com/Dissiyt)) -* gitlab-health (fix #670) -* gitlab-liveness (fix #670) -* gitlab-readiness (fix #670) +* gitlab-health (fix [#670](https://github.com/Linuxfabrik/monitoring-plugins/issues/670)) +* gitlab-liveness (fix [#670](https://github.com/Linuxfabrik/monitoring-plugins/issues/670)) +* gitlab-readiness (fix [#670](https://github.com/Linuxfabrik/monitoring-plugins/issues/670)) * gitlab-version +* ntp-w32tm (fix [#629](https://github.com/Linuxfabrik/monitoring-plugins/issues/629)) * openstack-nova-list * postgresql-version * statuspal diff --git a/assets/icingaweb2-module-director/all-the-rest.json b/assets/icingaweb2-module-director/all-the-rest.json index 90fdbd3b7..a6aa0f812 100644 --- a/assets/icingaweb2-module-director/all-the-rest.json +++ b/assets/icingaweb2-module-director/all-the-rest.json @@ -38030,6 +38030,49 @@ "volatile": null, "zone": null }, + "NTP - w32tm": { + "action_url": null, + "apply_for": null, + "assign_filter": null, + "check_command": null, + "check_interval": null, + "check_period": null, + "check_timeout": null, + "command_endpoint": null, + "disabled": false, + "display_name": null, + "enable_active_checks": null, + "enable_event_handler": null, + "enable_flapping": null, + "enable_notifications": null, + "enable_passive_checks": null, + "enable_perfdata": null, + "event_command": null, + "fields": [], + "flapping_threshold_high": null, + "flapping_threshold_low": null, + "groups": [], + "host": null, + "icon_image": null, + "icon_image_alt": null, + "imports": [ + "tpl-service-ntp-w32tm-windows" + ], + "max_check_attempts": null, + "notes": null, + "notes_url": null, + "object_name": "NTP - w32tm", + "object_type": "object", + "retry_interval": null, + "service_set": null, + "template_choice": null, + "use_agent": null, + "use_var_overrides": null, + "uuid": "b04ff98e-64e2-4b89-a478-367ec24d94fa", + "vars": {}, + "volatile": null, + "zone": null + }, "Procs": { "action_url": null, "apply_for": null, diff --git a/check-plugins/ntp-w32tm/.windows b/check-plugins/ntp-w32tm/.windows new file mode 100644 index 000000000..e69de29bb diff --git a/check-plugins/ntp-w32tm/README.rst b/check-plugins/ntp-w32tm/README.rst new file mode 100644 index 000000000..472b036f9 --- /dev/null +++ b/check-plugins/ntp-w32tm/README.rst @@ -0,0 +1,109 @@ +Check ntp-w32tm +=============== + +Overview +-------- + +This monitoring plugin runs ``w32tm /query /status /verbose`` (Windows) to help diagnose problems with the time settings. + + +Fact Sheet +---------- + +.. csv-table:: + :widths: 30, 70 + + "Check Plugin Download", "https://github.com/Linuxfabrik/monitoring-plugins/tree/main/check-plugins/ntp-w32tm" + "Check Interval Recommendation", "Once a minute" + "Can be called without parameters", "Yes" + "Compiled for", "Windows" + + +Help +---- + +.. code-block:: text + + usage: ntp-w32tm [-h] [-V] [-c CRIT] [--test TEST] [-w WARN] + + This monitoring plugin runs `w32tm /query /status /verbose` (Windows) to help + diagnose problems with the time settings. + + options: + -h, --help show this help message and exit + -V, --version show program's version number and exit + -c CRIT, --critical CRIT + Set the critical threshold for the time since "Last + Good Sync", in s. Default: 129600s + --test TEST For unit tests. Needs "path-to-stdout-file,path-to- + stderr-file,expected-retc". + -w WARN, --warning WARN + Set the warning threshold for the time since "Last + Good Sync", in s. Default: 28800s + + +Usage Examples +-------------- + +.. code-block:: bash + + ./ntp-w32tm --warning 28800 --critical 129600 + +Output: + +.. code-block:: text + + Leap Indicator: 3 (not synchronized), No NTP server used [WARNING], Last Sync Error: 1 (The computer did not resync because no time data was available.) + + Leap Indicator: 3(not synchronized) + Stratum: 0 (unspecified) + Precision: -23 (119.209ns per tick) + Root Delay: 0.0267908s + Root Dispersion: 0.0402331s + ReferenceId: 0x00000000 (unspecified) + Last Successful Sync Time: 9/16/2023 12:52:13 PM + Source: time.windows.com,0x8 + Poll Interval: 6 (64s) + + Phase Offset: 0.7679486s + ClockRate: 0.0156250s + State Machine: 0 (Unset) + Time Source Flags: 0 (None) + Server Role: 0 (None) + Last Sync Error: 1 (The computer did not resync because no time data was available.) + Time since Last Good Sync Time: 19.2218793s + + +States +------ + +* WARN if no NTP server is used. +* WARN if stratum is >= 5. +* WARN if "Leap Indicator" is not "0(no warning)" +* WARN if "Last Sync Error" is not "0" +* WARN or CRIT if "Time since Last Good Sync Time" is above a given threshold. + + +Perfdata / Metrics +------------------ + +.. csv-table:: + :widths: 25, 15, 60 + :header-rows: 1 + + Name, Type, Description + clock_rate, Milliseconds, + leap_indicator, Number, "Indicates whether an impending leap second is to be inserted or deleted in the last minute of the current day." + phase_offset, Milliseconds, + precision, Number, + root_delay, Milliseconds, "This is the total of the network path delays to the stratum-1 computer from which the computer is ultimately synchronized. In certain extreme situations, this value can be negative. (This can arise in a symmetric peer arrangement where the computers’ frequencies are not tracking each other and the network delay is very short relative to the turn-around time at each computer.)" + root_dispersion, Milliseconds, "This is the total dispersion accumulated through all the computers back to the stratum-1 computer from which the computer is ultimately synchronized. Dispersion is due to system clock resolution, statistical measurement variations etc." + stratum, Number, "The stratum indicates how many hops away from a computer with an attached reference clock we are. Such a computer is a stratum-1 computer, so the computer in the example is two hops away (that is to say, a.b.c is a stratum-2 and is synchronized from a stratum-1)." + time_since_last_good_sync_time, Seconds + + +Credits, License +---------------- + +* Authors: `Linuxfabrik GmbH, Zurich `_ +* License: The Unlicense, see `LICENSE file `_. diff --git a/check-plugins/ntp-w32tm/icingaweb2-module-director/ntp-w32tm.json b/check-plugins/ntp-w32tm/icingaweb2-module-director/ntp-w32tm.json new file mode 100644 index 000000000..8edf4fd16 --- /dev/null +++ b/check-plugins/ntp-w32tm/icingaweb2-module-director/ntp-w32tm.json @@ -0,0 +1,127 @@ +{ + "Command": { + "cmd-check-ntp-w32tm-windows": { + "arguments": { + "--critical": { + "value": "$ntp_w32tm_windows_critical$" + }, + "--warning": { + "value": "$ntp_w32tm_windows_warning$" + } + }, + "command": "C:\\ProgramData\\icinga2\\usr\\lib64\\nagios\\plugins\\ntp-w32tm.exe", + "disabled": false, + "fields": [ + { + "datafield_id": 1, + "is_required": "n", + "var_filter": null + }, + { + "datafield_id": 2, + "is_required": "n", + "var_filter": null + } + ], + "imports": [], + "is_string": null, + "methods_execute": "PluginCheck", + "object_name": "cmd-check-ntp-w32tm-windows", + "object_type": "object", + "timeout": "10", + "vars": {}, + "zone": null, + "uuid": "52bcb6ab-28d8-49aa-9daf-9a9f6f3c420a" + }, + "cmd-check-ntp-w32tm-windows-python": { + "arguments": {}, + "command": "C:\\Windows\\py C:\\ProgramData\\icinga2\\usr\\lib64\\nagios\\plugins\\ntp-w32tm.py", + "disabled": false, + "fields": [], + "imports": [ + "cmd-check-ntp-w32tm-windows" + ], + "is_string": null, + "methods_execute": null, + "object_name": "cmd-check-ntp-w32tm-windows-python", + "object_type": "object", + "timeout": null, + "vars": {}, + "zone": null, + "uuid": "57927ffd-db3a-469a-bc56-c1b555cf76a5" + } + }, + "ServiceTemplate": { + "tpl-service-ntp-w32tm-windows": { + "action_url": null, + "apply_for": null, + "assign_filter": null, + "check_command": "cmd-check-ntp-w32tm-windows", + "check_interval": 60, + "check_period": null, + "check_timeout": null, + "command_endpoint": null, + "disabled": false, + "display_name": null, + "enable_active_checks": null, + "enable_event_handler": null, + "enable_flapping": null, + "enable_notifications": true, + "enable_passive_checks": null, + "enable_perfdata": true, + "event_command": null, + "fields": [], + "flapping_threshold_high": null, + "flapping_threshold_low": null, + "groups": [], + "host": null, + "icon_image": "ntp-w32tm.png", + "icon_image_alt": null, + "imports": [ + "tpl-service-generic" + ], + "max_check_attempts": 5, + "notes": "This monitoring plugin runs `w32tm /query /status /verbose` (Windows) to help diagnose problems with the time settings.", + "notes_url": "https://github.com/Linuxfabrik/monitoring-plugins/tree/main/check-plugins/ntp-w32tm", + "object_name": "tpl-service-ntp-w32tm-windows", + "object_type": "template", + "retry_interval": 15, + "service_set": null, + "template_choice": null, + "use_agent": null, + "use_var_overrides": null, + "vars": { + "criticality": "B", + "ntp_w32tm_windows_critical": 129600, + "ntp_w32tm_windows_warning": 28800 + }, + "volatile": null, + "zone": null, + "uuid": "302f40db-9ad1-4d36-85d9-a4543ad98469" + } + }, + "Datafield": { + "1": { + "varname": "ntp_w32tm_windows_critical", + "caption": "NTP W32Tm: Critical", + "description": "Set the critical threshold for the time since \"Last Good Sync\", in s.", + "datatype": "Icinga\\Module\\Director\\DataType\\DataTypeString", + "format": null, + "settings": { + "visibility": "visible" + }, + "uuid": "fa437e67-a3e6-430f-906c-ad6330db9ffa" + }, + "2": { + "varname": "ntp_w32tm_windows_warning", + "caption": "NTP W32Tm: Warning", + "description": "Set the warning threshold for the time since \"Last Good Sync\", in s.", + "datatype": "Icinga\\Module\\Director\\DataType\\DataTypeString", + "format": null, + "settings": { + "visibility": "visible" + }, + "uuid": "308ec0c1-ec53-4f57-8f90-9078fa714248" + } + } +} diff --git a/check-plugins/ntp-w32tm/icingaweb2-module-director/ntp-w32tm.yml b/check-plugins/ntp-w32tm/icingaweb2-module-director/ntp-w32tm.yml new file mode 100644 index 000000000..e97e9e67b --- /dev/null +++ b/check-plugins/ntp-w32tm/icingaweb2-module-director/ntp-w32tm.yml @@ -0,0 +1,7 @@ +--- +variants: + - windows + +overwrites: + '["ServiceTemplate"]["tpl-service-ntp-w32tm-windows"]["enable_perfdata"]': true + '["ServiceTemplate"]["tpl-service-ntp-w32tm-windows"]["vars"]["criticality"]': 'B' diff --git a/check-plugins/ntp-w32tm/lib b/check-plugins/ntp-w32tm/lib new file mode 120000 index 000000000..58677ddb4 --- /dev/null +++ b/check-plugins/ntp-w32tm/lib @@ -0,0 +1 @@ +../../lib \ No newline at end of file diff --git a/check-plugins/ntp-w32tm/ntp-w32tm b/check-plugins/ntp-w32tm/ntp-w32tm new file mode 100755 index 000000000..76f2a86d1 --- /dev/null +++ b/check-plugins/ntp-w32tm/ntp-w32tm @@ -0,0 +1,166 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8; py-indent-offset: 4 -*- +# +# Author: Linuxfabrik GmbH, Zurich, Switzerland +# Contact: info (at) linuxfabrik (dot) ch +# https://www.linuxfabrik.ch/ +# License: The Unlicense, see LICENSE file. + +# https://github.com/Linuxfabrik/monitoring-plugins/blob/main/CONTRIBUTING.rst + +"""See the check's README for more details. +""" + +import argparse # pylint: disable=C0413 +import sys # pylint: disable=C0413 + +import lib.args # pylint: disable=C0413 +import lib.base # pylint: disable=C0413 +import lib.human # pylint: disable=C0413 +import lib.shell # pylint: disable=C0413 +import lib.test # pylint: disable=C0413 +import lib.txt # pylint: disable=C0413 +from lib.globals import (STATE_CRIT, STATE_OK, # pylint: disable=C0413 + STATE_UNKNOWN, STATE_WARN) + +__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland' +__version__ = '2023091601' + +DESCRIPTION = '''This monitoring plugin runs `w32tm /query /status /verbose` (Windows) + to help diagnose problems with the time settings.''' + +DEFAULT_WARN = 28800 # s (8h) +DEFAULT_CRIT = 129600 # s (36h) + + +def parse_args(): + """Parse command line arguments using argparse. + """ + parser = argparse.ArgumentParser(description=DESCRIPTION) + + parser.add_argument( + '-V', '--version', + action='version', + version='{0}: v{1} by {2}'.format('%(prog)s', __version__, __author__) + ) + + parser.add_argument( + '-c', '--critical', + help='Set the critical threshold for the time since "Last Good Sync", in s. ' + 'Default: %(default)ss', + dest='CRIT', + type=int, + default=DEFAULT_CRIT, + ) + + parser.add_argument( + '--test', + help='For unit tests. Needs "path-to-stdout-file,path-to-stderr-file,expected-retc".', + dest='TEST', + type=lib.args.csv, + ) + + parser.add_argument( + '-w', '--warning', + help='Set the warning threshold for the time since "Last Good Sync", in s. ' + 'Default: %(default)ss', + dest='WARN', + type=int, + default=DEFAULT_WARN, + ) + + return parser.parse_args() + + +def main(): + """The main function. Hier spielt die Musik. + """ + + # parse the command line, exit with UNKNOWN if it fails + try: + args = parse_args() + except SystemExit: + sys.exit(STATE_UNKNOWN) + + if args.TEST is None: + cmd = 'w32tm /query /status /verbose' + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(cmd)) # pylint: disable=W0612 + if stderr: + lib.base.cu(stderr) + else: + # do not call the command, put in test data + stdout, stderr, retc = lib.test.test(args.TEST) + + # init some vars + msg = [] + state = STATE_OK + perfdata = '' + peer_used = False + + # analyze data + for line in stdout.splitlines(): + line = line.strip() + + if line.startswith('Stratum'): + stratum = int(line.split()[1]) + peer_used = stratum != 0 + if not peer_used: + msg.append('No NTP server used {}'.format(lib.base.state2str(STATE_WARN))) + if stratum > 4: + msg.append('{} {}'.format(line, lib.base.state2str(STATE_WARN))) + state = STATE_WARN + continue + + if line.startswith('Leap Indicator'): + leap_indicator = lib.txt.extract_str(line, ': ', '(') + if line != 'Leap Indicator: 0(no warning)': + msg.append(line.replace('(', ' (')) + state = STATE_WARN + if line.startswith('Precision'): + precision = lib.txt.extract_str(line, ': ', '(').strip() + if line.startswith('Root Delay'): + root_delay = float(line.split()[-1].replace('s', '')) * 1000 # convert to ms + continue + if line.startswith('Root Dispersion'): + root_dispersion = float(line.split()[-1].replace('s', '')) * 1000 # convert to ms + continue + if line.startswith('Phase Offset'): + phase_offset = float(line.split()[-1].replace('s', '')) * 1000 # convert to ms + continue + if line.startswith('ClockRate'): + clock_rate = float(line.split()[-1].replace('s', '')) * 1000 # convert to ms + continue + if line.startswith('Last Sync Error'): + if 'Last Sync Error: 0' not in line: + msg.append(line) + state = STATE_WARN + continue + if line.startswith('Time since Last Good Sync Time'): + time_since_last_good_sync_time = float(line.split()[-1].replace('s', '')) + local_state = lib.base.get_state(time_since_last_good_sync_time, args.WARN, args.CRIT) + if local_state != STATE_OK: + msg.append('{} {}'.format(line, lib.base.state2str(STATE_WARN))) + state = lib.base.get_worst(local_state, state) + + # build the message + if state == STATE_OK: + msg.append('Everything is ok.') + + perfdata += lib.base.get_perfdata('clock_rate', clock_rate, 'ms', None, None, None, None) + perfdata += lib.base.get_perfdata('leap_indicator', leap_indicator, None, None, None, 0, None) + perfdata += lib.base.get_perfdata('phase_offset', phase_offset, 'ms', None, None, None, None) + perfdata += lib.base.get_perfdata('precision', precision, None, None, None, None, None) + perfdata += lib.base.get_perfdata('root_delay', root_delay, 'ms', None, None, None, None) + perfdata += lib.base.get_perfdata('root_dispersion', root_dispersion, 'ms', None, None, None, None) # pylint: disable=C0301 + perfdata += lib.base.get_perfdata('stratum', stratum, None, 5, None, 0, None) + perfdata += lib.base.get_perfdata('time_since_last_good_sync_time', time_since_last_good_sync_time, 's', None, None, None, None) # pylint: disable=C0301 + + # over and out + lib.base.oao(', '.join(msg) + '\n\n' + stdout, state, perfdata) + + +if __name__ == '__main__': + try: + main() + except Exception: # pylint: disable=W0703 + lib.base.cu() diff --git a/check-plugins/ntp-w32tm/unit-test/run b/check-plugins/ntp-w32tm/unit-test/run new file mode 100755 index 000000000..399952e5b --- /dev/null +++ b/check-plugins/ntp-w32tm/unit-test/run @@ -0,0 +1,253 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8; py-indent-offset: 4 -*- +# +# Author: Linuxfabrik GmbH, Zurich, Switzerland +# Contact: info (at) linuxfabrik (dot) ch +# https://www.linuxfabrik.ch/ +# License: The Unlicense, see LICENSE file. + +# https://github.com/Linuxfabrik/monitoring-plugins/blob/main/CONTRIBUTING.rst + +import sys +sys.path.append("..") # Adds higher directory to python modules path. + + + +import unittest + +from lib.globals import STATE_OK, STATE_UNKNOWN, STATE_WARN, STATE_CRIT +import lib.base +import lib.shell + + +class TestCheck(unittest.TestCase): + + check = '../ntp-w32tm' + + #self.assertEqual(retc, STATE_CRIT) + #self.assertIn('Waiting for more data (1).', stdout) + #self.assertRegex(stdout, r'1 error in Kernel Ring Buffer.') + + def test_if_check_runs_EXAMPLE01(self): + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(self.check + ' --test=stdout/EXAMPLE01,,0')) + self.assertIn('Everything is ok.', stdout) + self.assertIn('Leap Indicator: 0(no warning)', stdout) + self.assertIn('Stratum: 4 (secondary reference - syncd by (S)NTP)', stdout) + self.assertIn('Precision: -23 (119.209ns per tick)', stdout) + self.assertIn('Root Delay: 0.0296267s', stdout) + self.assertIn('Root Dispersion: 0.0448955s', stdout) + self.assertIn('ReferenceId: 0x28779426 (source IP: 40.119.148.38)', stdout) + self.assertIn('Last Successful Sync Time: 9/16/2023 12:47:56 PM', stdout) + self.assertIn('Source: time.windows.com,0x8', stdout) + self.assertIn('Poll Interval: 7 (128s)', stdout) + self.assertIn('Phase Offset: 0.0000039s', stdout) + self.assertIn('ClockRate: 0.0156250s', stdout) + self.assertIn('State Machine: 2 (Sync)', stdout) + self.assertIn('Time Source Flags: 0 (None)', stdout) + self.assertIn('Server Role: 0 (None)', stdout) + self.assertIn('Last Sync Error: 0 (The command completed successfully.)', stdout) + self.assertIn('Time since Last Good Sync Time: 7.8834592s', stdout) + self.assertEqual(stderr, '') + self.assertEqual(retc, STATE_OK) + + def test_if_check_runs_EXAMPLE02(self): + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(self.check + ' --test=stdout/EXAMPLE02,,0')) + self.assertIn('Leap Indicator: 3 (not synchronized), No NTP server used [WARNING], Last Sync Error: 1 (The computer did not resync because no time data was available.)', stdout) + self.assertIn('Leap Indicator: 3(not synchronized)', stdout) + self.assertIn('Stratum: 0 (unspecified)', stdout) + self.assertIn('Precision: -23 (119.209ns per tick)', stdout) + self.assertIn('Root Delay: 0.0267908s', stdout) + self.assertIn('Root Dispersion: 0.0402331s', stdout) + self.assertIn('ReferenceId: 0x00000000 (unspecified)', stdout) + self.assertIn('Last Successful Sync Time: 9/16/2023 12:52:13 PM', stdout) + self.assertIn('Source: time.windows.com,0x8', stdout) + self.assertIn('Poll Interval: 6 (64s)', stdout) + self.assertIn('Phase Offset: 0.7679486s', stdout) + self.assertIn('ClockRate: 0.0156250s', stdout) + self.assertIn('State Machine: 0 (Unset)', stdout) + self.assertIn('Time Source Flags: 0 (None)', stdout) + self.assertIn('Server Role: 0 (None)', stdout) + self.assertIn('Last Sync Error: 1 (The computer did not resync because no time data was available.)', stdout) + self.assertIn('Time since Last Good Sync Time: 19.2218793s', stdout) + self.assertEqual(stderr, '') + self.assertEqual(retc, STATE_WARN) + + def test_if_check_runs_EXAMPLE03(self): + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(self.check + ' --test=stdout/EXAMPLE03,,0')) + self.assertIn('Everything is ok.', stdout) + self.assertIn('Leap Indicator: 0(no warning)', stdout) + self.assertIn('Stratum: 1 (primary reference - syncd by radio clock)', stdout) + self.assertIn('Precision: -23 (119.209ns per tick)', stdout) + self.assertIn('Root Delay: 0.0003538s', stdout) + self.assertIn('Root Dispersion: 0.0100002s', stdout) + self.assertIn('ReferenceId: 0x00000000 (unspecified)', stdout) + self.assertIn('Last Successful Sync Time: 5/23/2023 7:51:39 PM', stdout) + self.assertIn('Source: VM IC Time Synchronization Provider', stdout) + self.assertIn('Poll Interval: 6 (64s)', stdout) + self.assertIn('Phase Offset: -0.0000013s', stdout) + self.assertIn('ClockRate: 0.0156250s', stdout) + self.assertIn('State Machine: 2 (Sync)', stdout) + self.assertIn('Time Source Flags: 3 (Authenticated Hardware )', stdout) + self.assertIn('Server Role: 0 (None)', stdout) + self.assertIn('Last Sync Error: 0 (The command completed successfully.)', stdout) + self.assertIn('Time since Last Good Sync Time: 15.7344985s', stdout) + self.assertEqual(stderr, '') + self.assertEqual(retc, STATE_OK) + + def test_if_check_runs_EXAMPLE04(self): + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(self.check + ' --test=stdout/EXAMPLE04,,0')) + self.assertIn('Leap Indicator: 3 (not synchronized), No NTP server used [WARNING], Last Sync Error: 1 (The computer did not resync because no time data was available.)', stdout) + self.assertIn('Leap Indicator: 3(not synchronized)', stdout) + self.assertIn('Stratum: 0 (unspecified)', stdout) + self.assertIn('Precision: -23 (119.209ns per tick)', stdout) + self.assertIn('Root Delay: 0.0000000s', stdout) + self.assertIn('Root Dispersion: 0.0000000s', stdout) + self.assertIn('ReferenceId: 0x00000000 (unspecified)', stdout) + self.assertIn('Last Successful Sync Time: unspecified', stdout) + self.assertIn('Source: Local CMOS Clock', stdout) + self.assertIn('Poll Interval: 6 (64s)', stdout) + self.assertIn('Phase Offset: 0.0000000s', stdout) + self.assertIn('ClockRate: 0.0156250s', stdout) + self.assertIn('State Machine: 0 (Unset)', stdout) + self.assertIn('Time Source Flags: 0 (None)', stdout) + self.assertIn('Server Role: 0 (None)', stdout) + self.assertIn('Last Sync Error: 1 (The computer did not resync because no time data was available.)', stdout) + self.assertIn('Time since Last Good Sync Time: 187.9314763s', stdout) + self.assertEqual(stderr, '') + self.assertEqual(retc, STATE_WARN) + + def test_if_check_runs_EXAMPLE05(self): + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(self.check + ' --test=stdout/EXAMPLE05,,0')) + self.assertIn('Leap Indicator: 3 (last minute has 61 seconds), Last Sync Error: 2 (The computer did not resync because only stale time data was available.)', stdout) + self.assertIn('Leap Indicator: 3(last minute has 61 seconds)', stdout) + self.assertIn('Stratum: 3 (secondary reference - syncd by (S)NTP)', stdout) + self.assertIn('Precision: -6 (15.625ms per tick)', stdout) + self.assertIn('Root Delay: 0.1794868s', stdout) + self.assertIn('Root Dispersion: 4.6419912s', stdout) + self.assertIn('ReferenceId: 0x41371515 (source IP: 65.55.21.21)', stdout) + self.assertIn('Last Successful Sync Time: 2011-12-05 23:25:18', stdout) + self.assertIn('Source: time.windows.com,0x9', stdout) + self.assertIn('Poll Interval: 6 (64s)', stdout) + self.assertIn('Phase Offset: 0.0000695s', stdout) + self.assertIn('ClockRate: 0.0156243s', stdout) + self.assertIn('State Machine: 1 (Hold)', stdout) + self.assertIn('Time Source Flags: 0 (None)', stdout) + self.assertIn('Server Role: 0 (None)', stdout) + self.assertIn('Last Sync Error: 2 (The computer did not resync because only stale time data was available.)', stdout) + self.assertIn('Time since Last Good Sync Time: 1281.9919104s', stdout) + self.assertEqual(stderr, '') + self.assertEqual(retc, STATE_WARN) + + def test_if_check_runs_EXAMPLE06(self): + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(self.check + ' --test=stdout/EXAMPLE06,,0')) + self.assertIn('Stratum: 5 (secondary reference - syncd by (S)NTP) [WARNING]', stdout) + self.assertIn('Leap Indicator: 0(no warning)', stdout) + self.assertIn('Stratum: 5 (secondary reference - syncd by (S)NTP)', stdout) + self.assertIn('Precision: -6 (15.625ms per tick)', stdout) + self.assertIn('Root Delay: 0.1093000s', stdout) + self.assertIn('Root Dispersion: 0.2018032s', stdout) + self.assertIn('ReferenceId: 0xABCDEFAB (source IP: n.n.n.n)', stdout) + self.assertIn('Last Successful Sync Time: 11/18/2012 2:26:21 AM', stdout) + self.assertIn('Source: DCNAME.company.com', stdout) + self.assertIn('Poll Interval: 14 (16384s)', stdout) + self.assertIn('Phase Offset: -0.0027702s', stdout) + self.assertIn('ClockRate: 0.0156001s', stdout) + self.assertIn('State Machine: 2 (Sync)', stdout) + self.assertIn('Time Source Flags: 2 (Authenticated )', stdout) + self.assertIn('Server Role: 0 (None)', stdout) + self.assertIn('Last Sync Error: 0 (The command completed successfully.)', stdout) + self.assertIn('Time since Last Good Sync Time: 10651.6021203s', stdout) + self.assertEqual(stderr, '') + self.assertEqual(retc, STATE_WARN) + + def test_if_check_runs_EXAMPLE07(self): + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(self.check + ' --test=stdout/EXAMPLE07,,0')) + self.assertIn('Everything is ok.', stdout) + self.assertIn('Leap Indicator: 0(no warning)', stdout) + self.assertIn('Stratum: 2 (secondary reference - syncd by (S)NTP)', stdout) + self.assertIn('Precision: -6 (15.625ms per tick)', stdout) + self.assertIn('Root Delay: 0.0312500s', stdout) + self.assertIn('Root Dispersion: 0.0314141s', stdout) + self.assertIn('ReferenceId: 0x81060F1E (source IP: 129.6.15.30)', stdout) + self.assertIn('Last Successful Sync Time: 3/25/2014 11:55:30 AM', stdout) + self.assertIn('Source: time-c.nist.gov', stdout) + self.assertIn('Poll Interval: 7 (128s)', stdout) + self.assertIn('Phase Offset: 0.0000667s', stdout) + self.assertIn('ClockRate: 0.0156001s', stdout) + self.assertIn('State Machine: 2 (Sync)', stdout) + self.assertIn('Time Source Flags: 0 (None)', stdout) + self.assertIn('Server Role: 64 (Time Service)', stdout) + self.assertIn('Last Sync Error: 0 (The command completed successfully.)', stdout) + self.assertIn('Time since Last Good Sync Time: 97.2535519s', stdout) + self.assertEqual(stderr, '') + self.assertEqual(retc, STATE_OK) + + def test_if_check_runs_EXAMPLE08(self): + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(self.check + ' --test=stdout/EXAMPLE08,,0')) + self.assertIn('Time since Last Good Sync Time: 38943.4367708s [WARNING]', stdout) + self.assertIn('Leap Indicator: 0(no warning)', stdout) + self.assertIn('Stratum: 4 (secondary reference - syncd by (S)NTP)', stdout) + self.assertIn('Precision: -6 (15.625ms per tick)', stdout) + self.assertIn('Root Delay: 0.0937500s', stdout) + self.assertIn('Root Dispersion: 1.0042565s', stdout) + self.assertIn('ReferenceId: 0xDEADBEEF (source IP: n.n.n.n)', stdout) + self.assertIn('Last Successful Sync Time: 10/24/2012 8:25:56 AM', stdout) + self.assertIn('Source: DCName.acmecorp.com', stdout) + self.assertIn('Poll Interval: 11 (2048s)', stdout) + self.assertIn('Phase Offset: 0.1063193s', stdout) + self.assertIn('ClockRate: 0.0156005s', stdout) + self.assertIn('State Machine: 1 (Hold)', stdout) + self.assertIn('Time Source Flags: 2 (Authenticated )', stdout) + self.assertIn('Server Role: 0 (None)', stdout) + self.assertIn('Last Sync Error: 0 (The command completed successfully.)', stdout) + self.assertIn('Time since Last Good Sync Time: 38943.4367708s', stdout) + self.assertEqual(stderr, '') + self.assertEqual(retc, STATE_WARN) + + def test_if_check_runs_EXAMPLE09(self): + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(self.check + ' --test=stdout/EXAMPLE09,,0')) + self.assertIn('Everything is ok.', stdout) + self.assertIn('Leap Indicator: 0(no warning)', stdout) + self.assertIn('Stratum: 2 (secondary reference - syncd by (S)NTP)', stdout) + self.assertIn('Precision: -6 (15.625ms per tick)', stdout) + self.assertIn('Root Delay: 0.0000000s', stdout) + self.assertIn('Root Dispersion: 0.0100000s', stdout) + self.assertIn('ReferenceId: 0x564D5450 (source IP: 86.77.84.80)', stdout) + self.assertIn('Last Successful Sync Time: 28/08/2014 08.52.00', stdout) + self.assertIn('Source: VM IC Time Synchronization Provider', stdout) + self.assertIn('Poll Interval: 6 (64s)', stdout) + self.assertIn('Phase Offset: 0.0051939s', stdout) + self.assertIn('ClockRate: 0.0156215s', stdout) + self.assertIn('State Machine: 2 (Sync)', stdout) + self.assertIn('Time Source Flags: 3 (Authenticated Hardware )', stdout) + self.assertIn('Server Role: 64 (Time Service)', stdout) + self.assertIn('Last Sync Error: 0 (The command completed successfully.)', stdout) + self.assertIn('Time since Last Good Sync Time: 3.3291425s', stdout) + self.assertEqual(stderr, '') + self.assertEqual(retc, STATE_OK) + + def test_if_check_runs_EXAMPLE10(self): + stdout, stderr, retc = lib.base.coe(lib.shell.shell_exec(self.check + ' --test=stdout/EXAMPLE10,,0')) + self.assertIn('Leap Indicator: 3 (not synchronized), No NTP server used [WARNING], Last Sync Error: 1 (The computer did not resync because no time data was available.)', stdout) + self.assertIn('Leap Indicator: 3(not synchronized)', stdout) + self.assertIn('Stratum: 0 (unspecified)', stdout) + self.assertIn('Precision: -23 (119.209ns per tick)', stdout) + self.assertIn('Root Delay: 0.0000000s', stdout) + self.assertIn('Root Dispersion: 0.0000000s', stdout) + self.assertIn('ReferenceId: 0x00000000 (unspecified)', stdout) + self.assertIn('Last Successful Sync Time: unspecified', stdout) + self.assertIn('Source: Local CMOS Clock', stdout) + self.assertIn('Poll Interval: 10 (1024s)', stdout) + self.assertIn('Phase Offset: 0.0000000s', stdout) + self.assertIn('ClockRate: 0.0156250s', stdout) + self.assertIn('State Machine: 0 (Unset)', stdout) + self.assertIn('Time Source Flags: 0 (None)', stdout) + self.assertIn('Server Role: 0 (None)', stdout) + self.assertIn('Last Sync Error: 1 (The computer did not resync because no time data was available.)', stdout) + self.assertIn('Time since Last Good Sync Time: 19.4881785s', stdout) + self.assertEqual(stderr, '') + self.assertEqual(retc, STATE_WARN) + + +if __name__ == '__main__': + unittest.main() diff --git a/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE01 b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE01 new file mode 100644 index 000000000..c3570f4ea --- /dev/null +++ b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE01 @@ -0,0 +1,17 @@ +Leap Indicator: 0(no warning) +Stratum: 4 (secondary reference - syncd by (S)NTP) +Precision: -23 (119.209ns per tick) +Root Delay: 0.0296267s +Root Dispersion: 0.0448955s +ReferenceId: 0x28779426 (source IP: 40.119.148.38) +Last Successful Sync Time: 9/16/2023 12:47:56 PM +Source: time.windows.com,0x8 +Poll Interval: 7 (128s) + +Phase Offset: 0.0000039s +ClockRate: 0.0156250s +State Machine: 2 (Sync) +Time Source Flags: 0 (None) +Server Role: 0 (None) +Last Sync Error: 0 (The command completed successfully.) +Time since Last Good Sync Time: 7.8834592s diff --git a/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE02 b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE02 new file mode 100644 index 000000000..b94a08cfe --- /dev/null +++ b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE02 @@ -0,0 +1,17 @@ +Leap Indicator: 3(not synchronized) +Stratum: 0 (unspecified) +Precision: -23 (119.209ns per tick) +Root Delay: 0.0267908s +Root Dispersion: 0.0402331s +ReferenceId: 0x00000000 (unspecified) +Last Successful Sync Time: 9/16/2023 12:52:13 PM +Source: time.windows.com,0x8 +Poll Interval: 6 (64s) + +Phase Offset: 0.7679486s +ClockRate: 0.0156250s +State Machine: 0 (Unset) +Time Source Flags: 0 (None) +Server Role: 0 (None) +Last Sync Error: 1 (The computer did not resync because no time data was available.) +Time since Last Good Sync Time: 19.2218793s diff --git a/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE03 b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE03 new file mode 100644 index 000000000..55055b100 --- /dev/null +++ b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE03 @@ -0,0 +1,17 @@ +Leap Indicator: 0(no warning) +Stratum: 1 (primary reference - syncd by radio clock) +Precision: -23 (119.209ns per tick) +Root Delay: 0.0003538s +Root Dispersion: 0.0100002s +ReferenceId: 0x00000000 (unspecified) +Last Successful Sync Time: 5/23/2023 7:51:39 PM +Source: VM IC Time Synchronization Provider +Poll Interval: 6 (64s) + +Phase Offset: -0.0000013s +ClockRate: 0.0156250s +State Machine: 2 (Sync) +Time Source Flags: 3 (Authenticated Hardware ) +Server Role: 0 (None) +Last Sync Error: 0 (The command completed successfully.) +Time since Last Good Sync Time: 15.7344985s diff --git a/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE04 b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE04 new file mode 100644 index 000000000..03a4027a3 --- /dev/null +++ b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE04 @@ -0,0 +1,17 @@ +Leap Indicator: 3(not synchronized) +Stratum: 0 (unspecified) +Precision: -23 (119.209ns per tick) +Root Delay: 0.0000000s +Root Dispersion: 0.0000000s +ReferenceId: 0x00000000 (unspecified) +Last Successful Sync Time: unspecified +Source: Local CMOS Clock +Poll Interval: 6 (64s) + +Phase Offset: 0.0000000s +ClockRate: 0.0156250s +State Machine: 0 (Unset) +Time Source Flags: 0 (None) +Server Role: 0 (None) +Last Sync Error: 1 (The computer did not resync because no time data was available.) +Time since Last Good Sync Time: 187.9314763s diff --git a/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE05 b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE05 new file mode 100644 index 000000000..2ddb363d8 --- /dev/null +++ b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE05 @@ -0,0 +1,17 @@ +Leap Indicator: 3(last minute has 61 seconds) +Stratum: 3 (secondary reference - syncd by (S)NTP) +Precision: -6 (15.625ms per tick) +Root Delay: 0.1794868s +Root Dispersion: 4.6419912s +ReferenceId: 0x41371515 (source IP: 65.55.21.21) +Last Successful Sync Time: 2011-12-05 23:25:18 +Source: time.windows.com,0x9 +Poll Interval: 6 (64s) + +Phase Offset: 0.0000695s +ClockRate: 0.0156243s +State Machine: 1 (Hold) +Time Source Flags: 0 (None) +Server Role: 0 (None) +Last Sync Error: 2 (The computer did not resync because only stale time data was available.) +Time since Last Good Sync Time: 1281.9919104s diff --git a/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE06 b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE06 new file mode 100644 index 000000000..bd8f0c986 --- /dev/null +++ b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE06 @@ -0,0 +1,17 @@ +Leap Indicator: 0(no warning) +Stratum: 5 (secondary reference - syncd by (S)NTP) +Precision: -6 (15.625ms per tick) +Root Delay: 0.1093000s +Root Dispersion: 0.2018032s +ReferenceId: 0xABCDEFAB (source IP: n.n.n.n) +Last Successful Sync Time: 11/18/2012 2:26:21 AM +Source: DCNAME.company.com +Poll Interval: 14 (16384s) + +Phase Offset: -0.0027702s +ClockRate: 0.0156001s +State Machine: 2 (Sync) +Time Source Flags: 2 (Authenticated ) +Server Role: 0 (None) +Last Sync Error: 0 (The command completed successfully.) +Time since Last Good Sync Time: 10651.6021203s diff --git a/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE07 b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE07 new file mode 100644 index 000000000..7cdbd2bff --- /dev/null +++ b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE07 @@ -0,0 +1,17 @@ +Leap Indicator: 0(no warning) +Stratum: 2 (secondary reference - syncd by (S)NTP) +Precision: -6 (15.625ms per tick) +Root Delay: 0.0312500s +Root Dispersion: 0.0314141s +ReferenceId: 0x81060F1E (source IP: 129.6.15.30) +Last Successful Sync Time: 3/25/2014 11:55:30 AM +Source: time-c.nist.gov +Poll Interval: 7 (128s) + +Phase Offset: 0.0000667s +ClockRate: 0.0156001s +State Machine: 2 (Sync) +Time Source Flags: 0 (None) +Server Role: 64 (Time Service) +Last Sync Error: 0 (The command completed successfully.) +Time since Last Good Sync Time: 97.2535519s diff --git a/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE08 b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE08 new file mode 100644 index 000000000..fbf6e0186 --- /dev/null +++ b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE08 @@ -0,0 +1,17 @@ +Leap Indicator: 0(no warning) +Stratum: 4 (secondary reference - syncd by (S)NTP) +Precision: -6 (15.625ms per tick) +Root Delay: 0.0937500s +Root Dispersion: 1.0042565s +ReferenceId: 0xDEADBEEF (source IP: n.n.n.n) +Last Successful Sync Time: 10/24/2012 8:25:56 AM +Source: DCName.acmecorp.com +Poll Interval: 11 (2048s) + +Phase Offset: 0.1063193s +ClockRate: 0.0156005s +State Machine: 1 (Hold) +Time Source Flags: 2 (Authenticated ) +Server Role: 0 (None) +Last Sync Error: 0 (The command completed successfully.) +Time since Last Good Sync Time: 38943.4367708s diff --git a/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE09 b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE09 new file mode 100644 index 000000000..cc4ef9f20 --- /dev/null +++ b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE09 @@ -0,0 +1,17 @@ +Leap Indicator: 0(no warning) +Stratum: 2 (secondary reference - syncd by (S)NTP) +Precision: -6 (15.625ms per tick) +Root Delay: 0.0000000s +Root Dispersion: 0.0100000s +ReferenceId: 0x564D5450 (source IP: 86.77.84.80) +Last Successful Sync Time: 28/08/2014 08.52.00 +Source: VM IC Time Synchronization Provider +Poll Interval: 6 (64s) + +Phase Offset: 0.0051939s +ClockRate: 0.0156215s +State Machine: 2 (Sync) +Time Source Flags: 3 (Authenticated Hardware ) +Server Role: 64 (Time Service) +Last Sync Error: 0 (The command completed successfully.) +Time since Last Good Sync Time: 3.3291425s \ No newline at end of file diff --git a/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE10 b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE10 new file mode 100644 index 000000000..f10ceed2b --- /dev/null +++ b/check-plugins/ntp-w32tm/unit-test/stdout/EXAMPLE10 @@ -0,0 +1,17 @@ +Leap Indicator: 3(not synchronized) +Stratum: 0 (unspecified) +Precision: -23 (119.209ns per tick) +Root Delay: 0.0000000s +Root Dispersion: 0.0000000s +ReferenceId: 0x00000000 (unspecified) +Last Successful Sync Time: unspecified +Source: Local CMOS Clock +Poll Interval: 10 (1024s) + +Phase Offset: 0.0000000s +ClockRate: 0.0156250s +State Machine: 0 (Unset) +Time Source Flags: 0 (None) +Server Role: 0 (None) +Last Sync Error: 1 (The computer did not resync because no time data was available.) +Time since Last Good Sync Time: 19.4881785s \ No newline at end of file