#!/usr/bin/env python3 # Removes boolean operator from: # - "set service dhcp-server shared-network-name <xyz> subnet 172.31.0.0/24 ip-forwarding enable (true|false)" # - "set service dhcp-server shared-network-name <xyz> authoritative (true|false)" # - "set service dhcp-server disabled (true|false)" import sys from vyos.configtree import ConfigTree if len(sys.argv) < 2: print("Must specify file name!") sys.exit(1) file_name = sys.argv[1] with open(file_name, 'r') as f: config_file = f.read() config = ConfigTree(config_file) if not config.exists(['service', 'dhcp-server']): # Nothing to do sys.exit(0) else: base = ['service', 'dhcp-server'] # Make node "set service dhcp-server dynamic-dns-update enable (true|false)" valueless if config.exists(base + ['dynamic-dns-update']): bool_val = config.return_value(base + ['dynamic-dns-update', 'enable']) # Delete the node with the old syntax config.delete(base + ['dynamic-dns-update']) if str(bool_val) == 'true': # Enable dynamic-dns-update with new syntax config.set(base + ['dynamic-dns-update'], value=None) # Make node "set service dhcp-server disabled (true|false)" valueless if config.exists(base + ['disabled']): bool_val = config.return_value(base + ['disabled']) # Delete the node with the old syntax config.delete(base + ['disabled']) if str(bool_val) == 'true': # Now disable DHCP server with the new syntax config.set(base + ['disable'], value=None) # Make node "set service dhcp-server hostfile-update (enable|disable) valueless if config.exists(base + ['hostfile-update']): bool_val = config.return_value(base + ['hostfile-update']) # Delete the node with the old syntax incl. all subnodes config.delete(base + ['hostfile-update']) if str(bool_val) == 'enable': # Enable hostfile update with new syntax config.set(base + ['hostfile-update'], value=None) # Run this for every instance if 'shared-network-name' for network in config.list_nodes(base + ['shared-network-name']): base_network = base + ['shared-network-name', network] # format as tag node to avoid loading problems config.set_tag(base + ['shared-network-name']) # Run this for every specified 'subnet' for subnet in config.list_nodes(base_network + ['subnet']): base_subnet = base_network + ['subnet', subnet] # format as tag node to avoid loading problems config.set_tag(base_network + ['subnet']) # Make node "set service dhcp-server shared-network-name <xyz> subnet 172.31.0.0/24 ip-forwarding enable" valueless if config.exists(base_subnet + ['ip-forwarding', 'enable']): bool_val = config.return_value(base_subnet + ['ip-forwarding', 'enable']) # Delete the node with the old syntax config.delete(base_subnet + ['ip-forwarding']) if str(bool_val) == 'true': # Recreate node with new syntax config.set(base_subnet + ['ip-forwarding'], value=None) # Rename node "set service dhcp-server shared-network-name <xyz> subnet 172.31.0.0/24 start <172.16.0.4> stop <172.16.0.9> if config.exists(base_subnet + ['start']): # This is the new "range" id for DHCP lease ranges r_id = 0 for range in config.list_nodes(base_subnet + ['start']): range_start = range range_stop = config.return_value(base_subnet + ['start', range_start, 'stop']) # Delete the node with the old syntax config.delete(base_subnet + ['start', range_start]) # Create the node for the new syntax # Note: range is a tag node, counter is its child, not a value config.set(base_subnet + ['range', r_id]) config.set(base_subnet + ['range', r_id, 'start'], value=range_start) config.set(base_subnet + ['range', r_id, 'stop'], value=range_stop) # format as tag node to avoid loading problems config.set_tag(base_subnet + ['range']) # increment range id for possible next range definition r_id += 1 # Delete the node with the old syntax config.delete(['service', 'dhcp-server', 'shared-network-name', network, 'subnet', subnet, 'start']) # Make node "set service dhcp-server shared-network-name <xyz> authoritative" valueless if config.exists(['service', 'dhcp-server', 'shared-network-name', network, 'authoritative']): authoritative = config.return_value(['service', 'dhcp-server', 'shared-network-name', network, 'authoritative']) # Delete the node with the old syntax config.delete(['service', 'dhcp-server', 'shared-network-name', network, 'authoritative']) # Recreate node with new syntax - if required if authoritative == "enable": config.set(['service', 'dhcp-server', 'shared-network-name', network, 'authoritative']) 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)