Last active
November 5, 2015 18:10
-
-
Save 112buddyd/99c2c472b893de698db2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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