Search code examples
pythonpython-2.7network-programmingtelnetcisco

Opening a user specified file with Python 2.7 to use in a Telnet session


I'm trying to write some code that can establish a Telnet session to a Cisco switch and use a separate text file for the commands. (The switch is on the other end of a satellite link so some latency is expected).

My code is below:

import telnetlib
import time
import sys

#Open telnet connection to devices
def open_telnet_conn(ip):
    try:
        #Define telnet parameters
        username = 'admin'
        password = 'password'
        telnet_port = 23
        telnet_timeout = 30
        reading_timeout = 30
        
        #Logging into device
        connection = telnetlib.Telnet(ip, telnet_port, telnet_timeout)
    
        #Waiting for the username prompt and sending the username
        output = connection.read_until("Username:", reading_timeout)
        connection.write(username + "\n")
        time.sleep(2)
        
        #Waiting for the password prompt and sending the password
        output = connection.read_until("Password:", reading_timeout)
        connection.write(password + "\n")
        time.sleep(2)   
        
        #Setting terminal length for entire output - no pagination
        connection.write("terminal length 0\n")
        time.sleep(2)
        
        #Entering global config mode
        connection.write("\n")
        connection.write("configure terminal\n")
        time.sleep(2)
        
        #Open user selected file for reading
        selected_cmd_file = open(raw_input('Please enter command file name with extension: '), 'r')
           
        #Starting from the beginning of the file
        selected_cmd_file.seek(0)
        
        #Writing each line in the file to the device
        for each_line in selected_cmd_file.readlines():
            connection.write(each_line + '\n')
            time.sleep(2)
    
        #Closing the file
        selected_cmd_file.close()
        
        #Test for reading command output
        switch_output = connection.read_very_eager()
        print switch_output
        
        #Closing the connection
        connection.close()

    except IOError:
        print "Input parameter error! Please check username, password and file name."

#Calling the Telnet function
open_telnet_conn('192.168.0.10')
raw_input('Press enter to exit')
sys.exit('Goodbye')

I keep hitting the IOError after typing in the filename with extension.

Could it be anything to do with the location of the text document? At the moment it's located in the same folder as the application.

I'm running it on a windows machine via command prompt.

---Update 29/12/17---

So I have managed to get python to read the text file, (I had to change the directory it was in). But now, once the script runs the commands from the text document (show running-config) it doesn't seem to collect the output as is desired.

This is the output I'm getting from the Python Terminal:

- Please enter command file name with extension: telnetcommands.txt
- SW-SM-01#terminal length 0
- SW-SM-01#
- SW-SM-01#configure terminal
- Enter configuration commands, one per line.  End with CNTL/Z.
- SW-SM-01(config)#end
- SW-SM-01#
- SW-SM-01#!
- SW-SM-01#
- SW-SM-01#show run
- Press enter to exit

I'm trying to get it to print out the running config.


Solution

  • Can you show the contents of the telnetcommands.txt file? If it just contains a single command show running-config, can you confirm that these commands work as you intend them to if you enter them manually in a telnet session?

    configure terminal
    show running-config
    

    Because some switches might not allow show running-config in the configuration mode.


    Update:

    Looks like you simply need to use the expect() function.

    Instead of:

        for each_line in selected_cmd_file.readlines():
            connection.write(each_line + '\n')
            time.sleep(2)
    

    Try to use:

        connection.read_very_eager()    # discard previous output
        for each_line in selected_cmd_file.readlines():
            connection.write(each_line.rstrip() + '\n')   # rstrip() for consistency
            index, match, text = connection.expect(['#'],30)
            time.sleep(1)    # wait for some extra output just in case
            print text + connection.read_very_eager()
    

    After this the following lines should be unnecessary:

        switch_output = connection.read_very_eager()
        print switch_output