#!/usr/bin/python3 import sys import os import yaml import subprocess import ipaddress import re def main(): args = sys.argv if len(args) < 2: print(f"Usage: {args[0]} /etc/netplan/00-installer-config.yaml") sys.exit() netplan_config_file = args[1] with open(netplan_config_file, 'r') as f: org_file_contents = f.read() netplan_config_yaml = yaml.safe_load(org_file_contents) if netplan_config_yaml == None: netplan_config_yaml = {} addresses = {} gateway4 = {} dhcp = {} network_block = netplan_config_yaml.get('network') no_network_block = False no_ethernets_block = False if network_block == None: no_network_block = True no_ethernets_block = True else: ethernets_block = network_block.get('ethernets') if ethernets_block == None: no_ethernets_block = True else: need_remove_interfaces = [] for interface in ethernets_block: interface_block = ethernets_block[interface] interface_addresses = interface_block.get('addresses') if interface_addresses != None: if len(interface_addresses) != 0: addresses[interface] = interface_addresses elif interface == '': need_remove_interfaces.append(interface) for interface in need_remove_interfaces: del netplan_config_yaml['network']['ethernets'][interface] if len(addresses) != 0: print("You alreay configure some addresses for interfaces!") for interface in addresses: interface_addresses = addresses[interface] for addr in interface_addresses: print(f"{interface}: {addr}") ans = input("Do you want to continue configure? (y/n)") if ans.lower() != "y": sys.exit() default_interfaces = list(set(subprocess.Popen("ip -o -4 route show to default | awk '{print $5}'", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip().split("\n"))) if '' in default_interfaces: default_interfaces.remove('') if len(default_interfaces) == 0: default_interfaces.extend(subprocess.Popen("ls /sys/class/net/|xargs", shell=True, stdout=subprocess.PIPE).stdout.read().decode().strip().split(" ")) if 'lo' in default_interfaces: default_interfaces.remove('lo') if len(default_interfaces) == 0: if len(args) > 2: default_interfaces = args[2] else: print("No network interface detected!") print(f"Usage: {args[0]} /etc/netplan/00-installer-config.yaml $interface_name") sys.exit() change_flag = False for interface in default_interfaces: old_address = addresses.get(interface) if old_address != None: for addr in old_address: print(f"Found {addr} for interface {interface}!") ans = input("Do you want to continue configure? (y/n)") if ans.lower() != "y": continue new_addr = "" dhcp4 = input(f"Do you want to use dynamic address(dhcp) for interface {interface}? (y/n)") if dhcp4.lower() != "y": dhcp4 = False while new_addr == "": new_addr = input(f"New address for interface {interface}: ") try: ipaddress.IPv4Address(new_addr) except: print("Invalid ipaddress!") new_addr = "" addresses[interface] = [new_addr + '/24'] new_gateway4 = input(f"New gateway4 for interface {interface}: (can leave blank by default 254)") gateway4[interface] = re.sub('[\\d]+$', '254', new_addr) if new_gateway4 != "": try: ipaddress.IPv4Address(new_gateway4) gateway4[interface] = new_gateway4 except: print("Invalid gateway4 ipaddress!") print(f"Change to default: {gateway4[interface]}") change_flag = True else: change_flag = True dhcp4 = True if old_address != None: del addresses[interface] dhcp[interface] = dhcp4 if no_network_block: netplan_config_yaml['network'] = {} change_flag = True if no_ethernets_block: change_flag = True netplan_config_yaml['network']['ethernets'] = {} if netplan_config_yaml['network'].get('version') == None: netplan_config_yaml['network']['version'] = 2 if change_flag: for interface in default_interfaces: interface_content = netplan_config_yaml['network']['ethernets'].get(interface) if interface_content == None: interface_content = {} netplan_config_yaml['network']['ethernets'][interface] = interface_content new_addr = addresses.get(interface) if new_addr != None: if type(new_addr) != list: new_addr = [new_addr] netplan_config_yaml['network']['ethernets'][interface]['addresses'] = new_addr else: tmp = netplan_config_yaml['network']['ethernets'][interface] if tmp.get('addresses') != None: del netplan_config_yaml['network']['ethernets'][interface]['addresses'] if tmp.get('nameservers') != None: del netplan_config_yaml['network']['ethernets'][interface]['nameservers'] if tmp.get('gateway4') != None: del netplan_config_yaml['network']['ethernets'][interface]['gateway4'] new_gateway4 = gateway4.get(interface) if new_gateway4 != None: netplan_config_yaml['network']['ethernets'][interface]['gateway4'] = new_gateway4 dhcp4 = dhcp.get(interface) if dhcp4 != None: netplan_config_yaml['network']['ethernets'][interface]['dhcp4'] = dhcp4 nameservers = interface_content.get('nameservers') if nameservers == None and dhcp4 == False: nameservers = {'addresses': []} if nameservers != None: nameservers_addresses = nameservers.get('addresses') if nameservers_addresses != None: default_nameservers = ['8.8.8.8', '8.8.4.4'] for nameserver in default_nameservers: if nameserver not in nameservers_addresses: nameservers_addresses.append(nameserver) nameservers['addresses'] = nameservers_addresses netplan_config_yaml['network']['ethernets'][interface]['nameservers'] = nameservers with open(netplan_config_file, 'w+') as f: yaml.dump(netplan_config_yaml, f) netplan_get_status = os.system('sudo netplan get') if netplan_get_status == 0: if os.system('sudo netplan try --timeout 10') == 0: print("Finish configuring netplan!") sys.exit(0) else: print("Something went wrong!") f.write(org_file_contents) print("Recover changed!") sys.exit(1) with open(netplan_config_file, 'w+') as f: print(org_file_contents) f.write(org_file_contents) print("Recover changed!") if __name__ == '__main__': main()