From 9c97bd1b0214e102ac36eae8b2c3c9ff672a0bf3 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Fri, 20 Aug 2021 17:06:05 +0200 Subject: vyos.configdict: add note when using leaf_node_changed() --- python/vyos/configdict.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'python/vyos/configdict.py') diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py index 0969a5353..a0056a142 100644 --- a/python/vyos/configdict.py +++ b/python/vyos/configdict.py @@ -108,7 +108,9 @@ def leaf_node_changed(conf, path): """ Check if a leaf node was altered. If it has been altered - values has been changed, or it was added/removed, we will return a list containing the old - value(s). If nothing has been changed, None is returned + value(s). If nothing has been changed, None is returned. + + NOTE: path must use the real CLI node name (e.g. with a hyphen!) """ from vyos.configdiff import get_config_diff D = get_config_diff(conf, key_mangling=('-', '_')) -- cgit v1.2.3 From f476e456e20393e7e7e91b73e369c9b033fbf048 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Fri, 20 Aug 2021 20:12:53 +0200 Subject: vyos.configdict: leaf_node_changed() must return empty dict when node is added vyos@vyos# show interfaces pppoe pppoe pppoe10 { + access-concentrator asdfg authentication { password bar user foo } default-route force no-peer-dns source-interface eth0.202 } vyos@vyos# python3 Python 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from vyos.config import Config >>> from vyos.configdict import get_interface_dict >>> from vyos.configdict import leaf_node_changed >>> conf = Config() >>> base = ['interfaces', 'pppoe'] >>> tmp = get_interface_dict(conf, base, 'pppoe10') >>> leaf_node_changed(conf, ['access-concentrator']) >>> [''] --- python/vyos/configdict.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'python/vyos/configdict.py') diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py index a0056a142..e15579b95 100644 --- a/python/vyos/configdict.py +++ b/python/vyos/configdict.py @@ -117,9 +117,11 @@ def leaf_node_changed(conf, path): D.set_level(conf.get_level()) (new, old) = D.get_value_diff(path) if new != old: + if old is None: + return [''] if isinstance(old, str): return [old] - elif isinstance(old, list): + if isinstance(old, list): if isinstance(new, str): new = [new] elif isinstance(new, type(None)): -- cgit v1.2.3 From 4d2201eed00ac4780d0196abf53dd9b7cb943a09 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Thu, 9 Sep 2021 10:42:46 +0200 Subject: vyos.configdict: T3814: use no_tag_node_value_mangle in get_interface_dict() This change is required and currently only impacts WireGuards peer configuration, so that the peers name is not mangled. --- python/vyos/configdict.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'python/vyos/configdict.py') diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py index e15579b95..24b76fb0b 100644 --- a/python/vyos/configdict.py +++ b/python/vyos/configdict.py @@ -347,8 +347,8 @@ def get_interface_dict(config, base, ifname=''): # setup config level which is extracted in get_removed_vlans() config.set_level(base + [ifname]) - dict = config.get_config_dict([], key_mangling=('-', '_'), - get_first_key=True) + dict = config.get_config_dict([], key_mangling=('-', '_'), get_first_key=True, + no_tag_node_value_mangle=True) # Check if interface has been removed. We must use exists() as # get_config_dict() will always return {} - even when an empty interface -- cgit v1.2.3 From e28a80a2b742ea3d9d4bcb8ae66c7a0d51aaaff6 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 19 Sep 2021 21:59:43 +0200 Subject: vyos.configdict: bugfix: leaf_node_changed() must return empty dict when node is added Commit f476e456 ("vyos.configdict: leaf_node_changed() must return empty dict when node is added") returned [''] as "empty" dict - but this is not empty. >>> if ['']: ... print('foo') ... foo It should rather be: [] --- python/vyos/configdict.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'python/vyos/configdict.py') diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py index 24b76fb0b..8d7142049 100644 --- a/python/vyos/configdict.py +++ b/python/vyos/configdict.py @@ -118,7 +118,7 @@ def leaf_node_changed(conf, path): (new, old) = D.get_value_diff(path) if new != old: if old is None: - return [''] + return [] if isinstance(old, str): return [old] if isinstance(old, list): -- cgit v1.2.3 From e80d0aebd691f1a707ab534b4d1340fa0b793e01 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 19 Sep 2021 22:06:02 +0200 Subject: vyos.ifconfig: T2738: do not remove OS assigned IP addresses from interface When using VRRP on any given interface and performing an action against that interface - be it even only changing the alias - will trigger a removal of the VRRP IP address. The issue is caused by: # determine IP addresses which are assigned to the interface and build a # list of addresses which are no longer in the dict so they can be removed cur_addr = self.get_addr() for addr in list_diff(cur_addr, new_addr): When the script calls into the library - we will drop all IP addresses set on the adapter but not available in the config dict. We should only remove the IP addresses marked by the CLI to be deleted! --- python/vyos/configdict.py | 3 +++ python/vyos/ifconfig/interface.py | 20 +++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) (limited to 'python/vyos/configdict.py') diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py index 8d7142049..5c6836e97 100644 --- a/python/vyos/configdict.py +++ b/python/vyos/configdict.py @@ -375,6 +375,9 @@ def get_interface_dict(config, base, ifname=''): # XXX: T2665: blend in proper DHCPv6-PD default values dict = T2665_set_dhcpv6pd_defaults(dict) + address = leaf_node_changed(config, ['address']) + if address: dict.update({'address_old' : address}) + # Check if we are a member of a bridge device bridge = is_member(config, ifname, 'bridge') if bridge: dict.update({'is_bridge_member' : bridge}) diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index 14b782db4..963f47c89 100755 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -1085,6 +1085,8 @@ class Interface(Control): >>> j.get_addr() ['2001:db8::ffff/64'] """ + if not addr: + raise ValueError() # remove from interface if addr == 'dhcp': @@ -1364,16 +1366,16 @@ class Interface(Control): # determine IP addresses which are assigned to the interface and build a # list of addresses which are no longer in the dict so they can be removed - cur_addr = self.get_addr() - for addr in list_diff(cur_addr, new_addr): - # we will delete all interface specific IP addresses if they are not - # explicitly configured on the CLI - if is_ipv6_link_local(addr): - eui64 = mac2eui64(self.get_mac(), 'fe80::/64') - if addr != f'{eui64}/64': + if 'address_old' in config: + for addr in list_diff(config['address_old'], new_addr): + # we will delete all interface specific IP addresses if they are not + # explicitly configured on the CLI + if is_ipv6_link_local(addr): + eui64 = mac2eui64(self.get_mac(), 'fe80::/64') + if addr != f'{eui64}/64': + self.del_addr(addr) + else: self.del_addr(addr) - else: - self.del_addr(addr) for addr in new_addr: self.add_addr(addr) -- cgit v1.2.3