多线程自动化运维linux的尝试 优化二

https://www.cnblogs.com/tingxin/p/13060440.html 优化

默认用ssh key 登录,并在日志的文件名加入进程ID

import paramiko
import threading
import sys,os
import datetime
from conf import logconf
import getpass

hostname = ""

def hostnamelist():
    """
     :return:  hostname list
    """
    global result,hosttoal
    try:
        hosts = open("vmhost", "r", encoding='utf-8')
        hostnames = hosts.readlines()
        hosts.seek(0)
        hosttoal = len(open("vmhost", "r", encoding='utf-8').readlines())
        print("There are  %d target host :/n%s" % (hosttoal,hostnames))
        hosts.close()
        return hostnames
    except FileNotFoundError:
        print('无法打开指定的文件!')
    except LookupError:
        print('指定了未知的编码!')
    except UnicodeDecodeError:
        print('读取文件时解码错误!')
    finally:
        if hosts:
            hosts.close()


class RemoteServer(object):
    """
    Container class for SSH functionality. Needs to be used in a with statement.
    """

    def __init__(self):
        self.ssh_client = None
        self.user = "root"
        self.password = None
        self.logtarget = ''
        self.server = ''
        self.status = True       #set all the reulst is running successfully
        self.ssh_client = paramiko.SSHClient()
        self.privatekey = ""
        self.keyfile = ""
        self.ssh_client.load_system_host_keys()
        self.ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.logtarget = os.path.basename(__file__).split('.')[0]
        print(os.path.basename(__file__))

    def __setattr__(self, key, value):
        self.__dict__[key]=value

    def __exit__(self, exc_type, exc_val, exc_tb):
        try:
            if self.ssh_client is not None:
                self.logger.info('Exit remote server (%s) now, Bye,Bye !', self.server)
                self.ssh_client.close()
        except:
            self.logger.error("received an exception closing the ssh connection.", exc_info=True)
        finally:
            self.ssh_client = None

    def connect(self):
        try:
            self.logger.info('tring to  connect  server %s', self.server)
            if self.password == None:
                self.logger.info("login with ssh key")
                self.privatekey = paramiko.RSAKey.from_private_key_file(self.keyfile)
                self.ssh_client.connect(self.server, 22, self.user, pkey=self.privatekey)
            else:
                self.logger.info("login with password")
                self.ssh_client.connect(self.server, 22, self.user, self.password)

        except paramiko.AuthenticationException:
            self.logger.error("Wrongful username or password.  Please try again", exc_info=True)
            try:
                self.ssh_client.connect(self.server,22, self.user, self.password)
            except:
                self.logger.error("Wrongful username or password.  Please try again", exc_info=True)
                sys.exit(1)
        except :
            self.logger.error('connect to remote server %s failed',self.server)
            self.logger.error("Unexpected error:", sys.exc_info()[0])
            exit()
        return self

    def execute(self,sudo=False):
        self.logfile = self.logtarget +'.' + self.server.split('.')[0]+'_'+str(os.getpid())
        self.logger = logconf.logconf(self.logfile)  # init log config
        self.connect()
        self.logger.info("connect to server %s Successfully !
", self.server)

        for command in commands:
            command = command.strip("
")
            try:
                starttime = datetime.datetime.now()
                self.logger.info('Start execute command: (%s) on host (%s) ',command,self.server)
                stdin, stdout, stderr = self.ssh_client.exec_command(command,timeout=180)
                self.logger.info('Following is the (%s) result 
',command)
                self.logger.info(stdout.read().decode(encoding='utf-8'))
                self.logger.info('Execute ({}) used times: ({}s) 
'.format(command, datetime.datetime.now() - starttime))
            except paramiko.SSHException:
                self.logger.error(stderr.read().decode(encoding='utf-8'),exc_info=True)
                self.logger.info("End of  execute on server (%s)",self.server)
                self.logger.error("Pls check the reason and run agin", self.server)
                exit()
                if sudo:
                    stdin.write(self.password + '
')
                    stdin.flush()
            if stderr.read().decode(encoding='utf-8'):
                self.logger.error(stderr.read().decode(encoding='utf-8'), exc_info=True)
                self.logger.info("End of  execute on server (%s)", self.server)
                self.logger.error("Pls check the command (%s) and run agin",command)
                self.status = False
                break
        if self.status == False:
            self.logger.info("One of the command is run failed  on (%s),pls check the logfile (%s) for detail information !!! 
", self.server,os.path.join(os.path.dirname(os.getcwd()),'worklog',self.logfile))
        else:
            self.logger.info("all the batch process running successfully on (%s) 
", self.server)

if __name__ == '__main__':

    # cmd  = ['date','hostname','cat /etc/security/limits.conf|grep -v ^#|grep -v ^$','cat /etc/security/limits.d/20-nproc.conf |grep -v ^#|grep -v ^$','cat /etc/sysctl.conf|grep -v ^#|grep -v ^$']
    commands=""
    with open("command.txt",'r',encoding='utf-8') as batch:
        commands = batch.readlines()
    print("following command will be execute %s" %(commands))
    username = "root"  # 用户名
    sshkey  = input("Passwor or key ? Yes for key ,No for password :")
    while True:
        if sshkey == "Yes"  or sshkey == "":
            password =""
            print("Login with ssh key")
            break
        else:
            print("Login with Password")
            password = getpass.getpass('please type password of %s :' % username)
            break
    # username = input("Please Input  Username :") # 用户名
    # command = input("pls input command , which can be split by comma :")
    print("........................................Batch Process Begin........................................")
    for targethost in hostnamelist():
        targethost = targethost.strip("
")
        sshhost = RemoteServer()
        sshhost.server,sshhost.port,sshhost.user = targethost,22,"root"
        if password:
            sshhost.password = password
        else:
            sshhost.keyfile = "..confid_rsa".replace('\', '/')
            if sshhost.keyfile:
                print("Found key file for autologin")
        batch = threading.Thread(sshhost.execute())
        batch.start()
        batch.join()
    print("........................................Batch Process  End........................................")
原文地址:https://www.cnblogs.com/tingxin/p/13060811.html