diff options
author | Daniil Baturin <daniil@vyos.io> | 2024-05-02 12:58:54 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-02 12:58:54 +0200 |
commit | 44008b19c5e8547521908b0df04f75215fb3fb79 (patch) | |
tree | db3a76b73c875de5b49014b9384d9435dc66b377 | |
parent | e019155e3d7a1383f480f2bdf4c7e17d807fc7db (diff) | |
parent | e2f0643d7b2a5b7f2f4774965c897b50b2427715 (diff) | |
download | vyos-1x-44008b19c5e8547521908b0df04f75215fb3fb79.tar.gz vyos-1x-44008b19c5e8547521908b0df04f75215fb3fb79.zip |
Merge pull request #3395 from vyos/mergify/bp/sagitta/pr-3307
ntp: T4909 rewrite NTP op mode in the new format (backport #3307)
-rw-r--r-- | op-mode-definitions/ntp.xml.in | 16 | ||||
-rw-r--r-- | src/op_mode/ntp.py | 164 |
2 files changed, 178 insertions, 2 deletions
diff --git a/op-mode-definitions/ntp.xml.in b/op-mode-definitions/ntp.xml.in index b8d0c43ec..17250a45e 100644 --- a/op-mode-definitions/ntp.xml.in +++ b/op-mode-definitions/ntp.xml.in @@ -6,13 +6,25 @@ <properties> <help>Show peer status of NTP daemon</help> </properties> - <command>${vyos_op_scripts_dir}/show_ntp.sh --sourcestats</command> + <command>${vyos_op_scripts_dir}/ntp.py show_sourcestats</command> <children> + <node name="activity"> + <properties> + <help>Report the number of servers and peers that are online and offline</help> + </properties> + <command>${vyos_op_scripts_dir}/ntp.py show_activity</command> + </node> + <node name="sources"> + <properties> + <help>Show information about the current time sources being accessed</help> + </properties> + <command>${vyos_op_scripts_dir}/ntp.py show_sources</command> + </node> <node name="system"> <properties> <help>Show parameters about the system clock performance</help> </properties> - <command>${vyos_op_scripts_dir}/show_ntp.sh --tracking</command> + <command>${vyos_op_scripts_dir}/ntp.py show_tracking</command> </node> </children> </node> diff --git a/src/op_mode/ntp.py b/src/op_mode/ntp.py new file mode 100644 index 000000000..e14cc46d0 --- /dev/null +++ b/src/op_mode/ntp.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2024 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import csv +import sys +from itertools import chain + +import vyos.opmode +from vyos.configquery import ConfigTreeQuery +from vyos.utils.process import cmd + +def _get_raw_data(command: str) -> dict: + # Returns returns chronyc output as a dictionary + + # Initialize dictionary keys to align with output of + # chrony -c. From some commands, its -c switch outputs + # more parameters, make sure to include them all below. + # See to chronyc(1) for definition of key variables + match command: + case "chronyc -c activity": + keys: list = [ + 'sources_online', + 'sources_offline', + 'sources_doing_burst_return_online', + 'sources_doing_burst_return_offline', + 'sources_with_unknown_address' + ] + + case "chronyc -c sources": + keys: list = [ + 'm', + 's', + 'name_ip_address', + 'stratum', + 'poll', + 'reach', + 'last_rx', + 'last_sample_adj_offset', + 'last_sample_mes_offset', + 'last_sample_est_error' + ] + + case "chronyc -c sourcestats": + keys: list = [ + 'name_ip_address', + 'np', + 'nr', + 'span', + 'frequency', + 'freq_skew', + 'offset', + 'std_dev' + ] + + case "chronyc -c tracking": + keys: list = [ + 'ref_id', + 'ref_id_name', + 'stratum', + 'ref_time', + 'system_time', + 'last_offset', + 'rms_offset', + 'frequency', + 'residual_freq', + 'skew', + 'root_delay', + 'root_dispersion', + 'update_interval', + 'leap_status' + ] + + case _: + raise ValueError(f"Raw mode: of {command} is not implemented") + + # Get -c option command line output, splitlines, + # and save comma-separated values as a flat list + output = cmd(command).splitlines() + values = csv.reader(output) + values = list(chain.from_iterable(values)) + + # Divide values into chunks of size keys and transpose + if len(values) > len(keys): + values = _chunk_list(values,keys) + values = zip(*values) + + return dict(zip(keys, values)) + +def _chunk_list(in_list, n): + # Yields successive n-sized chunks from in_list + for i in range(0, len(in_list), len(n)): + yield in_list[i:i + len(n)] + +def _is_configured(): + # Check if ntp is configured + config = ConfigTreeQuery() + if not config.exists("service ntp"): + raise vyos.opmode.UnconfiguredSubsystem("NTP service is not enabled.") + +def show_activity(raw: bool): + _is_configured() + command = f'chronyc' + + if raw: + command += f" -c activity" + return _get_raw_data(command) + else: + command += f" activity" + return cmd(command) + +def show_sources(raw: bool): + _is_configured() + command = f'chronyc' + + if raw: + command += f" -c sources" + return _get_raw_data(command) + else: + command += f" sources -v" + return cmd(command) + +def show_tracking(raw: bool): + _is_configured() + command = f'chronyc' + + if raw: + command += f" -c tracking" + return _get_raw_data(command) + else: + command += f" tracking" + return cmd(command) + +def show_sourcestats(raw: bool): + _is_configured() + command = f'chronyc' + + if raw: + command += f" -c sourcestats" + return _get_raw_data(command) + else: + command += f" sourcestats -v" + return cmd(command) + +if __name__ == '__main__': + try: + res = vyos.opmode.run(sys.modules[__name__]) + if res: + print(res) + except (ValueError, vyos.opmode.Error) as e: + print(e) + sys.exit(1) |