diff options
| author | Christian Breunig <christian@breunig.cc> | 2026-05-21 17:43:49 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-05-21 17:43:49 +0200 |
| commit | 6fa4967f49e988e4979c611ee9199bb14bef8536 (patch) | |
| tree | c66f4301450037fae9efdb29db61a9a6097c6ff4 | |
| parent | 036c1dc949815fddd71c03b09f579623b5b76bff (diff) | |
| parent | 7c4d75017464d01b6fe293eea031ad8a0418c8ee (diff) | |
| download | vyos-1x-6fa4967f49e988e4979c611ee9199bb14bef8536.tar.gz vyos-1x-6fa4967f49e988e4979c611ee9199bb14bef8536.zip | |
Merge pull request #5166 from anderbak/t8601-ntp-local-stratum
ntp: T8601: add local stratum option
| -rw-r--r-- | data/templates/chrony/chrony.conf.j2 | 5 | ||||
| -rw-r--r-- | interface-definitions/service_ntp.xml.in | 12 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_service_ntp.py | 43 | ||||
| -rwxr-xr-x | src/conf_mode/service_ntp.py | 3 |
4 files changed, 38 insertions, 25 deletions
diff --git a/data/templates/chrony/chrony.conf.j2 b/data/templates/chrony/chrony.conf.j2 index cc80e4d64..23b452f01 100644 --- a/data/templates/chrony/chrony.conf.j2 +++ b/data/templates/chrony/chrony.conf.j2 @@ -46,6 +46,11 @@ user {{ user }} {% endfor %} {% endif %} +{% if local_stratum is vyos_defined %} +# Enable local reference mode +local stratum {{ local_stratum }} +{% endif %} + # Allowed clients configuration {% if allow_client.address is vyos_defined %} {% for address in allow_client.address %} diff --git a/interface-definitions/service_ntp.xml.in b/interface-definitions/service_ntp.xml.in index c31b572bd..ebce1bbf4 100644 --- a/interface-definitions/service_ntp.xml.in +++ b/interface-definitions/service_ntp.xml.in @@ -109,6 +109,18 @@ </properties> <defaultValue>timezone</defaultValue> </leafNode> + <leafNode name="local-stratum"> + <properties> + <help>Local reference stratum</help> + <valueHelp> + <format>u32:1-15</format> + <description>Local reference stratum</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 1-15"/> + </constraint> + </properties> + </leafNode> <tagNode name="server"> <properties> <help>Network Time Protocol (NTP) server</help> diff --git a/smoketest/scripts/cli/test_service_ntp.py b/smoketest/scripts/cli/test_service_ntp.py index 6488182f3..deeae4708 100755 --- a/smoketest/scripts/cli/test_service_ntp.py +++ b/smoketest/scripts/cli/test_service_ntp.py @@ -19,6 +19,7 @@ import unittest from base_vyostest_shim import VyOSUnitTestSHIM from vyos.configsession import ConfigSessionError +from vyos.utils.file import read_file from vyos.utils.process import cmd from vyos.utils.process import process_named_running from vyos.xml_ref import default_value @@ -64,7 +65,7 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase): # Check generated configuration # this file must be read with higher permissions - config = cmd(f'sudo cat {NTP_CONF}') + config = read_file(NTP_CONF, sudo=True) self.assertIn('driftfile /run/chrony/drift', config) self.assertIn('dumpdir /run/chrony', config) self.assertIn('ntsdumpdir /run/chrony', config) @@ -79,6 +80,18 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase): for pool in pools: self.assertIn(f'pool {pool} iburst', config) + def test_local_stratum_without_upstream_server(self): + stratum = '10' + network = '192.0.2.0/24' + + self.cli_set(base_path + ['local-stratum', stratum]) + self.cli_set(base_path + ['allow-client', 'address', network]) + self.cli_commit() + + config = read_file(NTP_CONF, sudo=True) + self.assertIn(f'local stratum {stratum}', config) + self.assertIn(f'allow {network}', config) + def test_clients(self): # Test the allowed-networks statement listen_address = ['127.0.0.1', '::1'] @@ -89,19 +102,10 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase): for network in networks: self.cli_set(base_path + ['allow-client', 'address', network]) - # Verify "NTP server not configured" verify() statement - with self.assertRaises(ConfigSessionError): - self.cli_commit() - - servers = ['192.0.2.1', '192.0.2.2'] - for server in servers: - self.cli_set(base_path + ['server', server]) - self.cli_commit() # Check generated client address configuration - # this file must be read with higher permissions - config = cmd(f'sudo cat {NTP_CONF}') + config = read_file(NTP_CONF, sudo=True) for network in networks: self.assertIn(f'allow {network}', config) @@ -121,8 +125,7 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase): self.cli_commit() # Check generated client address configuration - # this file must be read with higher permissions - config = cmd(f'sudo cat {NTP_CONF}') + config = read_file(NTP_CONF, sudo=True) for interface in interfaces: self.assertIn(f'binddevice {interface}', config) @@ -152,14 +155,13 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase): self.cli_commit() # Check generated client address configuration - # this file must be read with higher permissions - config = cmd(f'sudo cat {NTP_CONF}') + config = read_file(NTP_CONF, sudo=True) self.assertIn('leapsectz right/UTC', config) # CLI default for mode in ['ignore', 'system', 'smear']: self.cli_set(base_path + ['leap-second', mode]) self.cli_commit() - config = cmd(f'sudo cat {NTP_CONF}') + config = read_file(NTP_CONF, sudo=True) if mode != 'smear': self.assertIn(f'leapsecmode {mode}', config) else: @@ -182,8 +184,7 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase): self.cli_commit() # Check generated configuration - # this file must be read with higher permissions - config = cmd(f'sudo cat {NTP_CONF}') + config = read_file(NTP_CONF, sudo=True) self.assertIn('driftfile /run/chrony/drift', config) self.assertIn('dumpdir /run/chrony', config) self.assertIn('ntsdumpdir /run/chrony', config) @@ -210,8 +211,7 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase): self.cli_commit() # Check generated configuration - # this file must be read with higher permissions - config = cmd(f'sudo cat {NTP_CONF}') + config = read_file(NTP_CONF, sudo=True) self.assertIn('driftfile /run/chrony/drift', config) self.assertIn('dumpdir /run/chrony', config) self.assertIn('ntsdumpdir /run/chrony', config) @@ -246,8 +246,7 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase): self.cli_commit() # Check generated configuration - # this file must be read with higher permissions - config = cmd(f'sudo cat {NTP_CONF}') + config = read_file(NTP_CONF, sudo=True) self.assertIn('driftfile /run/chrony/drift', config) self.assertIn('dumpdir /run/chrony', config) self.assertIn('ntsdumpdir /run/chrony', config) diff --git a/src/conf_mode/service_ntp.py b/src/conf_mode/service_ntp.py index 38e0df079..e734eeb76 100755 --- a/src/conf_mode/service_ntp.py +++ b/src/conf_mode/service_ntp.py @@ -66,9 +66,6 @@ def verify(ntp): if not ntp: return None - if 'server' not in ntp: - raise ConfigError('NTP server not configured') - verify_vrf(ntp) if 'interface' in ntp: |
