基于paramiko的文件批量分发和命令批量执行
在实际工作环境中,有可能需要去运维百台
服务器,甚至更多。以应用升级为例,对应用做升级操作,首先得停止应用服务,防止新的应用数据写入,并备份应用部署目录,然后替换成新的代码文件、配置文件等。替换完成后,启动应用服务。但是由于应用服务器数量过多,如果一台一台服务器去做升级,这会花费很多时间。这时,便可使用paramiko编写python脚本,让这些重复性的操作批量执行,去实现应用升级的自动化。这个小工具实现了在堡垒机模式和非堡机模式的运用。
1.maintool.py(控制整个脚本的执行),代码如下:
点击(此处)折叠或打开
创新互联建站服务项目包括大通网站建设、大通网站制作、大通网页制作以及大通网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,大通网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到大通省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
-
#!/usr/bin/python
-
#coding:utf-8
-
import sys
-
######脚本执行操作提示
-
def login():
-
print """\033[1;34m
-
1:批量分发文件(非堡垒机模式)
-
2:批量执行命令(非堡垒机模式)
-
3:批量下载文件(非堡垒机模式)
-
4:单台执行命令(非堡垒机模式)
-
5:批量分发文件(堡垒机模式)
-
6:批量执行命令(堡垒机模式)
-
7:增加需要服务器(非堡垒机模式)
-
8:删除不需要服务器(非堡垒机模式)
-
9:查看当前服务器列表(非堡垒机模式)
-
10:退出\033[0m
-
"""
-
#######定义用户选择函数
-
def choice():
-
import operation,blhost_operation
-
while True:
-
choice = raw_input("\033[1;32minput your choice:\033[0m").strip()
-
choice_list = ['1','2','3','4','5','6','7','8','9','10','help','exit']
-
if choice not in choice_list:
-
print "\033[1;33mtry again!\033[0m"
-
continue
-
if choice == '1':
-
operation.SendFile()###非堡机模式下文件分发
-
login()
-
if choice == '2':
-
operation.ExecuteCmd()###非堡机模式下命令执行
-
login()
-
if choice == '3':
-
operation.DownloadFile()###非堡机模式下文件下载
-
login()
-
if choice == '4':
-
operation.SingleServer()###单台服务器操作
-
login()
-
if choice == '5':
-
blhost_operation.SendFile()###堡垒机模式下文件分发
-
login()
-
if choice == '6':
-
blhost_operation.ExecuteCmd()###堡垒机模式下命令执行
-
login()
-
if choice == '7':
-
operation.AddServerList()###增加服务器名单
-
if choice == '8':
-
operation.DeleteServerList()###删除服务器名单
-
if choice == '9':
-
operation.ShowServerList()###展示服务器名单
-
login()
-
if choice == '10' or choice == 'exit':###退出脚本操作
-
print "\033[1;31mThank you for your use!\033[0m"
-
sys.exit(0)
-
if choice == 'help':
-
login()
-
if __name__ == '__main__':
-
login()
-
choice()
maintool.py执行效果如下:
2.operation.py(定义非堡垒机模式下的相关操作),代码如下:
-
#!/usr/bin/python
-
#coding:utf-8
-
import sys,time,threading
-
import getpass,commands
-
import paramiko,fabric
-
server_list=[] #HOSTNAME IP PWDROOT PWDWEBLOGIC PWDORACLE
-
result_dict={}
-
######读取文件内容,读取完成后关闭文件
-
f = open ('serverlist.txt')
-
for i in f.readlines():
-
server_list.append(i.split())
-
f.close()
-
######非堡垒机下文件的传送
-
def transfer(localpath,remotepath,hostname,username,password):
-
port = 22
-
try:
-
t = paramiko.Transport((hostname,port))
-
t.connect(username=username,password=password)
-
sftp = paramiko.SFTPClient.from_transport(t)
-
sftp.put(localpath,remotepath)
-
t.close()
-
result_dict[hostname] = hostname+"服务器文件传送完成"
-
print result_dict[hostname]
-
except Exception,e:
-
print str(e)
-
######定义文件下载函数
-
def download(remotepath,localpath,hostname,username,password):
-
port = 22
-
try:
-
t = paramiko.Transport((hostname,port))
-
t.connect(username=username,password=password)
-
sftp = paramiko.SFTPClient.from_transport(t)
-
sftp.get(remotepath,localpath)
-
t.close()
-
result_dict[hostname] = hostname+"服务器文件下载完成"
-
print result_dict[hostname]
-
except Exception,e:
-
print str(e)
-
######定义命令执行函数
-
def execmd(hostname,username,password,CMD):
-
paramiko.util.log_to_file('syslogin.log')###将用户登录服务器日志输出到syslogin.log
-
ssh = paramiko.SSHClient()###ssh登录服务器
-
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())###自动添加主机名及主机密钥到本地HostKeys对象,并将其保存,不依赖load_system_host_keys()的配置,即使~/.ssh/known_hosts不存在也不产生影响
-
ssh.connect(hostname=hostname,username=username,password=password)
-
stdin,stdout,stderr = ssh.exec_command(CMD)
-
result = stdout.read()
-
ssh.close()
-
result_dict[hostname] = hostname+"服务器命令执行结果如下:"+"\n"+result
-
print result_dict[hostname]
-
######执行结果打印
-
def result_dict_print():
-
global result_dict
-
while True:
-
if len(result_dict) == len(server_list):
-
break
-
print "\033[1;36m%s台服务器完成\033[0m" %(len(result_dict))
-
result_dict = {}
-
######非保垒机模式下文件的分发
-
def SendFile():
-
while True:
-
username = raw_input("\033[1;32m请输入你选择要用于发送文件的用户[root/weblogic/oracle]:\033[0m").strip()
-
username_list = ['root','weblogic','oracle','\n','exit']
-
if username not in username_list:
-
print "\033[0;32minput error!Please try again!If you need exit,please input exit!\033[0m"
-
continue
-
if username == 'exit':
-
sys.exit()
-
localpath = raw_input("\033[1;32m本地文件(绝对路径):\033[0m").strip()
-
remotepath = raw_input("\033[1;32m服务器目的地址(绝对路径):\033[0m").strip()
-
if username == 'root':
-
for list in server_list:
-
p = threading.Thread(target=transfer,args=(localpath,remotepath,list[1],username,list[2],))
-
p.start()
-
for list in server_list:
-
p.join(timeout=1)
-
if username == 'weblogic' or username == '':
-
username = 'weblogic'
-
for list in server_list:
-
p = threading.Thread(target=transfer,args=(localpath,remotepath,list[1],username,list[3],))
-
p.start()
-
if username == 'oracle':
-
username = 'oracle'
-
for list in server_list:
-
p = threading.Thread(target=transfer,args=(localpath,remotepath,list[1],username,list[4],))
-
p.start()
-
result_dict_print()
-
break
-
######非堡垒机模式下文件的下载
-
def DownloadFile():
-
while True:
-
username = raw_input("\033[1;32m请输入你选择要用于下载文件的用户[root/weblogic/oracle]:\033[0m").strip()
-
username_list = ['root','weblogic','oracle','\n','exit']
-
if username not in username_list:
-
print "\033[1;32minput error!Please try again!If you need exit,please input exit!\033[0m"
-
continue
-
if username == 'exit':
-
sys.exit()
-
remotepath = raw_input("\033[1;32m远程文件(绝对路径):\033[0m").strip()
-
localpath = raw_input("\033[1;32m服务器目的地址(目录名,默认为/opt/zzx/python/bin):\033[0m").strip()
-
if localpath == '':
-
localpath = '/opt/zzx/python/bin'
-
localpath = localpath+"/"
-
print localpath
-
count = remotepath.count('/')
-
basename = remotepath.split('/')[count]
-
if username == 'root':
-
for list in server_list:
-
p = threading.Thread(target=download,args=(remotepath,localpath+list[1]+"_"+basename,list[1],username,list[2],))
-
p.start()
-
for list in server_list:
-
p.join(timeout=1)
-
if username == 'weblogic' or username == '':
-
username = 'weblogic'
-
for list in server_list:
-
localpath = result1+list[1]+"_"+result2
-
p = threading.Thread(target=download,args=(remotepath,localpath,list[1],username,list[3],))
-
p.start()
-
if username == 'oracle':
-
for list in server_list:
-
localpath = result1+list[1]+"_"+result2
-
p = threading.Thread(target=download,args=(remotepath,localpath,list[1],username,list[4],))
-
p.start()
-
result_dict_print()
-
break
-
######非堡垒机模式下命令的执行
-
def ExecuteCmd():
-
while True:
-
username = raw_input("\033[1;32m请输入你选择要用于执行命令的用户[root/weblogic/oracle]:\033[0m").strip()
-
username_list = ['root','weblogic','oracle','\n','exit']
-
if username not in username_list:
-
print "\033[1;32minput error!Please try again!If you need exit,please input exit!\033[0m"
-
continue
-
if username == 'exit':
-
sys.exit()
-
CMD = raw_input("\033[1;37m请输入要执行的命令(不能带引号):\033[0m").strip()
-
if CMD == 'exit':
-
return
-
if username == 'root':
-
for list in server_list:
-
p = threading.Thread(target=execmd,args=(list[1],username,list[2],CMD,))
-
p.start()
-
if username == 'weblogic' or username == '':
-
username = 'weblogic'
-
for list in server_list:
-
p = threading.Thread(target=execmd,args=(list[1],username,list[3],CMD))
-
p.start()
-
if username == 'oracle':
-
for list in server_list:
-
p = threading.Thread(target=execmd,args=(list[1],username,list[4],CMD))
-
p.start()
-
result_dict_print()
-
break
-
######单台服务器操作
-
def SingleServer():
-
IP = raw_input("\033[1;32m请输入要执行命令的服务器IP地址:\033[0m").strip()
-
username = raw_input("\033[1;32m请输入要执行命令的服务器用户名:\033[0m").strip()
-
password = getpass.getpass()
-
CMD = raw_input("\033[1;32m请输入要执行的命令(不能带引号):\033[0m").strip()
-
execmd(IP,username,password,CMD)
-
######服务器名单添加
-
def AddServerList():
-
hostname = raw_input("\033[1;32m请输入服务器名称(如localhost):\033[0m").strip()
-
if hostname == 'quit' or hostname == 'exit':
-
return
-
ip = raw_input("\033[1;32m请输入服务器IP:\033[0m").strip()
-
root_passwd = raw_input("\033[1;32m请输入服务器root用户密码:\033[0m").strip()
-
weblogic_passwd = raw_input("\033[1;32m请输入服务器weblogic用户密码:\033[0m").strip()
-
oracle_passwd = raw_input("\033[1;32m请输入服务器oracle用户密码:\033[0m").strip()
-
f = file('serverlist.txt','a')
-
f.write("%s %s %s %s %s\n"%(hostname,ip,root_passwd,weblogic_passwd,oracle_passwd))
-
f.close()
-
raw_input("\033[1;32m重新执行程序后生效(敲任意键退出)...\033[0m")
-
time.sleep(0.2)
-
sys.exit()
-
######服务器名单删除
-
def DeleteServerList():
-
IP = raw_input("\033[1;32m请输入要删除服务器IP:\033[0m").strip()
-
if IP == 'quit' or IP == 'exit':
-
return
-
status,result = commands.getstatusoutput("sed -i '/\<%s\>/'d ./serverlist.txt" % IP)
-
raw_input("\033[1;32m重新执行程序后生效(敲任意键退出)...\033[0m")
-
time.sleep(0.2)
-
sys.exit()
-
######服务器名单显示
-
def ShowServerList():
-
i = 0
-
f = open('serverlist.txt','rb')
-
for line in f.readlines():
-
print line.strip()
-
i = i+1
-
f.close
-
print "\n总共%s台服务器" % i
3.blhost_operation.py(定义堡垒机模式下的相关操作),代码如下:
-
#!/usr/bin/python
-
#coding:utf-8
-
import sys,time,threading
-
import getpass,commands,os
-
import paramiko,fabric
-
server_list=[] #HOSTNAME IP PWDROOT PWDWEBLOGIC PWDORACLE
-
result_dict={}
-
######读取文件内容,读取完成后关闭文件
-
f = open ('serverlist.txt')
-
for i in f.readlines():
-
server_list.append(i.split())
-
f.close()
-
######堡垒机下文件的传送
-
def transfer(bllocalpath,remotepath,blhostname,blusername,blpassword,hostname,username,password):
-
passinfo='\'s password: '
-
paramiko.util.log_to_file('blhost_upload.log')
-
-
ssh=paramiko.SSHClient()
-
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())###自动添加主机名及主机密钥到本地HostKeys对象,并将其保存,不依赖load_system_host_keys()的配置,即使~/.ssh/known_hosts不存在也不产生影响
-
ssh.connect(hostname=blhostname,username=blusername,password=blpassword)
-
-
channel=ssh.invoke_shell()
-
channel.settimeout(100)
-
buff=''
-
resp=''
-
channel.send('scp '+bllocalpath+' '+username+'@'+hostname+':'+remotepath+'\n')
-
while not buff.endswith(passinfo):
-
try:
-
resp=channel.recv(9999)
-
except Exception,e:
-
print "Error info:receive nothing"
-
print str(e)
-
channel.close()
-
ssh.close()
-
sys.exit()
-
buff += resp
-
if not buff.find('yes/no')==-1:
-
channel.send('yes\n')
-
buff=''
-
buff=''
-
channel.send(password+'\n')
-
while not buff.endswith('# '):
-
resp=channel.recv(9999)
-
if not resp.find(passinfo)==-1:
-
print "Error info:Authentication failed."
-
print "Please confirm if your password is true!"
-
channel.close()
-
ssh.close()
-
sys.exit()
-
buff += resp
-
channel.close()
-
ssh.close()
-
result_dict[hostname] = hostname+"服务器文件传送完成"
-
print result_dict[hostname]
-
######堡垒机模式下命令执行
-
def execmd(blhostname,blusername,blpassword,hostname,username,password,CMD):
-
passinfo='\'s password: '
-
paramiko.util.log_to_file('blhost_syslogin.log')
-
-
ssh=paramiko.SSHClient()
-
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
-
ssh.connect(hostname=blhostname,username=blusername,password=blpassword)
-
-
channel=ssh.invoke_shell()
-
channel.settimeout(100)
-
-
buff=''
-
resp=''
-
channel.send('ssh '+username+'@'+hostname+'\n')
-
while not buff.endswith(passinfo):
-
try:
-
resp=channel.recv(9999)
-
except Exception,e:
-
print "fail to connect"
-
print "Error info: "+str(e)
-
channel.close()
-
ssh.close()
-
sys.exit()
-
buff += resp
-
if not buff.find('yes/no')==-1:
-
channel.send('yes\n')
-
buff=''
-
buff=''
-
channel.send(password+'\n')
-
while not buff.endswith('# '):
-
resp=channel.recv(9999)
-
if not resp.find(passinfo)==-1:
-
print "Error info:Authentication failed"
-
channel.close()
-
ssh.close()
-
sys.exit()
-
buff += resp
-
buff=''
-
channel.send('%s\n' % CMD)
-
try:
-
while not buff.endswith('# '):
-
resp=channel.recv(9999)
-
buff += resp
-
except Exception,e:
-
print "Error info:"+str(e)
-
-
result = buff
-
channel.close()
-
ssh.close()
-
result_dict[hostname] = hostname+"服务器命令执行结果如下:"+"\n"+result
-
print result_dict[hostname]
-
######执行结果打印
-
def result_dict_print():
-
global result_dict
-
while True:
-
if len(result_dict) == len(server_list):
-
break
-
print "\033[1;36m%s台服务器完成\033[0m" %(len(result_dict))
-
result_dict={}
-
######堡垒机模式下文件的批量分发
-
def SendFile():
-
while True:
-
blusername = raw_input("\033[1;32m请输入你选择要用于发送文件的堡垒机用户[root/weblogic/oracle]:\033[0m").strip()
-
blusername_list = ['root','weblogic','oracle','','exit']
-
if blusername not in blusername_list:
-
print "\033[0;32minput error!Please try again!If you need exit,please input exit!\033[0m"
-
continue
-
if blusername == 'exit':
-
return
-
blhostname=raw_input("\033[1;32m请输入你选择要用于发送文件的堡垒机IP:\033[0m").strip()
-
print "\033[1;32m请输入你选择要用于发送文件的堡垒机密码:\033[0m"
-
blpassword=getpass.getpass()
-
username=raw_input("\033[1;32m请输入你选择要用于接收文件的用户[root/weblogic/oracle]:\033[0m").strip()
-
bllocalpath=raw_input("\033[1;32m堡垒机本地文件(绝对路径):\033[0m").strip()
-
remotepath=raw_input("\033[1;32m服务器目的地址(绝对路径):\033[0m").strip()
-
if blusername == 'root':
-
for list in server_list:
-
p = threading.Thread(target=transfer,args=(bllocalpath,remotepath,blhostname,blusername,blpassword,list[1],username,list[2],))
-
p.start()
-
for list in server_list:
-
p.join(timeout=1)
-
if blusername == 'weblogic' or blusername == '':
-
blusername = 'weblogic'
-
for list in server_list:
-
p = threading.Thread(target=transfer,args=(bllocalpath,remotepath,blhostname,blusername,blpassword,list[1],username,list[3],))
-
p.start()
-
if blusername == 'oracle':
-
for list in server_list:
-
p = threading.Thread(target=transfer,args=(bllocalpath,remotepath,blhostname,blusername,blpassword,list[1],username,list[4],))
-
p.start()
-
result_dict_print()
-
break
-
######堡垒机模式下命令的批量执行
-
def ExecuteCmd():
-
网站栏目:基于paramiko的文件批量分发和命令批量执行
文章源于:http://kswjz.com/article/isgphh.html
扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流