python实验10 ⾃动检测⽹络配置变化
Posted 睡着的冰淇淋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python实验10 ⾃动检测⽹络配置变化相关的知识,希望对你有一定的参考价值。
实验运行环境
实验背景
在⽇常⽹络运维⼯作中,对⽹络设备的配置做备份,知道⽹络设备的配置被做了哪些改动,是⼀个⽹⼯最基本的⼯作。虽然这⼀⽬标可以⽤安全审计或者部署⼀些NMS软件来实现,但不是每家公司都有精⼒和预算来购买和布置的。
实验目的
使⽤difflib模块实现对每天的⽹络配置做⽐较,找出配置变化,并通过smtplib和email将报告从我这的QQ邮箱发送⾄我们指定的⽹易邮箱。 email负责构造邮件,stmplib负责发送。
difflib模块
Difflib是Python中内置的模块,功能强大也很复杂。
我们可以借助它其中的ndiff()函数来对两个字符串列表(注意是列表)里的内容做比较,进而找出它们之间的差异。
ndiff()返回的值是一个differ形式的生成器(generator),对我们网工来说,我们可以将交换机昨天和今天备份好的配置文件分别用open()函数打开,然后调用readlines()将两个配置文件里的文本内容转化为字符串列表,然后对它们使用difflib.ndiff()即可找出它们之间的差异,然后用list()函数将ndiff()返回的generator转换成列表,然后再配合for循环遍历该列表里的内容,将它们一一写入另外一个用作报告的文本文件中即可。
在使用difflib对交换机配置文件做对比时,有四种情况是需要我们注意的:
- 昨天(或之前)的某个已有的配置在今天的配置中被删除了
- 昨天(或之前)的某个没有的配置在今天的配置中被添加了
- 昨天(或之前)的某个配置在今天的配置中被改动了(字符长度没有变或者变短了)
- 昨天(或之前)的某个配置在今天的配置中被改动了(字符长度变长了)
下面一一举例说明:
- 昨天(或之前)的某个已有的配置在今天的配置中被删除了
比如说之前交换机里配置了一个叫做python,特权级别为15,密码为123的用户名:
username python privilege 15 password 0 123
昨天有人在交换机里输入了no username python将该用户名删除了,那么在我们调用difflib.ndiff()对昨天和今天的配置文件做对比后生成的报告中,该变化会被ndiff()显示如下(注意前面的减号“-”以及“-”后面的空格)
- username python privilege 15 password 0 123
2. 昨天(或之前)的某个没有的配置在今天的配置中被添加了
比如说我们之前在交换机的Gi0/0端口下面并没有配置duplex full:
interface GigabitEthernet0/0
no switchport
ip address 10.1.1.1 255.255.255.0
昨天有人在该端口下添加了duplex full这条命令,那么在我们调用difflib.ndiff()对昨天和今天的配置文件做对比后生成的报告中,该变化会被ndiff()显示如下(注意前面的加号“+”以及“+”后面的空格)
interface GigabitEthernet0/0
no switchport
+ duplex full
ip address 10.1.1.1 255.255.255.0
3. 昨天(或之前)的某个配置在今天的配置中被改动了(字符长度没有变或者变短了)
假设我们之前交换机的Gi0/1端口下面的IP地址为100.100.100.100:
interface GigabitEthernet0/1
no switchport
ip address 100.100.100.100 255.255.255.0
昨天有人将该端口的IP改为了100.100.100.199(字符长度没有改变),那么在我们调用difflib.ndiff()对昨天和今天的配置文件做对比后生成的报告中,该变化会被ndiff()显示如下(注意旧配置前的减号“-”和下面的问号“?”,以及新配置前的加号“+”和下面的问号“?”,问号后面指示配置具体改变位置的“^”符号不是我们脚本代码需要关心的)
- ip address 100.100.100.100 255.255.255.255
? ^^
+ ip address 100.100.100.199 255.255.255.255
?
如果昨天有人将Gi0/1的IP地址改为了100.100.100.1,(字符长度变短了),那么在我们调用difflib.ndiff()对昨天和今天的配置文件做对比后生成的报告中,该变化会被ndiff()显示如下(同样注意旧配置前的减号“-”和下面的问号“?”,以及新配置前的加号“+”和下面的问号“?”)
- ip address 100.100.100.100 255.255.255.255
? ^^
+ ip address 100.100.100.1 255.255.255.255
? ^
4. 昨天(或之前)的某个配置在今天的配置中被改动了(字符长度变长了)
假设我们之前交换机的Gi0/0端口下面的IP地址为10.1.1.1:
interface GigabitEthernet0/0
no switchport
ip address 10.1.1.1 255.255.255.0
昨天有人将该端口的IP改为了10.1.1.100(字符长度变长了),那么在我们调用difflib.ndiff()对昨天和今天的配置文件做对比后生成的报告中,该变化会被ndiff()显示如下(注意旧配置前的减号“-”以及新配置前的加号“+”和下面的问号“?”,问号后面指示配置具体改变位置的“++”符号不是我们脚本代码需要关心的)
- ip add 192.168.1.1 255.255.255.0
+ ip add 192.168.1.100 255.255.255.0
? ++
实验准备
在77/65行的QQ邮箱的密码需要用上面的授权码替代
由于发送的⽂件中含有中⽂,需要将stmplib模块的源代码的859⾏,ascii改成utf-8
⽹易stmp邮件默认编码解码不是utf-8,也需要修改过来
实验脚本1
代码在异步代码的基础上进⾏修改
(好像有点问题)
import difflib #内置模块,可以借助它其中的ndiff()函数来对两个字符串列表(注意是列表)⾥的内容做⽐较,进⽽找出它们之间的差异,ndiff()返回的值是⼀个differ形式的⽣成器(generator)
import asyncio
import netdev
import datetime #内置模块
import time
import smtplib
from email6.mime.multipart import MIMEMultipart #MIMEMultipart⽤来构建邮件
from email6.mime.text import MIMEText #MIMETex代表邮件的内容
device_list=["192.168.2.11","192.168.2.12","192.168.2.13"]
async def task(dev):
async with netdev.create(**dev) as ios:
commands=["do term len 0\\n","do show run\\n"]
output=await ios.send_config_set(commands)
# datetime.date.today().isoformat()来以yyyy-mm-dd的格式来显示今天的日期,比如2020-09-07,注意返回值的类型为字符串
#如果显示昨天的日期,可以使用(datetime.date.today() - datetime.timedelta(days=1)).isoformat()
with open(dev.get(host)+_+datetime.date.today().isoformat(),w+) as new_file,open(dev.get(host)+_+(datetime.date.today()-datetime.timedelta(days=1)).isoformat()) as old_file:
new_file.write(output)
new_file.close() #不关闭刚才写入的文本不会被保存
new_file=open(dev.get(host)+_+datetime.date.today()) #再次打开new_file,调用difflib.ndiff()对old_file.readlines()和new_file.readlines()做对比
diff=list(difflib.ndiff(old_file.readlines(),new_file.readlines())) #注意昨天的配置文件(old_file)要写在difflib.ndiff()里的左边,今天的配置文件(new_file)要写在右边,将返回的值以列表的形式赋值给函数diff
try:
with open(dev.get(host)+_+datetime.date.today().isoformat()+_report,w) as report_file:
for index,line in enumerate(diff): #enumerate是将⼀个可遍历的对象组合成⼀个索引序列
if line.startswith(- ) and diff[index + 1].startswith((?, +)) == False:
report_file.write(\\n已被移除的旧配置: + \\n\\n + line + \\n----------------\\n\\n)
elif line.startswith(+ ) and diff[index + 1].startswith(?) == False:
report_file.write(\\n已被添加的新配置: + \\n\\n + ...\\n + diff[index - 2] + diff[index - 1] + line + ...\\n + \\n----------------\\n)
elif line.startswith(- ) and diff[index + 1].startswith(?) and diff[index + 2].startswith(+ ) and diff[index + 3].startswith(?):
report_file.write(\\n已被修改的配置(长度不变或变短): \\n\\n + line + diff[index +以上是关于python实验10 ⾃动检测⽹络配置变化的主要内容,如果未能解决你的问题,请参考以下文章