需求:
- 主机分组
- 主机信息配置文件用configparser解析
- 可批量执行命令、发送文件,结果实时返回,执行格式如下 (小写的h被系统占中,H表示主机名,g表示组)
- batch_run -H h1,h2,h3 -g web_clusters,db_servers --cmd "df -h"
- 主机用户名密码、端口可以不同
- 执行远程命令使用paramiko模块
- 批量命令需使用multiprocessing并发
import configparser import paramiko import time import os import optparse from multiprocessing import Process, Lock class Tools(object): def __init__(self): parser = optparse.OptionParser() parser.add_option("-H", "--H", dest="high", help="high") parser.add_option("-g", "--g", dest="g", help="g") parser.add_option("--cmd", "--cmd", dest="cmd", help="cmd") self.options, self.args = parser.parse_args() self._data(self._file(self.options,self.args)) def _file(self,options,args): """判断属性是否为空,取出H和g""" file_list = [] file_list1=[] if args and args[0] == "batch_run": if options.high is not None or options.g is not None or options.cmd is not None: config = configparser.ConfigParser() config.read("host.conf") g = options.g.split(",") h = options.high.split(",") for i in g: if i not in config.options("server-g"): print("找不到%s信息组"%i) g.remove(i) for i in h: file_list.append(i) for i in g: s = config["server-g"][i] s = s.split(",") file_list = file_list +s ret1 = config.sections() del ret1[0] for i in file_list: if i in ret1: file_list1.append(i) else: print("找不到主机名%s" %i) continue return file_list1 else: exit("请输入正确的参数") def _data(self,file_list): data_dic = {} config = configparser.ConfigParser() config.read("host.conf") for i in file_list: data_dic[i] = { "server": config[i]["server"], "port": config[i]["port"], "username": config[i]["username"], "password": config[i]["password"] } lock = Lock() for i in data_dic: Process(target=self._ssh, args=(lock,data_dic[i])).start() def _ssh(self,l,data_dic): ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) l.acquire() print("---------%s----------" %data_dic["server"]) ssh.connect(data_dic["server"], int(data_dic["port"]),data_dic["username"], data_dic["password"]) stdin, stdout, stderr = ssh.exec_command(self.options.cmd) if stdout.read().decode(): stdin, stdout, stderr = ssh.exec_command(self.options.cmd) print(stdout.read().decode()) else: print (stderr.read().decode()) l.release() #判断是否进程同步 time.sleep(2) if __name__ == "__main__": t =Tools()
host.conf文件信息
[server-g] server1 = h1,h2 server2 = h3,h4 [h1] port = 22 username = root server = 172.16.240.80 password = root123 [h2] port = 22 username = root server = 172.16.240.96 password = root123 [h3] port = 22 username = root server = 172.16.240.82 password = root123 [h4] port = 22 username = root server = 172.16.240.95 password = root123
缺点:-H,-g 这两个必须也要同时执行。