diff options
author | hagbard <vyosdev@derith.de> | 2019-09-04 13:18:02 -0700 |
---|---|---|
committer | hagbard <vyosdev@derith.de> | 2019-09-04 13:18:02 -0700 |
commit | d1a121d54e114640da6f020c859865c9b5259091 (patch) | |
tree | a9e9b98165ef8688b339cfd954209b3892db3851 /python | |
parent | a4f34dfe7e003510a4e6263b012b79221a5a786f (diff) | |
parent | 952871200ecee584e7ed1bcb37bdaa06111e3a72 (diff) | |
download | vyos-1x-d1a121d54e114640da6f020c859865c9b5259091.tar.gz vyos-1x-d1a121d54e114640da6f020c859865c9b5259091.zip |
Merge branch 'current' of https://github.com/vyos/vyos-1x into current
Diffstat (limited to 'python')
-rw-r--r-- | python/vyos/configdict.py | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py index 157011839..4bc8863bb 100644 --- a/python/vyos/configdict.py +++ b/python/vyos/configdict.py @@ -18,6 +18,7 @@ A library for retrieving value dicts from VyOS configs in a declarative fashion. """ +from vyos import ConfigError def retrieve_config(path_hash, base_path, config): """ @@ -78,3 +79,118 @@ def retrieve_config(path_hash, base_path, config): config_hash[k][node] = retrieve_config(inner_hash, path + [node], config) return config_hash + + +def list_diff(first, second): + """ + Diff two dictionaries and return only unique items + """ + second = set(second) + return [item for item in first if item not in second] + + +def get_ethertype(ethertype_val): + if ethertype_val == '0x88A8': + return '802.1ad' + elif ethertype_val == '0x8100': + return '802.1q' + else: + raise ConfigError('invalid ethertype "{}"'.format(ethertype_val)) + + +def vlan_to_dict(conf): + """ + Common used function which will extract VLAN related information from config + and represent the result as Python dictionary. + + Function call's itself recursively if a vif-s/vif-c pair is detected. + """ + vlan = { + 'id': conf.get_level().split()[-1], # get the '100' in 'interfaces bonding bond0 vif-s 100' + 'address': [], + 'address_remove': [], + 'description': '', + 'dhcp_client_id': '', + 'dhcp_hostname': '', + 'dhcpv6_prm_only': False, + 'dhcpv6_temporary': False, + 'disable': False, + 'disable_link_detect': 1, + 'mac': '', + 'mtu': 1500 + } + # retrieve configured interface addresses + if conf.exists('address'): + vlan['address'] = conf.return_values('address') + + # Determine interface addresses (currently effective) - to determine which + # address is no longer valid and needs to be removed from the bond + eff_addr = conf.return_effective_values('address') + act_addr = conf.return_values('address') + vlan['address_remove'] = list_diff(eff_addr, act_addr) + + # retrieve interface description + if conf.exists('description'): + vlan['description'] = conf.return_value('description') + + # get DHCP client identifier + if conf.exists('dhcp-options client-id'): + vlan['dhcp_client_id'] = conf.return_value('dhcp-options client-id') + + # DHCP client host name (overrides the system host name) + if conf.exists('dhcp-options host-name'): + vlan['dhcp_hostname'] = conf.return_value('dhcp-options host-name') + + # DHCPv6 only acquire config parameters, no address + if conf.exists('dhcpv6-options parameters-only'): + vlan['dhcpv6_prm_only'] = conf.return_value('dhcpv6-options parameters-only') + + # DHCPv6 temporary IPv6 address + if conf.exists('dhcpv6-options temporary'): + vlan['dhcpv6_temporary'] = conf.return_value('dhcpv6-options temporary') + + # ignore link state changes + if conf.exists('disable-link-detect'): + vlan['disable_link_detect'] = 2 + + # disable bond interface + if conf.exists('disable'): + vlan['disable'] = True + + # Media Access Control (MAC) address + if conf.exists('mac'): + vlan['mac'] = conf.return_value('mac') + + # Maximum Transmission Unit (MTU) + if conf.exists('mtu'): + vlan['mtu'] = int(conf.return_value('mtu')) + + # ethertype is mandatory on vif-s nodes and only exists here! + # check if this is a vif-s node at all: + if conf.get_level().split()[-2] == 'vif-s': + vlan['vif_c'] = [] + vlan['vif_c_remove'] = [] + + # ethertype uses a default of 0x88A8 + tmp = '0x88A8' + if conf.exists('ethertype'): + tmp = conf.return_value('ethertype') + vlan['ethertype'] = get_ethertype(tmp) + + # get vif-c interfaces (currently effective) - to determine which vif-c + # interface is no longer present and needs to be removed + eff_intf = conf.list_effective_nodes('vif-c') + act_intf = conf.list_nodes('vif-c') + vlan['vif_c_remove'] = list_diff(eff_intf, act_intf) + + # check if there is a Q-in-Q vlan customer interface + # and call this function recursively + if conf.exists('vif-c'): + cfg_level = conf.get_level() + # add new key (vif-c) to dictionary + for vif in conf.list_nodes('vif-c'): + # set config level to vif interface + conf.set_level(cfg_level + ' vif-c ' + vif) + vlan['vif_c'].append(vlan_to_dict(conf)) + + return vlan |