From c9ba8952ad7c373d633516933ddb97e178e339c8 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Mon, 20 Jul 2020 21:45:24 +0200 Subject: interfaces: ifconfig: T2653: migrate to get_interface_dict() API After switching from raw parsing of the interface options to get_config_dict() this utilizes another utility function which wraps get_config_dict() and adds other common and reused parameters (like deleted or bridge member). Overall this drops redundant code (again) and makes the rest more maintainable as we only utilize a single function. --- src/conf_mode/interfaces-pppoe.py | 43 +++++++++++++++------------------------ 1 file changed, 16 insertions(+), 27 deletions(-) (limited to 'src/conf_mode/interfaces-pppoe.py') diff --git a/src/conf_mode/interfaces-pppoe.py b/src/conf_mode/interfaces-pppoe.py index 3ee57e83c..6947cc1e2 100755 --- a/src/conf_mode/interfaces-pppoe.py +++ b/src/conf_mode/interfaces-pppoe.py @@ -22,51 +22,40 @@ from copy import deepcopy from netifaces import interfaces from vyos.config import Config -from vyos.configdict import dict_merge +from vyos.configdict import get_interface_dict from vyos.configverify import verify_source_interface from vyos.configverify import verify_vrf from vyos.template import render from vyos.util import call -from vyos.xml import defaults from vyos import ConfigError from vyos import airbag airbag.enable() def get_config(): - """ Retrive CLI config as dictionary. Dictionary can never be empty, - as at least the interface name will be added or a deleted flag """ + """ + Retrive CLI config as dictionary. Dictionary can never be empty, as at least the + interface name will be added or a deleted flag + """ conf = Config() + base = ['interfaces', 'pppoe'] # determine tagNode instance if 'VYOS_TAGNODE_VALUE' not in os.environ: raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') - # retrieve interface default values - base = ['interfaces', 'pppoe'] - default_values = defaults(base) - # PPPoE is "special" the default MTU is 1492 - update accordingly - default_values['mtu'] = '1492' - ifname = os.environ['VYOS_TAGNODE_VALUE'] - base = base + [ifname] + pppoe = get_interface_dict(conf, base, ifname) - pppoe = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) - # Check if interface has been removed - if pppoe == {}: - pppoe.update({'deleted' : ''}) - - # We have gathered the dict representation of the CLI, but there are - # default options which we need to update into the dictionary - # retrived. - pppoe = dict_merge(default_values, pppoe) - - # Add interface instance name into dictionary - pppoe.update({'ifname': ifname}) + # PPPoE is "special" the default MTU is 1492 - update accordingly + # as the config_level is already st in get_interface_dict() - we can use [] + tmp = conf.get_config_dict([], key_mangling=('-', '_'), get_first_key=True) + if 'mtu' not in tmp: + pppoe['mtu'] = '1492' return pppoe def verify(pppoe): - if 'deleted' in pppoe.keys(): + if 'deleted' in pppoe: # bail out early return None @@ -92,7 +81,7 @@ def generate(pppoe): config_files = [config_pppoe, script_pppoe_pre_up, script_pppoe_ip_up, script_pppoe_ip_down, script_pppoe_ipv6_up, config_wide_dhcp6c] - if 'deleted' in pppoe.keys(): + if 'deleted' in pppoe: # stop DHCPv6-PD client call(f'systemctl stop dhcp6c@{ifname}.service') # Hang-up PPPoE connection @@ -130,11 +119,11 @@ def generate(pppoe): return None def apply(pppoe): - if 'deleted' in pppoe.keys(): + if 'deleted' in pppoe: # bail out early return None - if 'disable' not in pppoe.keys(): + if 'disable' not in pppoe: # Dial PPPoE connection call('systemctl restart ppp@{ifname}.service'.format(**pppoe)) -- cgit v1.2.3 From e70a304e36fc6456e16fea81ace4a0a5fd8bd1df Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sat, 25 Jul 2020 00:39:14 +0200 Subject: ifconfig: T2653: make ifname an optional argument to get_interface_dict() Further reduce the boiler-plate code to determine interface tag node or not. It can be passed into get_interface_dict() if explicitly required - else it is taken from the environment. --- python/vyos/configdict.py | 11 ++++++++--- src/conf_mode/interfaces-bonding.py | 10 ++-------- src/conf_mode/interfaces-bridge.py | 11 ++--------- src/conf_mode/interfaces-dummy.py | 8 +------- src/conf_mode/interfaces-ethernet.py | 8 +------- src/conf_mode/interfaces-geneve.py | 9 +-------- src/conf_mode/interfaces-loopback.py | 8 +------- src/conf_mode/interfaces-macsec.py | 8 +------- src/conf_mode/interfaces-pppoe.py | 8 +------- src/conf_mode/interfaces-pseudo-ethernet.py | 8 +------- src/conf_mode/interfaces-wireless.py | 8 +------- src/conf_mode/interfaces-wirelessmodem.py | 9 +-------- 12 files changed, 21 insertions(+), 85 deletions(-) (limited to 'src/conf_mode/interfaces-pppoe.py') diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py index 53b5f9492..126d6195a 100644 --- a/python/vyos/configdict.py +++ b/python/vyos/configdict.py @@ -15,8 +15,8 @@ """ A library for retrieving value dicts from VyOS configs in a declarative fashion. - """ +import os import jmespath from enum import Enum @@ -24,7 +24,6 @@ from copy import deepcopy from vyos import ConfigError from vyos.validate import is_member -from vyos.util import ifname_from_config def retrieve_config(path_hash, base_path, config): """ @@ -195,7 +194,7 @@ def get_removed_vlans(conf, dict): return dict -def get_interface_dict(config, base, ifname): +def get_interface_dict(config, base, ifname=''): """ Common utility function to retrieve and mandgle the interfaces available in CLI configuration. All interfaces have a common base ground where the @@ -205,6 +204,12 @@ def get_interface_dict(config, base, ifname): """ from vyos.xml import defaults + if not ifname: + # determine tagNode instance + if 'VYOS_TAGNODE_VALUE' not in os.environ: + raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') + ifname = os.environ['VYOS_TAGNODE_VALUE'] + # retrieve interface default values default_values = defaults(base) diff --git a/src/conf_mode/interfaces-bonding.py b/src/conf_mode/interfaces-bonding.py index 8e87a0059..3b238f1ea 100755 --- a/src/conf_mode/interfaces-bonding.py +++ b/src/conf_mode/interfaces-bonding.py @@ -60,13 +60,7 @@ def get_config(): """ conf = Config() base = ['interfaces', 'bonding'] - - # determine tagNode instance - if 'VYOS_TAGNODE_VALUE' not in os.environ: - raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') - - ifname = os.environ['VYOS_TAGNODE_VALUE'] - bond = get_interface_dict(conf, base, ifname) + bond = get_interface_dict(conf, base) # To make our own life easier transfor the list of member interfaces # into a dictionary - we will use this to add additional information @@ -107,7 +101,7 @@ def get_config(): # Check if we are a member of a bond device tmp = is_member(conf, interface, 'bonding') - if tmp and tmp != ifname: + if tmp and tmp != bond['ifname']: interface_config.update({'is_bond_member' : tmp}) # bond members must not have an assigned address diff --git a/src/conf_mode/interfaces-bridge.py b/src/conf_mode/interfaces-bridge.py index 9c43d1983..ee8e85e73 100755 --- a/src/conf_mode/interfaces-bridge.py +++ b/src/conf_mode/interfaces-bridge.py @@ -41,13 +41,7 @@ def get_config(): """ conf = Config() base = ['interfaces', 'bridge'] - - # determine tagNode instance - if 'VYOS_TAGNODE_VALUE' not in os.environ: - raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') - - ifname = os.environ['VYOS_TAGNODE_VALUE'] - bridge = get_interface_dict(conf, base, ifname) + bridge = get_interface_dict(conf, base) # determine which members have been removed tmp = node_changed(conf, ['member', 'interface']) @@ -69,13 +63,12 @@ def get_config(): # the default dictionary is not properly paged into the dict (see T2665) # thus we will ammend it ourself default_member_values = defaults(base + ['member', 'interface']) - for interface, interface_config in bridge['member']['interface'].items(): interface_config.update(default_member_values) # Check if we are a member of another bridge device tmp = is_member(conf, interface, 'bridge') - if tmp and tmp != ifname: + if tmp and tmp != bridge['ifname']: interface_config.update({'is_bridge_member' : tmp}) # Check if we are a member of a bond device diff --git a/src/conf_mode/interfaces-dummy.py b/src/conf_mode/interfaces-dummy.py index 6d2a78e30..8df86c8ea 100755 --- a/src/conf_mode/interfaces-dummy.py +++ b/src/conf_mode/interfaces-dummy.py @@ -35,13 +35,7 @@ def get_config(): """ conf = Config() base = ['interfaces', 'dummy'] - - # determine tagNode instance - if 'VYOS_TAGNODE_VALUE' not in os.environ: - raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') - - ifname = os.environ['VYOS_TAGNODE_VALUE'] - dummy = get_interface_dict(conf, base, ifname) + dummy = get_interface_dict(conf, base) return dummy def verify(dummy): diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py index 24ea0af7c..10758e35a 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -37,13 +37,7 @@ def get_config(): """ conf = Config() base = ['interfaces', 'ethernet'] - - # determine tagNode instance - if 'VYOS_TAGNODE_VALUE' not in os.environ: - raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') - - ifname = os.environ['VYOS_TAGNODE_VALUE'] - ethernet = get_interface_dict(conf, base, ifname) + ethernet = get_interface_dict(conf, base) return ethernet def verify(ethernet): diff --git a/src/conf_mode/interfaces-geneve.py b/src/conf_mode/interfaces-geneve.py index 868ab5ccf..1104bd3c0 100755 --- a/src/conf_mode/interfaces-geneve.py +++ b/src/conf_mode/interfaces-geneve.py @@ -37,14 +37,7 @@ def get_config(): """ conf = Config() base = ['interfaces', 'geneve'] - - # determine tagNode instance - if 'VYOS_TAGNODE_VALUE' not in os.environ: - raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') - - ifname = os.environ['VYOS_TAGNODE_VALUE'] - geneve = get_interface_dict(conf, base, ifname) - + geneve = get_interface_dict(conf, base) return geneve def verify(geneve): diff --git a/src/conf_mode/interfaces-loopback.py b/src/conf_mode/interfaces-loopback.py index 68a1392ff..0398cd591 100755 --- a/src/conf_mode/interfaces-loopback.py +++ b/src/conf_mode/interfaces-loopback.py @@ -32,13 +32,7 @@ def get_config(): """ conf = Config() base = ['interfaces', 'loopback'] - - # determine tagNode instance - if 'VYOS_TAGNODE_VALUE' not in os.environ: - raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') - - ifname = os.environ['VYOS_TAGNODE_VALUE'] - loopback = get_interface_dict(conf, base, ifname) + loopback = get_interface_dict(conf, base) return loopback def verify(loopback): diff --git a/src/conf_mode/interfaces-macsec.py b/src/conf_mode/interfaces-macsec.py index 06aee9ea0..ca15212d4 100755 --- a/src/conf_mode/interfaces-macsec.py +++ b/src/conf_mode/interfaces-macsec.py @@ -42,13 +42,7 @@ def get_config(): """ conf = Config() base = ['interfaces', 'macsec'] - - # determine tagNode instance - if 'VYOS_TAGNODE_VALUE' not in os.environ: - raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') - - ifname = os.environ['VYOS_TAGNODE_VALUE'] - macsec = get_interface_dict(conf, base, ifname) + macsec = get_interface_dict(conf, base) # Check if interface has been removed if 'deleted' in macsec: diff --git a/src/conf_mode/interfaces-pppoe.py b/src/conf_mode/interfaces-pppoe.py index 6947cc1e2..b9a88a949 100755 --- a/src/conf_mode/interfaces-pppoe.py +++ b/src/conf_mode/interfaces-pppoe.py @@ -38,13 +38,7 @@ def get_config(): """ conf = Config() base = ['interfaces', 'pppoe'] - - # determine tagNode instance - if 'VYOS_TAGNODE_VALUE' not in os.environ: - raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') - - ifname = os.environ['VYOS_TAGNODE_VALUE'] - pppoe = get_interface_dict(conf, base, ifname) + pppoe = get_interface_dict(conf, base) # PPPoE is "special" the default MTU is 1492 - update accordingly # as the config_level is already st in get_interface_dict() - we can use [] diff --git a/src/conf_mode/interfaces-pseudo-ethernet.py b/src/conf_mode/interfaces-pseudo-ethernet.py index 55f11e65e..4afea2b3a 100755 --- a/src/conf_mode/interfaces-pseudo-ethernet.py +++ b/src/conf_mode/interfaces-pseudo-ethernet.py @@ -40,13 +40,7 @@ def get_config(): """ conf = Config() base = ['interfaces', 'pseudo-ethernet'] - - # determine tagNode instance - if 'VYOS_TAGNODE_VALUE' not in os.environ: - raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') - - ifname = os.environ['VYOS_TAGNODE_VALUE'] - peth = get_interface_dict(conf, base, ifname) + peth = get_interface_dict(conf, base) mode = leaf_node_changed(conf, ['mode']) if mode: diff --git a/src/conf_mode/interfaces-wireless.py b/src/conf_mode/interfaces-wireless.py index 42b55ee6a..b6f247952 100755 --- a/src/conf_mode/interfaces-wireless.py +++ b/src/conf_mode/interfaces-wireless.py @@ -71,13 +71,7 @@ def get_config(): """ conf = Config() base = ['interfaces', 'wireless'] - - # determine tagNode instance - if 'VYOS_TAGNODE_VALUE' not in os.environ: - raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') - - ifname = os.environ['VYOS_TAGNODE_VALUE'] - wifi = get_interface_dict(conf, base, ifname) + wifi = get_interface_dict(conf, base) if 'security' in wifi and 'wpa' in wifi['security']: wpa_cipher = wifi['security']['wpa'].get('cipher') diff --git a/src/conf_mode/interfaces-wirelessmodem.py b/src/conf_mode/interfaces-wirelessmodem.py index 9a5dae9e0..4081be3c9 100755 --- a/src/conf_mode/interfaces-wirelessmodem.py +++ b/src/conf_mode/interfaces-wirelessmodem.py @@ -48,14 +48,7 @@ def get_config(): """ conf = Config() base = ['interfaces', 'wirelessmodem'] - - # determine tagNode instance - if 'VYOS_TAGNODE_VALUE' not in os.environ: - raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') - - ifname = os.environ['VYOS_TAGNODE_VALUE'] - wwan = get_interface_dict(conf, base, ifname) - + wwan = get_interface_dict(conf, base) return wwan def verify(wwan): -- cgit v1.2.3 From 84331764a81d7e31c5c4dd5466f347054283d377 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Mon, 3 Aug 2020 12:56:13 +0200 Subject: ifconfig: T2740: pass config dict to DHCP class for IPv6 This removes additional code paths as we can instatly work with the input dict the same was as it was done for PPPoE. This fixes the entire DHCPv6-PD support on non PPPoE interfaces as this was lost in translation while processing T2653. --- data/templates/dhcp-client/ipv6.tmpl | 53 +++++++++++++++++--------------- data/templates/dhcp-client/ipv6_new.tmpl | 47 ---------------------------- python/vyos/ifconfig/dhcp.py | 36 +++++++++------------- python/vyos/ifconfig/interface.py | 49 ++++++++++++----------------- src/conf_mode/interfaces-pppoe.py | 2 +- 5 files changed, 63 insertions(+), 124 deletions(-) delete mode 100644 data/templates/dhcp-client/ipv6_new.tmpl (limited to 'src/conf_mode/interfaces-pppoe.py') diff --git a/data/templates/dhcp-client/ipv6.tmpl b/data/templates/dhcp-client/ipv6.tmpl index 490f14726..112431c5f 100644 --- a/data/templates/dhcp-client/ipv6.tmpl +++ b/data/templates/dhcp-client/ipv6.tmpl @@ -4,41 +4,44 @@ interface {{ ifname }} { request domain-name-servers; request domain-name; -{% if dhcpv6_prm_only %} +{% if dhcpv6_options is defined %} +{% if dhcpv6_options.parameters_only is defined %} information-only; -{% endif %} -{% if not dhcpv6_temporary %} +{% endif %} +{% if dhcpv6_options.temporary is not defined %} send ia-na 1; # non-temporary address -{% endif %} -{% if dhcpv6_pd_interfaces %} +{% endif %} +{% if dhcpv6_options.prefix_delegation is defined %} send ia-pd 2; # prefix delegation +{% endif %} {% endif %} }; -{% if not dhcpv6_temporary %} +{% if dhcpv6_options is defined %} +{% if dhcpv6_options.temporary is not defined %} id-assoc na 1 { # Identity association NA }; -{% endif %} +{% endif %} -{% if dhcpv6_pd_interfaces %} +{% if dhcpv6_options.prefix_delegation is defined %} id-assoc pd 2 { -{% if dhcpv6_pd_length %} - prefix ::/{{ dhcpv6_pd_length }} infinity; -{% endif %} -{% for intf in dhcpv6_pd_interfaces %} - prefix-interface {{ intf.ifname }} { -{% if intf.sla_id %} - sla-id {{ intf.sla_id }}; -{% endif %} -{% if intf.sla_len %} - sla-len {{ intf.sla_len }}; -{% endif %} -{% if intf.if_id %} - ifid {{ intf.if_id }}; -{% endif %} +{% if dhcpv6_options.prefix_delegation.length is defined %} + prefix ::/{{ dhcpv6_options.prefix_delegation.length }} infinity; +{% endif %} +{% for interface in dhcpv6_options.prefix_delegation.interface %} + prefix-interface {{ interface }} { +{% if dhcpv6_options.prefix_delegation.interface[interface].sla_id is defined %} + sla-id {{ dhcpv6_options.prefix_delegation.interface[interface].sla_id }}; +{% endif %} +{% if dhcpv6_options.prefix_delegation.interface[interface].sla_len is defined %} + sla-len {{ dhcpv6_options.prefix_delegation.interface[interface].sla_len }}; +{% endif %} +{% if dhcpv6_options.prefix_delegation.interface[interface].address is defined %} + ifid {{ dhcpv6_options.prefix_delegation.interface[interface].address }}; +{% endif %} }; -{% endfor %} +{% endfor %} }; -{% endif %} - +{% endif %} +{% endif %} diff --git a/data/templates/dhcp-client/ipv6_new.tmpl b/data/templates/dhcp-client/ipv6_new.tmpl deleted file mode 100644 index 112431c5f..000000000 --- a/data/templates/dhcp-client/ipv6_new.tmpl +++ /dev/null @@ -1,47 +0,0 @@ -# generated by dhcp.py -# man https://www.unix.com/man-page/debian/5/dhcp6c.conf/ - -interface {{ ifname }} { - request domain-name-servers; - request domain-name; -{% if dhcpv6_options is defined %} -{% if dhcpv6_options.parameters_only is defined %} - information-only; -{% endif %} -{% if dhcpv6_options.temporary is not defined %} - send ia-na 1; # non-temporary address -{% endif %} -{% if dhcpv6_options.prefix_delegation is defined %} - send ia-pd 2; # prefix delegation -{% endif %} -{% endif %} -}; - -{% if dhcpv6_options is defined %} -{% if dhcpv6_options.temporary is not defined %} -id-assoc na 1 { - # Identity association NA -}; -{% endif %} - -{% if dhcpv6_options.prefix_delegation is defined %} -id-assoc pd 2 { -{% if dhcpv6_options.prefix_delegation.length is defined %} - prefix ::/{{ dhcpv6_options.prefix_delegation.length }} infinity; -{% endif %} -{% for interface in dhcpv6_options.prefix_delegation.interface %} - prefix-interface {{ interface }} { -{% if dhcpv6_options.prefix_delegation.interface[interface].sla_id is defined %} - sla-id {{ dhcpv6_options.prefix_delegation.interface[interface].sla_id }}; -{% endif %} -{% if dhcpv6_options.prefix_delegation.interface[interface].sla_len is defined %} - sla-len {{ dhcpv6_options.prefix_delegation.interface[interface].sla_len }}; -{% endif %} -{% if dhcpv6_options.prefix_delegation.interface[interface].address is defined %} - ifid {{ dhcpv6_options.prefix_delegation.interface[interface].address }}; -{% endif %} - }; -{% endfor %} -}; -{% endif %} -{% endif %} diff --git a/python/vyos/ifconfig/dhcp.py b/python/vyos/ifconfig/dhcp.py index a8b9a2a87..bd37970a2 100644 --- a/python/vyos/ifconfig/dhcp.py +++ b/python/vyos/ifconfig/dhcp.py @@ -15,6 +15,7 @@ import os +from vyos.configverify import verify_dhcpv6 from vyos.dicts import FixedDict from vyos.ifconfig.control import Control from vyos.template import render @@ -82,39 +83,31 @@ class _DHCPv4 (Control): class _DHCPv6 (Control): def __init__(self, ifname): super().__init__() - self.options = FixedDict(**{ - 'ifname': ifname, - 'dhcpv6_prm_only': False, - 'dhcpv6_temporary': False, - 'dhcpv6_pd_interfaces': [], - 'dhcpv6_pd_length': '' - }) - self._conf_file = f'/run/dhcp6c/dhcp6c.{ifname}.conf' + self.options = {'ifname' : ifname} + self._config = f'/run/dhcp6c/dhcp6c.{ifname}.conf' def set(self): """ - Configure interface as DHCPv6 client. The dhclient binary is automatically - started in background! + Configure interface as DHCPv6 client. The client is automatically + started in background when address is configured as DHCP. Example: - >>> from vyos.ifconfig import Interface >>> j = Interface('eth0') >>> j.dhcp.v6.set() """ - # better save then sorry .. should be checked in interface script - # but if you missed it we are safe! - if self.options['dhcpv6_prm_only'] and self.options['dhcpv6_temporary']: - raise Exception( - 'DHCPv6 temporary and parameters-only options are mutually exclusive!') + # better save then sorry .. should be checked in interface script but if you + # missed it we are safe! + verify_dhcpv6(self.options) - render(self._conf_file, 'dhcp-client/ipv6.tmpl', self.options, trim_blocks=True) - return self._cmd('systemctl restart dhcp6c@{ifname}.service'.format(**self.options)) + render(self._config, 'dhcp-client/ipv6.tmpl', self.options, trim_blocks=True) + return self._cmd('systemctl restart dhcp6c@{ifname}.service'.format( + **self.options)) def delete(self): """ - De-configure interface as DHCPv6 clinet. All auto generated files like + De-configure interface as DHCPv6 client. All auto generated files like pid, config and lease will be removed. Example: @@ -126,9 +119,8 @@ class _DHCPv6 (Control): self._cmd('systemctl stop dhcp6c@{ifname}.service'.format(**self.options)) # cleanup old config files - if os.path.isfile(self._conf_file): - os.remove(self._conf_file) - + if os.path.isfile(self._config): + os.remove(self._config) class DHCP(object): def __init__(self, ifname): diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index d477153e8..f5e43e172 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -822,6 +822,22 @@ class Interface(Control): value = '2' if 'disable_link_detect' in config else '1' self.set_link_detect(value) + # DHCP options + if 'dhcp_options' in config: + dhcp_options = config.get('dhcp_options') + if 'client_id' in dhcp_options: + self.dhcp.v4.options['client_id'] = dhcp_options.get('client_id') + + if 'host_name' in dhcp_options: + self.dhcp.v4.options['hostname'] = dhcp_options.get('host_name') + + if 'vendor_class_id' in dhcp_options: + self.dhcp.v4.options['vendor_class_id'] = dhcp_options.get('vendor_class_id') + + # DHCPv6 options + if 'dhcpv6_options' in config: + self.dhcp.v6.options = config + # Configure assigned interface IP addresses. No longer # configured addresses will be removed first new_addr = config.get('address', []) @@ -849,35 +865,6 @@ class Interface(Control): # checked before self.set_vrf(config.get('vrf', '')) - # DHCP options - if 'dhcp_options' in config: - dhcp_options = config.get('dhcp_options') - if 'client_id' in dhcp_options: - self.dhcp.v4.options['client_id'] = dhcp_options.get('client_id') - - if 'host_name' in dhcp_options: - self.dhcp.v4.options['hostname'] = dhcp_options.get('host_name') - - if 'vendor_class_id' in dhcp_options: - self.dhcp.v4.options['vendor_class_id'] = dhcp_options.get('vendor_class_id') - - # DHCPv6 options - if 'dhcpv6_options' in config: - dhcpv6_options = config.get('dhcpv6_options') - if 'parameters_only' in dhcpv6_options: - self.dhcp.v6.options['dhcpv6_prm_only'] = True - - if 'temporary' in dhcpv6_options: - self.dhcp.v6.options['dhcpv6_temporary'] = True - - if 'prefix_delegation' in dhcpv6_options: - prefix_delegation = dhcpv6_options.get('prefix_delegation') - if 'length' in prefix_delegation: - self.dhcp.v6.options['dhcpv6_pd_length'] = prefix_delegation.get('length') - - if 'interface' in prefix_delegation: - self.dhcp.v6.options['dhcpv6_pd_interfaces'] = prefix_delegation.get('interface') - # Configure ARP cache timeout in milliseconds - has default value tmp = jmespath.search('ip.arp_cache_timeout', config) value = tmp if (tmp != None) else '30' @@ -982,9 +969,11 @@ class Interface(Control): self.del_vlan(vif_s_id) # create/update 802.1ad (Q-in-Q VLANs) + ifname = config['ifname'] for vif_s_id, vif_s in config.get('vif_s', {}).items(): tmp=get_ethertype(vif_s.get('ethertype', '0x88A8')) s_vlan = self.add_vlan(vif_s_id, ethertype=tmp) + vif_s['ifname'] = f'{ifname}.{vif_s_id}' s_vlan.update(vif_s) # remove no longer required client VLAN (vif-c) @@ -994,6 +983,7 @@ class Interface(Control): # create/update client VLAN (vif-c) interface for vif_c_id, vif_c in vif_s.get('vif_c', {}).items(): c_vlan = s_vlan.add_vlan(vif_c_id) + vif_c['ifname'] = f'{ifname}.{vif_s_id}.{vif_c_id}' c_vlan.update(vif_c) # remove no longer required 802.1q VLAN interfaces @@ -1003,4 +993,5 @@ class Interface(Control): # create/update 802.1q VLAN interfaces for vif_id, vif in config.get('vif', {}).items(): vlan = self.add_vlan(vif_id) + vif['ifname'] = f'{ifname}.{vif_id}' vlan.update(vif) diff --git a/src/conf_mode/interfaces-pppoe.py b/src/conf_mode/interfaces-pppoe.py index b9a88a949..928113b49 100755 --- a/src/conf_mode/interfaces-pppoe.py +++ b/src/conf_mode/interfaces-pppoe.py @@ -108,7 +108,7 @@ def generate(pppoe): if tmp and len(tmp) > 0: # ipv6.tmpl relies on ifname - this should be made consitent in the # future better then double key-ing the same value - render(config_wide_dhcp6c, 'dhcp-client/ipv6_new.tmpl', pppoe, trim_blocks=True) + render(config_wide_dhcp6c, 'dhcp-client/ipv6.tmpl', pppoe, trim_blocks=True) return None -- cgit v1.2.3 From 98c2c5e0585e0806099a353de207f392223eff9a Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sat, 22 Aug 2020 23:15:29 +0200 Subject: dhcpv6-pd: T2677: optimize CLI interface for PD configuration The current CLI did not support multiple prefix-delegations per interface. Some ISPs only send one /64 to a client per prefix-delegation request, but they allow the customer to request multiple prefixes. The 'dhcpv6-options prefix-delegation' node has been renamed and converted to a tag node named 'dhcpv6-options pd'. The tag node specifies a PD request (>=0). In the past the user needed to know what prefix will be assigned and required to calculate the sla-len by himself. The 'sla-len' node was dropped and is now calculated in the background from the 'dhcpv6-options pd 0 length' node. It is no longer mandatory to supply the 'sla-id' node, if sla-id is not specified it is 'guessed' by counting upwards. Example configuration: ---------------------- ethernet eth1 { address dhcpv6 dhcpv6-options { pd 0 { length 56 interface eth2 { address 1 } } } } This will request a /56 assignment from the ISP and will delegate a /64 network to interface eth2. VyOS will use the interface address ::1 on the delegate interface (eth2) as its local address. --- data/templates/dhcp-client/ipv6.tmpl | 48 +++++++++------- interface-definitions/include/dhcp-options.xml.i | 2 +- interface-definitions/include/dhcpv6-options.xml.i | 40 ++++++-------- python/vyos/configdict.py | 64 ++++++++++++++++++---- src/conf_mode/interfaces-pppoe.py | 4 +- src/migration-scripts/interfaces/11-to-12 | 58 ++++++++++++++++++++ 6 files changed, 157 insertions(+), 59 deletions(-) create mode 100755 src/migration-scripts/interfaces/11-to-12 (limited to 'src/conf_mode/interfaces-pppoe.py') diff --git a/data/templates/dhcp-client/ipv6.tmpl b/data/templates/dhcp-client/ipv6.tmpl index 9673f302b..e9285d86b 100644 --- a/data/templates/dhcp-client/ipv6.tmpl +++ b/data/templates/dhcp-client/ipv6.tmpl @@ -8,37 +8,43 @@ interface {{ ifname }} { information-only; {% endif %} {% if dhcpv6_options is not defined or dhcpv6_options.temporary is not defined %} - send ia-na 1; # non-temporary address + send ia-na 0; # non-temporary address {% endif %} -{% if dhcpv6_options is defined and dhcpv6_options.prefix_delegation is defined %} - send ia-pd 2; # prefix delegation +{% if dhcpv6_options is defined and dhcpv6_options.pd is defined %} +{% for pd in dhcpv6_options.pd %} + send ia-pd {{ pd }}; # prefix delegation #{{ pd }} +{% endfor %} {% endif %} }; {% if dhcpv6_options is not defined or dhcpv6_options.temporary is not defined %} -id-assoc na 1 { - # Identity association NA +id-assoc na 0 { + # Identity association for non temporary address }; {% endif %} -{% if dhcpv6_options is defined and dhcpv6_options.prefix_delegation is defined %} -id-assoc pd 2 { -{% if dhcpv6_options.prefix_delegation.length is defined %} - prefix ::/{{ dhcpv6_options.prefix_delegation.length }} infinity; -{% endif %} -{% for interface in dhcpv6_options.prefix_delegation.interface %} +{% if dhcpv6_options is defined and dhcpv6_options.pd is defined %} +{% for pd in dhcpv6_options.pd %} +id-assoc pd {{ pd }} { +{# length got a default value #} + prefix ::/{{ dhcpv6_options.pd[pd].length }} infinity; +{% set sla_len = 64 - dhcpv6_options.pd[pd].length|int %} +{% set count = namespace(value=0) %} +{% for interface in dhcpv6_options.pd[pd].interface if dhcpv6_options.pd[pd].interface is defined %} prefix-interface {{ interface }} { -{% if dhcpv6_options.prefix_delegation.interface[interface].sla_id is defined %} - sla-id {{ dhcpv6_options.prefix_delegation.interface[interface].sla_id }}; -{% endif %} -{% if dhcpv6_options.prefix_delegation.interface[interface].sla_len is defined %} - sla-len {{ dhcpv6_options.prefix_delegation.interface[interface].sla_len }}; -{% endif %} -{% if dhcpv6_options.prefix_delegation.interface[interface].address is defined %} - ifid {{ dhcpv6_options.prefix_delegation.interface[interface].address }}; -{% endif %} + sla-len {{ sla_len }}; +{% if dhcpv6_options.pd[pd].interface[interface].sla_id is defined and dhcpv6_options.pd[pd].interface[interface].sla_id is not none %} + sla-id {{ dhcpv6_options.pd[pd].interface[interface].sla_id }}; +{% else %} + sla-id {{ count.value }}; +{% endif %} +{% if dhcpv6_options.pd[pd].interface[interface].address is defined and dhcpv6_options.pd[pd].interface[interface].address is not none %} + ifid {{ dhcpv6_options.pd[pd].interface[interface].address }}; +{% endif %} }; -{% endfor %} +{% set count.value = count.value + 1 %} +{% endfor %} }; +{% endfor %} {% endif %} diff --git a/interface-definitions/include/dhcp-options.xml.i b/interface-definitions/include/dhcp-options.xml.i index 0f71d9321..9989291fc 100644 --- a/interface-definitions/include/dhcp-options.xml.i +++ b/interface-definitions/include/dhcp-options.xml.i @@ -1,6 +1,6 @@ - DHCP options + DHCP client settings/options diff --git a/interface-definitions/include/dhcpv6-options.xml.i b/interface-definitions/include/dhcpv6-options.xml.i index 98a87dba2..5d088b83d 100644 --- a/interface-definitions/include/dhcpv6-options.xml.i +++ b/interface-definitions/include/dhcpv6-options.xml.i @@ -1,11 +1,24 @@ - DHCPv6 options + DHCPv6 client settings/options - + + + Acquire only config parameters, no address + + + + - DHCPv6 Prefix Delegation Options + DHCPv6 prefix delegation interface statement + + instance number + Prefix delegation instance (>= 0) + + + + @@ -19,6 +32,7 @@ + 64 @@ -52,28 +66,10 @@ - - - Site-Level aggregator (SLA) length - - 0-128 - Length of delegated prefix - - - - - - - - - - Acquire only config parameters, no address - - - + IPv6 "temporary" address diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py index 010eda45c..c1e93955e 100644 --- a/python/vyos/configdict.py +++ b/python/vyos/configdict.py @@ -93,7 +93,7 @@ def dict_merge(source, destination): tmp = deepcopy(destination) for key, value in source.items(): - if key not in tmp.keys(): + if key not in tmp: tmp[key] = value elif isinstance(source[key], dict): tmp[key] = dict_merge(source[key], tmp[key]) @@ -109,15 +109,15 @@ def T2665_default_dict_cleanup(dict): """ Cleanup default keys for tag nodes https://phabricator.vyos.net/T2665. """ # Cleanup for vif in ['vif', 'vif_s']: - if vif in dict.keys(): - for key in ['ip', 'mtu']: - if key in dict[vif].keys(): + if vif in dict: + for key in ['ip', 'mtu', 'dhcpv6_options']: + if key in dict[vif]: del dict[vif][key] # cleanup VIF-S defaults - if 'vif_c' in dict[vif].keys(): - for key in ['ip', 'mtu']: - if key in dict[vif]['vif_c'].keys(): + if 'vif_c' in dict[vif]: + for key in ['ip', 'mtu', 'dhcpv6_options']: + if key in dict[vif]['vif_c']: del dict[vif]['vif_c'][key] # If there is no vif-c defined and we just cleaned the default # keys - we can clean the entire vif-c dict as it's useless @@ -129,6 +129,21 @@ def T2665_default_dict_cleanup(dict): if not dict[vif]: del dict[vif] + if 'dhcpv6_options' in dict and 'pd' in dict['dhcpv6_options']: + if 'length' in dict['dhcpv6_options']['pd']: + del dict['dhcpv6_options']['pd']['length'] + + # delete empty dicts + if 'dhcpv6_options' in dict: + if 'pd' in dict['dhcpv6_options']: + # test if 'pd' is an empty node so we can remove it + if not dict['dhcpv6_options']['pd']: + del dict['dhcpv6_options']['pd'] + + # test if 'dhcpv6_options' is an empty node so we can remove it + if not dict['dhcpv6_options']: + del dict['dhcpv6_options'] + return dict def leaf_node_changed(conf, path): @@ -193,6 +208,16 @@ def get_removed_vlans(conf, dict): return dict + +def dict_add_dhcpv6pd_defaults(defaults, config_dict): + # Implant default dictionary for DHCPv6-PD instances + if 'dhcpv6_options' in config_dict and 'pd' in config_dict['dhcpv6_options']: + for pd, pd_config in config_dict['dhcpv6_options']['pd'].items(): + config_dict['dhcpv6_options']['pd'][pd] = dict_merge( + defaults, pd_config) + + return config_dict + def get_interface_dict(config, base, ifname=''): """ Common utility function to retrieve and mandgle the interfaces available @@ -257,15 +282,30 @@ def get_interface_dict(config, base, ifname=''): # remove wrongly inserted values dict = T2665_default_dict_cleanup(dict) - # The values are identical for vif, vif-s and vif-c as the all include the same - # XML definitions which hold the defaults + # Implant default dictionary for DHCPv6-PD instances + default_pd_values = defaults(base + ['dhcpv6-options', 'pd']) + dict = dict_add_dhcpv6pd_defaults(default_pd_values, dict) + + # Implant default dictionary in vif/vif-s VLAN interfaces. Values are + # identical for all types of VLAN interfaces as they all include the same + # XML definitions which hold the defaults. default_vif_values = defaults(base + ['vif']) for vif, vif_config in dict.get('vif', {}).items(): - vif_config = dict_merge(default_vif_values, vif_config) + dict['vif'][vif] = dict_add_dhcpv6pd_defaults( + default_pd_values, vif_config) + dict['vif'][vif] = T2665_default_dict_cleanup( + dict_merge(default_vif_values, vif_config)) + for vif_s, vif_s_config in dict.get('vif_s', {}).items(): - vif_s_config = dict_merge(default_vif_values, vif_s_config) + dict['vif_s'][vif_s] = dict_add_dhcpv6pd_defaults( + default_pd_values, vif_s_config) + dict['vif_s'][vif_s] = T2665_default_dict_cleanup( + dict_merge(default_vif_values, vif_s_config)) for vif_c, vif_c_config in vif_s_config.get('vif_c', {}).items(): - vif_c_config = dict_merge(default_vif_values, vif_c_config) + dict['vif_s'][vif_s]['vif_c'][vif_c] = dict_add_dhcpv6pd_defaults( + default_pd_values, vif_c_config) + dict['vif_s'][vif_s]['vif_c'][vif_c] = T2665_default_dict_cleanup( + dict_merge(default_vif_values, vif_c_config)) # Check vif, vif-s/vif-c VLAN interfaces for removal dict = get_removed_vlans(config, dict) diff --git a/src/conf_mode/interfaces-pppoe.py b/src/conf_mode/interfaces-pppoe.py index 928113b49..901ea769c 100755 --- a/src/conf_mode/interfaces-pppoe.py +++ b/src/conf_mode/interfaces-pppoe.py @@ -15,7 +15,6 @@ # along with this program. If not, see . import os -import jmespath from sys import exit from copy import deepcopy @@ -104,8 +103,7 @@ def generate(pppoe): render(script_pppoe_ipv6_up, 'pppoe/ipv6-up.script.tmpl', pppoe, trim_blocks=True, permission=0o755) - tmp = jmespath.search('dhcpv6_options.prefix_delegation.interface', pppoe) - if tmp and len(tmp) > 0: + if 'dhcpv6_options' in pppoe and 'pd' in pppoe['dhcpv6_options']: # ipv6.tmpl relies on ifname - this should be made consitent in the # future better then double key-ing the same value render(config_wide_dhcp6c, 'dhcp-client/ipv6.tmpl', pppoe, trim_blocks=True) diff --git a/src/migration-scripts/interfaces/11-to-12 b/src/migration-scripts/interfaces/11-to-12 new file mode 100755 index 000000000..0dad24642 --- /dev/null +++ b/src/migration-scripts/interfaces/11-to-12 @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2020 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 . + +# - rename 'dhcpv6-options prefix-delegation' from single node to a new tag node +# 'dhcpv6-options pd 0' +# - delete 'sla-len' from CLI - value is calculated on demand + +from sys import exit, argv +from vyos.configtree import ConfigTree + +if __name__ == '__main__': + if (len(argv) < 1): + print("Must specify file name!") + exit(1) + + file_name = argv[1] + with open(file_name, 'r') as f: + config_file = f.read() + + config = ConfigTree(config_file) + + for type in config.list_nodes(['interfaces']): + for interface in config.list_nodes(['interfaces', type]): + # cache current config tree + base_path = ['interfaces', type, interface, 'dhcpv6-options'] + old_base = base_path + ['prefix-delegation'] + new_base = base_path + ['pd'] + if config.exists(old_base): + config.set(new_base) + config.set_tag(new_base) + config.copy(old_base, new_base + ['0']) + config.delete(old_base) + + for pd in config.list_nodes(new_base): + for tmp in config.list_nodes(new_base + [pd, 'interface']): + sla_config = new_base + [pd, 'interface', tmp, 'sla-len'] + if config.exists(sla_config): + config.delete(sla_config) + + 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)) + exit(1) -- cgit v1.2.3 From ad69fb36201ee0930b76d80f0869284e26846991 Mon Sep 17 00:00:00 2001 From: John Estabrook Date: Fri, 28 Aug 2020 15:50:50 -0500 Subject: configd: T2582: add scripts to include list for daemon --- data/configd-include.json | 65 ++++++++++++++++++++++++++++- src/conf_mode/bcast_relay.py | 7 +++- src/conf_mode/dhcp_relay.py | 7 +++- src/conf_mode/dhcp_server.py | 7 +++- src/conf_mode/dhcpv6_relay.py | 7 +++- src/conf_mode/dhcpv6_server.py | 7 +++- src/conf_mode/dynamic_dns.py | 7 +++- src/conf_mode/firewall_options.py | 7 +++- src/conf_mode/host_name.py | 7 +++- src/conf_mode/http-api.py | 8 +++- src/conf_mode/https.py | 8 +++- src/conf_mode/igmp_proxy.py | 7 +++- src/conf_mode/intel_qat.py | 7 +++- src/conf_mode/interfaces-bonding.py | 7 +++- src/conf_mode/interfaces-bridge.py | 7 +++- src/conf_mode/interfaces-dummy.py | 7 +++- src/conf_mode/interfaces-ethernet.py | 7 +++- src/conf_mode/interfaces-geneve.py | 7 +++- src/conf_mode/interfaces-l2tpv3.py | 7 +++- src/conf_mode/interfaces-loopback.py | 7 +++- src/conf_mode/interfaces-macsec.py | 7 +++- src/conf_mode/interfaces-openvpn.py | 7 +++- src/conf_mode/interfaces-pppoe.py | 7 +++- src/conf_mode/interfaces-pseudo-ethernet.py | 7 +++- src/conf_mode/interfaces-tunnel.py | 8 +++- src/conf_mode/interfaces-vxlan.py | 7 +++- src/conf_mode/interfaces-wireguard.py | 7 +++- src/conf_mode/interfaces-wireless.py | 7 +++- src/conf_mode/interfaces-wirelessmodem.py | 7 +++- src/conf_mode/ipsec-settings.py | 7 +++- src/conf_mode/lldp.py | 7 +++- src/conf_mode/nat.py | 7 +++- src/conf_mode/ntp.py | 7 +++- src/conf_mode/protocols_igmp.py | 7 +++- src/conf_mode/protocols_mpls.py | 7 +++- src/conf_mode/protocols_pim.py | 7 +++- src/conf_mode/protocols_rip.py | 7 +++- src/conf_mode/protocols_static_multicast.py | 7 +++- src/conf_mode/salt-minion.py | 7 +++- src/conf_mode/service_console-server.py | 7 +++- src/conf_mode/service_ids_fastnetmon.py | 7 +++- src/conf_mode/service_ipoe-server.py | 7 +++- src/conf_mode/service_mdns-repeater.py | 7 +++- src/conf_mode/service_pppoe-server.py | 7 +++- src/conf_mode/service_router-advert.py | 7 +++- src/conf_mode/ssh.py | 7 +++- src/conf_mode/system-ip.py | 7 +++- src/conf_mode/system-ipv6.py | 7 +++- src/conf_mode/system-login-banner.py | 7 +++- src/conf_mode/system-login.py | 7 +++- src/conf_mode/system-options.py | 7 +++- src/conf_mode/system-syslog.py | 7 +++- src/conf_mode/system-timezone.py | 7 +++- src/conf_mode/system-wifi-regdom.py | 7 +++- src/conf_mode/system_console.py | 7 +++- src/conf_mode/system_lcd.py | 7 +++- src/conf_mode/task_scheduler.py | 7 +++- src/conf_mode/tftp_server.py | 7 +++- src/conf_mode/vpn_l2tp.py | 7 +++- src/conf_mode/vpn_pptp.py | 7 +++- src/conf_mode/vpn_sstp.py | 7 +++- src/conf_mode/vrf.py | 7 +++- src/conf_mode/vrrp.py | 7 +++- src/conf_mode/vyos_cert.py | 7 +++- 64 files changed, 382 insertions(+), 127 deletions(-) (limited to 'src/conf_mode/interfaces-pppoe.py') diff --git a/data/configd-include.json b/data/configd-include.json index fe51488c7..11d550f59 100644 --- a/data/configd-include.json +++ b/data/configd-include.json @@ -1 +1,64 @@ -[] +[ +"bcast_relay.py", +"dhcp_relay.py", +"dhcp_server.py", +"dhcpv6_relay.py", +"dhcpv6_server.py", +"dynamic_dns.py", +"firewall_options.py", +"host_name.py", +"http-api.py", +"https.py", +"igmp_proxy.py", +"intel_qat.py", +"interfaces-bonding.py", +"interfaces-bridge.py", +"interfaces-dummy.py", +"interfaces-ethernet.py", +"interfaces-geneve.py", +"interfaces-l2tpv3.py", +"interfaces-loopback.py", +"interfaces-macsec.py", +"interfaces-openvpn.py", +"interfaces-pppoe.py", +"interfaces-pseudo-ethernet.py", +"interfaces-tunnel.py", +"interfaces-vxlan.py", +"interfaces-wireguard.py", +"interfaces-wireless.py", +"interfaces-wirelessmodem.py", +"ipsec-settings.py", +"lldp.py", +"nat.py", +"ntp.py", +"protocols_igmp.py", +"protocols_mpls.py", +"protocols_pim.py", +"protocols_rip.py", +"protocols_static_multicast.py", +"salt-minion.py", +"service_console-server.py", +"service_ids_fastnetmon.py", +"service_ipoe-server.py", +"service_mdns-repeater.py", +"service_pppoe-server.py", +"service_router-advert.py", +"ssh.py", +"system-ip.py", +"system-ipv6.py", +"system-login-banner.py", +"system-options.py", +"system-syslog.py", +"system-timezone.py", +"system-wifi-regdom.py", +"system_console.py", +"system_lcd.py", +"task_scheduler.py", +"tftp_server.py", +"vpn_l2tp.py", +"vpn_pptp.py", +"vpn_sstp.py", +"vrf.py", +"vrrp.py", +"vyos_cert.py" +] \ No newline at end of file diff --git a/src/conf_mode/bcast_relay.py b/src/conf_mode/bcast_relay.py index a3e141a00..4a47b9246 100755 --- a/src/conf_mode/bcast_relay.py +++ b/src/conf_mode/bcast_relay.py @@ -29,8 +29,11 @@ airbag.enable() config_file_base = r'/etc/default/udp-broadcast-relay' -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() base = ['service', 'broadcast-relay'] relay = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) diff --git a/src/conf_mode/dhcp_relay.py b/src/conf_mode/dhcp_relay.py index f093a005e..352865b9d 100755 --- a/src/conf_mode/dhcp_relay.py +++ b/src/conf_mode/dhcp_relay.py @@ -36,9 +36,12 @@ default_config_data = { 'relay_agent_packets': 'forward' } -def get_config(): +def get_config(config=None): relay = default_config_data - conf = Config() + if config: + conf = config + else: + conf = Config() if not conf.exists(['service', 'dhcp-relay']): return None else: diff --git a/src/conf_mode/dhcp_server.py b/src/conf_mode/dhcp_server.py index 0eaa14c5b..fd4e2ec61 100755 --- a/src/conf_mode/dhcp_server.py +++ b/src/conf_mode/dhcp_server.py @@ -126,9 +126,12 @@ def dhcp_static_route(static_subnet, static_router): return string -def get_config(): +def get_config(config=None): dhcp = default_config_data - conf = Config() + if config: + conf = config + else: + conf = Config() if not conf.exists('service dhcp-server'): return None else: diff --git a/src/conf_mode/dhcpv6_relay.py b/src/conf_mode/dhcpv6_relay.py index 6ef290bf0..d4212b8be 100755 --- a/src/conf_mode/dhcpv6_relay.py +++ b/src/conf_mode/dhcpv6_relay.py @@ -35,9 +35,12 @@ default_config_data = { 'options': [], } -def get_config(): +def get_config(config=None): relay = deepcopy(default_config_data) - conf = Config() + if config: + conf = config + else: + conf = Config() if not conf.exists('service dhcpv6-relay'): return None else: diff --git a/src/conf_mode/dhcpv6_server.py b/src/conf_mode/dhcpv6_server.py index 53c8358a5..4ce4cada1 100755 --- a/src/conf_mode/dhcpv6_server.py +++ b/src/conf_mode/dhcpv6_server.py @@ -37,9 +37,12 @@ default_config_data = { 'shared_network': [] } -def get_config(): +def get_config(config=None): dhcpv6 = deepcopy(default_config_data) - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['service', 'dhcpv6-server'] if not conf.exists(base): return None diff --git a/src/conf_mode/dynamic_dns.py b/src/conf_mode/dynamic_dns.py index 5b1883c03..57c910a68 100755 --- a/src/conf_mode/dynamic_dns.py +++ b/src/conf_mode/dynamic_dns.py @@ -50,9 +50,12 @@ default_config_data = { 'deleted': False } -def get_config(): +def get_config(config=None): dyndns = deepcopy(default_config_data) - conf = Config() + if config: + conf = config + else: + conf = Config() base_level = ['service', 'dns', 'dynamic'] if not conf.exists(base_level): diff --git a/src/conf_mode/firewall_options.py b/src/conf_mode/firewall_options.py index 71b2a98b3..67bf5d0e2 100755 --- a/src/conf_mode/firewall_options.py +++ b/src/conf_mode/firewall_options.py @@ -32,9 +32,12 @@ default_config_data = { 'new_chain6': False } -def get_config(): +def get_config(config=None): opts = copy.deepcopy(default_config_data) - conf = Config() + if config: + conf = config + else: + conf = Config() if not conf.exists('firewall options'): # bail out early return opts diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py index 9d66bd434..f4c75c257 100755 --- a/src/conf_mode/host_name.py +++ b/src/conf_mode/host_name.py @@ -43,8 +43,11 @@ default_config_data = { hostsd_tag = 'system' -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() hosts = copy.deepcopy(default_config_data) diff --git a/src/conf_mode/http-api.py b/src/conf_mode/http-api.py index b8a084a40..472eb77e4 100755 --- a/src/conf_mode/http-api.py +++ b/src/conf_mode/http-api.py @@ -39,7 +39,7 @@ dependencies = [ 'https.py', ] -def get_config(): +def get_config(config=None): http_api = deepcopy(vyos.defaults.api_data) x = http_api.get('api_keys') if x is None: @@ -48,7 +48,11 @@ def get_config(): default_key = x[0] keys_added = False - conf = Config() + if config: + conf = config + else: + conf = Config() + if not conf.exists('service https api'): return None else: diff --git a/src/conf_mode/https.py b/src/conf_mode/https.py index a13f131ab..dc51cb117 100755 --- a/src/conf_mode/https.py +++ b/src/conf_mode/https.py @@ -47,8 +47,12 @@ default_server_block = { 'certbot' : False } -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() + if not conf.exists('service https'): return None diff --git a/src/conf_mode/igmp_proxy.py b/src/conf_mode/igmp_proxy.py index 49aea9b7f..754f46566 100755 --- a/src/conf_mode/igmp_proxy.py +++ b/src/conf_mode/igmp_proxy.py @@ -36,9 +36,12 @@ default_config_data = { 'interfaces': [], } -def get_config(): +def get_config(config=None): igmp_proxy = deepcopy(default_config_data) - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['protocols', 'igmp-proxy'] if not conf.exists(base): return None diff --git a/src/conf_mode/intel_qat.py b/src/conf_mode/intel_qat.py index 742f09a54..1e5101a9f 100755 --- a/src/conf_mode/intel_qat.py +++ b/src/conf_mode/intel_qat.py @@ -30,8 +30,11 @@ airbag.enable() # Define for recovering gl_ipsec_conf = None -def get_config(): - c = Config() +def get_config(config=None): + if config: + c = config + else: + c = Config() config_data = { 'qat_conf' : None, 'ipsec_conf' : None, diff --git a/src/conf_mode/interfaces-bonding.py b/src/conf_mode/interfaces-bonding.py index 3b238f1ea..16e6e4f6e 100755 --- a/src/conf_mode/interfaces-bonding.py +++ b/src/conf_mode/interfaces-bonding.py @@ -53,12 +53,15 @@ def get_bond_mode(mode): else: raise ConfigError(f'invalid bond mode "{mode}"') -def get_config(): +def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the interface name will be added or a deleted flag """ - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['interfaces', 'bonding'] bond = get_interface_dict(conf, base) diff --git a/src/conf_mode/interfaces-bridge.py b/src/conf_mode/interfaces-bridge.py index ee8e85e73..47c8c05f9 100755 --- a/src/conf_mode/interfaces-bridge.py +++ b/src/conf_mode/interfaces-bridge.py @@ -34,12 +34,15 @@ from vyos import ConfigError from vyos import airbag airbag.enable() -def get_config(): +def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the interface name will be added or a deleted flag """ - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['interfaces', 'bridge'] bridge = get_interface_dict(conf, base) diff --git a/src/conf_mode/interfaces-dummy.py b/src/conf_mode/interfaces-dummy.py index 8df86c8ea..44fc9cb9e 100755 --- a/src/conf_mode/interfaces-dummy.py +++ b/src/conf_mode/interfaces-dummy.py @@ -28,12 +28,15 @@ from vyos import ConfigError from vyos import airbag airbag.enable() -def get_config(): +def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the interface name will be added or a deleted flag """ - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['interfaces', 'dummy'] dummy = get_interface_dict(conf, base) return dummy diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py index 10758e35a..a8df64cce 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -30,12 +30,15 @@ from vyos import ConfigError from vyos import airbag airbag.enable() -def get_config(): +def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the interface name will be added or a deleted flag """ - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['interfaces', 'ethernet'] ethernet = get_interface_dict(conf, base) return ethernet diff --git a/src/conf_mode/interfaces-geneve.py b/src/conf_mode/interfaces-geneve.py index 1104bd3c0..cc2cf025a 100755 --- a/src/conf_mode/interfaces-geneve.py +++ b/src/conf_mode/interfaces-geneve.py @@ -30,12 +30,15 @@ from vyos import ConfigError from vyos import airbag airbag.enable() -def get_config(): +def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the interface name will be added or a deleted flag """ - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['interfaces', 'geneve'] geneve = get_interface_dict(conf, base) return geneve diff --git a/src/conf_mode/interfaces-l2tpv3.py b/src/conf_mode/interfaces-l2tpv3.py index 0978df5b6..8250a3df8 100755 --- a/src/conf_mode/interfaces-l2tpv3.py +++ b/src/conf_mode/interfaces-l2tpv3.py @@ -35,12 +35,15 @@ airbag.enable() k_mod = ['l2tp_eth', 'l2tp_netlink', 'l2tp_ip', 'l2tp_ip6'] -def get_config(): +def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the interface name will be added or a deleted flag """ - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['interfaces', 'l2tpv3'] l2tpv3 = get_interface_dict(conf, base) diff --git a/src/conf_mode/interfaces-loopback.py b/src/conf_mode/interfaces-loopback.py index 0398cd591..30a27abb4 100755 --- a/src/conf_mode/interfaces-loopback.py +++ b/src/conf_mode/interfaces-loopback.py @@ -25,12 +25,15 @@ from vyos import ConfigError from vyos import airbag airbag.enable() -def get_config(): +def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the interface name will be added or a deleted flag """ - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['interfaces', 'loopback'] loopback = get_interface_dict(conf, base) return loopback diff --git a/src/conf_mode/interfaces-macsec.py b/src/conf_mode/interfaces-macsec.py index ca15212d4..2866ccc0a 100755 --- a/src/conf_mode/interfaces-macsec.py +++ b/src/conf_mode/interfaces-macsec.py @@ -35,12 +35,15 @@ airbag.enable() # XXX: wpa_supplicant works on the source interface wpa_suppl_conf = '/run/wpa_supplicant/{source_interface}.conf' -def get_config(): +def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the interface name will be added or a deleted flag """ - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['interfaces', 'macsec'] macsec = get_interface_dict(conf, base) diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py index 1420b4116..958b305dd 100755 --- a/src/conf_mode/interfaces-openvpn.py +++ b/src/conf_mode/interfaces-openvpn.py @@ -192,9 +192,12 @@ def getDefaultServer(network, topology, devtype): return server -def get_config(): +def get_config(config=None): openvpn = deepcopy(default_config_data) - conf = Config() + if config: + conf = config + else: + conf = Config() # determine tagNode instance if 'VYOS_TAGNODE_VALUE' not in os.environ: diff --git a/src/conf_mode/interfaces-pppoe.py b/src/conf_mode/interfaces-pppoe.py index 901ea769c..1b4b9e4ee 100755 --- a/src/conf_mode/interfaces-pppoe.py +++ b/src/conf_mode/interfaces-pppoe.py @@ -30,12 +30,15 @@ from vyos import ConfigError from vyos import airbag airbag.enable() -def get_config(): +def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the interface name will be added or a deleted flag """ - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['interfaces', 'pppoe'] pppoe = get_interface_dict(conf, base) diff --git a/src/conf_mode/interfaces-pseudo-ethernet.py b/src/conf_mode/interfaces-pseudo-ethernet.py index fe2d7b1be..59edca1cc 100755 --- a/src/conf_mode/interfaces-pseudo-ethernet.py +++ b/src/conf_mode/interfaces-pseudo-ethernet.py @@ -34,12 +34,15 @@ from vyos import ConfigError from vyos import airbag airbag.enable() -def get_config(): +def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the interface name will be added or a deleted flag """ - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['interfaces', 'pseudo-ethernet'] peth = get_interface_dict(conf, base) diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py index ea15a7fb7..11d8d6edc 100755 --- a/src/conf_mode/interfaces-tunnel.py +++ b/src/conf_mode/interfaces-tunnel.py @@ -397,12 +397,16 @@ def ip_proto (afi): return 6 if afi == IP6 else 4 -def get_config(): +def get_config(config=None): ifname = os.environ.get('VYOS_TAGNODE_VALUE','') if not ifname: raise ConfigError('Interface not specified') - config = Config() + if config: + config = config + else: + config = Config() + conf = ConfigurationState(config, ['interfaces', 'tunnel ', ifname], default_config_data) options = conf.options changes = conf.changes diff --git a/src/conf_mode/interfaces-vxlan.py b/src/conf_mode/interfaces-vxlan.py index 47c0bdcb8..bea3aa25b 100755 --- a/src/conf_mode/interfaces-vxlan.py +++ b/src/conf_mode/interfaces-vxlan.py @@ -30,12 +30,15 @@ from vyos import ConfigError from vyos import airbag airbag.enable() -def get_config(): +def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the interface name will be added or a deleted flag """ - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['interfaces', 'vxlan'] vxlan = get_interface_dict(conf, base) diff --git a/src/conf_mode/interfaces-wireguard.py b/src/conf_mode/interfaces-wireguard.py index 8b64cde4d..e7c22da1a 100755 --- a/src/conf_mode/interfaces-wireguard.py +++ b/src/conf_mode/interfaces-wireguard.py @@ -33,12 +33,15 @@ from vyos import ConfigError from vyos import airbag airbag.enable() -def get_config(): +def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the interface name will be added or a deleted flag """ - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['interfaces', 'wireguard'] wireguard = get_interface_dict(conf, base) diff --git a/src/conf_mode/interfaces-wireless.py b/src/conf_mode/interfaces-wireless.py index b6f247952..9861f72db 100755 --- a/src/conf_mode/interfaces-wireless.py +++ b/src/conf_mode/interfaces-wireless.py @@ -64,12 +64,15 @@ def find_other_stations(conf, base, ifname): conf.set_level(old_level) return dict -def get_config(): +def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the interface name will be added or a deleted flag """ - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['interfaces', 'wireless'] wifi = get_interface_dict(conf, base) diff --git a/src/conf_mode/interfaces-wirelessmodem.py b/src/conf_mode/interfaces-wirelessmodem.py index 6d168d918..7d8110096 100755 --- a/src/conf_mode/interfaces-wirelessmodem.py +++ b/src/conf_mode/interfaces-wirelessmodem.py @@ -31,12 +31,15 @@ airbag.enable() k_mod = ['option', 'usb_wwan', 'usbserial'] -def get_config(): +def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the interface name will be added or a deleted flag """ - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['interfaces', 'wirelessmodem'] wwan = get_interface_dict(conf, base) return wwan diff --git a/src/conf_mode/ipsec-settings.py b/src/conf_mode/ipsec-settings.py index 015d1a480..11a5b7aaa 100755 --- a/src/conf_mode/ipsec-settings.py +++ b/src/conf_mode/ipsec-settings.py @@ -41,8 +41,11 @@ delim_ipsec_l2tp_begin = "### VyOS L2TP VPN Begin ###" delim_ipsec_l2tp_end = "### VyOS L2TP VPN End ###" charon_pidfile = "/var/run/charon.pid" -def get_config(): - config = Config() +def get_config(config=None): + if config: + config = config + else: + config = Config() data = {"install_routes": "yes"} if config.exists("vpn ipsec options disable-route-autoinstall"): diff --git a/src/conf_mode/lldp.py b/src/conf_mode/lldp.py index 1b539887a..6b645857a 100755 --- a/src/conf_mode/lldp.py +++ b/src/conf_mode/lldp.py @@ -146,9 +146,12 @@ def get_location(config): return intfs_location -def get_config(): +def get_config(config=None): lldp = deepcopy(default_config_data) - conf = Config() + if config: + conf = config + else: + conf = Config() if not conf.exists(base): return None else: diff --git a/src/conf_mode/nat.py b/src/conf_mode/nat.py index f79f0f42b..eb634fd78 100755 --- a/src/conf_mode/nat.py +++ b/src/conf_mode/nat.py @@ -167,9 +167,12 @@ def parse_configuration(conf, source_dest): return ruleset -def get_config(): +def get_config(config=None): nat = deepcopy(default_config_data) - conf = Config() + if config: + conf = config + else: + conf = Config() # read in current nftable (once) for further processing tmp = cmd('nft -j list table raw') diff --git a/src/conf_mode/ntp.py b/src/conf_mode/ntp.py index bba8f87a4..d6453ec83 100755 --- a/src/conf_mode/ntp.py +++ b/src/conf_mode/ntp.py @@ -27,8 +27,11 @@ airbag.enable() config_file = r'/etc/ntp.conf' systemd_override = r'/etc/systemd/system/ntp.service.d/override.conf' -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() base = ['system', 'ntp'] ntp = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) diff --git a/src/conf_mode/protocols_igmp.py b/src/conf_mode/protocols_igmp.py index ca148fd6a..6f4fc784d 100755 --- a/src/conf_mode/protocols_igmp.py +++ b/src/conf_mode/protocols_igmp.py @@ -29,8 +29,11 @@ airbag.enable() config_file = r'/tmp/igmp.frr' -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() igmp_conf = { 'igmp_conf' : False, 'old_ifaces' : {}, diff --git a/src/conf_mode/protocols_mpls.py b/src/conf_mode/protocols_mpls.py index bcb16fa04..e515490d0 100755 --- a/src/conf_mode/protocols_mpls.py +++ b/src/conf_mode/protocols_mpls.py @@ -29,8 +29,11 @@ config_file = r'/tmp/ldpd.frr' def sysctl(name, value): call('sysctl -wq {}={}'.format(name, value)) -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() mpls_conf = { 'router_id' : None, 'mpls_ldp' : False, diff --git a/src/conf_mode/protocols_pim.py b/src/conf_mode/protocols_pim.py index 8aa324bac..6d333e19a 100755 --- a/src/conf_mode/protocols_pim.py +++ b/src/conf_mode/protocols_pim.py @@ -29,8 +29,11 @@ airbag.enable() config_file = r'/tmp/pimd.frr' -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() pim_conf = { 'pim_conf' : False, 'old_pim' : { diff --git a/src/conf_mode/protocols_rip.py b/src/conf_mode/protocols_rip.py index 95e8ce901..8ddd705f2 100755 --- a/src/conf_mode/protocols_rip.py +++ b/src/conf_mode/protocols_rip.py @@ -28,8 +28,11 @@ airbag.enable() config_file = r'/tmp/ripd.frr' -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() base = ['protocols', 'rip'] rip_conf = { 'rip_conf' : False, diff --git a/src/conf_mode/protocols_static_multicast.py b/src/conf_mode/protocols_static_multicast.py index 232d1e181..99157835a 100755 --- a/src/conf_mode/protocols_static_multicast.py +++ b/src/conf_mode/protocols_static_multicast.py @@ -30,8 +30,11 @@ airbag.enable() config_file = r'/tmp/static_mcast.frr' # Get configuration for static multicast route -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() mroute = { 'old_mroute' : {}, 'mroute' : {} diff --git a/src/conf_mode/salt-minion.py b/src/conf_mode/salt-minion.py index 3343d1247..841bf6a39 100755 --- a/src/conf_mode/salt-minion.py +++ b/src/conf_mode/salt-minion.py @@ -44,9 +44,12 @@ default_config_data = { 'master_key': '' } -def get_config(): +def get_config(config=None): salt = deepcopy(default_config_data) - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['service', 'salt-minion'] if not conf.exists(base): diff --git a/src/conf_mode/service_console-server.py b/src/conf_mode/service_console-server.py index 613ec6879..0e5fc75b0 100755 --- a/src/conf_mode/service_console-server.py +++ b/src/conf_mode/service_console-server.py @@ -27,8 +27,11 @@ from vyos import ConfigError config_file = r'/run/conserver/conserver.cf' -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() base = ['service', 'console-server'] # Retrieve CLI representation as dictionary diff --git a/src/conf_mode/service_ids_fastnetmon.py b/src/conf_mode/service_ids_fastnetmon.py index d46f9578e..27d0ee60c 100755 --- a/src/conf_mode/service_ids_fastnetmon.py +++ b/src/conf_mode/service_ids_fastnetmon.py @@ -28,8 +28,11 @@ airbag.enable() config_file = r'/etc/fastnetmon.conf' networks_list = r'/etc/networks_list' -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() base = ['service', 'ids', 'ddos-protection'] fastnetmon = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) return fastnetmon diff --git a/src/conf_mode/service_ipoe-server.py b/src/conf_mode/service_ipoe-server.py index 553cc2e97..96cf932d1 100755 --- a/src/conf_mode/service_ipoe-server.py +++ b/src/conf_mode/service_ipoe-server.py @@ -55,8 +55,11 @@ default_config_data = { 'thread_cnt': get_half_cpus() } -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() base_path = ['service', 'ipoe-server'] if not conf.exists(base_path): return None diff --git a/src/conf_mode/service_mdns-repeater.py b/src/conf_mode/service_mdns-repeater.py index 1a6b2c328..729518c96 100755 --- a/src/conf_mode/service_mdns-repeater.py +++ b/src/conf_mode/service_mdns-repeater.py @@ -28,8 +28,11 @@ airbag.enable() config_file = r'/etc/default/mdns-repeater' -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() base = ['service', 'mdns', 'repeater'] mdns = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) return mdns diff --git a/src/conf_mode/service_pppoe-server.py b/src/conf_mode/service_pppoe-server.py index 39d34a7e2..45d3806d5 100755 --- a/src/conf_mode/service_pppoe-server.py +++ b/src/conf_mode/service_pppoe-server.py @@ -85,8 +85,11 @@ default_config_data = { 'thread_cnt': get_half_cpus() } -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() base_path = ['service', 'pppoe-server'] if not conf.exists(base_path): return None diff --git a/src/conf_mode/service_router-advert.py b/src/conf_mode/service_router-advert.py index 4e1c432ab..687d7068f 100755 --- a/src/conf_mode/service_router-advert.py +++ b/src/conf_mode/service_router-advert.py @@ -29,8 +29,11 @@ airbag.enable() config_file = r'/run/radvd/radvd.conf' -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() base = ['service', 'router-advert'] rtradv = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) diff --git a/src/conf_mode/ssh.py b/src/conf_mode/ssh.py index 7b262565a..a19fa72d8 100755 --- a/src/conf_mode/ssh.py +++ b/src/conf_mode/ssh.py @@ -31,8 +31,11 @@ airbag.enable() config_file = r'/run/ssh/sshd_config' systemd_override = r'/etc/systemd/system/ssh.service.d/override.conf' -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() base = ['service', 'ssh'] if not conf.exists(base): return None diff --git a/src/conf_mode/system-ip.py b/src/conf_mode/system-ip.py index 85f1e3771..64c9e6d05 100755 --- a/src/conf_mode/system-ip.py +++ b/src/conf_mode/system-ip.py @@ -35,9 +35,12 @@ default_config_data = { def sysctl(name, value): call('sysctl -wq {}={}'.format(name, value)) -def get_config(): +def get_config(config=None): ip_opt = deepcopy(default_config_data) - conf = Config() + if config: + conf = config + else: + conf = Config() conf.set_level('system ip') if conf.exists(''): if conf.exists('arp table-size'): diff --git a/src/conf_mode/system-ipv6.py b/src/conf_mode/system-ipv6.py index 3417c609d..f70ec2631 100755 --- a/src/conf_mode/system-ipv6.py +++ b/src/conf_mode/system-ipv6.py @@ -41,9 +41,12 @@ default_config_data = { def sysctl(name, value): call('sysctl -wq {}={}'.format(name, value)) -def get_config(): +def get_config(config=None): ip_opt = deepcopy(default_config_data) - conf = Config() + if config: + conf = config + else: + conf = Config() conf.set_level('system ipv6') if conf.exists(''): ip_opt['disable_addr_assignment'] = conf.exists('disable') diff --git a/src/conf_mode/system-login-banner.py b/src/conf_mode/system-login-banner.py index 5c0adc921..569010735 100755 --- a/src/conf_mode/system-login-banner.py +++ b/src/conf_mode/system-login-banner.py @@ -41,9 +41,12 @@ default_config_data = { 'motd': motd } -def get_config(): +def get_config(config=None): banner = default_config_data - conf = Config() + if config: + conf = config + else: + conf = Config() base_level = ['system', 'login', 'banner'] if not conf.exists(base_level): diff --git a/src/conf_mode/system-login.py b/src/conf_mode/system-login.py index b1dd583b5..2aca199f9 100755 --- a/src/conf_mode/system-login.py +++ b/src/conf_mode/system-login.py @@ -56,9 +56,12 @@ def get_local_users(): return local_users -def get_config(): +def get_config(config=None): login = default_config_data - conf = Config() + if config: + conf = config + else: + conf = Config() base_level = ['system', 'login'] # We do not need to check if the nodes exist or not and bail out early diff --git a/src/conf_mode/system-options.py b/src/conf_mode/system-options.py index 0aacd19d8..6ac35a4ab 100755 --- a/src/conf_mode/system-options.py +++ b/src/conf_mode/system-options.py @@ -31,8 +31,11 @@ curlrc_config = r'/etc/curlrc' ssh_config = r'/etc/ssh/ssh_config' systemd_action_file = '/lib/systemd/system/ctrl-alt-del.target' -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() base = ['system', 'options'] options = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) return options diff --git a/src/conf_mode/system-syslog.py b/src/conf_mode/system-syslog.py index cfc1ca55f..d29109c41 100755 --- a/src/conf_mode/system-syslog.py +++ b/src/conf_mode/system-syslog.py @@ -27,8 +27,11 @@ from vyos.template import render from vyos import airbag airbag.enable() -def get_config(): - c = Config() +def get_config(config=None): + if config: + c = config + else: + c = Config() if not c.exists('system syslog'): return None c.set_level('system syslog') diff --git a/src/conf_mode/system-timezone.py b/src/conf_mode/system-timezone.py index 0f4513122..4d9f017a6 100755 --- a/src/conf_mode/system-timezone.py +++ b/src/conf_mode/system-timezone.py @@ -29,9 +29,12 @@ default_config_data = { 'name': 'UTC' } -def get_config(): +def get_config(config=None): tz = deepcopy(default_config_data) - conf = Config() + if config: + conf = config + else: + conf = Config() if conf.exists('system time-zone'): tz['name'] = conf.return_value('system time-zone') diff --git a/src/conf_mode/system-wifi-regdom.py b/src/conf_mode/system-wifi-regdom.py index 30ea89098..874f93923 100755 --- a/src/conf_mode/system-wifi-regdom.py +++ b/src/conf_mode/system-wifi-regdom.py @@ -34,9 +34,12 @@ default_config_data = { 'deleted' : False } -def get_config(): +def get_config(config=None): regdom = deepcopy(default_config_data) - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['system', 'wifi-regulatory-domain'] # Check if interface has been removed diff --git a/src/conf_mode/system_console.py b/src/conf_mode/system_console.py index 6f83335f3..b17818797 100755 --- a/src/conf_mode/system_console.py +++ b/src/conf_mode/system_console.py @@ -26,8 +26,11 @@ airbag.enable() by_bus_dir = '/dev/serial/by-bus' -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() base = ['system', 'console'] # retrieve configuration at once diff --git a/src/conf_mode/system_lcd.py b/src/conf_mode/system_lcd.py index 31a09252d..a540d1b9e 100755 --- a/src/conf_mode/system_lcd.py +++ b/src/conf_mode/system_lcd.py @@ -29,8 +29,11 @@ airbag.enable() lcdd_conf = '/run/LCDd/LCDd.conf' lcdproc_conf = '/run/lcdproc/lcdproc.conf' -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() base = ['system', 'lcd'] lcd = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) diff --git a/src/conf_mode/task_scheduler.py b/src/conf_mode/task_scheduler.py index 51d8684cb..129be5d3c 100755 --- a/src/conf_mode/task_scheduler.py +++ b/src/conf_mode/task_scheduler.py @@ -53,8 +53,11 @@ def make_command(executable, arguments): else: return("sg vyattacfg \"{0}\"".format(executable)) -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() conf.set_level("system task-scheduler task") task_names = conf.list_nodes("") tasks = [] diff --git a/src/conf_mode/tftp_server.py b/src/conf_mode/tftp_server.py index d31851bef..ad5ee9c33 100755 --- a/src/conf_mode/tftp_server.py +++ b/src/conf_mode/tftp_server.py @@ -40,9 +40,12 @@ default_config_data = { 'listen': [] } -def get_config(): +def get_config(config=None): tftpd = deepcopy(default_config_data) - conf = Config() + if config: + conf = config + else: + conf = Config() base = ['service', 'tftp-server'] if not conf.exists(base): return None diff --git a/src/conf_mode/vpn_l2tp.py b/src/conf_mode/vpn_l2tp.py index 26ad1af84..13831dcd8 100755 --- a/src/conf_mode/vpn_l2tp.py +++ b/src/conf_mode/vpn_l2tp.py @@ -70,8 +70,11 @@ default_config_data = { 'thread_cnt': get_half_cpus() } -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() base_path = ['vpn', 'l2tp', 'remote-access'] if not conf.exists(base_path): return None diff --git a/src/conf_mode/vpn_pptp.py b/src/conf_mode/vpn_pptp.py index 32cbadd74..9f3b40534 100755 --- a/src/conf_mode/vpn_pptp.py +++ b/src/conf_mode/vpn_pptp.py @@ -56,8 +56,11 @@ default_pptp = { 'thread_cnt': get_half_cpus() } -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() base_path = ['vpn', 'pptp', 'remote-access'] if not conf.exists(base_path): return None diff --git a/src/conf_mode/vpn_sstp.py b/src/conf_mode/vpn_sstp.py index ddb499bf4..7fc370f99 100755 --- a/src/conf_mode/vpn_sstp.py +++ b/src/conf_mode/vpn_sstp.py @@ -65,10 +65,13 @@ default_config_data = { 'thread_cnt' : get_half_cpus() } -def get_config(): +def get_config(config=None): sstp = deepcopy(default_config_data) base_path = ['vpn', 'sstp'] - conf = Config() + if config: + conf = config + else: + conf = Config() if not conf.exists(base_path): return None diff --git a/src/conf_mode/vrf.py b/src/conf_mode/vrf.py index 56ca813ff..2f4da0240 100755 --- a/src/conf_mode/vrf.py +++ b/src/conf_mode/vrf.py @@ -76,8 +76,11 @@ def vrf_routing(c, match): return matched -def get_config(): - conf = Config() +def get_config(config=None): + if config: + conf = config + else: + conf = Config() vrf_config = deepcopy(default_config_data) cfg_base = ['vrf'] diff --git a/src/conf_mode/vrrp.py b/src/conf_mode/vrrp.py index 292eb0c78..f1ceb261b 100755 --- a/src/conf_mode/vrrp.py +++ b/src/conf_mode/vrrp.py @@ -32,11 +32,14 @@ from vyos.ifconfig.vrrp import VRRP from vyos import airbag airbag.enable() -def get_config(): +def get_config(config=None): vrrp_groups = [] sync_groups = [] - config = vyos.config.Config() + if config: + config = config + else: + config = vyos.config.Config() # Get the VRRP groups for group_name in config.list_nodes("high-availability vrrp group"): diff --git a/src/conf_mode/vyos_cert.py b/src/conf_mode/vyos_cert.py index fb4644d5a..dc7c64684 100755 --- a/src/conf_mode/vyos_cert.py +++ b/src/conf_mode/vyos_cert.py @@ -103,10 +103,13 @@ def generate_self_signed(cert_data): if san_config: san_config.close() -def get_config(): +def get_config(config=None): vyos_cert = vyos.defaults.vyos_cert_data - conf = Config() + if config: + conf = config + else: + conf = Config() if not conf.exists('service https certificates system-generated-certificate'): return None else: -- cgit v1.2.3