How to administer EDA firmware upgrade using python + paramiko

Ever wanted to upgrade a fleet of devices?

Here is a python3 example which uses parmiko, loops through a list of hostnames, and runs the cli administration commands to upgrade an Extrahop device.

################################
# use python3 to execute
# depends on paramiko.  Use pip to install paramiko
#
# v5
import paramiko
import time

# List of hosts to upgrade
hosts = ["hostname1",
"hostname2",
"hostname3"]

# You know what to do
username = "***"
password = "***"

if username == '***':
    print("Set username and password first")
    exit()

# The version of software to upgrade to
software = "https://yourfileserver/eda-complete-8.5.1.1566.tar"

def upgradeEDA(host):
    print("upgradeEDA: " + host)

    session = paramiko.SSHClient()
    session.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    session.connect(hostname=host,
            username=username,
            password=password)

    DEVICE_ACCESS = session.invoke_shell()
    print ("Shell session started")

    ## First read any output so far
    out = ''
    # sleep is essential, recv_ready returns False without sleep
    time.sleep(1)
    while DEVICE_ACCESS.recv_ready():
        out += DEVICE_ACCESS.recv(2048).decode('utf-8')

    # get the last line of the output
    out = out.split('\n')[-1]

    # output where we are
    print(out)

    print("Send command 'en'")
    DEVICE_ACCESS.send('en\n')

    # check for password prompt
    out = ''
    # sleep is essential
    time.sleep(1)
    while DEVICE_ACCESS.recv_ready():
        print ("For understanding")
        out += DEVICE_ACCESS.recv(2048).decode('utf-8')

    print("GOT BAK:")
    print(out)

    if out.strip() == 'Password:':
        DEVICE_ACCESS.send(password+'\n')
        print ("Password sent....")
    else:
        DEVICE_ACCESS.send(password+'\n')
        print ("Did not detect Password: prompt - sent password anyway")

    # not sure, try to see if we get anything back from the device
    out = ''
    time.sleep(1)
    while DEVICE_ACCESS.recv_ready():
        print ("4 understanding too")
        out += DEVICE_ACCESS.recv(2048).decode('utf-8')

    print ("Here...")
    print (out)

    print ("Send 'configure' command")
    DEVICE_ACCESS.send('configure\n')

    # obviously this needs to be a function! It is executed every time to read the output from the device
    time.sleep(1)
    out = ''
    while DEVICE_ACCESS.recv_ready():
        out = DEVICE_ACCESS.recv(2048).decode('utf-8')

    print ("Got back after 'configure' sent:")
    print (out)

    DEVICE_ACCESS.send('install '+software+'\n')

    # our little receive loop again
    time.sleep(1)
    out = ''
    while DEVICE_ACCESS.recv_ready():
        chunk = DEVICE_ACCESS.recv(2048).decode('utf-8')
        print ("Chunk:")
        print (chunk)
        out += chunk
        print ("sleep...")
        time.sleep(1)

    print ("OUTPUT AFTER FILE RECEIVED BY EDA:")
    print (out)

    # Give device five minutes to "do its thang"
    # NOTE: There two (2) 1-second sleeps() inside the loop
    # math 300 / 2 == 150
    for i in range(150):
        print ("RUN LOOP #: " + str(i))

        # Let's loop one more time for fun and see if more things need to be read or waited upon
        out = ''
        time.sleep(1)
        while DEVICE_ACCESS.recv_ready():
            chunk = DEVICE_ACCESS.recv(2048).decode('utf-8')
            print ("read chunk again ....")
            print (chunk)
            out += chunk
            print ("Final read loop. Sleeping...")
            time.sleep(1)

    print ("FINAL OUTPUT:")
    print (out)

    # Close out the session
    session.close()

for h in hosts:
    upgradeEDA(h)
2 Likes