1 #!usr/bin/env python 2 #-*-coding:utf-8-*- 3 # Author calmyan 4 5 import configparser 6 import os ,sys 7 import threading,time 8 import paramiko,queue 9 BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(
__file__
)))#获取相对路径转为绝对路径赋于变量 10 sys.path.append(BASE_DIR)#增加环境变量 11 from cfg import config 12 13
class
Fabric_gr(object): 14 def __init__(self,gr_name):#组名 15 self.gr_name=
'%s%s'
%(config.AUTH_FILE,gr_name)#主机组用户名密码文件路径 16 self.config_info=configparser.ConfigParser()#读数据对象 17 self.name_l=[]#定义一个列表 18 self.attr=[] 19 self.file_dir=
''
#上传文件路径 20 self.get_file=
''
#下载传文件路径 21 22 def group_open(self):#打开组文件 23 self.config_info.read(self.gr_name)#读取文件 24
for
i in range(len(self.config_info.sections())): 25 self.name_l.append(self.config_info.sections()[i])#信息添加到列表 26
else
: 27
print
(
'主机列表:'
.center(40,
'='
)) 28
for
i in self.name_l: 29
print
((
'[%s]'
%i).center(40,
' '
)) 30 31 def inst_attr(self,inst):#获取指令 32 self.instruction=inst 33 self.attr=self.instruction.split() 34 self.inst_a=self.attr[0] 35 36 def inst(self):#指令判断 37
if
self.inst_a in config.INST_LIST: 38
return
True 39
else
: 40
return
False 41 42 def open_list(self):#创建 线程 方法 43
if
self.inst_a==config.PUT: 44
if
self.File_Dir():#查找本地文件 45 pass 46
else
: 47
return
48 self.re_lilst=[]#定义一个列表 49
for
j in range(len(self.name_l)): 50 sttr=self.config_info.sections()[j]#获取到对象 51 user_dict={}#创建一个空字典 52
for
i,v in self.config_info[sttr].items():#可以循环输出 获ip 用户 密码 端口 53 user_dict[i]=v 54 sttr=threading.Thread(target=self.thr_run,args=(sttr,user_dict[config.USER],user_dict[config.PWD],int(user_dict[config.PORTS])))#创建新线程 55 sttr.start()#启动线程 56 self.re_lilst.append(sttr)#不用JOIN,避免阻塞为串行 57
else
: 58
for
i in self.re_lilst:#等待线程 完成 59 i.join() 60 61 def open_list2(self):#创建 线程 方法 62 self.re_lilst=[]#定义一个列表 63
for
j in range(len(self.name_l)): 64 sttr=self.config_info.sections()[j]#获取到对象 65 user_dict={}#创建一个空字典 66
for
i,v in self.config_info[sttr].items():#可以循环输出 获ip 用户 密码 端口 67 user_dict[i]=v 68 sttr=threading.Thread(target=self.ssh_run,args=(sttr,user_dict[config.USER],user_dict[config.PWD],int(user_dict[config.PORTS])))#创建新线程 69 sttr.start()#启动线程 70 self.re_lilst.append(sttr)#不用JOIN,避免阻塞为串行 71
else
: 72
for
i in self.re_lilst:#等待线程 完成 73 i.join() 74 75 76 def thr_run(self,addrs,user,paswd,ports):#传输通道 77
try
: 78 transport=paramiko.Transport((addrs,ports))#传输模块 Transport 服务器地址 端口 79 transport.connect(username=user,password=paswd)#用户名,,密码 80 sftp=paramiko.SFTPClient.from_transport(transport)#调用传输方法 81
print
(
'[%s]连接成功!'
%addrs) 82 self.file_dir=
'%s/%s'
%(config.FILE_DIR,self.attr[1])#上传文件路径 83
if
self.inst_a==config.PUT: 84 sftp.put(self.file_dir,self.attr[2])#上传文件 ,本地路径文件 ,服务器的路径文件 85
print
(
'【%s】文件上传完成!'
%addrs) 86 elif self.inst_a==config.GET: 87 self.get_file=
'%s/%s_%s'
%(config.GET_FILE_DIR,addrs,self.attr[2])#下载文件路径 88
print
(self.get_file) 89 sftp.get(self.attr[1],self.get_file)#下载文件 ,服务器的路径文件 ,本地路径文件 90
print
(
'【%s】文件下载完成!'
%addrs) 91
else
: 92
print
(
'【%s】文件相关操作失败!'
%addrs) 93 pass 94 except Exception
as
e: 95
print
(e) 96 97 def File_Dir(self):#判断文件是否存在 98 file=self.attr[1] 99 100
print
(file)101 self.file_dir=
'%s/%s'
%(config.FILE_DIR,file)#文件路径102
if
os.path.isfile(self.file_dir):103
print
(
'成功找到文件!'
)104
return
True105
else
:106
print
(
'文件不存在!'
)107
return
False108 def ssh_run(self,addrs,user,paswd,ports):#ssh109 ssh =paramiko.SSHClient()#创建一个SSH连接对象110 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())#允许连接不在KNOV_HOSTs文件中的主机 自动添加111
try
:112 ssh.connect(hostname=addrs,port=ports,username=user,password=paswd)#连接,主机 端口 用户名 密码113
print
(
'[%s]连接成功!'
%addrs)114 except Exception
as
e:115
print
(e)116 return117 stdin,stdout,stderr=ssh.exec_command(self.instruction)#.exec_command 为执行命令,返回结果 ,标准输入,标准输出,标准错误,错误与输出只会返回其一118 result=stdout.read()#获取结果119
try
:120
if
len(result)<1:#如果为空 返回错误信息121 result=stderr.read()122
print
(addrs.center(60,'='))123
print
(result.decode())124
else
:125
print
(addrs.center(60,'='))126
print
(result.decode())127 except Exception
as
e:128
print
(e)129 130 131 info_l='''--------指令帮助--------132 上传文件: put file /home/tmp/file (指令 本地文件 服务端位置文件)133 下载文件: get /home/tmp/file file (指令 服务端位置文件 本地文件)134 其他指令: ssh相关命令 如 df pwd ifconfig ls等135 查看帮助: helps136 返回上层: quit137 退出程序: exit138 '''139 140 141 def loging():142
print
(info_l)143
while
True:144 s=os.listdir(config.AUTH_FILE)145
print
('主机组'.center(60,'='))146
for
i,v in enumerate(s):147
print
('编号:%s 组名:%s'%(i,v))148 gr_name=input('选择组:')149
if
gr_name=='
exit
':150
exit
()151
if
gr_name=='helps':152
print
(info_l)153 continue154
try
:155 gr_file=s[int(gr_name)]156 157 lst=Fabric_gr(gr_file)#实例连接158 lst.group_open()#打开159
while
True:160 #
print
(info_l)161 inst=input('指令>>>:
')162 if inst=='
exit
':163 exit()164 if inst=='
quit
':165 continue166 if inst=='
helps':167
print
(info_l)168 continue169 lst.inst_attr(inst)#获取指令170
if
lst.inst():#指令判断171 lst.open_list()#开启线程创建172
else
:173 lst.open_list2()174 pass175 except ValueError
as
e:176
print
(e)