Python error handling Paramiko - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Networking (https://python-forum.io/forum-12.html) +--- Thread: Python error handling Paramiko (/thread-4462.html) |
Python error handling Paramiko - pythondiy - Aug-18-2017 Hello, I am writing a Python script, using Paramiko, to ssh to servers one by one to test connectivity. The issue I am having is, if one of the server is unavailable, I get a stack trace and my program stops running there on. How do I just report something like "connection refused" and move on to another host please? import logging import sys import getpass import paramiko from paramiko import client import threading, paramiko username = raw_input("Username: ") password = getpass.getpass("Password: ") class ssh: client = None shell = None transport = None def __init__(self, address): print("Connecting to server : " + address + ".") self.client = paramiko.client.SSHClient() self.client.set_missing_host_key_policy(paramiko.client.AutoAddPolicy()) self.client.connect(address, username=username, password=password, look_for_keys=False) def sendCommand(self, command): if(self.client): stdin, stdout, stderr = self.client.exec_command(command) while not stdout.channel.exit_status_ready(): #Print data whena available if stdout.channel.recv_ready(): alldata = stdout.channel.recv(1024) prevdata = b"1" while prevdata: prevdata = stdout.channel.recv(1024) alldata += prevdata print(str(alldata)) else: print("Connection not opened.") connection = ssh("host1") connection.sendCommand("uptime") connection = ssh("host2") connection.sendCommand("uptime") connection = ssh("host3") RE: Python error handling Paramiko - nilamo - Aug-18-2017 If you're getting an error, and want to handle it safely, then you're looking for exception handling: https://docs.python.org/3/tutorial/errors.html >>> def i_always_fail(): ... print("here we go!") ... raise Exception("dead") ... >>> i_always_fail() here we go! Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in i_always_fail Exception: dead >>> try: ... i_always_fail() ... except Exception as err: ... print("Error happened: {}".format(err)) ... here we go! Error happened: dead RE: Python error handling Paramiko - oldseven - Aug-22-2017 I think you'd better to use multiple threads. Here is an example: # _*_ coding:utf-8 _*_ import time import os import paramiko import threading import datetime import traceback import re current_path = os.getcwd() # customize the following path # the content of host list file should be: # officename swname swip username password # eg: marvin huawei 10.0.0.7 jack 123456 host_list_path = current_path + '/sw.txt' # puts your commands to this file one by one line command_list_path = current_path + '/command.txt' # Don't add backslash at the end of path. log_path = '/home/seven/log' # get current time now = datetime.datetime.now() # get thread lock thread = threading.Lock() # thread list threads = [] # success hosts list success_hosts = [] # failed hosts list fail_hosts = [] #Use for loop to telnet into each routers and execute commands class Bakconf(threading.Thread): def __init__(self, swname, host, username, password, port, day_dir, screen_command): threading.Thread.__init__(self) self.swname = swname self.host = host self.username = username self.password = password self.port = port self.log_dir = day_dir self.screen_command = screen_command def run(self): try: paramiko.util.log_to_file('ssh.log') ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) print("Connecting to server %s" % self.host) ssh_client.connect(self.host, self.port, self.username, self.password, allow_agent = False, look_for_keys = False, timeout=10) print("Successfully connected to server %s." % self.host) chan = ssh_client.invoke_shell() time.sleep(2) if chan.send_ready(): chan.send(self.screen_command+"\n") else: raise("Channel not ready!") sleep_time = 10 # execute commands in commands file. for command in open(command_list_path, 'r').read().splitlines(): chan.send(command+"\n") print("%s is running. Sleep for %d seconds!" % (self.host, sleep_time)) time.sleep(sleep_time) # write output to log file. filename = self.log_dir + "/%s:%i-%.2i-%.2i-%.2i:%.2i:%.2i.log" % (self.swname, now.year, now.month, now.day, now.hour, now.minute, now.second) with open(filename,"ab+") as fp: resp = chan.recv(9999999) fp.write(resp) print("Host %s was exported Successfully!" % self.host) chan.send('quit\n') ssh_client.close() success_hosts.append(self.host) except: fail_hosts.append(self.host) print("Can't connect to %s" % self.host) print("port=%s, username=%s, password=%s" % (self.port, self.username, self.password)) traceback.print_exc() print("Thread exit!\n") return def main(): for line in open(host_list_path, 'r').read().splitlines(): if line: try: officename, swname, swip, username, password, screen_command = re.split(',\s?', line) except: print("\nThe style of host list file is incorrect.\n")292.82 return office_dir = log_path + "/" + officename if not os.path.exists(office_dir): os.makedirs(office_dir) day_dir = office_dir + "/%i-%.2i-%i" % (now.year, now.month, now.day) if not os.path.exists(day_dir): os.mkdir(day_dir) bakconf_thread = Bakconf(swname, swip, username, password, 22, day_dir, screen_command) bakconf_thread.start() threads.append(bakconf_thread) for t in threads: t.join() print("Finish!\nSucceeded hosts: %s\nFailed hosts: %s" % (success_hosts, fail_hosts)) if __name__=="__main__": main() Better not to use 'exec_command' command. SSH client will be closed if this command is executed. And you have to reconnect to the server if you want to execute other commands. So: 'chan = ssh_client.invoke_shell()' is a good choice. |