侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

python主机批量管理脚本(下)

2023-11-25 星期六 / 0 评论 / 0 点赞 / 56 阅读 / 7104 字

接着上节生成的配置文件信息,我们要实现根据配置文件内容实现主机的批量管理。功能亮点:(1)支持raw_iuput列退格重新编辑(2)日志显示加亮(3)使用多进程提升执行效率使用效果图:实现代码如下:#

接着上节生成的配置文件信息,我们要实现根据配置文件内容实现主机的批量管理。

功能亮点:

(1)支持raw_iuput列退格重新编辑(2)日志显示加亮(3)使用多进程提升执行效率

使用效果图:

实现代码如下:

#!/usr/bin/env python#-*- coding:utf-8 -*-#update:20161222#auth:dsc#description:批量管理工具import os,paramiko,sys,time,ConfigParserfrom multiprocessing import Process,Poolimport base64import readline''' 返回命令列表 '''_BACK_CMD_LIST = ('quit','q','exit','bye')''' 不作为命令列表 '''_DO_NOTHING_LIST = ('','/n','/r',None)''' 禁用命令列表 '''_FORBDI_CMD = ('more','less','vi')''' 进程池大小 '''PROCESSES = 30''' 文件分发基础目录 '''DISTRIBUTE_BASE_DIR = '/tmp'''' 初始化配置文件 '''class InitConf:    def __init__(self,conf_file):        try:            file_path = os.path.join(sys.path[0],conf_file)            self.cf = ConfigParser.SafeConfigParser()            self.cf.read(conf_file)        except Exception as e:            Log('RED','ConfigParserError:%s' % (str(e)))            sys.exit(1)    ''' 读取文件配置信息 '''    def readConf(self):        hosts=[]        try:            opts = eval(self.cf.get('host','connList'))            for opt in opts:                host = []                s = eval(self.cf.get('information',opt))                host.append(s['ip'])                host.append(s['user'])                host.append(base64.b64decode(s['password']))                host.append(s['port'])                hosts.append(host)        except Exception as e:            Log('RED','ReadConfError:%s' % (str(e)))            sys.exit(1)        return hosts''' 初始化ssh服务 '''def init_server():    server = paramiko.SSHClient()    server.load_system_host_keys()    server.set_missing_host_key_policy(paramiko.AutoAddPolicy())    return server    ''' 执行命令 '''def exec_pools_cmd(server,server_list,action,cargs):        start = time.time()    p = Pool(processes = PROCESSES)    for h in server_list:        if action == 'ssh_run':            p.apply_async(ssh_run,[h,] + cargs)        elif action == 'distribute_file':            p.apply_async(distribute_file,[h,] + cargs)    p.close()    p.join()    end = time.time()    print '/033[31;1mCost time:%ss/033[0m' % str(end - start)        ''' 初始化日志目录 '''      def chkLogs():    if not os.path.exists(os.path.join(sys.path[0],'log')):        os.makedirs(os.path.join(sys.path[0],'log'))''' 获取用户输入 '''def user_input(str):    try:        cmd = raw_input('/033[32;0m[%s]=>/033[0m' %(str)).strip()        return cmd    except KeyboardInterrupt:        Log('NOMAL','/nKeyboardInterrupt')        return None    except Exception:        print '/n'        sys.exit(1)''' 定义日志输出格式 '''def Log(type,msg):    date_detail = time.strftime('%Y_%m_%d %H:%M:%S')    logText='[%s] %s' %(date_detail,msg)    if type == 'NOMAL':        print '/033[32;1m%s/033[0m' %(msg)    elif type == 'GREEN':        print '/033[32;1m[INFO ] %s/033[0m' %(logText)    elif type == 'RED':        print '/033[31;1m[ERROR] %s/033[0m' %(logText)    elif type == 'YELLOW':        print '/033[33;1m[WARN ] %s/033[0m' %(logText)''' 操作日志记录 '''def log_write(uargs):    date_detail = time.strftime('%Y_%m_%d %H:%M:%S')    log = 'Time:%s | Type:%s | Detial:%s | Server:%s | Result:%s/n' % (date_detail,uargs[0],uargs[1],uargs[2],uargs[3])    with open('./log/user_%s_record.log' % (time.strftime('%Y_%m_%d')),'a+') as f:        f.write(log)''' 命令执行函数 '''def ssh_run(host_info,cmd,server):    try:        ip,username,password,port= host_info[0],host_info[1],host_info[2],host_info[3]                server.connect(ip,int(port),username,password,timeout=5)        stdin,stdout,stderr = server.exec_command(cmd)        cmd_result = stdout.read(),stderr.read()         for rs in cmd_result:            for line in rs.split('/n'):                if line.strip() == '':                    continue                else:                    Log('NOMAL','[%s]: %s' %(ip,line))    except Exception as e:        log_write(['cmd batch',cmd,ip,'failed'])        Log('RED','[%s]: %s' % (ip,str(e)))    else:        log_write(['cmd batch',cmd,ip,'success'])''' 文件分发函数 '''def distribute_file(host_info,file_name):     try:        ip,uname,passwd,port = host_info[0],host_info[1],host_info[2],int(host_info[3])        RemoteFile = os.path.join(DISTRIBUTE_BASE_DIR,os.path.basename(file_name))        t = paramiko.Transport((ip,int(port)))        t.connect(username=uname,password=passwd)        sftp = paramiko.SFTPClient.from_transport(t)        sftp.put(file_name,RemoteFile)        t.close()    except Exception as e:        log_write(['distribute file',file_name,ip,'failed'])        Log('RED','[%s] : %s' % (ip,str(e)))    else:        log_write(['distribute file',file_name,ip,'success'])        Log('GREEN','Distribute %s to %s:%s Successfully!' % (file_name,ip,RemoteFile))''' 主函数 '''def main(conf_name):    p = InitConf(conf_name)    server_list = p.readConf()    server = init_server()        while True:        print '''    -------------------------       [1]Execute command.       [2]Distribute files.       [q]Exit.    -------------------------/n'''        choice = user_input('Choice')        if choice == '1':            while True:                cmd = user_input('Cmd')                if cmd in _BACK_CMD_LIST:                    break                elif cmd in _DO_NOTHING_LIST:                    continue                elif (set(_FORBDI_CMD) & set(cmd.split())) != set([]):                    ''' 禁止使用命令列表 '''                    Log('RED','Can not use %s command!' %(str(_FORBDI_CMD)))                    continue                exec_pools_cmd(server,server_list,'ssh_run',[cmd,server])        elif choice == '2':            while True:                file_name = user_input('Distribute')                start = time.time()                if file_name in _BACK_CMD_LIST:                    break                elif file_name == None:                    continue                file_chcek = os.path.isfile(file_name)                if file_chcek == False:                    Log('YELLOW','The file does not exist or it is a directory!')                    continue                exec_pools_cmd(server,server_list,'distribute_file',[file_name,])        elif choice in _BACK_CMD_LIST:            server.close()            sys.exit()        else:            continue''' 程序入口 '''             if __name__ == '__main__':        if len(sys.argv) < 2:        Log('RED','Usage: python %s test.conf' %(sys.argv[0]))        sys.exit(1)    else:        os.system('clear')        conf_name = sys.argv[1]        main(conf_name)

广告 广告

评论区