Extreme_Config_to_Zyxel_Config

using python to transform config automatically.

Purpose

  Change config from extreme[ECS4120-28T] to zyxel[XGS2220-54] devices.

Code

# header
import re
 
# read HTML for parsing
file_r = "device.txt"
with open(file_r, "r", encoding='utf-8') as f:
    content = f.readlines()
 
# loop for all devices
i = 0
for i in range(len(content)):
 
    # initialize
    output = ""
    errDevice = ""
    zi = 4
 
    # clean the spaces in front of the string
    content[i] = content[i].strip()
    print(content[i])
 
    # split the string 
    split_strings = re.split("\s+" ,content[i])
    school_name = split_strings[0]
 
    # check the len is correct or not 
    if len(school_name) == 0:
        break
 
    device_name = split_strings[1]
    ip_address  = split_strings[2]
 
    output = output + "學校名稱 : " + school_name + "\n"
    output = output + "裝置名稱 : " + device_name + "\n"
    output = output + "IP 位址 : " + ip_address + "\n====================\n"

    # ======
    if len(device_name) >= 3 and device_name[0] == "E" and device_name[1] == "C" and device_name[2] == "S":
        file_r3 = school_name + "_" + device_name + ".txt"
        with open(file_r3, "r", encoding='utf-8') as f3:
            content2 = f3.readlines()
 
            # initialize
            vlan_flag_100 = 0
            vlan_flag_101 = 0
 
            for j in range(len(content2)):
                content2[j] = content2[j].strip()
                split_strings2 = re.split("\s+" ,content2[j])
 
                # hostname
                if(len(split_strings2) == 2 and split_strings2[0] == "hostname" and split_strings2[1][0] == "s"):
                    output = output + "Z13 hostname : " + split_strings2[1] + "\n"
 
                # dhcp helper
                if(len(split_strings2) >= 5 and split_strings2[1] == "dhcp" and split_strings2[2] == "relay"):
                    output = output + "Z14 dhcp relay helper-address : " + split_strings2[4] + "\n"
               
                # ipv4 gateway
                if(len(split_strings2) >= 4 and split_strings2[0] == "ip" and split_strings2[1] == "route"):
                    output = output + "Z3 gateway : " + split_strings2[4] + "\n"
               
                # ipv6 gateway
                if(len(split_strings2) >= 4 and split_strings2[0] == "ipv6" and split_strings2[1] == "route"):
                    output = output + "Z11 gateway : " + split_strings2[3] + "\n"
 
                # vlan 100(WAN)
                if(len(split_strings2) >= 3 and split_strings2[0] == "interface" and split_strings2[1] == "vlan" and split_strings2[2] == "100"):
                    vlan_flag_100 = 1
                    continue
                elif(vlan_flag_100 == 1 and split_strings2[0] == "ip" and split_strings2[1] == "address"):
                    output = output + "Z1 vlan 100(wan) : " + split_strings2[2] + "\n"
                    output = output + "Z2 vlan 100(wan) mask : " + split_strings2[3]  + "\n"
                elif(vlan_flag_100 == 1 and split_strings2[0] == "ipv6" and split_strings2[1] == "address"):
                    output = output + "Z10 vlan 100(wan) ipv6 : " + split_strings2[2] + "\n"
                elif(vlan_flag_100 == 1 and split_strings2[0] == "ipv6" and split_strings2[1] == "enable"):
                    continue
                else:
                    vlan_flag_100 = 0
 
                # vlan 101(LAN)
                if(len(split_strings2) >= 3 and split_strings2[0] == "interface" and split_strings2[1] == "vlan" and split_strings2[2] == "101"):
                    vlan_flag_101 = 1
                    continue
                elif(vlan_flag_101 == 1 and split_strings2[0] == "ip" and split_strings2[1] == "address"):
                    output = output + "Z" + str(zi) + " vlan 101(lan) : " + split_strings2[2] + "\n"
                    zi = zi + 1
                    output = output + "Z" + str(zi) + " vlan 101(lan) : " + split_strings2[3]  + "\n"
                    zi = zi + 1
                    if(split_strings2[len(split_strings2) - 1] != "secondary"):
                        output = output + "Z15 dhcp relay source-address : " + split_strings2[len(split_strings2) - 2] + "\n"
 
                elif(vlan_flag_101 == 1 and split_strings2[0] == "ipv6" and split_strings2[1] == "address"):
                    output = output + "Z11 vlan 101(lan) ipv6 : " + split_strings2[2] + "\n"
                elif(vlan_flag_101 == 1 and split_strings2[0] == "ipv6" and split_strings2[1] == "enable"):
                    continue
                else:
                    vlan_flag_101 = 0
    else:
        errDevice = errDevice + school_name + " " + device_name + " " + ip_address + "\n"
        print("Cannot Download!!!!!!\n")
 
    output = output + "\n"
    print(output)

    # Find the line of "Z" is the first character
    z_lines = re.findall(r'Z\d+.*', output)

    # Show all lines of "Z"
    z_map = {}
    for line in z_lines:
        match = re.match(r'(Z\d+).*?:\s*(.+)', line)
        if match:
            z_key = match.group(1)
            z_value = match.group(2).strip()

            # Remain the last Z value
            z_map[z_key] = z_value  

    # sort z_map of z
    for k in sorted(z_map.keys(), key=lambda x: int(x[1:])):
        print(f"{k} -> {z_map[k]}")
    print("\n=======================\n")


    # open template file
    with open("config_template.txt", "r", encoding="utf-8") as f:
        config_template = f.read()

    # change correct parameter into z number
    def replace_z_tags(template, z_map):
        def repl(match):
            tag = match.group(0)
            return z_map.get(tag, f"<Not define:{tag}>") 
        return re.sub(r'Z\d+', repl, template)

    final_config = replace_z_tags(config_template, z_map)

    # Remove the line contains "Not define"
    cleaned_config = "\n".join(
        line for line in final_config.splitlines()
        if "<Not define:" not in line
    )

    # write the file
    filename = "After_change_" + school_name + "_" + device_name + ".txt"
    with open(filename, "w", encoding="utf-8") as f:
        f.write(cleaned_config)

device.txt

001 ECS4120-28T 10.10.10.1
002 ECS4120-28T 10.10.10.2
003 ECS4120-28T 10.10.10.3

config_template.txt

config

vlan 1
  no fix 1-54
  no ip address 192.168.1.1 255.255.255.0
exit


vlan 100
  normal 1-53 
  fixed 54 
  forbidden "" 
  untagged 54
  ip address Z1 Z2
  ip address default-gateway Z3
exit


vlan 101
  normal 54 
  fixed "1-53"
  forbidden ""
  untagged 1-53
  ip address Z4 Z5
  ip address Z6 Z7
  ip address Z8 Z9
exit


interface vlan 1 
  no ipv6 
  no ipv6 address dhcp client ia-na   
exit


interface vlan 100 
  ipv6
  ipv6 address Z10
  ipv6 address default-gateway Z11
exit 


interface vlan 101
  ipv6
  ipv6 address Z12
exit


interface port-channel 1-53
  pvid 101
  loopguard
exit
interface port-channel 54
  pvid 100
  loopguard
exit

ip name-server "No way"

no spanning-tree 
loopguard

hostname Z13
time timezone 800
timesync server "No way"
timesync ntp
snmp-server get-community "No way"
snmp-server set-community "No way"
dhcp relay 101 helper-address Z14
dhcp relay 101 source-address Z15

admin-password "No way"
exit
write mem