HP Procurve to Cisco switchport migration with Python and Netmiko
Summertime usually means a busy period for Network Engineers, customers are on holidays and we have the opportunity to performs all the changes that impact network connectivity.
For me this usually means core switch replacement.
Today I was moving a configuration from an HP8200 to a Cisco 4500, taking care of all the details of ports, trunks, VLANs.
From this:
to this:
}When a task is manual, boring, repetitive and error-prone some automation skills can help.
The process
I prefer to write as little CLI commands as possible, so I start to work with and Excel spreadsheet with all the migration notes and what I call a switchmap.
In the switchmap, along with other information, I map the ports on the old switch to the ports on the new switch, something like
a1 g1/1
a2 g1/2
and so on for all the ports and modules.
This mapping will be used as input for the actual script.
Reading VLAN information from HP
From the HP switch it is possible to read detailed VLAN information and description for each port with this command:
sh vlans ports c1 detail
The output for a trunk port is something like this:
Status and Counters - VLAN Information - for ports C1
Port name: LINK_TO_IMPORTANT_ACCESS_SWITCH
VLAN ID Name | Status Voice Jumbo Mode
------- -------------------- + ---------- ----- ----- --------
100 Server | Port-based No No Tagged
101 Clients | Port-based No No Tagged
102 WiFi | Port-based No No Tagged
103 GuestWiFi | Port-based No No Tagged
104 CCTV | Port-based No No Tagged
105 MGMT | Port-based No No Untagged
106 IOT | Port-based No No Tagged
107 DMZ | Port-based No No Tagged
An access port would be like this:
Status and Counters - VLAN Information - for ports C2
Port name: LINK_TO_IMPORTANT_ACCESS_SWITCH
VLAN ID Name | Status Voice Jumbo Mode
------- -------------------- + ---------- ----- ----- --------
101 Clients | Port-based No No Untagged
The script
The script I created connects via SSH to the HP switch using NETMIKO. It uses the switchmap to read the list of switch ports, for each port it gets all the VLAN details.
With this information a for loop creates a file with all the commands translated to Cisco syntax. Notice that it's not an elegant implementation, it adds each single vlan to the trunk instead of creating ranges, but it works fine.
Check on GitHub repository for lateast release
1 from netmiko import ConnectHandler
2 import getpass
3 swip = raw_input('IP ADDRESS: ')
4 swun = raw_input('SWITCH USERNAME: ')
5 swpass = getpass.getpass()
6 connection = ConnectHandler(ip=swip, device_type='hp_procurve', username=swun, password=swpass)
7 cisco_output = open("cisco_output.txt", 'w')
8 portlist = open("portlist.total.txt", 'r')
9 for port in portlist:
10 porthp = port.strip().split()[0]
11 portcisco = port.strip().split()[1]
12 print ("MAPPING HP PORT "+porthp+" TO CISCO PORT "+portcisco)
13 command="sh vlans ports "+porthp+" detail"
14 result = connection.send_command(command)
15 cisco_output.write("interface "+portcisco+"\n")
16 trunk = 0
17 if "Tagged" in result:
18 trunk = 1
19 cisco_output.write("switchport mode trunk\n")
20 cisco_output.write("switchport trunk allowed vlan 1\n")
21 if "Untagged" not in result:
22 cisco_output.write("switchport trunk native vlan 1\n")
23 else:
24 cisco_output.write("switchport mode access\n")
25 for line in result.splitlines():
26 if "Tagged" in line and trunk:
27 fields = line.strip().split()
28 cisco_output.write("switchport trunk allowed vlan add "+fields[0]+"\n")
29 elif "Untagged" in line:
30 fields = line.strip().split()
31 if trunk: cisco_output.write("switchport trunk allowed vlan add "+fields[0]+"\n"+"switchport trunk native vlan "+fields[0]+"\n")
32 else: cisco_output.write("switchport access vlan "+fields[0]+"\n")
33 elif "Port name" in line:
34 fields = line.strip().split(":")
35 cisco_output.write("description "+fields[1]+"\n")
36 cisco_output.close()
37 connection.disconnect()
This script is licensed under CC BY-SA.
Port-channels
To migrate port-channels (HP calls them Trunks) just use a different mapping file like
Trk1 po1
Trk2 po2
Trk3 po3
Trk4 po4
Trk5 po5
On the Cisco switches we still need to create the port channels.
Final considerations
This script successfully migrated over 90 access and trunk ports. I consider this a success!
Robots will steal our job one day?
I think I'll leave to the robot who wants to replace me just the boring tasks and I'll keep the most creative ones.
Welcome to my fellow robot, we'll be great friends!