I have a love-hate relationship with Expect. I love what it can do for automating interactive sessions with routers, but I hate the unpredictability associated with interactive sessions. It seems that we will make a script, tweak it enough to make it work, just to do it all over again in a few months. It is just a fragile process, whenever there is a new hardware, new terminal server, or even a new OS, we will hit something that require some more fine tuning. We are much better off with known API, autoprovioning via DHCP/TFTP, or other tools for what we use Expect for today.
But until the day when all the network vendor can agree on a given set of API and hooks (if ever), Expect is still a must have in any network engineer's tool bag. It will save you time and keep you sane.
Note that this is a post for the regular Expect based on Tcl, more on PExpect module in later post.
For those who have not heard of Expect, or want a refresher, here are a few documentation link.
References:
http://wiki.tcl.tk/201 (updated link on 12/29/2016)
Here is a useful link for special ASCII Characters, when you want to send those Ctrl-C, Ctrl-X, space, etc:
http://www.bbdsoft.com/ascii.html
[Update 12/29/2016, this link expired (thank you Kirk for pointing it out). Still searching for a good link]
[Update 12/29/2016, this link expired (thank you Kirk for pointing it out). Still searching for a good link]
At the heart of the game, Expect is about 1. spawing a child process, 2. look for certain words in the stream via expect, 3. send something over.
So say I want to telnet to a bunch of Public route-servers and look at how bing.com's IP looks from the route server. I find out that bing.com resolves to 131.253.13.32 from where I am at.
Non-authoritative answer:
Name: bing.com
Address: 131.253.13.32
From Route Server (http://traceroute.org/#Route%20Servers) I can find a list of public route servers that I can telnet to.
1. Using AT&T's route server as a first example, I am going to write a simple script that telnets to the box and displays the bgp information:
#!/usr/bin/expect
set timout 5
# Spawns a child process that telnets to AT&T public route server
spawn telnet route-server.ip.att.net
# The expect command waits until the child process returns "Username:"
# then sends 'reviews' and a return key
expect "Username:" {send "rviews\r"};
# The process then sits and wait for the route-server> prompt
# Then sends the command for route 131.253.13.32 (one of the ip for bing.com)
expect "route-server>" {send "show ip bgp 131.253.13.32\r"};
# The output is longer than 1 page, so it sendds the ASCII key for space twice
send "\032\032"
# Looks for the same prompt, then types 'exit'
expect "route-server>" {send exit\r};
2. The first script can now be cron'd and give me the information that I wanted. But what if I want to telnet to a bunch of route-server, not just AT&T? Here is a modified version that uses the first argument as the telnet target:
#!/usr/bin/expect
set routeServ [lindex $argv 0]
set timout 20
spawn telnet $routeServ
expect "Username:" {send "rviews\r"};
expect {
-re "route.*" {send "show ip bgp 131.253.13.32\r"};
}
send "\032\032"
expect {
-re "route.*" {send exit\r};
}
Notice that the script also now uses -re to indicate the expected string back will be regular expression. This is because some of the route server prompt are 'route-server>' as in the case of AT&T and Comcast, while some are 'route-view>', as in the case of Oregon Route-View servers.
Now that is just another script that I can use Python to tie in, reading from a list of route-servers:
$cat route-servers
route-server.ip.att.net
route-server.newyork.ny.ibone.comcast.net
route-views.oregon-ix.net
$
Here is the Python script:
#!/usr/bin/env python
import subprocess
f = open("route-servers", "r")
for i in f.readlines():
subprocess.check_call(["./routeServ_2.exp", i.strip()])
3. Now we are getting somewhere, but there is another problem: the command is embedded into the Expect script itself. So if I want to run more commands, I need to modify the expect script itself. That is not very flexible. I will make one more modification to the Expect script itself so that it reads all the command from another text file:
$cat commands.txt
show ip route 131.253.13.32
show ip bgp 131.253.13.32
Here is the new version of the Expect script. Note that 'timeout -1' disables the default timeout of 10 seconds, as some of the route-servers are pretty slow.
#!/usr/bin/expect
set routeServ [lindex $argv 0]
# disable the timeout value in the next line
# since some of the route-servers are really slow
set timout -1
spawn telnet $routeServ
expect "Username:" {send "rviews\r"};
expect {
-re "route-.*" {send \r}
}
#process the command file
#this can be more elegant, but this is more clear
set file [open "commands.txt" r]
set file_data [read $file]
set command [split $file_data "\n"]
foreach line $command {
puts $line
expect {
-re "route-.*" {send $line\r}
continue
}
send "\032\032\032"
sleep 2
}
Now I will tie it in with Python, there is no change to the Python script except that it calls the new Expect script. By using Python, I can leverage the getpass, subprocess, sys, and other standard libraries and not have to deal with Tcl or Expect.
#!/usr/bin/env python
import subprocess
f = open("route-servers", "r")
for i in f.readlines():
subprocess.check_call(["./routeServ_3.exp", i.strip()])
4. Here is the output of the result as it shows on the screen (Comcast route server does not allow for 'show ip route x.x.x.x', boo):
$./routeServ_3.py
spawn telnet route-server.ip.att.net
Trying 12.0.1.28...
Connected to route-server.cbbtier3.att.net.
Escape character is '^]'.
-------------- route-server.ip.att.net ---------------
--------- AT&T IP Services Route Monitor -----------
The information available through route-server.ip.att.net is offered
by AT&T's Internet engineering organization to the Internet community.
This router maintains eBGP peerings with customer-facing routers
throughout the AT&T IP Services Backbone:
IPv4:
12.123.21.243 Atlanta 12.123.133.124 Austin 12.123.41.250 Cambridge
12.123.5.240 Chicago 12.123.17.244 Dallas 12.123.139.124 Detroit
12.123.37.250 Denver 12.123.134.124 Houston 12.123.29.249 LA
12.123.1.236 New York 12.123.33.249 Orlando 12.123.137.124 Philly
12.123.142.124 Phoenix 12.123.145.124 SanDiego 12.123.13.241 SanFran
12.123.25.245 St.Louis 12.123.45.252 Seattle 12.123.9.241 WashDC
IPv6:
2001:1890:FF:FFFF:12:122:124:12 Atlanta
2001:1890:FF:FFFF:12:122:127:66 Chicago
2001:1890:FF:FFFF:12:122:124:138 Dallas
2001:1890:FF:FFFF:12:122:120:7 Fort Lauderdale
2001:1890:FF:FFFF:12:122:125:6 Los Angeles
2001:1890:FF:FFFF:12:122:125:44 New York
2001:1890:FF:FFFF:12:122:125:106 Philadelphia
2001:1890:FF:FFFF:12:122:125:132 Phoenix
2001:1890:FF:FFFF:12:122:126:232 San Francisco
2001:1890:FF:FFFF:12:122:125:224 Seattle
2001:1890:FF:FFFF:12:122:126:9 St. Louis
2001:1890:FF:FFFF:12:122:126:64 Washington
*** Please Note:
Ping and traceroute delay figures measured here are unreliable, due to the
high CPU load experienced when complicated "show" commands are running.
For questions about this route-server, send email to: jayb@att.com
*** Log in with username "rviews", no password required ***
User Access Verification
Username: Kerberos: No default realm defined for Kerberos!
rviews
route-server>show ip route 131.253.13.32
route-server>show ip bgp 131.253.13.32
show ip route 131.253.13.32
Routing entry for 131.253.12.0/22
Known via "bgp 65000", distance 20, metric 0
Tag 7018, type external
Last update from 12.123.1.236 22:16:35 ago
Routing Descriptor Blocks:
* 12.123.1.236, from 12.123.1.236, 22:16:35 ago
Route metric is 0, traffic share count is 1
AS Hops 3
Route tag 7018
route-server>
show ip bgp 131.253.13.32
BGP routing table entry for 131.253.12.0/22, version 36560492
Paths: (18 available, best #2, table Default-IP-Routing-Table)
Not advertised to any peer
7018 8075 8075, (received & used)
12.123.13.241 from 12.123.13.241 (12.123.13.241)
Origin IGP, localpref 100, valid, external
Community: 7018:2500 7018:32113
7018 8075 8075, (received & used)
12.123.1.236 from 12.123.1.236 (12.123.1.236)
Origin IGP, localpref 100, valid, external, best
Community: 7018:2500 7018:38001
7018 8075 8075, (received & used)
12.123.142.124 from 12.123.142.124 (12.123.142.124)
Origin IGP, localpref 100, valid, external
Community: 7018:2500 7018:33051
7018 8075 8075, (received & used)
12.123.133.124 from 12.123.133.124 (12.123.133.124)
Origin IGP, localpref 100, valid, external
Community: 7018:2500 7018:36244
7018 8075 8075, (received & used)
12.123.17.244 from 12.123.17.244 (12.123.17.244)
Origin IGP, localpref 100, valid, external
Community: 7018:2500 7018:36244
7018 8075 8075, (received & used)
12.123.21.243 from 12.123.21.243 (12.123.21.243)
Origin IGP, localpref 100, valid, external
Community: 7018:2500 7018:36244
7018 8075 8075, (received & used)
12.123.137.124 from 12.123.137.124 (12.123.137.124)
Origin IGP, localpref 100, valid, external
Community: 7018:2500 7018:38001
7018 8075 8075, (received & used)
12.123.41.250 from 12.123.41.250 (12.123.41.250)
Origin IGP, localpref 100, valid, external
Community: 7018:2500 7018:38001
7018 8075 8075, (received & used)
12.123.139.124 from 12.123.139.124 (12.123.139.124)
route-server>spawn telnet route-server.newyork.ny.ibone.comcast.net
Trying 66.208.229.1...
Connected to route-server.newyork.ny.ibone.comcast.net.
Escape character is '^]'.
********************************************************************************
Comcast NETO Route Server
This route server is provided by Comcast National Engineering &
Technical Operations to provide visibility into the Internet routing table
from the perspective of Comcast's network. This server has BGP peerings to
the following routers and the Internet routing table view from each device:
68.86.80.0 - Ashburn, VA
68.86.80.2 - New York, NY
68.86.80.5 - Chicago, IL
68.86.80.6 - Chicago, IL 2
68.86.80.7 - Denver, CO
68.86.80.10 - San Jose, CA
68.86.80.11 - Los Angeles, CA
68.86.80.12 - Atlanta, GA
68.86.80.13 - Dallas, TX
Note: Due to high CPU utilization on this device, ping and traceroute results
may be unreliable. This route server should not be used to measure network
performance as a result.
Login with username: rviews
Location: New York City
Network: Comcast Route Server
********************************************************************************
User Access Verification
Username: Kerberos: No default realm defined for Kerberos!
rviews
route-server.newyork.ny.ibone>show ip route 131.253.13.32
route-server.newyork.ny.ibone>show ip bgp 131.253.13.32
show ip route 131.253.13.32
Command authorization failed.
route-server.newyork.ny.ibone>
show ip bgp 131.253.13.32
BGP routing table entry for 131.253.12.0/22, version 1378467282
Paths: (8 available, best #8, table Default-IP-Routing-Table)
Advertised to update-groups:
2
8075 8075, (received & used)
68.86.1.38 (metric 81950) from 68.86.80.11 (68.86.1.11)
Origin IGP, metric 0, localpref 300, valid, internal
Community: 7922:38 7922:3020
Originator: 68.86.1.38, Cluster list: 68.86.1.11, 68.86.1.10
8075 8075, (received & used)
68.86.1.75 (metric 74391) from 68.86.80.13 (68.86.1.13)
Origin IGP, metric 0, localpref 300, valid, internal
Community: 7922:75 7922:3020
Originator: 68.86.1.75, Cluster list: 68.86.1.13, 68.86.1.7
8075 8075, (received & used)
68.86.1.40 (metric 69750) from 68.86.80.12 (68.86.1.12)
Origin IGP, metric 0, localpref 300, valid, internal
Community: 7922:40 7922:3020
Originator: 68.86.1.40, Cluster list: 68.86.1.12
8075 8075, (received & used)
68.86.1.42 (metric 66845) from 68.86.80.0 (68.86.1.0)
Origin IGP, metric 0, localpref 300, valid, internal
Community: 7922:42 7922:3020
Originator: 68.86.1.42, Cluster list: 68.86.1.0
8075 8075, (received & used)
68.86.1.38 (metric 81950) from 68.86.80.10 (68.86.1.10)
Origin IGP, metric 0, localpref 300, valid, internal
Community: 7922:38 7922:3020
Originator: 68.86.1.38, Cluster list: 68.86.1.10
8075 8075, (received & used)
68.86.1.43 (metric 69675) from 68.86.80.6 (68.86.1.6)
Origin IGP, metric 0, localpref 300, valid, internal
Community: 7922:43 7922:3020
Originator: 68.86.1.43, Cluster list: 68.86.1.6
8075 8075, (received & used)
68.86.1.75 (metric 74391) from 68.86.80.7 (68.86.1.7)
Origin IGP, metric 0, localpref 300, valid, internal
route-server.newyork.ny.ibone>spawn telnet route-views.oregon-ix.net
Trying 128.223.51.103...
Connected to route-views.oregon-ix.net.
Escape character is '^]'.
**********************************************************************
Oregon Exchange BGP Route Viewer
route-views.oregon-ix.net / route-views.routeviews.org
route views data is archived on http://archive.routeviews.org
This hardware is part of a grant from Cisco Systems.
Please contact help@routeviews.org if you have questions or
comments about this service, its use, or if you might be able to
contribute your view.
This router has views of the full routing tables from several ASes.
The list of ASes is documented under "Current Participants" on
http://www.routeviews.org/.
**************
route-views.routeviews.org is now using AAA for logins. Login with
username "rviews". See http://routeviews.org/aaa.html
**********************************************************************
User Access Verification
Username: rviews
route-views>show ip route 131.253.13.32
route-views>show ip bgp 131.253.13.32
show ip route 131.253.13.32
Routing entry for 131.253.12.0/22
Known via "bgp 6447", distance 20, metric 0
Tag 8075, type external
Last update from 207.46.32.34 7w0d ago
Routing Descriptor Blocks:
* 207.46.32.34, from 207.46.32.34, 7w0d ago
Route metric is 0, traffic share count is 1
AS Hops 1
Route tag 8075
route-views>
show ip bgp 131.253.13.32
BGP routing table entry for 131.253.12.0/22, version 215869
Paths: (33 available, best #20, table Default-IP-Routing-Table)
Not advertised to any peer
3277 3267 8075 8075
194.85.102.33 from 194.85.102.33 (194.85.4.4)
Origin IGP, localpref 100, valid, external
Community: 3277:3267 3277:65100 3277:65320 3277:65326 3277:65330
3333 3356 8075 8075
193.0.0.56 from 193.0.0.56 (193.0.0.56)
Origin IGP, localpref 100, valid, external
3561 3356 8075 8075
206.24.210.102 from 206.24.210.102 (206.24.210.102)
Origin IGP, localpref 100, valid, external
3356 8075 8075
4.69.184.193 from 4.69.184.193 (4.69.184.193)
Origin IGP, metric 0, localpref 100, valid, external
Community: 209:80 209:888 701:30 703:30 1120:2 1299:2869 1299:5509 1299:5583 2914:470 3356:3 3356:22 3356:100 3356:123 3356:575 3356:2012 3549:200 3549:666 4657:905 5511:1550 6453:80 6762:20008 7018:80 7473:22009 7473:23009 10026:11010 10026:11020 10026:11030 10026:11040 10026:11050 10026:11060 10026:11070 10026:11080 10026:11090 10026:11100 25160:209 25160:1239 65009:7018
2914 3356 8075 8075
129.250.0.11 from 129.250.0.11 (129.250.0.12)
Origin IGP, metric 6, localpref 100, valid, external
Community: 2914:420 2914:1008 2914:2000 2914:3000 65504:3356
19214 12989 8075 8075
208.74.64.40 from 208.74.64.40 (208.74.64.40)
Origin IGP, localpref 100, valid, external
101 101 8075 8075
209.124.176.223 from 209.124.176.223 (209.124.176.223)
Origin IGP, localpref 100, valid, external
Community: 101:20400 101:22200
Extended Community: RT:101:22200
6939 8075 8075
216.218.252.164 from 216.218.252.164 (216.218.252.164)
Origin IGP, localpref 100, valid, external
1239 3356 8075 8075
144.228.241.130 from 144.228.241.130 (144.228.241.130)
route-views>$
Thanks for the feedback, John. :)
ReplyDeleteThanks for this interesting post. Its really helpful. I like to ask you what one can do to be able to use expect to hop from one server to a device just like when hoping thru a Cisco terminal server to access a device thru console. But in this case the Cisco terminal server is a RedHat server.
ReplyDeleteLinux Server(Telnet) --> Linux Server(Telnet) --> Device
Does one spawn another telnet child process on the second Linux Server?
If that is the case how can one achieve this.
I will Appreciate your suggestions and help.
Thanks for reading and the kind words. Have you tried using Subprocess to spun off Minicom or other serial programs? You might have to alter the program default with command line options to go directly into the program itself.
DeleteAnother option that is more scalable is to use a Linux-based terminal server. Cisco TS has limited configuration options in serial line and with human in mind, so sometimes you are stuck. I am not affiliated with Digi and you are free to use anything, they make a resonably priced TS such as https://www.digi.com/products/consoleservers/digicm#overview.
As a Linux-based server, the options are wide open for you.
Let me know what you think.
You can try pyexpect, it's very easy to use and has the same basic functionalities as expet has but in pure python.
ReplyDelete@Eric Chou: You can also use pyserial for that porpuse.
Ah, good point. I have used it with Arduino for serial connection but forgot about that here. Thanks!
DeleteYou know, I had a chance to do this earlier, using Raspberry Pi with /dev/ttyUSB0 Keyspan serial-to-usb adapter to console in to a switch. Minicom works, serial.Serial().readline() works when I power cycle the device but the loop I put up for continuously reading the input didnt work.
DeleteMinicom works, so I know the serial cable is good. But I ended up just resorting back to PExpect instead of using PySerial. Personally I think PySerial is better if you need a serial connection that reads one or a few lines at a time; for router provisioning as a continuous interactive session PExpect/Expect is still a better option.
Great Article
ReplyDeleteFinal Year Projects for CSE in Python
FInal Year Project Centers in Chennai
Python Training in Chennai
Python Training in Chennai
You have shared a very informative article here. If you are interested to buy dedicated vpn at the lowest price, visit vpnshazam.com
ReplyDeleteThank you again for all the knowledge you distribute,Good post. I was very interested in the article, it's quite inspiring I should admit. I like visiting you site since I always come across interesting articles like this one.Great Job, I greatly appreciate that.Do Keep sharing! Regards, OMC parts
ReplyDeleteVPN services establish secure and encrypted connections to provide greater privacy. VPNShazam offers one of the best VPN reseller program which allows clients to start their own VPN service. For the more details you can visit on Resell VPN
ReplyDeleteDumpsaway.com provides authentic IT Certification exams preparation material guaranteed to make you pass in the first attempt. Download instant free demo & begin preparation.
ReplyDeletehttps://www.dumpsaway.com