Python实现自动备份网络设备配置

Python实现自动备份网络设备配置

最近研究一个非常好使的能够自动登录网络设备并把想要的信息保存下来并且自动上传到ftp服务器的Python脚本,这里主要跟大家分享一下Python NetMiko模块的使用。


安装方法: pip install netmiko

此库已经被python收录:pypi.python.org/pypi/ne

官方指导手册:pynet.twb-tech.com/blog


实验运行环境:

整个环境都在EVE-ng(Vmware Esxi上运行)的平台上运行

操作系统:Kali-linux(VMware Esxi主机上运行)

网络设备:思科路由器

Python编辑器:Sublime text 3.0

Python版本:Python3.5

需要准备的文件:ips和commands(ips文件存放IP地址列表,commands文件存放需要执行的命令,文件内容存放格式都是一个行一个)

实验拓扑:

EVE-NG


演示代码:

NetMiko主程序:

#!/usr/bin/python3.5
# -*- coding: utf-8 -*-

from netmiko import ConnectHandler
from ftp_client import main     #导入ftp上传模块
import os
import time
import re

def Cisco(ip):
	#cisco swith_config export function
	cisco_881 = {
	'device_type': 'cisco_ios',
	'ip': ip,
	'username': 'cisco',
	'password': 'cisco',
	'port': '22',
	'secret': 'cisco',
	'verbose': False,
	}
'''思科设备的username cisco privilege 15 password cisco,privilege 15权限为
最大可以执行的命令越多
'''
	print (u'正在连接Devices:{0}\n'.format(ip))
	net_connect = ConnectHandler(**cisco_881)
	net_connect.enable()

	timestr = time.strftime('%Y-%m-%d', time.localtime(time.time()))

	for cmds in open('commands', 'r'):
		cmd = cmds.replace('\n',' ')
		filename = (u'{0}_{1}_{2}.txt'.format(ip,cmd.replace(' ','_').replace('/','-'), timestr))
		save = open('/root/python_code/config_scrtpt/config/' + filename, 'w')
		print (u'正在执行命令:\n' + cmds)
		result = net_connect.send_command(cmds)
		time.sleep(1)
		save.write(result)
		print(u'命令执行完毕,结果保存于当前目录{0}中!\n'.format(filename))
		save.close()
	net_connect.disconnect()

if __name__ == '__main__':
	for ips in open('ips','r'):
		ip = ips.replace('\n','')
		try:
			Cisco(ip)
		except Exception as e:
			print ('连接超时! ',e)
			pass
		time.sleep(1)
	print (u'=====上传文件至目标服务器=====')
	main()   #ftp上传主程序
	print (u'\n文件上传成功!')

		


FTP上传主程序:

#!/usr/bin/python3.5
# -*- coding: utf-8 -*-

from ftplib import FTP
import re
import os

def ftpconnect(host, username, password):
	ftp = FTP()
	ftp.connect(host, 21)
	ftp.login(username, password)
	return ftp

def uploadfile(ftp, localpath, remotepath):
	bufsize = 1024
	fp = open(localpath, 'rb')
	ftp.storbinary('STOR ' + remotepath, fp, bufsize)
	ftp.set_debuglevel(0)
	fp.close()
	
def filename():
        #获取指定路径下的所有文件将文件名存放到列表
	f1 = os.getcwd() + '/config/'
	f2 = os.listdir(f1)
	filename = []
	for i in f2:
        #正则找出所有结尾为txt的文件,然后添加到filename列表里
		if ''.join(re.findall('.tx(t$)',i)) == 't':
			filename.append(i)
	return filename

def main():
	# print ('正在连接服务器...')
	ftp = ftpconnect('192.168.31.254', 'config', 'config')
        #获取路径/root/python_code/config_script
	path1 = os.getcwd()
        #/root/python_code/config_script + '/config/'
	fullpath = path1 + '/config/'
	# print ('文件所在路径'+fullpath)
        #获取待上传的文件名
	fn = filename()
        #文件上传到ftp服务器后的文件名称,与源文件保持一致eg:123.txt
	fullremotepath = fn
	# print (fullremotepath)
        #本地路径需要加上路径+具体文件名eg:/root/python_code/config_script/123.txt
	fulllocalpath = []
	for i in fn:
		fulllocalpath.append(fullpath + i)
	for r in range(len(fulllocalpath)):
		for l in range(len(fulllocalpath)):
'''
1,首先第一个for第一次循环第二个for也是第一次循环时r=0,l=0,r=l,此时p1和p2会被赋值,
2,然后第二个for循环的第二次循环r依然=0,l=1,p1和p2不会被赋值
3,当第一个for第二次循环时第二个for第一次循环r=1,l=0,p1和p2不会被赋值, 
4,第二个for的第二次循环r=1,l=1,此时p1和p2会被赋值
'''
			if r == l:
				p1 = fulllocalpath[l]
				p2 = fullremotepath[r]
#得出的结果就是uploadfile(ftp, '/root/python_code/config_script/123.txt', '123.txt')
				uploadfile(ftp, p1, p2)
	print ('列出目标服务器文件列表:')
	ftp.dir()
	ftp.quit()

if __name__ == '__main__':
	main()


效果截图:

如果目标关机或者端口不可达会返回time-out
程序执行过程中
文件上传成功后list出所有文件名

编辑于 2018-08-21

文章被以下专栏收录