Python3 Threading for SSH

This article describes on how to utilize Python Threading module as a complement to make our SSH application more powerful. On threading module, it has Method of operation of the threading.Thread class: The class threading.Thread has a method start(), which can start a Thread. It triggers off the method run(), which has to be overloaded. The join() method makes sure that the main program waits until all threads have terminated. Before we integrate Python Threading module to our previous SSH application, We are going to give a basic tutorial regarding threading.

Threading Basic

At the beginning, let’s create a function like below. This function will show how Python function will execute a code without a threading.

import time
import datetime

def myfunction():
    date_time = datetime.datetime.now().strftime("%I:%M:%S %p")
    print("Start a Thread at %s" % date_time)
    time.sleep(2)
    print("End a Thread at %s" % date_time)
    print("")

for i in range(5):
    myfunction()

output:

Start a Thread at 10:28:58 PM
End a Thread at 10:28:58 PM

Start a Thread at 10:29:00 PM
End a Thread at 10:29:00 PM

Start a Thread at 10:29:02 PM
End a Thread at 10:29:02 PM

Start a Thread at 10:29:04 PM
End a Thread at 10:29:04 PM

Start a Thread at 10:29:06 PM
End a Thread at 10:29:06 PM

On above output, according to the timestamp, we can see print statement executed one by one once the the previous thread is finished. Now let’s add threading module utilized on your codes.

import threading
import datetime
import time

def myfunction2():
    date_time = datetime.datetime.now().strftime("%I:%M:%S %p")
    print("Start a Thread at %s\n" % date_time, end="")
    time.sleep(2)
    print("End a Thread at %s\n" % date_time, end="")

thread_instance = []
for i in range(5):
    trd = threading.Thread(target=myfunction2)
    trd.start()
    thread_instance.append(trd)

for thread in thread_instance:
    thread.join()

Output:

Start a Thread at 05:19:02 PM
Start a Thread at 05:19:02 PM
Start a Thread at 05:19:02 PM
Start a Thread at 05:19:02 PM
Start a Thread at 05:19:02 PM
End a Thread at 05:19:02 PM
End a Thread at 05:19:02 PM
End a Thread at 05:19:02 PM
End a Thread at 05:19:02 PM
End a Thread at 05:19:02 PM

By utilizing threading module, now we can execute the all threads at the same time. You may see the timestamp is identical for each threads.

Python Partial Codes

After we learn basic knowledge of treading module, let’s implement it on our previous SSH application.

# import threading module
import threading

# Create function for ssh threads
def SSH_Thread():
    # create list for each thread
    thread_instance = []
    # create ip address list of the devices
    list_ip = ["172.16.0.21", "172.16.0.22"]
    for ip in list_ip:
        trd = threading.Thread(target=ssh_conn, args=(ip.strip("\n"),))
        trd.start()
        thread_instance.append(trd)
         
    for trd in thread_instance:
        trd.join()

Python Full Codes

import paramiko
import time
import datetime
import re
import threading

def ssh_conn(ip):
    try:
        date_time = datetime.datetime.now().strftime("%Y-%m-%d")
        date_time_s = datetime.datetime.now().strftime("%I:%M:%S %p")
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(ip, port=22, username='cisco', password='router', look_for_keys=False, timeout=None)
        connection = ssh.invoke_shell()
        connection.send("\n")
        connection.send("terminal length 0\n")
        time.sleep(1)
        connection.send("\n")
        connection.send("show ip eigrp neighbor\n")
        time.sleep(3)
        file_output = connection.recv(9999).decode(encoding='utf-8')
        hostname = (re.search('(.+)#', file_output)).group().strip('#')
        outFile = open(hostname + "-" + str(date_time) + ".txt", "w")
        outFile.writelines(file_output[1328:-3])
        outFile.close()
        ssh.close()
        if re.search('% Invalid input detected', file_output):
            print("* There was at least one IOS syntax error on device %s" % hostname)
        else:
            print("{} is done it was started at {}" .format(hostname, date_time_s))

    except paramiko.AuthenticationException:
        print("User or password incorrect, Please try again!!!")

def SSH_Thread():
    thread_instance = []
    list_ip = ["172.16.0.21", "172.16.0.22"]
    for ip in list_ip:
        trd = threading.Thread(target=ssh_conn, args=(ip.strip("\n"),))
        trd.start()
        thread_instance.append(trd)

    for trd in thread_instance:
        trd.join()

if __name__ == '__main__':
    SSH_Thread()

After you execute above codes, you will be notified that the task is completed at the same time like below.

R1 is done, it was started at 05:22:18 PM
R2 is done, it was started at 05:22:18 PM

Happy labbing!!!.

Contributor:

Ananto Yudi Hendrawan
Network Engineer - CCIE Service Provider #38962, RHCSA, VCP6-DCV
nantoyudi@gmail.com