summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--python/vyos/config.py57
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_bonding.py22
-rwxr-xr-xsmoketest/scripts/cli/test_service_salt.py94
-rwxr-xr-xsrc/conf_mode/salt-minion.py2
-rw-r--r--src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper2
5 files changed, 162 insertions, 15 deletions
diff --git a/python/vyos/config.py b/python/vyos/config.py
index a5c1ad122..287fd2ed1 100644
--- a/python/vyos/config.py
+++ b/python/vyos/config.py
@@ -142,31 +142,41 @@ class Config(object):
def exists(self, path):
"""
- Checks if a node with given path exists in the running or proposed config
+ Checks if a node or value with given path exists in the proposed config.
+
+ Args:
+ path (str): Configuration tree path
Returns:
- True if node exists, False otherwise
+ True if node or value exists in the proposed config, False otherwise
Note:
- This function cannot be used outside a configuration sessions.
+ This function should not be used outside of configuration sessions.
In operational mode scripts, use ``exists_effective``.
"""
- if not self._session_config:
+ if self._session_config is None:
return False
+
+ # Assume the path is a node path first
if self._session_config.exists(self._make_path(path)):
return True
else:
+ # If that check fails, it may mean the path has a value at the end.
# libvyosconfig exists() works only for _nodes_, not _values_
- # libvyattacfg one also worked for values, so we emulate that case here
+ # libvyattacfg also worked for values, so we emulate that case here
if isinstance(path, str):
path = re.split(r'\s+', path)
path_without_value = path[:-1]
- path_str = " ".join(path_without_value)
try:
- value = self._session_config.return_value(self._make_path(path_str))
- return (value == path[-1])
+ # return_values() is safe to use with single-value nodes,
+ # it simply returns a single-item list in that case.
+ values = self._session_config.return_values(self._make_path(path_without_value))
+
+ # If we got this far, the node does exist and has values,
+ # so we need to check if it has the value in question among its values.
+ return (path[-1] in values)
except vyos.configtree.ConfigTreeError:
- # node doesn't exist at all
+ # Even the parent node doesn't exist at all
return False
def session_changed(self):
@@ -380,7 +390,7 @@ class Config(object):
def exists_effective(self, path):
"""
- Check if a node exists in the running (effective) config
+ Checks if a node or value exists in the running (effective) config.
Args:
path (str): Configuration tree path
@@ -392,10 +402,31 @@ class Config(object):
This function is safe to use in operational mode. In configuration mode,
it ignores uncommited changes.
"""
- if self._running_config:
- return(self._running_config.exists(self._make_path(path)))
+ if self._running_config is None:
+ return False
+
+ # Assume the path is a node path first
+ if self._running_config.exists(self._make_path(path)):
+ return True
+ else:
+ # If that check fails, it may mean the path has a value at the end.
+ # libvyosconfig exists() works only for _nodes_, not _values_
+ # libvyattacfg also worked for values, so we emulate that case here
+ if isinstance(path, str):
+ path = re.split(r'\s+', path)
+ path_without_value = path[:-1]
+ try:
+ # return_values() is safe to use with single-value nodes,
+ # it simply returns a single-item list in that case.
+ values = self._running_config.return_values(self._make_path(path_without_value))
+
+ # If we got this far, the node does exist and has values,
+ # so we need to check if it has the value in question among its values.
+ return (path[-1] in values)
+ except vyos.configtree.ConfigTreeError:
+ # Even the parent node doesn't exist at all
+ return False
- return False
def return_effective_value(self, path, default=None):
"""
diff --git a/smoketest/scripts/cli/test_interfaces_bonding.py b/smoketest/scripts/cli/test_interfaces_bonding.py
index 4f2fe979a..9bb561275 100755
--- a/smoketest/scripts/cli/test_interfaces_bonding.py
+++ b/smoketest/scripts/cli/test_interfaces_bonding.py
@@ -165,5 +165,27 @@ class BondingInterfaceTest(BasicInterfaceTest.TestCase):
self.cli_commit()
+ def test_bonding_uniq_member_description(self):
+ ethernet_path = ['interfaces', 'ethernet']
+ for interface in self._interfaces:
+ for option in self._options.get(interface, []):
+ self.cli_set(self._base_path + [interface] + option.split())
+
+ self.cli_commit()
+
+ # Add any changes on bonding members
+ # For example add description on separate ethX interfaces
+ for interface in self._interfaces:
+ for member in self._members:
+ self.cli_set(ethernet_path + [member, 'description', member + '_interface'])
+
+ self.cli_commit()
+
+ # verify config
+ for interface in self._interfaces:
+ slaves = read_file(f'/sys/class/net/{interface}/bonding/slaves').split()
+ for member in self._members:
+ self.assertIn(member, slaves)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_salt.py b/smoketest/scripts/cli/test_service_salt.py
new file mode 100755
index 000000000..5b328677e
--- /dev/null
+++ b/smoketest/scripts/cli/test_service_salt.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2022 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 unittest
+
+from socket import gethostname
+from base_vyostest_shim import VyOSUnitTestSHIM
+
+from vyos.util import process_named_running
+from vyos.util import read_file
+from vyos.util import cmd
+
+PROCESS_NAME = 'salt-minion'
+SALT_CONF = '/etc/salt/minion'
+base_path = ['service', 'salt-minion']
+
+class TestServiceSALT(VyOSUnitTestSHIM.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(TestServiceSALT, cls).setUpClass()
+
+ # ensure we can also run this test on a live system - so lets clean
+ # out the current configuration :)
+ cls.cli_delete(cls, base_path)
+
+ def tearDown(self):
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ # delete testing SALT config
+ self.cli_delete(base_path)
+ self.cli_commit()
+
+ # For an unknown reason on QEMU systems (e.g. where smoketests are executed
+ # from the CI) salt-minion process is not killed by systemd. Apparently
+ # no issue on VMWare.
+ if cmd('systemd-detect-virt') != 'kvm':
+ self.assertFalse(process_named_running(PROCESS_NAME))
+
+ def test_default(self):
+ servers = ['192.0.2.1', '192.0.2.2']
+
+ for server in servers:
+ self.cli_set(base_path + ['master', server])
+
+ self.cli_commit()
+
+ # commiconf = read_file() Check configured port
+ conf = read_file(SALT_CONF)
+ self.assertIn(f'- {server}', conf)
+
+ # defaults
+ hostname = gethostname()
+ self.assertIn(f'hash_type: sha256', conf)
+ self.assertIn(f'id: {hostname}', conf)
+ self.assertIn(f'mine_interval: 60', conf)
+
+ def test_options(self):
+ server = '192.0.2.3'
+ hash = 'sha1'
+ id = 'foo'
+ interval = '120'
+
+ self.cli_set(base_path + ['master', server])
+ self.cli_set(base_path + ['hash', hash])
+ self.cli_set(base_path + ['id', id])
+ self.cli_set(base_path + ['interval', interval])
+
+ self.cli_commit()
+
+ # commiconf = read_file() Check configured port
+ conf = read_file(SALT_CONF)
+ self.assertIn(f'- {server}', conf)
+
+ # defaults
+ self.assertIn(f'hash_type: {hash}', conf)
+ self.assertIn(f'id: {id}', conf)
+ self.assertIn(f'mine_interval: {interval}', conf)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/src/conf_mode/salt-minion.py b/src/conf_mode/salt-minion.py
index 841bf6a39..5a8528741 100755
--- a/src/conf_mode/salt-minion.py
+++ b/src/conf_mode/salt-minion.py
@@ -39,7 +39,7 @@ default_config_data = {
'user': 'minion',
'group': 'vyattacfg',
'salt_id': gethostname(),
- 'mine_interval': '60',
+ 'interval': '60',
'verify_master_pubkey_sign': 'false',
'master_key': ''
}
diff --git a/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper b/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
index fc035766b..2bd2d1d22 100644
--- a/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
+++ b/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
@@ -23,7 +23,7 @@ function iptovtysh () {
local VTYSH_GATEWAY=""
local VTYSH_DEV=""
local VTYSH_TAG="210"
- local VTYSH_DISTANCE=""
+ local VTYSH_DISTANCE=$IF_METRIC
# convert default route to 0.0.0.0/0
if [ "$4" == "default" ] ; then
VTYSH_NETADDR="0.0.0.0/0"