需求:
题目:简单主机批量管理工具
需求:
- 主机分组
- 主机信息配置文件用configparser解析
- 可批量执行命令、发送文件,结果实时返回,执行格式如下
- 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/
- 主机用户名密码、端口可以不同
- 执行远程命令使用paramiko模块
- 批量命令需使用multiprocessing并发
思路:
代码:
import threading import paramiko import os,sys BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #添加环境变量 sys.path.append(BASE_DIR) from conf import setting class Mythread(threading.Thread): def __init__(self,user_id,user_port,user_name,user_password): super(Mythread,self).__init__() self.user_id=user_id self.user_port=user_port self.user_name=user_name self.user_password=user_password def run(self): #run是这种类写法必须写的,线程的启动就是通过run执行带动的 command_name=cmd.split()[0] if hasattr(self,command_name): #是否存在这个命令如果有则直接执行它 getattr(self,command_name)() else: setattr(self,command_name,self.command) getattr(self,command_name)() #执行命令的函数 def command(self): #创建一个ssh对象 ssh=paramiko.SSHClient() #连接服务器 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname=self.user_id, port=self.user_port, username=self.user_name, password=self.user_password) #执行命令 stdin,stdout,stderr=ssh.exec_command(cmd) res,err=stdout.read(),stderr.read() result=res if res else err print(result.decode()) ssh.close() #上传文件的函数 def put(self): filename=cmd.split()[1] transport=paramiko.Transport((self.user_id,self.user_port)) transport.connect(username=self.user_name,password=self.user_password) sftp=paramiko.SFTPClient.from_transport(transport) """实现了将aa这个文件上传到linux的/tmp/下"""#每个用户都是在这个统一路径下 sftp.put(filename,'/tmp/test_from_win') #注意上传,与下载来的文件的路径默认都在代码所在的文件夹中 transport.close() #选择组,进行批量管理,通过这个函数获得了所需要的那个组的信息,以字典的形式获取 def selet_list(): for key in setting.msg_dic: print(key,setting.msg_dic[key]) select=input("请输入您需要选的组数,group1 or group2").strip() select_dict=setting.msg_dic.get(select) print("如下为您选择的组的成员信息".center(50,"-")) for i in select_dict: print(i,select_dict[i]) return select_dict #将获得的主机信息与Linux中的虚拟机进行交互 def interactive(show_list): #将子线程的信息储存到其中 small_list=[] for key in show_list: host,port,username,password=show_list[key]["IP"],show_list[key]["port"],show_list[key]["username"],show_list[key]["password"] func=Mythread(host,port,username,password) t=threading.Thread(target=func.run) t.start() small_list.append(t) for i in small_list: i.join() cmd=input("请输入命令") show_list=selet_list() interactive(show_list)
main.py
#存储着各个主机的接口信息,资源有限分为两个组,我只对第一个组中的两个ip进行测试 msg_dic={"group1":{"host1":{"IP":"192.168.60.128", "username":"mark", "password":"A1029577407!", "port":22}, "host2":{"IP":"192.168.60.129", "username":"agust2", "password":"A1029577407!", "port":22}}, "group2":{"h1":{"IP":"192.168.2.1", "username":"111", "password":"aaa", "port":22}} }
setting.py
为了偷懒,我登陆器没有写,等后续在更改!!!!!!