Switching configs using TCL scripts and Cisco IOS Menus

Following on from a previous post where we looked at managing multiple router configurations and how we could swap between them, I thought it would be nice to have this in a menu using TCL.

Something like this maybe?

Cisco IOS Menu

Implementing menus on Cisco IOS is a fairly straight-forward business, and there are plenty of examples on how to build menus that can do ping tests and trace routes. this one is slightly more complex as it involves the “config replace” command.

Before we go into how to create the menu it’s important to point out an issue I had along the way. My original method, which was just calling the config replace command from the menu did not work as the router would hang on the following line:

*Sep  5 12:19:45.211: %PARSER-6-EXPOSEDLOCKRELEASED: Exclusive configuration lock released from terminal '0' -Process= "Exec", ipl= 0, pid= 3

I would have to turn the router off and back on again, I could not find any way around this. So I had to find another method of doing this, and that was to incorporate a TCL script to get it to work.

Calling configure replace from TCL

Tcl (pronounced tickle) is a pretty cool scripting language, it’s been around for a while and if you have done any Linux programming then it should be pretty familiar. We will definitely be revisiting TCL later on.

We start by entering the TCL shell by typing “tclsh” at the command prompt

Router#tclsh

Next, we output the next commands to a file we are going to hold in flash (after we cd to flash and do a “mkdir myScripts” to create the directory). The w+ opens it in read/write mode.

Router(tcl)#puts [open flash:/myScripts/confrep2.tcl w+] {

the next lines are the commands that will be in the script.

+>tclsh
+>set labname [lindex $argv 0]
+>exec "configure replace flash:/myConfigs/$labname force"
+>}

So to explain, we need to specify the scripting language (tclsh), and then set a variable that will be passed so we name the variable “labname” and set it as the the first (0) argument ($argv). Then we give the actual command to execute, which is an exec mode argument “configure replace” and specify the path to the file, and again we specify that the argument passed in the calling of the script will be the filename (using $labname), lastly the “force” keyword is used to allow us to do the config replace without needing to wait or confirm anything.

The final line (the closing brace) matches up with the opening brace and tells the IOS that we have finished this script.

The screenshot below shows the complete syntax, along with exiting from the tclsh (remember to do this otherwise things will get weird…!).

TCL shell

Building a menu and submenu in Cisco IOS

For this menu we have two vendors to choose from (INE and Cisco 360) – and all this is is a factory-fresh config, with just the MOTD banner changed to show which lab, though closer to the end I did change the hostname on the different configs to make it more obvious.

This menu will allow us to select from two different vendors, and from there choose one of the two available labs via a sub-menu.

We start by creating the master menu:

menu ConfigMenu title ^ Config Menu ^
menu ConfigMenu prompt ^ Choose an option ^
menu ConfigMenu text 1 Load INE Configs
menu ConfigMenu command 1 menu INE
menu ConfigMenu text 2 Load 360 Configs
menu ConfigMenu command 2 menu 360
menu ConfigMenu text 3 Exit Menu
menu ConfigMenu command 3 exit
menu ConfigMenu line-mode

The first line gives the menu a title, and the second line sets a prompt for the user.
Line 3 and 5 set the text for the menu item and 4 and 6 then set the command that will be used, which in our case calls another menu (INE or 360). Finally, on lines 7 and 8, we allow the user to exit out of the menu. the final two lines just make the menu look nicer.

The sub-menus

The INE and 360 menus are very similar to the first, but instead of calling a menu, we instruct the menu to call out TCL script.

menu INE title ^ Load INE Labs ^
menu INE prompt ^ Choose a lab to load: ^
menu INE text 1 Load INE Lab 1
menu INE command 1 tclsh flash:/myScripts/confrep2.tcl INE-1.txt
menu INE text 2 Load INE Lab 2
menu INE command 2 tclsh flash:/myScripts/confrep2.tcl INE-2.txt
menu INE text 3 exit to main menu
menu INE command 3 menu-exit
menu INE line-mode

The 360 is the same as the INE but with just the appropriate bits changed:

menu 360 title ^ Load 360 Labs ^
menu 360 prompt ^ Choose a lab to load: ^
menu 360 text 1 Load 360 Lab 1
menu 360 command 1 tclsh flash:/myScripts/confrep2.tcl 360-1.txt
menu 360 text 2 Load 360 Lab 2
menu 360 command 2 tclsh flash:/myScripts/confrep2.tcl 360-2.txt
menu 360 text 3 exit to main menu
menu 360 command 3 menu-exit
menu 360 line-mode

A “sh run” shows the completed menu

menu-run

So now we can call the menu by issuing the command “menu ConfigMenu” from the prompt we can now see our new menu.

Cisco IOS menu in action

menu-1

You need to press enter when you get the “Exclusive configuration lock” message, and also press 3 to exit the menu, but then you should get:

menu-2

So it is probably quicker than typing the full config replace, maybe only just, but then with the CCIE – timing is everything. It’s also a good way to start working with tcl and there is a chance that you might be asked to configure a menu during the CCIE lab exam.

I hope to update this post with a start-to-finish video shortly.

Cisco IOS menu tips

1. Write it all out in notepad (or your text editor of choice) first, then you can paste it onto the router. This is especially important as if you try and remove a line from the menu it will actually delete the entire menu, so if you type “no menu ConfigMenu command 3”, you will lose all of ConfigMenu.

2. Make sure that the menu (once you have it working as you want it to) is on all your configs, otherwise, you won’t be able to use it to switch to another saved configuration.

Last note

I would like to give thanks to the guys over at Blindhog for their post that really helped in getting this working!