类 Fabric 主机管理程序开发
类 Fabric 主机管理程序开发:
1. 运行程序列出主机组或者主机列表
2. 选择指定主机或主机组
3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载)
4. 充分使用多线程或多进程
5. 不同主机的用户名密码、端口可以不同
1 import configparser 2 import os ,sys 3 BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量 4 sys.path.append(BASE_DIR)#增加环境变量 5 from core.main import loging 6 if __name__ == '__main__': 7 8 loging()
1 import configparser 2 import os, sys 3 4 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 获取相对路径转为绝对路径赋于变量 5 sys.path.append(BASE_DIR) # 增加环境变量 6 from conf import config 7 8 9 # 修改个信息 磁盘大小 10 def set_info(gr_name, addse, name, pwd, ports): 11 config_info = configparser.ConfigParser() # 读数据 12 file_dir = '%s%s' % (config.AUTH_FILE, gr_name) # 主机组用户名密码文件路径 13 14 config_info[addse] = {} # ip 主机 15 config_info.set(addse, config.USER, name) # 用户 16 config_info.set(addse, config.PWD, pwd) # 密码 17 config_info.set(addse, config.PORTS, ports) # 端口 18 with open(file_dir, 'a') as f: 19 config_info.write(f) # 写入文件 20 # config_info.write(open(file_dir,'a'))#写入文件 21 print('创建完成'.center(60, '=')) 22 print('组:【%s】\nIP:[%s]\n用户名:[%s]\n密码:[%s]\n端口:[%s]' % (gr_name, addse, name, pwd, ports)) 23 24 25 if __name__ == '__main__': 26 gr_name = input('组名:') # 组 27 addse = input('IP地址:') # ip地址 28 name = input('用户名:') # 用户 29 pwd = input('密码:') # 密码 30 ports = input('端口:') # 端口 31 32 set_info(gr_name, addse, name, pwd, ports)
1 import configparser 2 import os ,sys 3 BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量 4 sys.path.append(BASE_DIR)#增加环境变量 5 6 AUTH_FILE='%s/db/'%BASE_DIR#主机组 信息用户名密码文件路径 7 FILE_DIR='%s/put_file'%BASE_DIR#要上传文件所在的目录 8 GET_FILE_DIR='%s/get_file'%BASE_DIR#要上传文件所在的目录 9 #print(AUTH_FILE) 10 PWD='pwd'#密码 11 USER='user' 12 PORTS='ports' 13 INST_LIST=['put','get']#指令列表 14 15 PUT='put' 16 GET='get'
import configparser import os ,sys import threading,time import paramiko,queue BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量 sys.path.append(BASE_DIR)#增加环境变量 from conf import config class Fabric_gr(object): def __init__(self,gr_name):#组名 self.gr_name='%s%s'%(config.AUTH_FILE,gr_name)#主机组用户名密码文件路径 self.config_info=configparser.ConfigParser()#读数据对象 self.name_l=[]#定义一个列表 self.attr=[] self.file_dir=''#上传文件路径 self.get_file=''#下载传文件路径 def group_open(self):#打开组文件 self.config_info.read(self.gr_name)#读取文件 for i in range(len(self.config_info.sections())): self.name_l.append(self.config_info.sections()[i])#信息添加到列表 else: print('主机列表:'.center(40,'=')) for i in self.name_l: print(('[%s]'%i).center(40,' ')) def inst_attr(self,inst):#获取指令 self.instruction=inst self.attr=self.instruction.split() self.inst_a=self.attr[0] def inst(self):#指令判断 if self.inst_a in config.INST_LIST: return True else: return False def open_list(self):#创建 线程 方法 if self.inst_a==config.PUT: if self.File_Dir():#查找本地文件 pass else: return self.re_lilst=[]#定义一个列表 for j in range(len(self.name_l)): sttr=self.config_info.sections()[j]#获取到对象 user_dict={}#创建一个空字典 for i,v in self.config_info[sttr].items():#可以循环输出 获ip 用户 密码 端口 user_dict[i]=v sttr=threading.Thread(target=self.thr_run,args=(sttr,user_dict[config.USER],user_dict[config.PWD],int(user_dict[config.PORTS])))#创建新线程 sttr.start()#启动线程 self.re_lilst.append(sttr)#不用JOIN,避免阻塞为串行 else: for i in self.re_lilst:#等待线程 完成 i.join() def open_list2(self):#创建 线程 方法 self.re_lilst=[]#定义一个列表 for j in range(len(self.name_l)): sttr=self.config_info.sections()[j]#获取到对象 user_dict={}#创建一个空字典 for i,v in self.config_info[sttr].items():#可以循环输出 获ip 用户 密码 端口 user_dict[i]=v sttr=threading.Thread(target=self.ssh_run,args=(sttr,user_dict[config.USER],user_dict[config.PWD],int(user_dict[config.PORTS])))#创建新线程 sttr.start()#启动线程 self.re_lilst.append(sttr)#不用JOIN,避免阻塞为串行 else: for i in self.re_lilst:#等待线程 完成 i.join() def thr_run(self,addrs,user,paswd,ports):#传输通道 try: transport=paramiko.Transport((addrs,ports))#传输模块 Transport 服务器地址 端口 transport.connect(username=user,password=paswd)#用户名,,密码 sftp=paramiko.SFTPClient.from_transport(transport)#调用传输方法 print('[%s]连接成功!'%addrs) self.file_dir='%s/%s'%(config.FILE_DIR,self.attr[1])#上传文件路径 if self.inst_a==config.PUT: sftp.put(self.file_dir,self.attr[2])#上传文件 ,本地路径文件 ,服务器的路径文件 print('【%s】文件上传完成!'%addrs) elif self.inst_a==config.GET: self.get_file='%s/%s_%s'%(config.GET_FILE_DIR,addrs,self.attr[2])#下载文件路径 print(self.get_file) sftp.get(self.attr[1],self.get_file)#下载文件 ,服务器的路径文件 ,本地路径文件 print('【%s】文件下载完成!'%addrs) else: print('【%s】文件相关操作失败!'%addrs) pass except Exception as e: print(e) def File_Dir(self):#判断文件是否存在 file=self.attr[1] print(file) self.file_dir='%s/%s'%(config.FILE_DIR,file)#文件路径 if os.path.isfile(self.file_dir): print('成功找到文件!') return True else: print('文件不存在!') return False def ssh_run(self,addrs,user,paswd,ports):#ssh ssh =paramiko.SSHClient()#创建一个SSH连接对象 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())#允许连接不在KNOV_HOSTs文件中的主机 自动添加 try: ssh.connect(hostname=addrs,port=ports,username=user,password=paswd)#连接,主机 端口 用户名 密码 print('[%s]连接成功!'%addrs) except Exception as e: print(e) return stdin,stdout,stderr=ssh.exec_command(self.instruction)#.exec_command 为执行命令,返回结果 ,标准输入,标准输出,标准错误,错误与输出只会返回其一 result=stdout.read()#获取结果 try: if len(result)<1:#如果为空 返回错误信息 result=stderr.read() print(addrs.center(60,'=')) print(result.decode()) else: print(addrs.center(60,'=')) print(result.decode()) except Exception as e: print(e) info_l='''--------指令帮助-------- 上传文件: put file /home/tmp/file (指令 本地文件 服务端位置文件) 下载文件: get /home/tmp/file file (指令 服务端位置文件 本地文件) 其他指令: ssh相关命令 如 df pwd ifconfig ls等 查看帮助: helps 返回上层: quit 退出程序: exit ''' def loging(): print(info_l) while True: s=os.listdir(config.AUTH_FILE) print('主机组'.center(60,'=')) for i,v in enumerate(s): print('编号:%s 组名:%s'%(i,v)) gr_name=input('选择组:') if gr_name=='exit': exit() if gr_name=='helps': print(info_l) continue try: gr_file=s[int(gr_name)] lst=Fabric_gr(gr_file)#实例连接 lst.group_open()#打开 while True: #print(info_l) inst=input('指令>>>:') if inst=='exit': exit() if inst=='quit': continue if inst=='helps': print(info_l) continue lst.inst_attr(inst)#获取指令 if lst.inst():#指令判断 lst.open_list()#开启线程创建 else: lst.open_list2() pass except ValueError as e: print(e)