[python] 简单主机批量管理工具(多进程模式)
2017-11-05 17:54
866 查看
题目:简单主机批量管理工具
需求:
1、主机分组,主机信息配置文件用configparser解析
2、可批量执行命令、发送文件,结果实时返回,执行格式如下
batch_run -h h1,h2,h3 -g web_clusters,db_servers -cmd "df -h"
batch_scp -h h1,h2,h3 -g web_clusters,db_servers -action put -local test.py -remote /tmp/
3、主机用户名密码、端口可以不同
4、执行远程命令使用paramiko模块
5、批量命令需使用multiprocessing并发
6、记录操作日志
README
设计说明
1、按提题目要求,使用各个规定好的模块来开发,实现起来很简单,特别是使用multiprocessing实现多线程并发操作,本来以为会最难的部分,却是最简单的,建议后来者把这功能放在最后来实现。
2、困扰我较长时间的倒是主机信息文件中,内容格式的设计。由于题目要求主机用户名和端口可以不同,也就是你在执行一条命令的时候,连接远程的主机列表中,账号密码端口不一定都相同,这些信息都是从文件中读取。我可以在文件里,按照ip:port:username:passwd存放主机信息,但考虑到实际生产环境中,一般都是相同应用的几台主机这些信息都一致(便于管理需要),参照了他人的格式,我最终选择了如下格式(请见后面hosts.txt示例)。
3、接收文件功能我没有实现,考虑到从多台主机上同时拷贝文件到本机上,会使文件重复覆盖,直接拷贝不可行,其中一种理想的方式是,文件拷贝过来后,将文件名+来源主机名这样的方式。这也许是出题人考虑到这个功能实现会有些麻烦,所以题目里只要求发送文件,并未要求接收文件。
over!
目录结构
├── bin
│ ├── start.py 主程序
├── conf
│ ├── hosts.txt 主机信息配置文件
│ └── server.conf 程序运行配置文件
└── log
└── log.txt 操作日志
start.py
hosts.txt示例,可自行修改
server.conf
需求:
1、主机分组,主机信息配置文件用configparser解析
2、可批量执行命令、发送文件,结果实时返回,执行格式如下
batch_run -h h1,h2,h3 -g web_clusters,db_servers -cmd "df -h"
batch_scp -h h1,h2,h3 -g web_clusters,db_servers -action put -local test.py -remote /tmp/
3、主机用户名密码、端口可以不同
4、执行远程命令使用paramiko模块
5、批量命令需使用multiprocessing并发
6、记录操作日志
README
设计说明
1、按提题目要求,使用各个规定好的模块来开发,实现起来很简单,特别是使用multiprocessing实现多线程并发操作,本来以为会最难的部分,却是最简单的,建议后来者把这功能放在最后来实现。
2、困扰我较长时间的倒是主机信息文件中,内容格式的设计。由于题目要求主机用户名和端口可以不同,也就是你在执行一条命令的时候,连接远程的主机列表中,账号密码端口不一定都相同,这些信息都是从文件中读取。我可以在文件里,按照ip:port:username:passwd存放主机信息,但考虑到实际生产环境中,一般都是相同应用的几台主机这些信息都一致(便于管理需要),参照了他人的格式,我最终选择了如下格式(请见后面hosts.txt示例)。
3、接收文件功能我没有实现,考虑到从多台主机上同时拷贝文件到本机上,会使文件重复覆盖,直接拷贝不可行,其中一种理想的方式是,文件拷贝过来后,将文件名+来源主机名这样的方式。这也许是出题人考虑到这个功能实现会有些麻烦,所以题目里只要求发送文件,并未要求接收文件。
over!
目录结构
├── bin
│ ├── start.py 主程序
├── conf
│ ├── hosts.txt 主机信息配置文件
│ └── server.conf 程序运行配置文件
└── log
└── log.txt 操作日志
start.py
#!/usr/bin/env python # -*- coding:utf-8 -*- import paramiko import os, time, configparser, logging, json,re from multiprocessing import Process def formattime(): ####格式化时间,输出格式如:2017-09-16 16:32:35 return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) ####读取配置文件#### base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) config_file = os.path.join(base_dir, 'conf/server.conf') ####设置应用配置文件所在文件路径 cf = configparser.ConfigParser() ####创建一个ConfigParser() 实例,用于读取配置信息 cf.read(config_file) ####读取应用配置文件信息 ####设定日志目录#### logfile = cf.get('log', 'logfile') ####读取主机组信息#### hostsfile = cf.get('hosts_conf', 'hosts_file') ####获取主机配置文件所在文件路径 hf = configparser.ConfigParser() ####创建另外一个ConfigParser() 实例,用于读取主机相关信息 hf.read(hostsfile) ####从主机配置文件读取信息 sects = hf.sections() ####设置日志格式### logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S', filename=logfile, filemode='a+') def gethostinfo(): ####从主机配置文件中取出主机的IP/PORT/USERNAME/PASSWORD信息,组成类似 {group_name:{ip:{port:22,username:try,passwd:123456}} 形式#### dict = {} for a in sects: ip_list = hf.get(a, 'ip').split(',') port = hf.getint(a, 'port') username = hf.get(a, 'username') password = hf.get(a, 'password') dict_ip = {} for ip in ip_list: dict_ip[ip] = {'port': port, 'username': username, 'password': password} # print(dict_ip) dict[a] = dict_ip #print(dict) return dict ####远程执行命令#### def remote_ssh(ip,port,username,password,cmd): try: transport = paramiko.Transport((ip, port)) transport.connect(username=username, password=password) ssh = paramiko.SSHClient() ssh._transport = transport stdin, stdout, stderr = ssh.exec_command(cmd) print(stdout.read().decode(),stderr.read().decode()) except Exception as e: print(e) ####远程传输文件#### def remote_ftp(ip,port,username,password,action,local_file,remote_file): try: transport = paramiko.Transport((ip, port)) transport.connect(username=username, password=password) sftp = paramiko.SFTPClient.from_transport(transport) #print(type(action),len(action)) if action == 'put': print('准备上传文件') sftp.put(local_file,remote_file) print('传输完毕') elif action == 'get': print("暂不支持get操作") # sftp.get(remote_file,local_file) else: print("error, no put or get",action) except Exception as e: print(e) finally: transport.close() if __name__ == '__main__': hostinfo_dict = gethostinfo() while True: cmd = input('>>>:').strip() ####需要输入类似: batch_run -h h1,h2,h3 -g web_clusters,db_servers -cmd "df -h" logging.info(cmd) if 'batch_run' in cmd: catch = re.findall('batch_run\s+-h\s+(.*?)\s+-g\s+(.*?)\s+-cmd\s+[\"|\'](.*?)[\"|\']',cmd,re.I) #print(catch) input_ip_list = catch[0][0].split(',') input_group_list = catch[0][1].split(',') input_running_cmd = catch[0][2] #print(input_ip_list,input_group_list,input_running_cmd) for group_name in input_group_list: if group_name in hostinfo_dict: for ip in input_ip_list: if ip in hostinfo_dict[group_name]: print("login,", ip, hostinfo_dict[group_name][ip]['port'], hostinfo_dict[group_name][ip]['username'],hostinfo_dict[group_name][ip]['password'], input_running_cmd) #remote_ssh(ip, hostinfo_dict[group_name][ip]['port'], hostinfo_dict[group_name][ip]['username'], hostinfo_dict[group_name][ip]['password'], input_running_cmd) p = Process(target=remote_ssh, args=(ip, hostinfo_dict[group_name][ip]['port'], hostinfo_dict[group_name][ip]['username'], hostinfo_dict[group_name][ip]['password'], input_running_cmd,)) ####使用多线程同时处理ssh请求,args中最后的逗号不能省略 p.start() #p.join() ####开启该行为串行操作 elif 'batch_scp' in cmd: catch = re.findall('batch_scp\s+-h\s+(.*?)\s+-g\s+(.*?)\s+-action\s+(.*?)\s-local\s+(.*?)\s+-remote\s+(.*)', cmd, re.I) #print(catch) input_ip_list = catch[0][0].split(',') input_group_list = catch[0][1].split(',') input_action = catch[0][2] input_local_file = catch[0][3] input_remote_file = catch[0][4] #print(input_ip_list, input_group_list, input_action,input_local_file,input_remote_file) for group_name in input_group_list: if group_name in hostinfo_dict: for ip in input_ip_list: if ip in hostinfo_dict[group_name]: print("transfer,", ip, hostinfo_dict[group_name][ip]['port'], hostinfo_dict[group_name][ip]['username'],hostinfo_dict[group_name][ip]['password'], input_action,input_local_file,input_remote_file) #remote_ftp(ip, hostinfo_dict[group_name][ip]['port'], hostinfo_dict[group_name][ip]['username'],hostinfo_dict[group_name][ip]['password'], input_action, input_local_file, input_remote_file) p = Process(target=remote_ftp, args=(ip, hostinfo_dict[group_name][ip]['port'], hostinfo_dict[group_name][ip]['username'],hostinfo_dict[group_name][ip]['password'], input_action, input_local_file, input_remote_file,)) ####使用多线程同时处理ssh请求,args中最后的逗号不能省略 p.start() else: print(' 命令输入错误,请按 batch_run -h h1,h2,h3 -g web_clusters,db_servers -cmd "df -h"\n', '或者 batch_scp -h h1,h2,h3 -g web_clusters,db_servers -action put -local test.py -remote /tmp/ 格式输入命令')
hosts.txt示例,可自行修改
[g1] ip = 192.168.1.1,192.168.1.2,192.168.1.3 port = 22 username = root password = 123456 [g2] ip = 192.168.1.4,192.168.1.5 port = 22 username = root password = 123456 [g3] ip = 192.168.1.6 port = 22 username = root password = 123456
server.conf
###Default configuration### [DEFAULT] logfile = ../log/log.txt hosts_file = ../conf/hosts.txt ###Configuration file of hosts### [hosts_conf] hosts_file = ../conf/hosts.txt ###Log file### [log] logfile = ../log/log.txt
相关文章推荐
- 详解python之简单主机批量管理工具
- python之简单主机批量管理工具
- python之简单主机批量管理工具
- python之简单主机批量管理工具
- python之简单主机批量管理工具
- python之简单主机批量管理工具
- 使用Python实现简单主机批量管理工具
- python之简单主机批量管理工具
- 用Python开发主机批量管理工具
- python写的ssh简单批量管理工具
- 【Python之旅】第六篇(七):开发简易主机批量管理工具
- [ Python - 10 ] 练习:批量管理主机工具
- Python接口测试第一讲(代码管理工具git的简单操作)
- supervisor - Python进程管理工具
- supervisor - Python进程管理工具
- 【python】openstack管理小工具(增删查改,批量ping)
- Python 进程管理工具 Supervisor 使用教程
- Python 进程管理工具 Supervisor 使用教程
- supervisor - Python进程管理工具(转)
- python多进程线程练习:主机批量管理