diff options
Diffstat (limited to 'python/vyos/configdict.py')
-rw-r--r-- | python/vyos/configdict.py | 87 |
1 files changed, 59 insertions, 28 deletions
diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py index 04ddc10e9..53decfbf5 100644 --- a/python/vyos/configdict.py +++ b/python/vyos/configdict.py @@ -201,11 +201,12 @@ def is_member(conf, interface, intftype=None): intftype is optional, if not passed it will search all known types (currently bridge and bonding) - Returns: - None -> Interface is not a member - interface name -> Interface is a member of this interface - False -> interface type cannot have members + Returns: dict + empty -> Interface is not a member + key -> Interface is a member of this interface """ + from vyos.ifconfig import Section + ret_val = {} intftypes = ['bonding', 'bridge'] @@ -222,7 +223,8 @@ def is_member(conf, interface, intftype=None): member = base + [intf, 'member', 'interface', interface] if conf.exists(member): tmp = conf.get_config_dict(member, key_mangling=('-', '_'), - get_first_key=True, no_tag_node_value_mangle=True) + get_first_key=True, + no_tag_node_value_mangle=True) ret_val.update({intf : tmp}) return ret_val @@ -293,16 +295,23 @@ def is_source_interface(conf, interface, intftype=None): """ ret_val = None intftypes = ['macsec', 'pppoe', 'pseudo-ethernet', 'tunnel', 'vxlan'] - if intftype not in intftypes + [None]: + if not intftype: + intftype = intftypes + + if isinstance(intftype, str): + intftype = [intftype] + elif not isinstance(intftype, list): + raise ValueError(f'Interface type "{type(intftype)}" must be either str or list!') + + if not all(x in intftypes for x in intftype): raise ValueError(f'unknown interface type "{intftype}" or it can not ' 'have a source-interface') - intftype = intftypes if intftype == None else [intftype] for it in intftype: base = ['interfaces', it] for intf in conf.list_nodes(base): - lower_intf = base + [intf, 'source-interface'] - if conf.exists(lower_intf) and interface in conf.return_values(lower_intf): + src_intf = base + [intf, 'source-interface'] + if conf.exists(src_intf) and interface in conf.return_values(src_intf): ret_val = intf break @@ -358,13 +367,14 @@ def get_pppoe_interfaces(conf, vrf=None): """ Common helper functions to retrieve all interfaces from current CLI sessions that have DHCP configured. """ pppoe_interfaces = {} + conf.set_level([]) for ifname in conf.list_nodes(['interfaces', 'pppoe']): # always reset config level, as get_interface_dict() will alter it conf.set_level([]) # we already have a dict representation of the config from get_config_dict(), # but with the extended information from get_interface_dict() we also # get the DHCP client default-route-distance default option if not specified. - ifconfig = get_interface_dict(conf, ['interfaces', 'pppoe'], ifname) + _, ifconfig = get_interface_dict(conf, ['interfaces', 'pppoe'], ifname) options = {} if 'default_route_distance' in ifconfig: @@ -455,8 +465,8 @@ def get_interface_dict(config, base, ifname=''): if bond: dict.update({'is_bond_member' : bond}) # Check if any DHCP options changed which require a client restat - dhcp = node_changed(config, ['dhcp-options'], recursive=True) - if dhcp: dict.update({'dhcp_options_changed' : ''}) + dhcp = is_node_changed(config, base + [ifname, 'dhcp-options']) + if dhcp: dict.update({'dhcp_options_changed' : {}}) # Some interfaces come with a source_interface which must also not be part # of any other bond or bridge interface as it is exclusivly assigned as the @@ -515,8 +525,8 @@ def get_interface_dict(config, base, ifname=''): if bridge: dict['vif'][vif].update({'is_bridge_member' : bridge}) # Check if any DHCP options changed which require a client restat - dhcp = node_changed(config, ['vif', vif, 'dhcp-options'], recursive=True) - if dhcp: dict['vif'][vif].update({'dhcp_options_changed' : ''}) + dhcp = is_node_changed(config, base + [ifname, 'vif', vif, 'dhcp-options']) + if dhcp: dict['vif'][vif].update({'dhcp_options_changed' : {}}) for vif_s, vif_s_config in dict.get('vif_s', {}).items(): # Add subinterface name to dictionary @@ -554,8 +564,8 @@ def get_interface_dict(config, base, ifname=''): if bridge: dict['vif_s'][vif_s].update({'is_bridge_member' : bridge}) # Check if any DHCP options changed which require a client restat - dhcp = node_changed(config, ['vif-s', vif_s, 'dhcp-options'], recursive=True) - if dhcp: dict['vif_s'][vif_s].update({'dhcp_options_changed' : ''}) + dhcp = is_node_changed(config, base + [ifname, 'vif-s', vif_s, 'dhcp-options']) + if dhcp: dict['vif_s'][vif_s].update({'dhcp_options_changed' : {}}) for vif_c, vif_c_config in vif_s_config.get('vif_c', {}).items(): # Add subinterface name to dictionary @@ -594,8 +604,8 @@ def get_interface_dict(config, base, ifname=''): {'is_bridge_member' : bridge}) # Check if any DHCP options changed which require a client restat - dhcp = node_changed(config, ['vif-s', vif_s, 'vif-c', vif_c, 'dhcp-options'], recursive=True) - if dhcp: dict['vif_s'][vif_s]['vif_c'][vif_c].update({'dhcp_options_changed' : ''}) + dhcp = is_node_changed(config, base + [ifname, 'vif-s', vif_s, 'vif-c', vif_c, 'dhcp-options']) + if dhcp: dict['vif_s'][vif_s]['vif_c'][vif_c].update({'dhcp_options_changed' : {}}) # Check vif, vif-s/vif-c VLAN interfaces for removal dict = get_removed_vlans(config, base + [ifname], dict) @@ -633,7 +643,9 @@ def get_accel_dict(config, base, chap_secrets): from vyos.util import get_half_cpus from vyos.template import is_ipv4 - dict = config.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True, no_tag_node_value_mangle=True) + dict = config.get_config_dict(base, key_mangling=('-', '_'), + get_first_key=True, + no_tag_node_value_mangle=True) # We have gathered the dict representation of the CLI, but there are default # options which we need to update into the dictionary retrived. @@ -653,6 +665,18 @@ def get_accel_dict(config, base, chap_secrets): # added to individual local users instead - so we can simply delete them if dict_search('client_ipv6_pool.prefix.mask', default_values): del default_values['client_ipv6_pool']['prefix']['mask'] + # delete empty dicts + if len (default_values['client_ipv6_pool']['prefix']) == 0: + del default_values['client_ipv6_pool']['prefix'] + if len (default_values['client_ipv6_pool']) == 0: + del default_values['client_ipv6_pool'] + + # T2665: IPoE only - it has an interface tag node + # added to individual local users instead - so we can simply delete them + if dict_search('authentication.interface', default_values): + del default_values['authentication']['interface'] + if dict_search('interface', default_values): + del default_values['interface'] dict = dict_merge(default_values, dict) @@ -674,11 +698,9 @@ def get_accel_dict(config, base, chap_secrets): dict.update({'name_server_ipv4' : ns_v4, 'name_server_ipv6' : ns_v6}) del dict['name_server'] - # Add individual RADIUS server default values + # T2665: Add individual RADIUS server default values if dict_search('authentication.radius.server', dict): - # T2665 default_values = defaults(base + ['authentication', 'radius', 'server']) - for server in dict_search('authentication.radius.server', dict): dict['authentication']['radius']['server'][server] = dict_merge( default_values, dict['authentication']['radius']['server'][server]) @@ -688,22 +710,31 @@ def get_accel_dict(config, base, chap_secrets): if 'disable_accounting' in dict['authentication']['radius']['server'][server]: dict['authentication']['radius']['server'][server]['acct_port'] = '0' - # Add individual local-user default values + # T2665: Add individual local-user default values if dict_search('authentication.local_users.username', dict): - # T2665 default_values = defaults(base + ['authentication', 'local-users', 'username']) - for username in dict_search('authentication.local_users.username', dict): dict['authentication']['local_users']['username'][username] = dict_merge( default_values, dict['authentication']['local_users']['username'][username]) - # Add individual IPv6 client-pool default mask if required + # T2665: Add individual IPv6 client-pool default mask if required if dict_search('client_ipv6_pool.prefix', dict): - # T2665 default_values = defaults(base + ['client-ipv6-pool', 'prefix']) - for prefix in dict_search('client_ipv6_pool.prefix', dict): dict['client_ipv6_pool']['prefix'][prefix] = dict_merge( default_values, dict['client_ipv6_pool']['prefix'][prefix]) + # T2665: IPoE only - add individual local-user default values + if dict_search('authentication.interface', dict): + default_values = defaults(base + ['authentication', 'interface']) + for interface in dict_search('authentication.interface', dict): + dict['authentication']['interface'][interface] = dict_merge( + default_values, dict['authentication']['interface'][interface]) + + if dict_search('interface', dict): + default_values = defaults(base + ['interface']) + for interface in dict_search('interface', dict): + dict['interface'][interface] = dict_merge(default_values, + dict['interface'][interface]) + return dict |