2003 Triumph Speedmaster
3,000 Miles
2004 tank paint job
2004 windshield
dresser bars, knee pads, mirrors, and signal relocators to come.
Pexpect, Python, and Managing Devices — Tratto

A few months ago I decided to write a web application that would essentially run like RANCID, I named it “tratto.” Since then I decided that it would be better to nail down a basic python framework first, then integrate it into say.. a django application. In all of my years as an engineer I had never leveraged expect to accomplish simple and repetitive tasks. I am a recent python “convert” and wanted to write a simple app that could be used as a framework for managing and monitoring network connected devices and hosts. Tratto uses pexpect to connect and parse ssh and telnet sessions.
This framework provides an easy way to connect to remote devices and issue commands and store the output. I also wanted an easy way to “extend” this framework and be able to add ways to connect to any operating system (or at least use default shell behavior as a baseline). I manage a wide variety of devices and I wanted to support at least the default implementations of Cisco IOS, OpenBSD, Mac OS X, and Aruba OS. Here is how you would add an operating system’s parameters to Tratto (Systems.py):
class ArubaOS(OperatingSystem): '''aruba configs''' PROMPTLINE ='#' PAGINATES =True DISABLE_PAGINATION = 'terminal length 0' GET_CONFIG ="show run"
There are 3 files included in Tratto right now:
- Connectivity.py — This is a class which manages sessions using pexpect
- Systems.py — This is the class which manages all the operating parameters
- driver.py — This is an example file of how to use Tratto to fetch whatever info you want
Here is an example of how to use the framework to connect to devices and issue commands:
#!/usr/bin/env python
import Connectivity
import Systems
#telnet to a cisco switch
m = Systems.OperatingSystems['IOS']
s = Connectivity.Session("192.168.6.1",23,telnet,m)
s.login("akonkol", "mypass")
s.sendcommand("show ver")
s.sendcommand("show clock")
s.sendcommand("show run")
s.logout()
#ssh to a apple machine
m = Systems.OperatingSystems['OSX']
s = Connectivity.Session("127.0.0.1",22,"ssh",m)
s.login("akonkol", "mypass")
#sendcommand will echo response by default, you can store that
#response in a variable if you wish
result = s.sendcommand("df -h")
print result
s.getversion()
s.logout()
#ssh to openbsd box
m = Systems.OperatingSystems['OBSD']
s = Connectivity.Session("192.168.5.1",22,"ssh",m)
s.login("akonkol", "mypass")
print s.sendcommand("cat /etc/passwd")
print s.sendcommand("arp -a")
s.logout()
The Future
With Tratto you can technically pull information from any networked device and use that data for whatever you please. Current ideas are integrating Tratto into
- a config repository application with a web frontend (like RANCID)
- a network mapping application using cdp neighbors
- monitoring platform which performs different commands based on certain scenarios (”show interfaces” when IP SLA shows latency)
This is my first attempt at releasing python software, so if you think something could be better let me know.
Download Tratto
Enabling VNC Server on MAC OS X Leopard
Recently I needed to troubleshoot some issues using a GUI web browser from an outside connection. This link shows how to enable vnc server on your mac using the command line. After doing that, and configuring port forwarding on my firewall I was all set.
Configuring A Cisco 2600 Series Router as a Terminal Server
I have a small lab I put together to help bash around new ideas, it consists of:
- 2 Cisco 2611s
- 2 Cisco 3500 XLs
Recently I’ve been jumping between devices using a single console cable… and that got old pretty quick. I was able to pickup a NM-16A Async module which provides 16 more lines to my 2600. To use this card I also needed a Cisco octal cable.
Steps:
1) After inserting the card and screwing in the octal cable you can verify that there is added line capacity:
Router_A#show version | i line
16 terminal line(s)
2) Before you proceed you will need to find out what line numbers your new NM-16A uses, in my case it was 33-48:
Router_A#show line
Tty Typ Tx/Rx A Modem Roty AccO AccI Uses Noise Overruns Int
* 0 CTY - - - - - 6 0 0/0 -
33 TTY 9600/9600 - - - - - 2 1 35/106 -
34 TTY 9600/9600 - - - - - 4 19 0/0 -
35 TTY 9600/9600 - - - - - 0 0 0/0 -
36 TTY 9600/9600 - - - - - 0 0 0/0 -
37 TTY 9600/9600 - - - - - 0 0 0/0 -
38 TTY 9600/9600 - - - - - 0 0 0/0 -
39 TTY 9600/9600 - - - - - 0 0 0/0 -
40 TTY 9600/9600 - - - - - 0 0 0/0 -
41 TTY 9600/9600 - - - - - 0 0 0/0 -
42 TTY 9600/9600 - - - - - 0 0 0/0 -
43 TTY 9600/9600 - - - - - 0 0 0/0 -
44 TTY 9600/9600 - - - - - 0 0 0/0 -
45 TTY 9600/9600 - - - - - 0 0 0/0 -
46 TTY 9600/9600 - - - - - 0 0 0/0 -
47 TTY 9600/9600 - - - - - 0 0 0/0 -
48 TTY 9600/9600 - - - - - 0 0 0/0 -
65 AUX 9600/9600 - - - - - 0 0 0/0 -
3) You need to create a loopback to be used to telnet to each of the lines:
interface Loopback0
ip address 126.0.0.1 255.255.255.255
no ip redirects
end
4) Next you need to configure the lines of this card with your preferred settings:
line 33 48
no flush-at-activation
transport preferred telnet
transport input all
stopbits 1
flowcontrol hardware
5) Finally, it’s nice to add ip hosts on the router for ease of use. Note that the tcp port number for our new lines are named with 20xx where “xx” is the actual line number. For example, our first line is “33″ so you need to connect to port “2033.” After this is done plug the rollover cable coming from the octal cable labeled “1″ into the console port of the device you want to manage. In my scenario, cable “1″ == line 33 == port 2033, cable “2″ == line 34 == port 2034, etc…
ip host r2 2033 126.0.0.1
ip host s1 2034 126.0.0.1
You should now have a console server in which you can “reverse” telnet into other devices connected through the octal cable.
You should be able to issue commands such as “telnet r2″ and be dropped into a console session.
To return to the router press “control + shift + 6 +x.”
To disconnect the session type “disconnect <connection number>” or “disconnect <hostname> .”
Here is the relevant configuration parameters:
ip host r2 2033 126.0.0.1
ip host s1 2034 126.0.0.1
interface Loopback0
ip address 126.0.0.1 255.255.255.255
no ip redirects
line 33 48
exec-timeout 0 0
no flush-at-activation
logging synchronous
no exec
notify
transport preferred telnet
transport input all
stopbits 1
flowcontrol hardware
A big thank you to Gerry Murray for initial guidance and introducing me to this.






