系統環境:
[root@localhost autoback]# python
Python 2.7.9 (default, Mar 23 2017, 06:02:44)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-17)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
[root@localhost autoback]# cat /etc/redhat-release
CentOS release 6.5 (Final)
[root@localhost autoback]# uname -a
Linux localhost.localdomain 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
如果沒有pip工具需要下載下傳安裝,通過pip安裝pexpect子產品,或者通過其它方式安裝pexpect子產品。通過pip安裝pexpect子產品如下:
pip install pexpect
小程式通過FTP和TFTP進行配置檔案的備份,是以需要提前在作業系統上安裝FTP和TFTP的用戶端:
yum install ftp tftp
本程式可以備份三種交換機的配置,或者經過修改支援備份更多的裝置類型。
華三交換機和juniper交換機通過ftp進行配置備份,需要在交換機上開啟ftp的服務。
h3c交換機:
ftp server enable
local-user XX
service-type ftp
juniepr交換機
set system services ftp
show configuration | display set | save config.txt 這條指令會将配置檔案儲存在/var/home/xx/的目錄下
因為我們的思科交換機不支援ftp,是以采用了tftp的方式進行配置備份,針對思科交換機,需要開啟tftp服務
思科交換機:
tftp-server nvram:startup-config
在具體的使用過程中需要注意交換機配置檔案的位置,如果配置檔案的位置有差異,可能會導緻程式執行有問題,配置檔案會備份到/data/(xx-xx-xx)的檔案夾下,以日期為目錄進行儲存。
程式是需要建立一個名叫switch_mgt_ip.txt的檔案,寫入裝置類型和管理IP,放在和程式同樣的目錄下,程式會輪詢檔案的每一行,讀取裝置型号和管理IP,并通過這個判斷是執行哪一個裝置型号的備份腳本,檔案的内容如下所示:
h3c 1.1.1.1
cisco 2.2.2.2
下面是具體的程式示例:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pexpect
import os
import time
#定義h3c裝置的配置備份函數
def ftp_h3c(ipAddress,cur_path): #參數為IP位址和目前目錄
loginName = 'XXXX'
loginPassword = 'XXXX'
cmd = 'ftp ' + ipAddress
child = pexpect.spawn(cmd) #通過pexpect的spawn類調用ftp子程式
index = child.expect(["(?i)name","(?i)No route to host",pexpect.EOF,pexpect.TIMEOUT]) #通過expect方法得到執行spawn後的輸出
if (index == 0): #如果輸出包含有name
child.sendline(loginName) #輸入登入名
index = child.expect(["(?i)password",pexpect.EOF,pexpect.TIMEOUT]) #輸入登入名後的提示資訊
if (index != 0): #如果輸入登入名後,提示沒有包含password
print "ftp login failed"
child.close(force=Ture)
child.sendline(loginPassword) #如果輸入登入名後,有password的提示,輸入登入密碼
index = child.expect( ['ftp>','Login incorrect','Service not available',pexpect.EOF,pexpect.TIMEOUT])
if (index == 0): #輸入密碼後,有ftp>的提示,證明登入成功
print 'Congratulations! ftp login correct!'
child.sendline("bin") #使用二進制進行ftp的下載下傳,二進制的下載下傳速度快
print 'getting a file...'
child.sendline("get startup.cfg") #下載下傳配置檔案,需要确定配置檔案名為startup.cfg
index = child.expect( ['received.*ftp>',pexpect.EOF,pexpect.TIMEOUT]) #如果下載下傳檔案後,有received....ftp證明下載下傳成功
if (index != 0):
print "failed to get file"
child.close(force=True)
print 'successfully received the file'
child.sendline("bye")
ptime = time.strftime("%Y-%m-%d", time.localtime()) #擷取目前時間,精确到日期
cfg_name = ipAddress + '_' + ptime + '.cfg' #儲存檔案名以IP和日期命名
get_path = cur_path + '/startup.cfg'
save_path = '/data/' + ptime + '/' + cfg_name #配置檔案所儲存的目錄,/data/日期
Save_cfg = ' '.join(['mv',get_path,save_path])
pexpect.run(Save_cfg)
elif (index == 1): #如果比對到login incorrect說明登入失敗
print " You entered an invalid login name or password,Programe quits!"
child.close(force=True)
else: #如果比對到EOF或TIMEOUT,程式退出
print "ftp login failed! index = " + str(index)
elif index == 1: #如果輸入ftp指令後,提示no route to host說明輸入主機不對,程式退出
print "ftp login failed,due to unknown host"
child.close(force=True)
else:
print "ftp login faile,due to TIMEOUT or EOF"
clild.close(force=True)
#定義思科裝置的配置備份函數
def tftp_cisco(ipAddress,cur_path):
cmd = 'tftp ' + ipAddress
child = pexpect.spawn(cmd) #通過pexpect的spawn類調用tftp子程式
index = child.expect( ['tftp>',pexpect.EOF,pexpect.TIMEOUT]) #通過pexpect的expect方法得到執行spawn後的輸出
if (index == 0):
print 'Congratulations! tftp login correct!'
child.sendline("get startup-config") #需要在裝置上對nvram:startup-config開啟tftp服務
print 'successfully received the file'
child.sendline("q")
ptime = time.strftime("%Y-%m-%d", time.localtime())
cfg_name = ipAddress + '_' + ptime + '.cfg'
get_path = cur_path + '/startup-config'
save_path = '/data/' + ptime + '/' + cfg_name
Save_cfg = ' '.join(['mv',get_path,save_path])
pexpect.run(Save_cfg)
print "tftp login failed! index = " + str(index)
#定義juniper裝置的配置備份函數
def ftp_juniper(ipAddress,cur_path):
child = pexpect.spawn(cmd)
index = child.expect(["(?i)name","(?i)Unknow host",pexpect.EOF,pexpect.TIMEOUT])
child.sendline(loginName)
index = child.expect(["(?i)password",pexpect.EOF,pexpect.TIMEOUT])
if (index != 0):
child.sendline(loginPassword)
if (index == 0):
child.sendline("cd /var/home/XXXX") #需要在裝置上将配置儲存到/var/home/XXXX的目錄下,且檔案名為config.txt
child.sendline("bin")
child.sendline("get config.txt")
index = child.expect( ['received.*ftp>',pexpect.EOF,pexpect.TIMEOUT])
ptime = time.strftime("%Y-%m-%d", time.localtime())
cfg_name = ipAddress + '_' + ptime + '.cfg'
get_path = cur_path + '/config.txt'
save_path = '/data/' + ptime + '/' + cfg_name
elif (index == 1):
else:
elif index == 1:
file_mgtip = file('switch_mgt_ip.txt') #打開寫有裝置型号和管理IP的檔案
data_mgtip = file_mgtip.readlines() #将檔案的所有行讀出
ftime = time.strftime("%Y-%m-%d", time.localtime()) #用于建立基于日期的檔案夾
pexpect.run('mkdir -p /data/' + ftime)
app_path = os.getcwd() #擷取程式儲存路徑
print app_path
for i in range(len(data_mgtip)): #根據行數進行循環
entry_mgtip = data_mgtip[i].split() #将一行以空格為分隔符拆成清單
i += 1
if ('h3c' in entry_mgtip): #如果某一行包含H3C,讀取後邊的IP位址并調用H3C的配置備份函數
h3c_ip = entry_mgtip[1]
ftp_h3c(ipAddress = h3c_ip,cur_path = app_path)
elif ('cisco' in entry_mgtip):
cisco_ip = entry_mgtip[1]
tftp_cisco(ipAddress = cisco_ip,cur_path = app_path)
elif ('juniper' in entry_mgtip):
juniper_ip = entry_mgtip[1]
ftp_juniper(ipAddress = juniper_ip,cur_path = app_path)