python实验10 ?动检测?络配置变化

丈夫欲遂平生志,一载寒窗一举汤。这篇文章主要讲述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对交换机配置文件做对比时,有四种情况是需要我们注意的:

  1. 昨天(或之前)的某个已有的配置在今天的配置中被删除了
  2. 昨天(或之前)的某个没有的配置在今天的配置中被添加了
  3. 昨天(或之前)的某个配置在今天的配置中被改动了(字符长度没有变或者变短了)
  4. 昨天(或之前)的某个配置在今天的配置中被改动了(字符长度变长了)
下面一一举例说明:
  1. 昨天(或之前)的某个已有的配置在今天的配置中被删除了
比如说之前交换机里配置了一个叫做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代码在异步代码的基础上进?修改
【python实验10 ?动检测?络配置变化】(好像有点问题)
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 +

    推荐阅读