#!/usr/bin/env python3 # De-nest PPPoE interfaces # Migrate boolean nodes to valueless import sys from vyos.configtree import ConfigTree def migrate_dialer(config, tree, intf): for pppoe in config.list_nodes(tree): # assemble string, 0 -> pppoe0 new_base = ['interfaces', 'pppoe', 'pppoe' + pppoe] config.set(new_base) # format as tag node to avoid loading problems config.set_tag(['interfaces', 'pppoe']) # # Firewall migrieren # firewall = tree + [pppoe, 'firewall'] if config.exists(firewall): config.copy(firewall, new_base + ['firewall']) policy = tree + [pppoe, 'policy'] if config.exists(policy): config.copy(policy, new_base + ['policy']) # # QoS migrieren # redirect = tree + [pppoe, 'redirect'] if config.exists(redirect): config.copy(redirect, new_base + ['redirect']) traffic_policy = tree + [pppoe, 'traffic-policy'] if config.exists(traffic_policy): config.copy(traffic_policy, new_base + ['traffic-policy']) # # Quagga migrieren # ip = tree + [pppoe, 'ip'] if config.exists(ip): config.copy(ip, new_base + ['ip']) ipv6 = tree + [pppoe, 'ipv6'] if config.exists(ipv6): config.copy(ipv6, new_base + ['ipv6']) # # Interface migration # config.set(new_base + ['link'], value=intf) default_route = tree + [pppoe, 'default-route'] if config.exists(default_route): tmp = config.return_value(default_route) config.set(new_base + ['default-route'], value=tmp) disable = tree + [pppoe, 'disable'] if config.exists(disable): tmp = config.return_value(disable) config.set(new_base + ['disable'], value=tmp) mtu = tree + [pppoe, 'mtu'] if config.exists(mtu): tmp = config.return_value(mtu) config.set(new_base + ['mtu'], value=tmp) nameserver = tree + [pppoe, 'name-server'] if config.exists(nameserver): tmp = config.return_value(nameserver) config.set(new_base + ['name-server'], value=tmp) password = tree + [pppoe, 'password'] if config.exists(password): tmp = config.return_value(password) config.set(new_base + ['password'], value=tmp) userid = tree + [pppoe, 'user-id'] if config.exists(userid): tmp = config.return_value(userid) config.set(new_base + ['user-id'], value=tmp) # remove enable-ipv6 node and rather place it under ipv6 node ipv6_enable = tree + [pppoe, 'enable-ipv6'] if config.exists(ipv6_enable): config.set(new_base + ['ipv6', 'enable']) ipv6_slaac = tree + [pppoe, 'ipv6', 'address', 'autoconf'] if config.exists(ipv6_slaac): config.set(new_base + ['ipv6', 'address', 'autoconf']) if __name__ == '__main__': if (len(sys.argv) < 1): print("Must specify file name!") exit(1) file_name = sys.argv[1] with open(file_name, 'r') as f: config_file = f.read() config = ConfigTree(config_file) pppoe_links = ['bonding', 'ethernet'] for link_type in pppoe_links: if not config.exists(['interfaces', link_type]): continue for interface in config.list_nodes(['interfaces', link_type]): # check if PPPoE exists base_if = ['interfaces', link_type, interface] pppoe_if = base_if + ['pppoe'] if config.exists(pppoe_if): for dialer in config.list_nodes(pppoe_if): migrate_dialer(config, pppoe_if, interface) # Delete old PPPoE interface config.delete(pppoe_if) # bail out early if there are no VLAN interfaces to migrate if not config.exists(base_if + ['vif']): continue # Migrate PPPoE interfaces attached to a VLAN for vlan in config.list_nodes(base_if + ['vif']): vlan_if = base_if + ['vif', vlan] pppoe_if = vlan_if + ['pppoe'] if config.exists(pppoe_if): for dialer in config.list_nodes(pppoe_if): intf = "{}.{}".format(interface, vlan) migrate_dialer(config, pppoe_if, intf) # Delete old PPPoE interface config.delete(pppoe_if) # Add interface description that this is required for PPPoE if not config.exists(vlan_if + ['description']): config.set(vlan_if + ['description'], value='PPPoE link interface') 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)) sys.exit(1)