From fffe427497a6227cc1074d73afe2d06466dcc70d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= Date: Wed, 27 Nov 2024 20:12:12 +0100 Subject: [PATCH] Implement NTP client status --- src/confd/yang/confd.inc | 2 +- src/confd/yang/infix-system.yang | 77 +++++++++++++++++++ ...9-13.yang => infix-system@2024-11-27.yang} | 0 src/statd/python/yanger/yanger.py | 36 +++++++++ src/statd/statd.c | 3 + 5 files changed, 117 insertions(+), 1 deletion(-) rename src/confd/yang/{infix-system@2024-09-13.yang => infix-system@2024-11-27.yang} (100%) diff --git a/src/confd/yang/confd.inc b/src/confd/yang/confd.inc index 96573e99..f626676a 100644 --- a/src/confd/yang/confd.inc +++ b/src/confd/yang/confd.inc @@ -32,7 +32,7 @@ MODULES=( "infix-lldp@2023-08-23.yang" "infix-dhcp-client@2024-09-20.yang" "infix-meta@2024-10-18.yang" - "infix-system@2024-09-13.yang" + "infix-system@2024-11-27.yang" "infix-services@2024-05-30.yang" "ieee802-ethernet-interface@2019-06-21.yang" "infix-ethernet-interface@2024-02-27.yang" diff --git a/src/confd/yang/infix-system.yang b/src/confd/yang/infix-system.yang index 2627ea45..393f4052 100644 --- a/src/confd/yang/infix-system.yang +++ b/src/confd/yang/infix-system.yang @@ -10,12 +10,22 @@ module infix-system { prefix iana-tz; } + import ietf-inet-types { + prefix inet; + reference + "RFC 6991: Common YANG Data Types"; + } + include infix-system-software; organization "KernelKit"; contact "kernelkit@googlegroups.com"; description "Infix augments and deviations to ietf-system."; + revision 2024-11-27 { + description "Add NTP status"; + reference "internal"; + } revision 2024-09-13 { description "Add some informative help about different shells and security."; reference "internal"; @@ -115,6 +125,42 @@ module infix-system { base shell-type; } + typedef source-state { + reference "rfc5905: Network Time Protocol Version 4: Protocol and Algorithms Specification"; + type enumeration { + enum selected { + description "Selected NTP server for synchronization"; + } + enum candidate { + description "Valid for synchronization, is used together with thes elected best server and also acting as backup"; + } + enum outlier { + description "Valid timesource but discarded by the clustering algorithm"; + } + enum unusable { + description "Unreachable or unresponsable"; + } + enum falseticker { + description "suspected of providing incorrect time"; + } + enum unstable { + description "Too variable or unstable source"; + } + } + } + typedef source-mode { + type enumeration { + enum server { + description "Normal NTP server"; + } + enum peer { + description "Symmetric peer"; + } + enum local-clock { + description "Reference clock"; + } + } +} /* * Typedefs */ @@ -256,6 +302,37 @@ module infix-system { } } + augment "/sys:system-state" { + container ntp { + description "NTP status"; + container sources { + list source { + key address; + leaf address { + type inet:ip-address; + description "Address to NTP server"; + } + leaf mode { + type source-mode; + description "Source mode"; + } + leaf state { + type source-state; + description "Source state"; + } + leaf stratum { + type uint8; + description "Stratum of NTP server"; + } + leaf poll { + type uint8; + description "Interval between transmitted NTP messages, expressed as a power of two in seconds"; + } + + } + } + } + } deviation "/sys:system/sys:hostname" { deviate replace { type infix-sys:hostname; diff --git a/src/confd/yang/infix-system@2024-09-13.yang b/src/confd/yang/infix-system@2024-11-27.yang similarity index 100% rename from src/confd/yang/infix-system@2024-09-13.yang rename to src/confd/yang/infix-system@2024-11-27.yang diff --git a/src/statd/python/yanger/yanger.py b/src/statd/python/yanger/yanger.py index 53bffca5..487a4bcc 100755 --- a/src/statd/python/yanger/yanger.py +++ b/src/statd/python/yanger/yanger.py @@ -1053,6 +1053,36 @@ def add_interface(ifname, yang_ifaces): add_container_ifaces(yang_ifaces) +def add_system_ntp(out): + data = run_cmd(["chronyc", "-c", "sources"], "chronyc-sources.txt", "") + source = [] + state_mode_map = { + "^": "server", + "=": "peer", + "#": "local-clock" + } + source_state_map = { + "*": "selected", + "+": "candidate", + "-": "outlier", + "?": "unusable", + "x": "falseticker", + "~": "unstable" + } + for line in data: + src = {} + line = line.split(',') + src["address"] = line[2] + src["source-mode"] = state_mode_map[line[0]] + src["source-state"] = source_state_map[line[1]] + src["stratum"] = int(line[3]) + src["poll"] = int(line[4]) + source.append(src) + + insert(out, "infix-system:ntp", "sources", "source", source) +def add_system(yang_data): + add_system_ntp(yang_data) + def main(): global TESTPATH global logger @@ -1133,6 +1163,12 @@ def main(): } add_container(yang_data['infix-containers:containers']['container']) + elif args.model == 'ietf-system': + yang_data = { + "ietf-system:system-state": { + } + } + add_system(yang_data['ietf-system:system-state']) else: logger.warning(f"Unsupported model {args.model}", file=sys.stderr) sys.exit(1) diff --git a/src/statd/statd.c b/src/statd/statd.c index 099380ce..3c194e6c 100644 --- a/src/statd/statd.c +++ b/src/statd/statd.c @@ -37,6 +37,7 @@ #define XPATH_ROUTING_BASE "/ietf-routing:routing/control-plane-protocols/control-plane-protocol" #define XPATH_ROUTING_TABLE "/ietf-routing:routing/ribs" #define XPATH_HARDWARE_BASE "/ietf-hardware:hardware" +#define XPATH_SYSTEM_BASE "/ietf-system:system-state" #define XPATH_ROUTING_OSPF XPATH_ROUTING_BASE "/ospf" #define XPATH_CONTAIN_BASE "/infix-containers:containers" @@ -340,6 +341,8 @@ static int subscribe_to_all(struct statd *statd) return SR_ERR_INTERNAL; if (subscribe(statd, "ietf-hardware", XPATH_HARDWARE_BASE, sr_generic_cb)) return SR_ERR_INTERNAL; + if (subscribe(statd, "ietf-system", XPATH_SYSTEM_BASE, sr_generic_cb)) + return SR_ERR_INTERNAL; #ifdef CONTAINERS if (subscribe(statd, "infix-containers", XPATH_CONTAIN_BASE, sr_generic_cb)) return SR_ERR_INTERNAL;