[ Python - 10 ] 练习:批量管理主机工具
需求:
- 主机分组
- 登录后显示主机分组,选择分组后查看主机列表
- 可批量执行命令、发送文件,结果实时返回
- 主机用户名密码可以不同
流程图:
说明:
## 需求:
- 主机分组
- 登录后显示主机分组,选择分组后查看主机列表
- 可批量执行命令、发送文件,结果实时返回
- 主机用户名密码可以不同
## 目录结构
batch-manage
bin/
start.py # 启动主程序
conf/
setting.py # 远程主机配置文件
core/
control.py # RemoteControl类,用于远程主机执行命令及上传
local.py # 本地数据处理
## 说明
目前实现可批量执行命令,上传文件功能。
## 运行环境
windows
python3.0+
代码下载地址:https://github.com/hukeyy/batch-manage
bin/
start.py
#!_*_coding:utf-8_*_ # Author: hkey import threading, os, sys base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(base_dir) from core import control from core import local from conf import setting if __name__ == '__main__': for host in setting.hosts.keys(): host_tuple = local.options() print('\33[42;1m[put file or inter system command.]\33[0m') while True: cmd = input('>>>').strip() if len(cmd) == 0: continue t_list = [] for host in host_tuple: remote_control = control.RemoteControl(cmd, *host) t = threading.Thread(target=remote_control.run,) t.setDaemon(True) t.start() t_list.append(t) for t in t_list: t.join()
conf/
setting.py
#!_*_coding:utf-8_*_ # Author: hkey
## 元组在python中是不可变对象,保存序列时,应当尽量采用这种方式
hosts = {'测试系统':(('10.0.0.11', 22, 'root', '123456'), ('10.0.0.12', 22, 'root', '123456'), ), '生产系统':(('10.0.0.12', 22, 'root', '123456'), ), }
core/
control.py
#!_*_coding:utf-8_*_ # Author: hkey import paramiko class RemoteControl(object):
'''远程主机操作类''' def __init__(self, cmd, *kw): self.hostname = kw[0] self.port = kw[1] self.username = kw[2] self.password = kw[3] self.cmd = cmd def run(self):
'''通过反射功能将程序解耦''' cmd = self.cmd.split()[0] if hasattr(self, cmd): getattr(self, cmd)() else: setattr(self, cmd, self.command) getattr(self, cmd)() def put(self): '''上传文件''' # try: transport = paramiko.Transport(self.hostname, self.port) transport.connect(username=self.username, password=self.password) sftp = paramiko.SFTPClient.from_transport(transport) sftp.put(self.cmd.split()[1], self.cmd.split()[2]) transport.close() print('\33[32;1m【%s】上传文件【%s】成功!' %(self.hostname, self.cmd.split()[1])) # except Exception as e: # print('\33[31;1m错误:【%s】: 【%s】\33[0m' %(self.hostname, e)) def command(self): '''执行系统静态命令''' ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname=self.hostname, port=self.port, username=self.username, password=self.password) stdin, stdout, stderr = ssh.exec_command(self.cmd) res, err = stdout.read(), stderr.read() result = res if res else err print('\33[32;1m%s\33[0m'.center(50, '-') % self.hostname) print(result.decode()) ssh.close()
core/
local.py
#!_*_coding:utf-8_*_ # Author: hkey import os, sys base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(base_dir) from conf import setting def options():
'''通过配置文件setting.py,用户选择主机组并通过用户选择的组获取到主机的信息''' for host in setting.hosts.keys(): print(host) while True: choice = input('please choice groupname:') if len(choice) ==0: continue if choice in setting.hosts.keys(): for host in setting.hosts[choice]: print(host[0]) return setting.hosts[choice] else: print('groupname not exist.') break