Tuesday, May 21, 2019

I got POAP working in GNS3, here are some tips if you want to do the same.

About a month ago I posted a thread in here asking if anyone had gotten POAP working in GNS3. After many many hours fighting with this I finally got POAP to work on a N9k ov image running in GNS3. I found several "gotchas" that only exist in the virtualised GNS3 environment. I figured I would share what I learned here in the hopes it might save someone else a lot of time on their project.

*Warning, I am very new at network automation and python, so my solution is probably in no way the most elegant or efficient, but it works. I am 100% open to suggestions of better ways to go about this*

The image I used was nxosv-final.7.0.3.I7.4.qcow2 . I got it from Cisco VIRL after purchasing a license.

I first downloaded a sample poap.py script from ger-sheehan on github. (Finding one on cisco was difficult, and the link that was supposed to have it 404'd)

One of the "gotchas" with using the poap.py script in GNS3 is that the N9K in GNS3 does not have a BIOS version. The script fails when it tries to find this. Here is what I mean:

Here is what the script expects to find with regex on a real switch.

Here is what the script really finds when running regex to look for the bios version on a GNS3 N9k.

Here is the part of the code where this breaks:

#Original POAP.py def get_bios_version(): """ Gets the BIOS version of the switch from CLI. Output is handled differently for 6.x and 7.x/higher version. """ cli_output = cli("show version") if legacy: result = re.search(r'BIOS.*version\s*(.*)\n', cli_output[1]) if result is not None: return result.group(1) else: result = re.search(r'BIOS.*version\s*(.*)\n', cli_output) if result is not None: return result.group(1) poap_log("Unable to get switch Bios version") 

To get around this, I just made the function always return a true value. (I copied a real bios version from a real N9k)

#Modified POAP.py def get_bios_version(): """ Gets the BIOS version of the switch from CLI. Output is handled differently for 6.x and 7.x/higher version. """ cli_output = cli("show version") if legacy: result = re.search(r'BIOS.*version\s*(.*)\n', cli_output[1]) if result is not None: return 07.56 #result.group(1) else: result = re.search(r'BIOS.*version\s*(.*)\n', cli_output) if result is not None: return 07.56 #result.group(1) poap_log("Unable to get switch Bios version") 

The result is that the bios check is then effectively skipped.

The other variables I had to change in the script were the options dictionary:

options = { "username": "root", "password": "password", "hostname": "192.168.1.5", "transfer_protocol": "tftp", "mode": "serial_number", "target_system_image": "nxos.7.0.3.I4.7.bin", } 

I also had to change some of the variables under

def set_defaults_and_validate_options(): 

In that function you need to pay close attention to the paths you are telling the switch to use:

 set_default("transfer_protocol", "tftp") # Directory where the config resides set_default("config_path", "/") #This needs to be / because the tftp server goes straight to #the tftpboot directory # Target image and its path (single image is default) set_default("target_system_image", "") set_default("target_image_path", "/") set_default("target_kickstart_image", "") # Destination image and its path set_default("destination_path", "/bootflash") set_default("destination_system_image", options["target_system_image"]) set_default("destination_kickstart_image", options["target_kickstart_image"]) set_default("destination_midway_system_image", "midway_system.bin") set_default("destination_midway_kickstart_image", "midway_kickstart.bin") # User app path set_default("user_app_path", "/var/lib/tftpboot/") 

Take special note of . set_default("user_app_path", "/var/lib/tftpboot/")

This has to be the path to the folder hosted by your tftp server. Make it look like this. Don't put a "." in front of the first "/", don't add the server ip in front of it, nothing, just make it like that. If you migrate this project over to another environment, be sure to update this path.

Additionally, I found that when I started the poap process with my poap.py script, I would often fail at the MD5 validation stage. The 2nd line of the poap script contains the MD5 checksum. After that is a bit of code you're told to run to update it if you make changes to the script, but I never seemed to have luck with this. I even tried independently checking the MD5 sum of the file on my ubuntu machine and manually copying that into the 2nd line of the script, but this also didn't work. The easiest solution I found was to wait until poap failed and copy the value the switch spits out:

2019 May 21 09:06:30 switch %$ VDC-1 %$ %POAP-2-POAP_INFO: [9FGXT7WG1QB-0C:8B:D0:F4:F5:07] - Script file size 75944, MD5 checksum e4cc15591475ced861f01937cba78ddb 

I had the same problem with the md5 checksums of my conf files, so I disabled md5 under def set_defaults_and_validate_options():

 # MD5 Verification set_default("disable_md5", True) 

The next, and perhaps most frustrating, "gotcha" I encountered was the fact that my virtual N9ks kept deleting their boot images upon reboot. To be honest, I still don't understand why this is happening. I would load a new switch, and then sometimes the switch would not have nxos.7.0.3.I7.4.bin in the bootflash: .

This happens whenever I interrupt POAP and reload the switch.

switch# dir bootflash: 4096 May 20 12:51:42 2019 .rpmstore/ 4096 May 20 12:52:10 2019 .swtam/ 270404 May 20 14:26:01 2019 20190520_133154_poap_30771_init.log 4306 May 21 11:10:41 2019 20190521111031_poap_30601_script.log 4306 May 21 11:12:55 2019 20190521111244_poap_30601_script.log 4306 May 21 11:15:09 2019 20190521111459_poap_30601_script.log 4306 May 21 11:17:22 2019 20190521111711_poap_30601_script.log 1703 May 21 08:50:14 2019 20190521_085006_poap_30566_init.log 47181 May 21 08:59:46 2019 20190521_085514_poap_30552_init.log 477355 May 21 11:20:33 2019 20190521_100552_poap_30601_init.log 0 May 20 12:51:51 2019 bootflash_sync_list 0 May 21 08:50:36 2019 platform-sdk.cmd 4096 May 21 11:17:22 2019 scripts/ 4096 May 20 13:31:49 2019 virt_strg_pool_bf_vdc_1/ 4096 May 20 13:30:55 2019 virtual-instance/ 59 May 20 13:30:45 2019 virtual-instance.conf Usage for bootflash://sup-local 541712384 bytes used 2995507200 bytes free 3537219584 bytes total 

To fix this I had to manually tftp the file over from my tftp server VM (an ubuntu VM) to my switch:

switch# conf t Enter configuration commands, one per line. End with CNTL/Z. switch(config)# int mgmt0 #I connected my switch over mgmt0 int to the network switch(config-if)# ip address 192.168.1.15 255.255.255.0 #give the int an IP on your LAN switch(config-if)# no shut switch(config-if)# end switch# copy tftp: bootflash: Enter source filename: nxos.7.0.3.I7.4.bin # This should be the .bin file you want to transfer Enter vrf (If no input, current vrf 'default' is considered): management #use VRF management Enter hostname for the tftp server: 192.168.1.10 #This should be the IP of your TFTP server Trying to connect to tftp server...... Connection to Server Established. [# ] 1.53MB #This takes forever.... 

Once this finally finished I had to re-enable poap and reload.

switch(config)# boot poap enable switch(config)# end switch# copy run startup-config [########################################] 100% Copy complete, now saving to disk (please wait)... Copy complete. switch# reload 

Often upon reloading the switch I would fall into this loader prompt:

 Loader Version 5.01.0 Entering interactive mode loader > 

To continue booting enter "dir" to list the contents of bootflash: and then "boot <your image file>".

Transferring the nxos.7.0.3.I7.4.bin file to my Ubuntu VM in VMware workstation was a pain. I found the best way to do it was to create a shared folder on my windows machine and link that to my VM. I found a good video showing how to do this.

Another annoying "gotcha" with using these N9ks in GNS3 is that the Serial Numbers always change! This then makes your poap process fail if you are looking for configuration files by S/N. (conf.<S/N)

I usually had to wait until the poap process started to see what S/N the switch would use this time and then go and change my conf.<S/N> file name accordingly.

2019 May 21 11:07:00 switch %$ VDC-1 %$ %POAP-2-POAP_INFO: [98JOF5MZNZM-0C:8B:D0:F4:F5:07] #this list is [S/N:MAC] 

Here is a link to my copy of the poap script that I currently have working.

On my TODO list for this project is to trim this poap script down to just the bare essentials. My goal is simply to bring the switch up and make it reachable on my network. I don't want to do any checks or configuration beyond that. I plan on using Ansible to manage the entire device life cycle. Poap just gets the switch up and online so ansible can take over.

I hope this was helpful to someone.



No comments:

Post a Comment