在實(shí)際工作環(huán)境中,有可能需要去運(yùn)維百臺(tái)
服務(wù)器,甚至更多。以應(yīng)用升級(jí)為例,對(duì)應(yīng)用做升級(jí)操作,首先得停止應(yīng)用服務(wù),防止新的應(yīng)用數(shù)據(jù)寫(xiě)入,并備份應(yīng)用部署目錄,然后替換成新的代碼文件、配置文件等。替換完成后,啟動(dòng)應(yīng)用服務(wù)。但是由于應(yīng)用服務(wù)器數(shù)量過(guò)多,如果一臺(tái)一臺(tái)服務(wù)器去做升級(jí),這會(huì)花費(fèi)很多時(shí)間。這時(shí),便可使用paramiko編寫(xiě)python腳本,讓這些重復(fù)性的操作批量執(zhí)行,去實(shí)現(xiàn)應(yīng)用升級(jí)的自動(dòng)化。這個(gè)小工具實(shí)現(xiàn)了在堡壘機(jī)模式和非堡機(jī)模式的運(yùn)用。
1.maintool.py(控制整個(gè)腳本的執(zhí)行),代碼如下:
點(diǎn)擊(此處)折疊或打開(kāi)
創(chuàng)新互聯(lián)建站服務(wù)項(xiàng)目包括大通網(wǎng)站建設(shè)、大通網(wǎng)站制作、大通網(wǎng)頁(yè)制作以及大通網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃等。多年來(lái),我們專(zhuān)注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,大通網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶(hù)以成都為中心已經(jīng)輻射到大通省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶(hù)的支持與信任!
-
#!/usr/bin/python
-
#coding:utf-8
-
import sys
-
######腳本執(zhí)行操作提示
-
def login():
-
print """\033[1;34m
-
1:批量分發(fā)文件(非堡壘機(jī)模式)
-
2:批量執(zhí)行命令(非堡壘機(jī)模式)
-
3:批量下載文件(非堡壘機(jī)模式)
-
4:單臺(tái)執(zhí)行命令(非堡壘機(jī)模式)
-
5:批量分發(fā)文件(堡壘機(jī)模式)
-
6:批量執(zhí)行命令(堡壘機(jī)模式)
-
7:增加需要服務(wù)器(非堡壘機(jī)模式)
-
8:刪除不需要服務(wù)器(非堡壘機(jī)模式)
-
9:查看當(dāng)前服務(wù)器列表(非堡壘機(jī)模式)
-
10:退出\033[0m
-
"""
-
#######定義用戶(hù)選擇函數(shù)
-
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()###非堡機(jī)模式下文件分發(fā)
-
login()
-
if choice == '2':
-
operation.ExecuteCmd()###非堡機(jī)模式下命令執(zhí)行
-
login()
-
if choice == '3':
-
operation.DownloadFile()###非堡機(jī)模式下文件下載
-
login()
-
if choice == '4':
-
operation.SingleServer()###單臺(tái)服務(wù)器操作
-
login()
-
if choice == '5':
-
blhost_operation.SendFile()###堡壘機(jī)模式下文件分發(fā)
-
login()
-
if choice == '6':
-
blhost_operation.ExecuteCmd()###堡壘機(jī)模式下命令執(zhí)行
-
login()
-
if choice == '7':
-
operation.AddServerList()###增加服務(wù)器名單
-
if choice == '8':
-
operation.DeleteServerList()###刪除服務(wù)器名單
-
if choice == '9':
-
operation.ShowServerList()###展示服務(wù)器名單
-
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執(zhí)行效果如下:
2.operation.py(定義非堡壘機(jī)模式下的相關(guān)操作),代碼如下:
-
#!/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={}
-
######讀取文件內(nèi)容,讀取完成后關(guān)閉文件
-
f = open ('serverlist.txt')
-
for i in f.readlines():
-
server_list.append(i.split())
-
f.close()
-
######非堡壘機(jī)下文件的傳送
-
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+"服務(wù)器文件傳送完成"
-
print result_dict[hostname]
-
except Exception,e:
-
print str(e)
-
######定義文件下載函數(shù)
-
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+"服務(wù)器文件下載完成"
-
print result_dict[hostname]
-
except Exception,e:
-
print str(e)
-
######定義命令執(zhí)行函數(shù)
-
def execmd(hostname,username,password,CMD):
-
paramiko.util.log_to_file('syslogin.log')###將用戶(hù)登錄服務(wù)器日志輸出到syslogin.log
-
ssh = paramiko.SSHClient()###ssh登錄服務(wù)器
-
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())###自動(dòng)添加主機(jī)名及主機(jī)密鑰到本地HostKeys對(duì)象,并將其保存,不依賴(lài)load_system_host_keys()的配置,即使~/.ssh/known_hosts不存在也不產(chǎn)生影響
-
ssh.connect(hostname=hostname,username=username,password=password)
-
stdin,stdout,stderr = ssh.exec_command(CMD)
-
result = stdout.read()
-
ssh.close()
-
result_dict[hostname] = hostname+"服務(wù)器命令執(zhí)行結(jié)果如下:"+"\n"+result
-
print result_dict[hostname]
-
######執(zhí)行結(jié)果打印
-
def result_dict_print():
-
global result_dict
-
while True:
-
if len(result_dict) == len(server_list):
-
break
-
print "\033[1;36m%s臺(tái)服務(wù)器完成\033[0m" %(len(result_dict))
-
result_dict = {}
-
######非保壘機(jī)模式下文件的分發(fā)
-
def SendFile():
-
while True:
-
username = raw_input("\033[1;32m請(qǐng)輸入你選擇要用于發(fā)送文件的用戶(hù)[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本地文件(絕對(duì)路徑):\033[0m").strip()
-
remotepath = raw_input("\033[1;32m服務(wù)器目的地址(絕對(duì)路徑):\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
-
######非堡壘機(jī)模式下文件的下載
-
def DownloadFile():
-
while True:
-
username = raw_input("\033[1;32m請(qǐng)輸入你選擇要用于下載文件的用戶(hù)[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遠(yuǎn)程文件(絕對(duì)路徑):\033[0m").strip()
-
localpath = raw_input("\033[1;32m服務(wù)器目的地址(目錄名,默認(rèn)為/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
-
######非堡壘機(jī)模式下命令的執(zhí)行
-
def ExecuteCmd():
-
while True:
-
username = raw_input("\033[1;32m請(qǐng)輸入你選擇要用于執(zhí)行命令的用戶(hù)[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請(qǐng)輸入要執(zhí)行的命令(不能帶引號(hào)):\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
-
######單臺(tái)服務(wù)器操作
-
def SingleServer():
-
IP = raw_input("\033[1;32m請(qǐng)輸入要執(zhí)行命令的服務(wù)器IP地址:\033[0m").strip()
-
username = raw_input("\033[1;32m請(qǐng)輸入要執(zhí)行命令的服務(wù)器用戶(hù)名:\033[0m").strip()
-
password = getpass.getpass()
-
CMD = raw_input("\033[1;32m請(qǐng)輸入要執(zhí)行的命令(不能帶引號(hào)):\033[0m").strip()
-
execmd(IP,username,password,CMD)
-
######服務(wù)器名單添加
-
def AddServerList():
-
hostname = raw_input("\033[1;32m請(qǐng)輸入服務(wù)器名稱(chēng)(如localhost):\033[0m").strip()
-
if hostname == 'quit' or hostname == 'exit':
-
return
-
ip = raw_input("\033[1;32m請(qǐng)輸入服務(wù)器IP:\033[0m").strip()
-
root_passwd = raw_input("\033[1;32m請(qǐng)輸入服務(wù)器root用戶(hù)密碼:\033[0m").strip()
-
weblogic_passwd = raw_input("\033[1;32m請(qǐng)輸入服務(wù)器weblogic用戶(hù)密碼:\033[0m").strip()
-
oracle_passwd = raw_input("\033[1;32m請(qǐng)輸入服務(wù)器oracle用戶(hù)密碼:\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重新執(zhí)行程序后生效(敲任意鍵退出)...\033[0m")
-
time.sleep(0.2)
-
sys.exit()
-
######服務(wù)器名單刪除
-
def DeleteServerList():
-
IP = raw_input("\033[1;32m請(qǐng)輸入要?jiǎng)h除服務(wù)器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重新執(zhí)行程序后生效(敲任意鍵退出)...\033[0m")
-
time.sleep(0.2)
-
sys.exit()
-
######服務(wù)器名單顯示
-
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臺(tái)服務(wù)器" % i
3.blhost_operation.py(定義堡壘機(jī)模式下的相關(guān)操作),代碼如下:
-
#!/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={}
-
######讀取文件內(nèi)容,讀取完成后關(guān)閉文件
-
f = open ('serverlist.txt')
-
for i in f.readlines():
-
server_list.append(i.split())
-
f.close()
-
######堡壘機(jī)下文件的傳送
-
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())###自動(dòng)添加主機(jī)名及主機(jī)密鑰到本地HostKeys對(duì)象,并將其保存,不依賴(lài)load_system_host_keys()的配置,即使~/.ssh/known_hosts不存在也不產(chǎn)生影響
-
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+"服務(wù)器文件傳送完成"
-
print result_dict[hostname]
-
######堡壘機(jī)模式下命令執(zhí)行
-
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+"服務(wù)器命令執(zhí)行結(jié)果如下:"+"\n"+result
-
print result_dict[hostname]
-
######執(zhí)行結(jié)果打印
-
def result_dict_print():
-
global result_dict
-
while True:
-
if len(result_dict) == len(server_list):
-
break
-
print "\033[1;36m%s臺(tái)服務(wù)器完成\033[0m" %(len(result_dict))
-
result_dict={}
-
######堡壘機(jī)模式下文件的批量分發(fā)
-
def SendFile():
-
while True:
-
blusername = raw_input("\033[1;32m請(qǐng)輸入你選擇要用于發(fā)送文件的堡壘機(jī)用戶(hù)[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請(qǐng)輸入你選擇要用于發(fā)送文件的堡壘機(jī)IP:\033[0m").strip()
-
print "\033[1;32m請(qǐng)輸入你選擇要用于發(fā)送文件的堡壘機(jī)密碼:\033[0m"
-
blpassword=getpass.getpass()
-
username=raw_input("\033[1;32m請(qǐng)輸入你選擇要用于接收文件的用戶(hù)[root/weblogic/oracle]:\033[0m").strip()
-
bllocalpath=raw_input("\033[1;32m堡壘機(jī)本地文件(絕對(duì)路徑):\033[0m").strip()
-
remotepath=raw_input("\033[1;32m服務(wù)器目的地址(絕對(duì)路徑):\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
-
######堡壘機(jī)模式下命令的批量執(zhí)行
-
def ExecuteCmd():
-
本文名稱(chēng):基于paramiko的文件批量分發(fā)和命令批量執(zhí)行
網(wǎng)頁(yè)鏈接:http://weahome.cn/article/isgphh.html