Skip to content

Commit

Permalink
Create IOS_update_threating_w_stack.py
Browse files Browse the repository at this point in the history
  • Loading branch information
nouse4it authored Nov 12, 2020
1 parent f899215 commit 116faae
Showing 1 changed file with 326 additions and 0 deletions.
326 changes: 326 additions & 0 deletions IOS_update_threating_w_stack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,326 @@
"""
Category: Netmiko Config Script
Author: nouse4it <[email protected]>
IOS_update_threating_w_stack.py
Illustrate the following conecepts:
- Update IOS of given IOS-based Switch; Test with 2960x
-- Including 2960x-Stacks
- Process handling happend parallel by threating
- Including MD5-Check after copy of Software to Switch to ensure integrity
"""

__author__ = "nouse4it"
__author_email__ = "[email protected]"
__copyright__ = "Copyright (c) 2020 nouse4it "

# Importing all needed Modules
import netmiko
from netmiko import SCPConn,ConnectHandler
import os,sys,subprocess,re
from pprint import pprint
import json
import threading
import time

#------------------------------------------------------------------------------
def check_md5(filename):
command = 'md5sum '+filename
o = subprocess.getoutput(command)
output = o.split(' ')
return output[0]
#------------------------------------------------------------------------------
def set_boot(net_connect,file):
get_old_vers = net_connect.send_command('sh version | i System image file is')
old_vers = get_old_vers.split('"')[1]
net_connect.config_mode()
net_connect.send_command('boot system switch all flash:{},{} '.format(file,old_vers))
net_connect.exit_config_mode()
output = net_connect.send_command('sh boot | i BOOT')
print('Following Boot String was set: {}', format(output))
net_connect.send_command('wr')
#------------------------------------------------------------------------------
def reload(net_connect):
net_connect.send_command('reload',expect_string='')
net_connect.send_command('\n')
#------------------------------------------------------------------------------
def archive_run(net_connect,filename):
result = net_connect.send_command("show run")
# close SSH connection
# net_connect.disconnect()
file = open(filename,"w")
file.write(result)
file.close()
#------------------------------------------------------------------------------
def verify_md5(net_connect,file,md5):
result = net_connect.send_command("verify /md5 flash:{} {}".format(file,md5))
# close SSH connection
# net_connect.disconnect()
reg = re.compile(r'Verified')
verify = reg.findall(result)
if verify:
result = True
else:
result = False
return result
#------------------------------------------------------------------------------
def verify_space(net_connect,file):
result = net_connect.send_command("show flash:")
# close SSH connection
# net_connect.disconnect()
reg = re.compile(r'(\d+)\sbytes\sfree')
space = int(reg.findall(result)[0])
reg = re.compile(r'.*-rwx.*({})'.format(file))
exist = reg.findall(result)
f_size = os.path.getsize(file)
if space >= f_size:
result = 'True'
if space < f_size:
result = 'False'
if exist:
exist = 'True'
else:
exist = 'False'
return result,exist
#------------------------------------------------------------------------------
def transfer_file(net_connect,file):
net_connect.config_mode()
net_connect.send_command('ip scp server enable')
scp_conn = SCPConn(net_connect)
s_file = file
d_file = file
scp_conn.scp_transfer_file(s_file, d_file)
#------------------------------------------------------------------------------
def stack_check(net_connect,file):
output = net_connect.send_command("sh run | i GigabitEthernet")
intf = output.splitlines()
if 'interface GigabitEthernet4/0/1' in intf:
print('It´s a 4-Switch Stack')
print('Copying Image to flash4:')
net_connect.send_command('copy flash:%s flash4:' %(file), expect_string='Destination filename')
net_connect.send_command('\n', expect_string=r'#', delay_factor=5)

print('Copying Image to flash3:')
net_connect.send_command('copy flash:%s flash3:' %(file), expect_string='Destination filename')
net_connect.send_command('\n', expect_string=r'#', delay_factor=5)

print('Copying Image to flash2:')
net_connect.send_command('copy flash:%s flash2:' %(file), expect_string='Destination filename')
net_connect.send_command('\n', expect_string=r'#', delay_factor=5)

elif 'interface GigabitEthernet3/0/1' in intf:
print('It´s a 3-Switch Stack')
print('Copying Image to flash3:')
net_connect.send_command('copy flash:%s flash3:' %(file), expect_string='Destination filename')
net_connect.send_command('\n', expect_string=r'#', delay_factor=5)

print('Copying Image to flash2:')
net_connect.send_command('copy flash:%s flash2:' %(file), expect_string='Destination filename')
net_connect.send_command('\n', expect_string=r'#', delay_factor=5)

elif 'interface GigabitEthernet2/0/1' in intf:
print('It´s a 2-Switch Stack')
print('Copying Image to flash2:')
net_connect.send_command('copy flash:%s flash2:' %(file), expect_string='Destination filename')
net_connect.send_command('\n', expect_string=r'#', delay_factor=5)

elif 'interface GigabitEthernet1/0/1' in intf:
print('It´s not a Stack besides quoted! No additional copy needed')

return
#------------------------------------------------------------------------------
def read_devices( devices_filename ):

devices = {} # create our dictionary for storing devices and their info

with open( devices_filename ) as devices_file:

for device_line in devices_file:

device_info = device_line.strip().split(',') #extract device info from line

device = {'ipaddr': device_info[0],
'type': device_info[1],
'name': device_info[2],
'stack': device_info[3]} # create dictionary of device objects ...

devices[device['ipaddr']] = device # store our device in the devices dictionary
# note the key for devices dictionary entries is ipaddr

print ('\n----- devices --------------------------')
pprint( devices )

return devices

#------------------------------------------------------------------------------
def command_worker( device, creds ):

#---- Connect to the device ----
if device['type'] == 'cisco-nxos': device_type = 'cisco_nxos'
elif device['type'] == 'cisco-ios': device_type = 'cisco_ios'
else: device_type = 'cisco_ios' # attempt Cisco IOS as default

print ('---- Connecting to device {0}, username={1}, password={2}'.format( device['ipaddr'],
creds[0], creds[1] ))
# ---- Connect to the device
session = ConnectHandler(device_type=device_type, ip=device['ipaddr'],
username=creds[0], password=creds[1])

if device_type == 'cisco_nxos':
#verify if there is enough free space on device to upload ios file
net_connect = session
ver = verify_space(net_connect,file_s)
print("\n\n Verifying sufficient space available on the file system ... %s\n\n" %(device['ipaddr']))

if ver[0] == 'True' and ver[1] == 'False':
print("\n\n Success! - proceed with image upload")
print ("\n\nUploading file : %s ...\n\n" %(file_s))
#transferring file to device
net_connect = session
transfer_file(net_connect,file_s)
print ("\n\nSuccess! - upload file: %s to device: %s was successfull ... \n\n" % (file_s,device['ipaddr']))

#veryfing md5
net_connect.exit_config_mode()
md5 = check_md5(file_s)
print ("\n\nVerifying md5 checksum on device ... %s\n\n" %(device['ipaddr']))
net_connect = session
v_md5 = verify_md5(net_connect, file_s,md5)
if v_md5 == True:
print("\n\n MD5 Check... Success! - Starting archive running config")
filename = device['ipaddr']+"-running-config.txt"
print ("\n\nSaving running config into file: %s \n\n" %(filename))
archive_run(net_connect,filename)
print("\n\n Archvie Config... Success! - proceed with inserting boot system command")
set_boot(net_connect, file_s)
print("\n\n Inserting Boot System Command... Success! - proceed with reload")
try:
reload(net_connect)
except:
print("Reloading ... ")
else:
print("\n\n Abort !!!\n\n")
else:
print("\n\n Error veryfiing md5 checksum on device, quitting !!!\n\n")

elif ver[0] == 'False' and ver[1] == 'False':
print("\n\n Not enough free space on device ... %s \n\n" %(device['ipaddr']))

elif ver[1] == 'True':
print ("\n\nFile already uploaded on device ... %s \n\n" %(device['ipaddr']))

if device_type == 'cisco_ios' and device['stack'] == 'yes':
#verify if there is enough free space on device to upload ios file
net_connect = session
ver = verify_space(net_connect,file_s)
print("\n\n Verifying sufficient space available on the file system ... %s\n\n" %(device['ipaddr']))

if ver[0] == 'True' and ver[1] == 'False':
print("\n\n Success! - proceed with image upload")
print ("\n\nUploading file : %s ...\n\n" %(file_s))
#transferring file to device
net_connect = session
transfer_file(net_connect,file_s)
print ("\n\nSuccess! - upload file: %s to device: %s was successfull ... \n\n" % (file_s,device['ipaddr']))

#veryfing md5
net_connect.exit_config_mode()
md5 = check_md5(file_s)
print ("\n\nVerifying md5 checksum on device ... %s\n\n" %(device['ipaddr']))
net_connect = session
v_md5 = verify_md5(net_connect, file_s,md5)
if v_md5 == True:
print("\n\n MD5 Check... Success! - Starting check how many Switches in Stack")
net_connect.exit_config_mode()
stack_check(net_connect,file_s)
filename = device['ipaddr']+"-running-config.txt"
print ("\n\nSaving running config into file: %s \n\n" %(filename))
archive_run(net_connect,filename)
print("\n\n Archvie Config... Success! - proceed with inserting boot system command")
set_boot(net_connect, file_s)
print("\n\n Inserting Boot System Command... Success! - proceed with reload")
try:
reload(net_connect)
except:
print("Reloading ... ")
else:
print("\n\n Abort !!!\n\n")
else:
print("\n\n Error veryfiing md5 checksum on device, quitting !!!\n\n")

elif ver[0] == 'False' and ver[1] == 'False':
print("\n\n Not enough free space on device ... %s \n\n" %(device['ipaddr']))

elif ver[1] == 'True':
print ("\n\nFile already uploaded on device ... %s \n\n" %(device['ipaddr']))

if device_type == 'cisco_ios' and device['stack'] == 'no':
#verify if there is enough free space on device to upload ios file
net_connect = session
ver = verify_space(net_connect,file_s)
print("\n\n Verifying sufficient space available on the file system ... %s\n\n" %(device['ipaddr']))

if ver[0] == 'True' and ver[1] == 'False':
print("\n\n Success! - proceed with image upload")
print ("\n\nUploading file : %s ...\n\n" %(file_s))
#transferring file to device
net_connect = session
transfer_file(net_connect,file_s)
print ("\n\nSuccess! - upload file: %s to device: %s was successfull ... \n\n" % (file_s,device['ipaddr']))

#veryfing md5
net_connect.exit_config_mode()
md5 = check_md5(file_s)
print ("\n\nVerifying md5 checksum on device ... %s\n\n" %(device['ipaddr']))
net_connect = session
v_md5 = verify_md5(net_connect, file_s,md5)
if v_md5 == True:
print("\n\n MD5 Check... Success! - Starting archive running config")
filename = device['ipaddr']+"-running-config.txt"
print ("\n\nSaving running config into file: %s \n\n" %(filename))
archive_run(net_connect,filename)
print("\n\n Archvie Config... Success! - proceed with inserting boot system command")
set_boot(net_connect, file_s)
print("\n\n Inserting Boot System Command... Success! - proceed with reload")
try:
reload(net_connect)
except:
print("Reloading ... ")
else:
print("\n\n Abort !!!\n\n")
else:
print("\n\n Error veryfiing md5 checksum on device, quitting !!!\n\n")

elif ver[0] == 'False' and ver[1] == 'False':
print("\n\n Not enough free space on device ... %s \n\n" %(device['ipaddr']))

elif ver[1] == 'True':
print ("\n\nFile already uploaded on device ... %s \n\n" %(device['ipaddr']))

session.disconnect()

return

#==============================================================================
# ---- Main: Run Commands
#==============================================================================

file_s = input("Enter Image Filename: ")
username = input("Enter Username: ")
password = input("Enter Password: ")

devices = read_devices('devices-file')
creds = (username, password)

config_threads_list = []

for ipaddr,device in devices.items():
print('Creating thread for: ', device)
config_threads_list.append(threading.Thread(target=command_worker, args=(device, creds)))

print('\n---- Begin running command threading ----\n')
for config_thread in config_threads_list:
config_thread.start()

for config_thread in config_threads_list:
config_thread.join()

0 comments on commit 116faae

Please sign in to comment.