summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Fort <nicolasfort1988@gmail.com>2023-07-06 17:40:37 +0000
committerNicolas Fort <nicolasfort1988@gmail.com>2023-07-25 09:35:52 +0000
commit5f2e9cb81d89a5cfecbac01bec054b3ba4e8dff5 (patch)
tree3c8a963489ad77e35b7c30be55145f0980c0f7ed
parente8ff7aa564b03c6338b2c053f3c24a08fd2cf323 (diff)
downloadvyos-1x-5f2e9cb81d89a5cfecbac01bec054b3ba4e8dff5.tar.gz
vyos-1x-5f2e9cb81d89a5cfecbac01bec054b3ba4e8dff5.zip
T5154: NTP: allow maximum of one ipv4 and one ipv6 address on parameter <listen-address>. Also allow only one single value <interface>.
-rw-r--r--data/templates/chrony/chrony.conf.j24
-rw-r--r--interface-definitions/include/version/ntp-version.xml.i2
-rw-r--r--interface-definitions/ntp.xml.in2
-rwxr-xr-xsmoketest/scripts/cli/test_service_ntp.py2
-rwxr-xr-xsrc/conf_mode/ntp.py34
-rwxr-xr-xsrc/migration-scripts/ntp/2-to-362
6 files changed, 90 insertions, 16 deletions
diff --git a/data/templates/chrony/chrony.conf.j2 b/data/templates/chrony/chrony.conf.j2
index 7a36fe69d..0daec8fb8 100644
--- a/data/templates/chrony/chrony.conf.j2
+++ b/data/templates/chrony/chrony.conf.j2
@@ -53,8 +53,6 @@ bindaddress {{ address }}
{% endfor %}
{% endif %}
{% if interface is vyos_defined %}
-{% for ifname in interface %}
-binddevice {{ ifname }}
-{% endfor %}
+binddevice {{ interface }}
{% endif %}
{% endif %}
diff --git a/interface-definitions/include/version/ntp-version.xml.i b/interface-definitions/include/version/ntp-version.xml.i
index 9eafbf7f0..155c824dc 100644
--- a/interface-definitions/include/version/ntp-version.xml.i
+++ b/interface-definitions/include/version/ntp-version.xml.i
@@ -1,3 +1,3 @@
<!-- include start from include/version/ntp-version.xml.i -->
-<syntaxVersion component='ntp' version='2'></syntaxVersion>
+<syntaxVersion component='ntp' version='3'></syntaxVersion>
<!-- include end -->
diff --git a/interface-definitions/ntp.xml.in b/interface-definitions/ntp.xml.in
index 2275dd61c..4e874434b 100644
--- a/interface-definitions/ntp.xml.in
+++ b/interface-definitions/ntp.xml.in
@@ -57,7 +57,7 @@
</children>
</tagNode>
#include <include/allow-client.xml.i>
- #include <include/generic-interface-multi.xml.i>
+ #include <include/generic-interface.xml.i>
#include <include/listen-address.xml.i>
#include <include/interface/vrf.xml.i>
</children>
diff --git a/smoketest/scripts/cli/test_service_ntp.py b/smoketest/scripts/cli/test_service_ntp.py
index 046e5eea6..47e012913 100755
--- a/smoketest/scripts/cli/test_service_ntp.py
+++ b/smoketest/scripts/cli/test_service_ntp.py
@@ -108,7 +108,7 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase):
self.assertIn(f'bindaddress {listen}', config)
def test_03_ntp_interface(self):
- interfaces = ['eth0', 'eth1']
+ interfaces = ['eth0']
for interface in interfaces:
self.cli_set(base_path + ['interface', interface])
diff --git a/src/conf_mode/ntp.py b/src/conf_mode/ntp.py
index 92cb73aab..95766c44c 100755
--- a/src/conf_mode/ntp.py
+++ b/src/conf_mode/ntp.py
@@ -24,6 +24,7 @@ from vyos.util import call
from vyos.util import chmod_750
from vyos.util import get_interface_config
from vyos.template import render
+from vyos.template import is_ipv4
from vyos import ConfigError
from vyos import airbag
airbag.enable()
@@ -62,16 +63,29 @@ def verify(ntp):
if 'interface' in ntp:
# If ntpd should listen on a given interface, ensure it exists
- for interface in ntp['interface']:
- verify_interface_exists(interface)
-
- # If we run in a VRF, our interface must belong to this VRF, too
- if 'vrf' in ntp:
- tmp = get_interface_config(interface)
- vrf_name = ntp['vrf']
- if 'master' not in tmp or tmp['master'] != vrf_name:
- raise ConfigError(f'NTP runs in VRF "{vrf_name}" - "{interface}" '\
- f'does not belong to this VRF!')
+ interface = ntp['interface']
+ verify_interface_exists(interface)
+
+ # If we run in a VRF, our interface must belong to this VRF, too
+ if 'vrf' in ntp:
+ tmp = get_interface_config(interface)
+ vrf_name = ntp['vrf']
+ if 'master' not in tmp or tmp['master'] != vrf_name:
+ raise ConfigError(f'NTP runs in VRF "{vrf_name}" - "{interface}" '\
+ f'does not belong to this VRF!')
+
+ if 'listen_address' in ntp:
+ ipv4_addresses = 0
+ ipv6_addresses = 0
+ for address in ntp['listen_address']:
+ if is_ipv4(address):
+ ipv4_addresses += 1
+ else:
+ ipv6_addresses += 1
+ if ipv4_addresses > 1:
+ raise ConfigError(f'NTP Only admits one ipv4 value for listen-address parameter ')
+ if ipv6_addresses > 1:
+ raise ConfigError(f'NTP Only admits one ipv6 value for listen-address parameter ')
return None
diff --git a/src/migration-scripts/ntp/2-to-3 b/src/migration-scripts/ntp/2-to-3
new file mode 100755
index 000000000..7d4e0bd83
--- /dev/null
+++ b/src/migration-scripts/ntp/2-to-3
@@ -0,0 +1,62 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2023 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/>.
+
+# T5154: allow only one ip address per family for parameter 'listen-address'
+# Allow only one interface for parameter 'interface'
+# If more than one are specified, remove such entries
+
+import sys
+
+from vyos.configtree import ConfigTree
+from vyos.template import is_ipv4
+from vyos.template import is_ipv6
+
+if (len(sys.argv) < 1):
+ print("Must specify file name!")
+ sys.exit(1)
+
+file_name = sys.argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+config = ConfigTree(config_file)
+
+base_path = ['service', 'ntp']
+if not config.exists(base_path):
+ # Nothing to do
+ sys.exit(0)
+
+if config.exists(base_path + ['listen-address']) and (len([addr for addr in config.return_values(base_path + ['listen-address']) if is_ipv4(addr)]) > 1):
+ for addr in config.return_values(base_path + ['listen-address']):
+ if is_ipv4(addr):
+ config.delete_value(base_path + ['listen-address'], addr)
+
+if config.exists(base_path + ['listen-address']) and (len([addr for addr in config.return_values(base_path + ['listen-address']) if is_ipv6(addr)]) > 1):
+ for addr in config.return_values(base_path + ['listen-address']):
+ if is_ipv6(addr):
+ config.delete_value(base_path + ['listen-address'], addr)
+
+if config.exists(base_path + ['interface']):
+ if len(config.return_values(base_path + ['interface'])) > 1:
+ config.delete(base_path + ['interface'])
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print("Failed to save the modified config: {}".format(e))
+ sys.exit(1)