最近在做交换机备份脚本发现网上很多照着写下来都无法正常执行。
将自己成功的代码贴出来希望大家能少走弯路希望对大家有用:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Author: Linxy -- <592901071@qq.com>
Purpose: Juniper备份脚本
Created: 2017-6-23
"""
import datetime
import sys
import os
import telnetlib
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
import smtplib
su=[]
fa=[]
#获取年月日的str数据
def getymd (ymd):
d=datetime.datetime.now()
if ymd=='y':
return str(d.year)
elif ymd=='m':
return str(d.month)
elif ymd=='d':
return str(d.day)
#p1='./switch/'+getymd('y')+'/'+getymd('m')+'/'+getymd('d')
l1=[getymd('y'),getymd('m'),getymd('d')]
#print(l1)
p1='./switch'
if os.path.isdir(p1):
pass
else:
os.mkdir(p1)
for i in l1:
p1=p1+'/'+i
if os.path.isdir(p1):
pass
else:
os.mkdir(p1)
filename1='./sw.txt'#交换机IP地址列表存放位置 注意要把最后一个IP以后的空格和回车全部删除
filename2='./ssg.txt'
def fc_srx(p2): #文件处理部分的函数
if os.path.getsize(p2)==0:
'''
密码不对时候 telnet的执行是成功的只是read_all的时候没有结尾的标记所以无法读出返回值
但仍然会建立空txt文档所以需要在此再进行一次判断并把需要的值写入fa[]中
'''
fa.append(host+'\n')
print(host+" is failed")
else:
with open(p2,'r') as f:
lines=f.readlines()
with open(p2,'w') as w:
for I in lines:
I=I.replace('---(more)---','')
I=I.replace(' ','')
I=I.replace('\r','')
I=I.replace('\n','')
if I=='':
pass
else :
w.write(I+'\r\n')
def fc_ssg(p2):
if os.path.getsize(p2)==0:
#print(host+' is failed')
'''
密码不对时候 telnet的执行是成功的只是read_all的时候没有结尾的标记所以无法读出返回值
但仍然会建立空txt文档所以需要在此再进行一次判断并把需要的值写入fa[]中
'''
fa.append(host+'\n')
print(host+" is failed")
else:
with open(p2,'r') as f:
lines=f.readlines()
with open(p2,'w') as w:
for I in lines:
I=I.replace('--- more ---','')
I=I.replace(' ','')
I=I.replace('\r','')
I=I.replace('\n','')
if I=='':
pass
else :
w.write(I+'\r\n')
def juniper_bak (host):#备份juniper函数
user='这里是交换机帐号'
password='这里是交换机密码'
print ('Backing up:'+host)
tn=telnetlib.Telnet(host.encode('utf-8'),port=23,timeout=4)
tn.read_until(b"login:")
tn.write(user.encode('utf-8')+'\n'.encode('utf-8'))
tn.read_until(b"Password:")
tn.write(password.encode('utf-8')+'\n'.encode('utf-8'))
tn.read_until(b'> ')
tn.write(b'show configuration | display set '+'\n'.encode('utf-8'))
for i in range(300) :
tn.write(b' ')
tn.write(b'q\n')
tn.write(b'q\n')
p2=p1+'/'+host+'/'+host+'.txt'
if os.path.isdir(p1+'/'+host):
pass
else:
os.mkdir(p1+'/'+host)
with open(p2,'w') as f:
f.write(tn.read_all().decode())
tn.close()
fc_srx(p2)
def ssg_bak (host):#备份ssg函数
user='这里是ssg设备帐号'
password='这里是ssg设备密码'
print ('Backing up:'+host)
tn=telnetlib.Telnet(host.encode('utf-8'),port=23,timeout=4)
tn.read_until(b"login:")
tn.write(user.encode('utf-8')+'\n'.encode('utf-8'))
tn.read_until(b"password:")
tn.write(password.encode('utf-8')+'\n'.encode('utf-8'))
tn.read_until(b'>')
tn.write(b'get config'+'\n'.encode('utf-8'))
for i in range(50000) :#看具体设备有些设备输入200个空格即可获取到全部回显
tn.write(b' ')
tn.write(b'exit\n')
p2=p1+'/'+host+'/'+host+'.txt'
if os.path.isdir(p1+'/'+host):
pass
else:
os.mkdir(p1+'/'+host)
with open(p2,'w') as f:
f.write(tn.read_all().decode(encoding='gbk'))
tn.close()
fc_ssg(p2)
def sendmail_cxr(tx):#发送邮件函数
def _format_addr(s): #注意此函数实际传入的S格式为‘字符串 <邮箱地址>’
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
from_addr = '这里是发送邮件的邮箱地址'
password = '这里是邮箱密码'
to_addr = '接收邮件的地址1'
to_addr2='接收邮件的地址2'
smtp_server = 'SMT服务的域名要写这里'
msg = MIMEText(tx, 'plain', 'utf-8')
msg['From'] = _format_addr('邮件相关的格式不要细究 <%s>' % from_addr)
msg['To'] = _format_addr('邮件相关的格式不要细究 <%s>'% to_addr)
msg['Subject'] = Header('今日备份情况', 'utf-8').encode() #邮件主题
server = smtplib.SMTP(smtp_server, 25)
#server.set_debuglevel(1)
server.login(from_addr, password)
server.sendmail(from_addr, [to_addr,to_addr2], msg.as_string())
server.quit()
if __name__=='__main__':
with open (filename2,'r')as fo:
for line in fo.readlines():
if line.split(' ')[0]!='':
line=line.replace('\n','')
host=line.split(' ')[0]
try:
ssg_bak(host)
su.append(host+'\n')
except:
print(host+" is failed")
fa.append(host+'\n')
with open (filename1,'r')as fo:
for line in fo.readlines():
if line.split(' ')[0]!='':
line=line.replace('\n','')
host=line.split(' ')[0]
try:
juniper_bak(host)
su.append(host+'\n')
except:
print(host+" is failed")
fa.append(host+'\n')
'''
密码不对时候 telnet的执行是成功的只是read_all的时候没有结尾的标记所以无法读出返回值
但仍然会建立空txt文档所以需要在文本处理环节再进行一次判断并把需要的值写入fa[]中
'''
#print(su)
#print(fa)
tx=''
if len(su)!=0:
txsu='备份成功\n'+''.join(su)
csu=0
for i in su:
csu=csu+1
tx=tx+txsu+'总计成功'+str(csu)+'个'+'\n\n'
if len(fa)!=0:
cfa=0
for i in fa:
cfa=cfa+1
txfa='备份失败\n'+''.join(fa)
tx=tx+txfa+'总计失败'+str(cfa)+'个'+'\n\n'
sendmail_cxr(tx)
脚本还存在问题。
1、在linux上定时执行 但ssg部分每次定时执行都无法正常备份。
2、手动执行脚本时,经常随机出现某交换机备份失败。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ssh备份交换机
#!/usr/bin/env python
#coding:utf-8
####此方法适用锐捷 中兴####
import time
import paramiko
t = paramiko.Transport("192.168.1.0",22)
t.connect(username="xxx", password="xxx")
chan = t.open_session()
chan.get_pty()
chan.invoke_shell()
time.sleep(0.2)
chan.send('terminal length 0'+'\n')#先配置交换机一次性输出全部内容。
time.sleep(0.2)
chan.send('show running-config'+'\n')
time.sleep(2)
time.sleep(0.5)
result = chan.recv(65535)
print(str(result,'utf-8'))
############此方法H3C可用################
############华为需再vty接口下设置 screen-length 0################
#华为H3C需要先配置一次性输出全部内容
#华为和H3C的全页打印显示配置信息的命令:
#user-interface vty 0 4
#screen-length 0
#display current-configuration
#!/usr/bin/env python
#coding:utf-8
import paramiko
#创建sshclient对象
ssh = paramiko.SSHClient()
#允许将信任的主机自动加入到host_allow 列表,此方法必须放在connect方法的前面
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#调用connect方法连接服务器
ssh.connect(hostname='192.168.0.1',port=22,username='xxx',password='xxx')
while True:
input_command = input('>>>:')
if input_command == 'quit':
break
#执行命令,输出结果在stdout中,如果是错误则放在stderr中
stdin,stdout,stderr = ssh.exec_command(input_command)
result = stdout.read() #read方法读取输出结果
if len(result) == 0: #判断如果输出结果长度等于0表示为错误输出
print(stderr.read())
else:
print(str(result,'utf-8'))
ssh.close()