python 网络设备管理_使用Python实现定期备份网络设备配置信息

前言

好久没有更新博客了,最近私人的事情比较多,所以一直没有时间来更新。正好十一假期后比较空闲,所以又继续自学Python。前段时间在工作中遇到网络设备配置丢失的问题,还好之前有备份的配置,正好这次研究下使用Python备份网络设备的配置信息,实现定期备份,这样就不怕配置丢失的问题了。

pexpect模块

首先肯定要使用到pexpect模块了,这样只要登录网络设备,执行显示配置信息命令,就可以将配置信息统统抓取下来了。

一个简单的pexpect模块示例:

# This connects to the openbsd ftp site and

# downloads the recursive directory listing.

import pexpect

child = pexpect.spawn('ftp ftp.openbsd.org')

child.expect('Name .*: ')

child.sendline('anonymous')

child.expect('Password:')

child.sendline('noah@example.com')

child.expect('ftp> ')

child.sendline('lcd /tmp')

child.expect('ftp> ')

child.sendline('cd pub/OpenBSD')

child.expect('ftp> ')

child.sendline('get README')

child.expect('ftp> ')

child.sendline('bye')

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

# This connects to the openbsd ftp site and

# downloads the recursive directory listing.

importpexpect

child=pexpect.spawn('ftp ftp.openbsd.org')

child.expect('Name .*: ')

child.sendline('anonymous')

child.expect('Password:')

child.sendline('noah@example.com')

child.expect('ftp> ')

child.sendline('lcd /tmp')

child.expect('ftp> ')

child.sendline('cd pub/OpenBSD')

child.expect('ftp> ')

child.sendline('get README')

child.expect('ftp> ')

child.sendline('bye')

通过上面的示例可以看到pexpect模块的基本使用方法:

基本使用方法

1、首先需要import一下pexpect模块:

import pexpect

2、通过spawn()类来新建一个你需要执行远程命令的连接:

child = pexpect.spawn('CMD#这里是你需要执行的交互式命令')

3、通过expect()方法来捕获需要匹配的交互式信息:(如:提示需要输入用户名“login:”)

child.expect('Name .*: ')

4、通过sendline()方法来执行交互式窗口需要输入的信息:(如:输入用户名或执行退出命令)

child.sendline('anonymous') or child.sendline('bye')

以上为基本的一些基本的方法,还有一些更高级的方法和类,如:run方法。这里就不过多的说明了,有兴趣的化可以看官方的说明文档。传送门

抓取配置信息

上面说了怎么使用pexpect模块,下面就通过几段代码来说明,我是获取设备的配置信息。(这里因为我测试环境中绝大部分的设备都是H3C的,所以查看配置信息命令就默认使用了H3C的命令,如果不是同一厂商,则需要对设备厂商进行辨别,并执行相应的命令。)

针对Telnet方式的配置抓取代码:

def telnet(name,ip,passwd):

child = pexpect.spawn('telnet %s' % ip)

fout = open('/home/zxw/backup_conf/' + today + '/' + '%s_%s.txt' % (name, ip), 'wb+')

child.logfile = fout

child.expect(['login:', 'Username'])

child.sendline('admin')

child.expect('(?i)ssword:')

child.sendline('%s' % passwd)

child.expect('' % name)

child.sendline('display current-configuration')

while index(child) == 0:

child.send(' ')

child.sendline('quit')

1

2

3

4

5

6

7

8

9

10

11

12

13

deftelnet(name,ip,passwd):

child=pexpect.spawn('telnet %s'%ip)

fout=open('/home/zxw/backup_conf/'+today+'/'+'%s_%s.txt'%(name,ip),'wb+')

child.logfile=fout

child.expect(['login:','Username'])

child.sendline('admin')

child.expect('(?i)ssword:')

child.sendline('%s'%passwd)

child.expect(''%name)

child.sendline('display current-configuration')

whileindex(child)==0:

child.send(' ')

child.sendline('quit')

针对SSH方式的配置抓取代码:

def ssh(name,ip,passwd):

child = pexpect.spawn('ssh admin@%s' % ip)

fout = open('/home/zxw/backup_conf/' + today + '/' + '%s_%s.txt' % (name, ip), 'wb+')

child.logfile = fout

child.expect('admin@%s\'s password:' % ip)

child.sendline('%s' % passwd)

child.expect('' % name)

child.sendline('display current-configuration')

while index(child) == 0:

child.send(' ')

child.sendline('quit')

1

2

3

4

5

6

7

8

9

10

11

defssh(name,ip,passwd):

child=pexpect.spawn('ssh admin@%s'%ip)

fout=open('/home/zxw/backup_conf/'+today+'/'+'%s_%s.txt'%(name,ip),'wb+')

child.logfile=fout

child.expect('admin@%s\'s password:'%ip)

child.sendline('%s'%passwd)

child.expect(''%name)

child.sendline('display current-configuration')

whileindex(child)==0:

child.send(' ')

child.sendline('quit')

上面两段基本一样,只是pexpect.spawn这里区分了远程的方式。这里还用到了一个自定义的函数index()来对一般远程登录时需要手动下翻的“—-more—-”来进行自动翻页,附上index()函数代码:

def index(child):

name1 = '---- More ----'

index = child.expect([name1, '' % sw_name])

return index

1

2

3

4

defindex(child):

name1='---- More ----'

index=child.expect([name1,''%sw_name])

returnindex

获取设备登录信息

上面说过了怎么获取设备的配置信息,但是既然需要实现自动备份功能,而且在工作中我们肯定也管理着众多的网络设备,不可能针对每个设备都执行下上面的命令,所以批量的执行是必须的。我这里采用了读取配置文件的方式进行获取设备的登录信息,这样只要一个for...in循环就可以依次执行完成备份操作了。

先是配置文件的格式:

[标签] #用于获取总的设备列表,便于后面使用for...in循环

name = 设备名称

ip = 设备ip地址

passwd = 登录密码

remote = 设备远程登录方式 telnet或ssh

1

2

3

4

5

[标签]#用于获取总的设备列表,便于后面使用for...in循环

name=设备名称

ip=设备ip地址

passwd=登录密码

remote=设备远程登录方式telnet或ssh

如:

[FW10508]

name = S10508_FireWall

ip = 10.10.10.1

passwd = password

remote = ssh

[SW10508]

name = SW_S10508

ip = 10.10.10.2

passwd = password

remote = ssh

[12508]

name = SW-S12508X

ip = 10.10.10.3

passwd = password

remote = telnet

[YW6800]

name = 6800-YeWu

ip = 10.10.10.4

passwd = password

remote = telnet

[WAN5100]

name = WAN_Conn_Switch

ip = 10.10.10.5

passwd = password

remote = telnet

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

[FW10508]

name=S10508_FireWall

ip=10.10.10.1

passwd=password

remote=ssh

[SW10508]

name=SW_S10508

ip=10.10.10.2

passwd=password

remote=ssh

[12508]

name=SW-S12508X

ip=10.10.10.3

passwd=password

remote=telnet

[YW6800]

name=6800-YeWu

ip=10.10.10.4

passwd=password

remote=telnet

[WAN5100]

name=WAN_Conn_Switch

ip=10.10.10.5

passwd=password

remote=telnet

获取设备登录信息:

def get_cfg(sw_tag):

global sw_name, sw_ip, sw_passwd, sw_remote

#config = configparser.ConfigParser(allow_no_value = True)

#config.read(ini_file)

sw_name = config.get(sw_tag, 'name')

sw_ip = config.get(sw_tag, 'ip')

sw_passwd = config.get(sw_tag, 'passwd')

sw_remote = config.get(sw_tag, 'remote')

return sw_name, sw_ip, sw_passwd, sw_remote

config_path = './config.ini'

if os.path.exists(config_path): #判断配置文件是否存在

config = configparser.ConfigParser(allow_no_value = True)

config.read(config_path)

dev_list = config.sections() #获取设备列表

else:

print('Missing configuration files')

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

defget_cfg(sw_tag):

globalsw_name,sw_ip,sw_passwd,sw_remote

#config = configparser.ConfigParser(allow_no_value = True)

#config.read(ini_file)

sw_name=config.get(sw_tag,'name')

sw_ip=config.get(sw_tag,'ip')

sw_passwd=config.get(sw_tag,'passwd')

sw_remote=config.get(sw_tag,'remote')

returnsw_name,sw_ip,sw_passwd,sw_remote

config_path='./config.ini'

ifos.path.exists(config_path):#判断配置文件是否存在

config=configparser.ConfigParser(allow_no_value=True)

config.read(config_path)

dev_list=config.sections()#获取设备列表

else:

print('Missing configuration files')

批量执行备份

实现上面两个功能后,就可以对设备配置信息进行批量备份了:

for device in dev_list:

get_cfg(device)

if sw_remote == 'ssh':

if test_port(sw_ip,22) == 0:

ssh(sw_name,sw_ip,sw_passwd)

print(': finished' % sw_name)

else:

print('can not connect deivce:' % sw_name)

elif sw_remote == 'telnet':

if test_port(sw_ip,23) == 0:

telnet(sw_name,sw_ip,sw_passwd)

print(': finished' % sw_name)

else:

print('can not connect deivce:' % sw_name)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

fordeviceindev_list:

get_cfg(device)

ifsw_remote=='ssh':

iftest_port(sw_ip,22)==0:

ssh(sw_name,sw_ip,sw_passwd)

print(': finished'%sw_name)

else:

print('can not connect deivce:'%sw_name)

elifsw_remote=='telnet':

iftest_port(sw_ip,23)==0:

telnet(sw_name,sw_ip,sw_passwd)

print(': finished'%sw_name)

else:

print('can not connect deivce:'%sw_name)

这里我还对设备是否能够远程连接进行了测试,避免因为配置文件中某些设备无法远程连接导致其他设备备份失败:

def test_port(ip,port):

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s.settimeout(3)

host = (ip,port)

try:

s.connect(host)

s.close()

return 0

except Exception as e:

s.close()

return 1

1

2

3

4

5

6

7

8

9

10

11

deftest_port(ip,port):

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s.settimeout(3)

host=(ip,port)

try:

s.connect(host)

s.close()

return0

exceptExceptionase:

s.close()

return1

压缩备份

定期备份配置文件带来最明显的问题就是磁盘空间的增长,所以压缩是最好的选择。

def zip_dir(dir_name, zipfile_name):

f = zipfile.ZipFile(zipfile_name, 'w', zipfile.ZIP_DEFLATED)

for root, dirs, files in os.walk(dir_name):

for name in files:

f.write(os.path.join(root, name))

os.remove(os.path.join(root, name))

f.close()

os.rmdir(path)

zipfile_name = path + '.zip'

try:

zip_dir(path, zipfile_name)

print('compress the backup files successd.')

except IOError as e:

print(e)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

defzip_dir(dir_name,zipfile_name):

f=zipfile.ZipFile(zipfile_name,'w',zipfile.ZIP_DEFLATED)

forroot,dirs,filesinos.walk(dir_name):

fornameinfiles:

f.write(os.path.join(root,name))

os.remove(os.path.join(root,name))

f.close()

os.rmdir(path)

zipfile_name=path+'.zip'

try:

zip_dir(path,zipfile_name)

print('compress the backup files successd.')

exceptIOErrorase:

print(e)

这里在将文件加入压缩文件后,就直接进行删除操作,将备份目录及目录下文件全部删除。

实现效果

执行成功显示:

--------------------2018-10-23--------------------

start backup task ...

: finished.

: finished.

: finished.

: finished.

: finished.

: finished.

compress the backup files successd.

finished backup task.

1

2

3

4

5

6

7

8

9

10

--------------------2018-10-23--------------------

startbackuptask...

:finished.

:finished.

:finished.

:finished.

:finished.

:finished.

compressthebackupfilessuccessd.

finishedbackuptask.

查看备份目录:

[root@localhost backup_conf]# ll -h

total 28K

dr----x--t. 2 root root 194 Oct 23 14:14 20181012

dr----x--t. 2 root root 194 Oct 15 17:27 20181015

-rw-r--r--. 1 root root 27K Oct 23 15:48 20181023.zip #这里为新创建的备份压缩文件

1

2

3

4

5

[root@localhostbackup_conf]# ll -h

total28K

dr----x--t.2rootroot194Oct2314:1420181012

dr----x--t.2rootroot194Oct1517:2720181015

-rw-r--r--.1rootroot27KOct2315:4820181023.zip#这里为新创建的备份压缩文件

还有一个重要的配置,就是将脚本加入crontab中,定期执行:

1 0 * * 6 root python3 /home/zxw/pytest/backup_conf/backup_swconfig.py >> output.log

1

10**6rootpython3/home/zxw/pytest/backup_conf/backup_swconfig.py>>output.log

查看log文件:

--------------------2018-10-23--------------------

start backup task ...

: finished.

: finished.

: finished.

: finished.

: finished.

: finished.

compress the backup files successd.

finished backup task.

1

2

3

4

5

6

7

8

9

10

--------------------2018-10-23--------------------

startbackuptask...

:finished.

:finished.

:finished.

:finished.

:finished.

:finished.

compressthebackupfilessuccessd.

finishedbackuptask.

总结

编辑前

这里也只是实现了一些我目前需要的基本功能,后面也可能基于这个代码再增加一些更高级而且实用的功能,比如说跨厂商的。还有就是对备份文件的压缩打包,节省存储空间。

这里我实现了对备份文件的压缩打包,节省了存储空间。

完整代码

附上完整的代码:

#!/usr/bin/python

#coding:utf-8

# @Author: zhangxw

# @Blog: www.conum.cn

import pexpect

import sys

import datetime

import os

import configparser

import socket

import zipfile

def get_cfg(sw_tag):

global sw_name, sw_ip, sw_passwd, sw_remote

#config = configparser.ConfigParser(allow_no_value = True)

#config.read(ini_file)

sw_name = config.get(sw_tag, 'name')

sw_ip = config.get(sw_tag, 'ip')

sw_passwd = config.get(sw_tag, 'passwd')

sw_remote = config.get(sw_tag, 'remote')

return sw_name, sw_ip, sw_passwd, sw_remote

def index(child):

name1 = '---- More ----'

index = child.expect([name1, '' % sw_name])

return index

def telnet(name,ip,passwd):

#try:

child = pexpect.spawn('telnet %s' % ip)

fout = open('/home/zxw/backup_conf/' + today + '/' + '%s_%s.txt' % (name, ip), 'wb+')

child.logfile = fout

child.expect(['login:', 'Username'])

child.sendline('admin')

child.expect('(?i)ssword:')

child.sendline('%s' % passwd)

child.expect('' % name)

child.sendline('display current-configuration')

while index(child) == 0:

child.send(' ')

child.sendline('quit')

def ssh(name,ip,passwd):

#try:

child = pexpect.spawn('ssh admin@%s' % ip)

fout = open('/home/zxw/backup_conf/' + today + '/' + '%s_%s.txt' % (name, ip), 'wb+')

child.logfile = fout

child.expect('admin@%s\'s password:' % ip)

child.sendline('%s' % passwd)

child.expect('' % name)

child.sendline('display current-configuration')

while index(child) == 0:

child.send(' ')

child.sendline('quit')

def test_port(ip,port):

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s.settimeout(3)

host = (ip,port)

try:

s.connect(host)

s.close()

return 0

except Exception as e:

s.close()

return 1

def zip_dir(dir_name, zipfile_name):

f = zipfile.ZipFile(zipfile_name, 'w', zipfile.ZIP_DEFLATED)

for root, dirs, files in os.walk(dir_name):

for name in files:

f.write(os.path.join(root, name))

os.remove(os.path.join(root, name))

f.close()

os.rmdir(path)

today = datetime.date.today().strftime('%Y%m%d')

print('--------------------' + datetime.date.today().strftime('%Y-%m-%d') + '--------------------')

print('start backup task ... ')

path = '/home/zxw/backup_conf/' + today

if os.path.exists(path) != True:

os.mkdir(path,777)

config_path = './config.ini'

if os.path.exists(config_path):

config = configparser.ConfigParser(allow_no_value = True)

config.read(config_path)

dev_list = config.sections()

else:

print('Missing configuration files')

for device in dev_list:

get_cfg(device)

if sw_remote == 'ssh':

if test_port(sw_ip,22) == 0:

ssh(sw_name,sw_ip,sw_passwd)

print(': finished.' % sw_name)

else:

print('can not connect deivce:.' % sw_name)

elif sw_remote == 'telnet':

if test_port(sw_ip,23) == 0:

telnet(sw_name,sw_ip,sw_passwd)

print(': finished.' % sw_name)

else:

print('can not connect deivce:.' % sw_name)

zipfile_name = path + '.zip'

try:

zip_dir(path, zipfile_name)

print('compress the backup files successd.')

except IOError as e:

print(e)

print('finished backup task.')

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

#!/usr/bin/python

#coding:utf-8

# @Author: zhangxw

# @Blog: www.conum.cn

importpexpect

importsys

importdatetime

importos

importconfigparser

importsocket

importzipfile

defget_cfg(sw_tag):

globalsw_name,sw_ip,sw_passwd,sw_remote

#config = configparser.ConfigParser(allow_no_value = True)

#config.read(ini_file)

sw_name=config.get(sw_tag,'name')

sw_ip=config.get(sw_tag,'ip')

sw_passwd=config.get(sw_tag,'passwd')

sw_remote=config.get(sw_tag,'remote')

returnsw_name,sw_ip,sw_passwd,sw_remote

defindex(child):

name1='---- More ----'

index=child.expect([name1,''%sw_name])

returnindex

deftelnet(name,ip,passwd):

#try:

child=pexpect.spawn('telnet %s'%ip)

fout=open('/home/zxw/backup_conf/'+today+'/'+'%s_%s.txt'%(name,ip),'wb+')

child.logfile=fout

child.expect(['login:','Username'])

child.sendline('admin')

child.expect('(?i)ssword:')

child.sendline('%s'%passwd)

child.expect(''%name)

child.sendline('display current-configuration')

whileindex(child)==0:

child.send(' ')

child.sendline('quit')

defssh(name,ip,passwd):

#try:

child=pexpect.spawn('ssh admin@%s'%ip)

fout=open('/home/zxw/backup_conf/'+today+'/'+'%s_%s.txt'%(name,ip),'wb+')

child.logfile=fout

child.expect('admin@%s\'s password:'%ip)

child.sendline('%s'%passwd)

child.expect(''%name)

child.sendline('display current-configuration')

whileindex(child)==0:

child.send(' ')

child.sendline('quit')

deftest_port(ip,port):

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s.settimeout(3)

host=(ip,port)

try:

s.connect(host)

s.close()

return0

exceptExceptionase:

s.close()

return1

defzip_dir(dir_name,zipfile_name):

f=zipfile.ZipFile(zipfile_name,'w',zipfile.ZIP_DEFLATED)

forroot,dirs,filesinos.walk(dir_name):

fornameinfiles:

f.write(os.path.join(root,name))

os.remove(os.path.join(root,name))

f.close()

os.rmdir(path)

today=datetime.date.today().strftime('%Y%m%d')

print('--------------------'+datetime.date.today().strftime('%Y-%m-%d')+'--------------------')

print('start backup task ... ')

path='/home/zxw/backup_conf/'+today

ifos.path.exists(path)!=True:

os.mkdir(path,777)

config_path='./config.ini'

ifos.path.exists(config_path):

config=configparser.ConfigParser(allow_no_value=True)

config.read(config_path)

dev_list=config.sections()

else:

print('Missing configuration files')

fordeviceindev_list:

get_cfg(device)

ifsw_remote=='ssh':

iftest_port(sw_ip,22)==0:

ssh(sw_name,sw_ip,sw_passwd)

print(': finished.'%sw_name)

else:

print('can not connect deivce:.'%sw_name)

elifsw_remote=='telnet':

iftest_port(sw_ip,23)==0:

telnet(sw_name,sw_ip,sw_passwd)

print(': finished.'%sw_name)

else:

print('can not connect deivce:.'%sw_name)

zipfile_name=path+'.zip'

try:

zip_dir(path,zipfile_name)

print('compress the backup files successd.')

exceptIOErrorase:

print(e)

print('finished backup task.')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值