Changing the Configurations of Many Routers at Once
Problem
You want to make a configuration change to a large number of routers.
Solution
The Expect script in Example 1-2 makes the same configuration changes to a list of routers by using Telnet. When it finishes running, the script produces a status report to identify which devices, if any, failed to update properly. No arguments are required or expected.
Example 1-2. rtrchg.exp
#!/usr/local/bin/expect # # rtrcfg.exp -- a script to perform mass configuration changes to # a list of routers using telnet and Expect # # # Set Behavior set tftp "172.25.1.1" set workingdir /home/cisco/rtr # puts stdout "Enter user name:" gets stdin userid system stty -echo puts stdout "Enter login password:" gets stdin vtypasswd puts stdout " Enter enable password:" gets stdin enablepwd system stty echo system "cp $workingdir/NEWCONFIG /tftpboot/NEWCONFIG" set RTR [open "$workingdir/RTR_LIST" r] set LOG [open "$workingdir/RESULT" w] while {[gets $RTR router] != -1} { if {[ string range $router 0 0 ] != "#"} { set timeout 10 spawn telnet; expect "telnet>"; send "open $router " expect { {Username} { send "$userid " expect { {*Password*} { send "$vtypasswd " } } } {Password} { send "$vtypasswd " } timeout { puts $LOG "$router - telnet failed" close; wait; continue } } expect { {Password} { puts $LOG "$router - vty login failed" close; wait; continue } {Username} { puts $LOG "$router - vty login failed" close; wait; continue } {>} { puts $LOG "$router - vty login ok" } timeout { puts $LOG "$router - vty login failed" close; wait; continue } } send "enable " expect "Password" send "$enablepwd " # expect { {*#} { puts $LOG "$router - enable login ok" } {*>} { puts $LOG "$router - enable login failed" close; wait; continue } timeout { puts $LOG "$router - enable login failed" close; wait; continue } } # CMDs set timeout 30 send "copy tftp://$tftp/NEWCONFIG running-config " expect "running-config" send " " expect { {OK} { puts $LOG "$router - TFTP successful"} timeout { puts $LOG "$router - TFTP failed" close; wait; continue } } send "copy running-config startup-config " expect { {OK} { puts $LOG "$router - config saved"} timeout { puts $LOG "$router - config failed" close; wait; continue } } #CMDs send "exit "; close; wait } } close $RTR; close $LOG system "rm /tftpboot/NEWCONFIG" |
Discussion
This script uses the Expect language to emulate how a performing human router engineer would do a series of configuration updates via TFTP. The script logs into each router in a list and uses TFTP to download a set of configuration changes into the router's running configuration. It then saves the new configuration file to NVRAM to make sure that it will survive any power failures, and moves on to the next router in the list. Automating a routine but time-consuming procedure with a script like this saves time and decreases the chances of fatigue-induced errors.
The script is designed to work with either normal router passwords or AAA-enabled username and password combinations, which we describe in Chapter 3. The script begins by asking you to supply a username. If one or more of your routers aren't configured to use AAA or local authentication, the script will simply ignore this username and insert the password instead.
After asking for the username, the script will prompt you to enter a login password that will either be your VTY password or AAA password. Then the script will ask for the enable password, and it will then begin to perform its task.
|
You must change two variables in this script for it to work in your network. The first variable is called tftp. You must set this value to your TFTP server's IP address. The second variable you need to change is workingdir, which must contain the name of the directory that holds the list of routers, the file of configuration changes, and the location where the script will put its report.
The script is written in the Expect language and requires Expect to be loaded on your server and available in the /usr/local/bin directory. For more information on the Expect language, please see Appendix A or Exploring Expect by Don Libes (O'Reilly).
The script expects to find two special files in the working directory. The first is called RTR_LIST, and contains a list of router names, with one name on each line. The second file is called NEWCONFIG, which contains all required configuration changes. We also recommend you put the configuration command end on that the last line of the NEWCONFIG file to avoid the error messages that we mentioned in Recipe 1.1.
Here is a typical example of the sort of things you might put in the configuration file:
Freebsd% cat NEWCONFIG enable secret cisco end
Using this file, the script will log into all routers and change the enable secret password. You could put any number of commands in this configuration file, but naturally the script will download the exact same set of configuration commands into every router, so you should never change anything that is unique to a particular router, such as an IP address, this way. This method is perfect for changing things like passwords, SNMP community strings, and access-lists, which can be the same on all routers.
The script will copy the NEWCONFIG file into the /tftpboot directory so it can then use TFTP to transfer it to each of the routers. It is a good idea to ensure that your server's TFTP is working correctly before launching the script.
When the script finishes, it will create a status file called RESULT in the working directory. This status file will contain detailed status reports of what happened on each router. The easiest way to see a list of the routers that the script failed to change is to use the Unix grep command to search for the keyword "fail", as follows:
Freebsd% grep fail RESULT toronto - enable login failed boston - telnet failed test - enable login failed frame - enable login failed
See Also
Recipe 1.1; Appendix A; Exploring Expect by Don Libes (O'Reilly)