Skip to content

Instantly share code, notes, and snippets.

@112buddyd
Last active November 5, 2015 18:10
Show Gist options
  • Save 112buddyd/99c2c472b893de698db2 to your computer and use it in GitHub Desktop.
Save 112buddyd/99c2c472b893de698db2 to your computer and use it in GitHub Desktop.
import time, threading, paramiko, getpass, logging, sys, datetime
from multiprocessing.pool import ThreadPool
"""
To Do:
-Settings file, stores number of threads and debug levels
-In get_creds, attempt to login to one device to test credentials instead of many and locking account.
-Change reporting at end to declare successful devices and failed devices.
"""
#logging setup
timestr = time.strftime("%Y%m%d-%H%M")
logfile = timestr + '-ConfigPush.log'
logging.basicConfig(filename=logfile, level=logging.DEBUG, format='%(asctime)s %(levelname)s:%(message)s')
logging.getLogger("paramiko").setLevel(logging.INFO)
#Variables
user = ''
password = ''
iplistfile = ''
commandfile = ''
iplist = []
commands = []
running_threads = []
all_threads = []
#Functions
def get_creds(): #Gets user credentials
#get username input, will force non-blank name
global user
user = input('Username: ')
if user == '':
print ('Invalid username, please try again.')
user = input('Username: ')
#get password using getpass module, password will not be displayed while typing
global password
password = getpass.getpass('Password: ')
if password == '':
print('Password can not be blank, try again.')
password = getpass.getpass('Password: ')
#logging for function
logging.info('Username is %s', user)
logging.info('Password acquired.')
def get_files(): #Gets filenames from user for iplist and commands
#get file with list of IP addresses
global iplistfile
iplistfile = input('File containg list of IPs: ')
if iplistfile == '':
print ('Invalid list, please try again.')
iplistfile = input('File containg list of IPs: ')
#get file with list of commands
global commandfile
commandfile = input('File containing list of commands: ')
if commandfile == '':
print('Invalid list, please try again.')
commandfile = input('File containing list of commands: ')
#logging for function
logging.info('IP List is %s.', iplistfile)
logging.info('Command list is %s.', commandfile)
def open_files(): #Opens given iplist and command files and converts to lists
global iplist
try:
f = open(iplistfile, 'r')
logging.debug("Saved contents of %s to list 'iplist'.", iplistfile)
except:
logging.critical('Unable to open %s. Exiting.', iplistfile)
print('Unable to open {}. Exiting.'.format(iplistfile))
sys.exit()
iplist = f.readlines()
f.close()
global commands
try:
f = open(commandfile, 'r')
logging.debug("Saved contents of %s to list 'commands'.", commandfile)
except:
logging.critical('Unable to open %s. Exiting.', commandfile)
print('Unable to open {}. Exiting.'.format(commandfile))
sys.exit()
commands = f.readlines()
f.close()
def push(ip): #Opens SSH connection to given IP, runs commands, and closes session.
global commands
global user
global password
host = ip.rstrip()
#Logging into device
session = paramiko.SSHClient()
#For testing purposes, this allows auto-accepting unknown host keys
#Do not use in production! The default would be RejectPolicy
session.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#Connect to the device using username and password
try:
logging.info('Attempting connection to %s.', host)
print('Attempting connection to {}.'.format(host))
session.connect(hostname=host, username=user, password=password)
except paramiko.SSHException as e:
logging.critical('Password entered is incorrect. Unable to connect to %s.', host)
print('Password entered is incorrect. Unable to connect to {}.'.format(host))
logging.debug(e)
return
except paramiko.AuthenticationException as e:
logging.critical('Authentication failed to %s for some reason.', host)
print('Authentication failed for some reason. Unable to connect to {}.'.format(host))
logging.debug(e)
return
except Exception as e:
logging.critical('Socket connection to %s failed.', host)
print('Socket connection to {} failed.'.format(host))
logging.debug(e)
return
#Start an interactive shell session on the router
connection = session.invoke_shell()
#Setting terminal length for entire output - disable pagination
connection.send("terminal length 0\n")
time.sleep(1)
#send each line in command file, wait 1 sec, then send next
for command in commands:
command = command.rstrip()
connection.send(command + '\n')
time.sleep(1)
logging.info('Commands applied to %s.', host)
print('Commands applied to {}.'.format(host))
#output for searching for errors
router_output = connection.recv(65535)
session.close()
logging.info('Closed session to %s.', host)
print('Closed session to {}.'.format(host))
def run(threads=10):
print('Starting jobs.')
start_time = datetime.datetime.now()
pool = ThreadPool(threads)
pool.map(push, set(iplist))
pool.close()
pool.join()
end_time = datetime.datetime.now()
print('All jobs completed in {}.'.format(end_time-start_time))
#begin running of functions
get_creds()
get_files()
open_files()
run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment