2021-10-16
作者:互联网
NetDevOps实践(一)华为CE交换机:基线检查——本机发往日志服务器的IP与设备的LoopBack 0下的IP进行对比
本文说明:
1、本篇文章部分借鉴了弈心《网路行者》实验思想,推荐移步阅读。
2、特别鸣谢:朱嘉盛,在我初学Python的道路上给予无私的帮助。以及他专栏内的文章给了我不少的灵感。
3、感谢现工作中同组的同事。
文章目录
前言
作为一名网络工程师,少不了每天跟路由器、交换机及他们的配置打交道。当我们在对设备进行基线检查时,我们大可以将设备配置进行导出,然后用notepad打开搜索关键字进行“人肉”比对。然而,这仅仅适用于小规模的网络拓扑,而面对稍微大一点的网络架构,我们将有可能会对100台、1000台甚至上万台设备进行相关的基线检查时,“人肉”核验的效率显得十分低下。下面我将用Python程序对不同的交换机的配置进行基线检查。提示:以下是本篇文章正文内容,下面案例可供参考
一、需求
- 基线检查:核验info-center loghost这行配置中的 source-ip(下文简称loghost_sip)是否跟LoopBack0下配置的IP是否一致。(下述仅为一台交换机中的部分需要检查的基线配置)
#
info-center loghost 192.168.10.1 public-net source-ip 2.2.2.2 channel 6 port 27381
#
router id 2.2.2.2
#
interface LoopBack0
description Router-ID
ip address 2.2.2.2 255.255.255.255
#
- 如果需要检查多个交换机的配置文件,请在编写该Python文件的文件夹中新建一个文件夹用于存储交换机的配置文件。
二、思考与实践
笔者在实践中,一开始是利用Router-id后的IP与loghost_sip进行对比(因为一开始我实在想不到该如何提取LoopBack0接口下的IP,使用正则表达式连掩码都给我匹配出来了),但是同时我又考虑到,我们在日常的配置中,一般是先配置LoopBack0接口然后再配置Router-id的,但如果Router-id在配置过程中就已经出现错误了,那么将会导致本次基线检查的结果也会出现一定的错误。为了更合理的完成需求,我还是决定使用LoopBack0下的IP与loghost_sip进行配置检查。
Ⅰ. (1)如何获取文件的名称?(2)如何打开文件?(3)如何获取文件中的内容?
代码如下所示:import os
Folder = os.listdir('Configration') #获取系统中装着交换机配置的Configuration文件夹的位置,并将位置赋予Folder变量
for document in Folder: #使用For循环语句遍历文件夹中的所有文件
print(document) #测试是否能够输出交换机配置文件的名称
with open('Configuration'+'\\'+document,'r',encoding = "utf-8") as file:
#上述语句表示以“读”的方式,编码“utf-8”打开文件
lines = file.readlines() #将文件内容转换成一个列表
print(lines) #测试数据类型
参阅了书籍和网络上相关的资料之后,我发现可以使用os中的listdir()方法来获取当前文件的位置。获取到文件的位置之后,使用for语句进行循环,并使用print(document)来测试。此处输出的结果为文件名称。而获取文件名称之后,使用了with open() as f:的语句来打开文件,最后并用readlines()方法对文件进行读取。
第一部分的程序执行结果如下图所示:
Ⅱ.如何提取配置中info-center这一行的命令中的loghost_sip
注:第二部分程序运行逻辑与第一部分程序相关联。
import re
keyword_public_net = 'public-net'
keyword_source_ip = 'source-ip '
'''
注意细节,因为命令中source-ip后含有一个空格才是IP地址。所以要在'source-ip'这个关键字的字符串后加一个空格,否则将会导致第四部分的程序运行时
出现偏差。
'''
keyword_channel = ' channel' #注意细节,因为命令中channel前含有一个空格才是IP地址。原因同上。
(第一部分程序,此处略)
for line in lines: #遍历转换成配置列表中的元素,可以理解为循环配置文件中的每行命令
#print(line.strip())
if keyword_public_net in line: #调用if语句进行判断,将拥有关键字'public-net'的命令行放入变量command_1之中
#print(line)
command_1 = line
#print(command_1)
result_1 = re.compile(keyword_source_ip + '(.*)' + keyword_channel,re.S)
#定义一个关键字匹配规则,匹配命令中source-ip和channel中间的IP。re.S(re.DOTALL)表示匹配换行符在内的所有字符串。
ip_address_1 = result_1.findall(command_1) #使用定义的规则result_1匹配得到loghost_sip
#print(ip_address_1) #输出查看一下ip_address_1的数据类型,结果为列表
ip_1 = ''.join(ip_address_1) #将得到的列表转换成字符串
print('发往日志服务器的IP为: '+ip_1)
查看配置(代指整份交换机配置,并非需求中的几行配置)我发现,配置中的这条命令有一个独一无二的关键词,就是’public-net’,我打算先使用关键词’public-net’把这条配置命令先进行抓取,然后再使用正则表达式匹配source-ip和channel中的IP地址。
Ⅲ.如何提取配置中Loopback0接口下的IP?
注:第三部分程序运行逻辑与第一、二部分程序相关联。
keyword_interface_loop0 = 'interface LoopBack0\n'
#定义带有'interface LoopBack0\n'的关键字变量,由于实际中还有其他配置命令与interface LoopBack0一样,所以我在后面加了一个换行符
注:第一第二部分程序略。
for line in lines:
if keyword_interface_loop0 in line: #目的为了抓取含有interface LoopBack0配置命令的行
loopback0_index = lines.index(keyword_interface_loop0) #获取interface LoopBack0命令行的索引
loopback0_ip_index = lines[loopback0_index+2] #提取interface LoopBack0接口下第二行的配置
lo0_ip_cmd_list = loopback0_ip_index.split() #转换成列表,抓取Loop0_IP
ip_2 = lo0_ip_cmd_list[2]
print('本设备的LoopBack0的IP为:'+ip_2)
这里利用了index()方法,定位Loop0这行命令在配置中的位置,因为我们这儿在接口下要求有description(描述),所以将抓取到的Loop0索引+2获得Loop0接口下的IP配置命令,然后将此命令转换成为列表,提取真正的Loop0的IP。
Ⅳ.比较loghost_sip与Loop0下的IP是否一致。
注:第四部分程序运行逻辑与前面一、二、三部分程序相关联。
if ip_1 == ip_2: #如果抓取到的两个IP相等,则基线核查无误。
print('发往日志服务器的源IP与LoopBack0接口下的IP相等')
if ip_1 != ip_2: #如果抓取到的两个IP不相等,则判断有误。
print('Warning:发往日志服务器的源IP与LoopBack0接口下的IP不相等,请登录设备进行核实')
print('-'*100) #为了使输出的结果更直观。所以使用横线进行分隔
程序总览
import os
import re
keyword_public_net = 'public-net'
keyword_source_ip = 'source-ip '
keyword_channel = ' channel'
keyword_interface_loop0 = 'interface LoopBack0\n'
Folder = os.listdir('Configuration')
for document in Folder:
print(document)
with open('Configuration'+'\\'+document,'r',encoding = "utf-8") as file:
lines = file.readlines() #将文件内容转换成一个列表
for line in lines:
if keyword_public_net in line:
command_1 = line
result_1 = re.compile(keyword_source_ip + '(.*)' + keyword_channel,re.S)
ip_address_1 = result_1.findall(command_1)
ip_1 = ''.join(ip_address_1) #将得到的列表转换成字符串
print('发往日志服务器的IP为: '+ip_1)
for line in lines:
if keyword_interface_loop0 in line:
loopback0_index = lines.index(keyword_interface_loop0)
loopback0_ip_index = lines[loopback0_index+2]
lo0_ip_cmd_list = loopback0_ip_index.split()
ip_2 = lo0_ip_cmd_list[2]
print('本设备的LoopBack0的IP为:'+ip_2)
if ip_1 == ip_2:
print('发往日志服务器的源IP与LoopBack0接口下的IP相等')
if ip_1 != ip_2:
print('Warning:发往日志服务器的源IP与LoopBack0接口下的IP不相等,请登录设备进行核实')
print('-'*100)
程序运行结果显示
总结
-
作为初学者,在离开书本后,拿到第一个需求的时,我们总会感觉实现是一件非常困难的事情。这是,我们可以基于当前学到的知识进行需求拆解,将一个需求拆分成几个在我们预期中可以达到的小目标,并各个击破。
-
本文使用了不少的方法,为了加深印象,在这里我并提出几个问题。(1) 如何将字符串转换成列表?(2)如何将列表转换成字符串?(3)正则模块之中,可以运用什么方法进行关键词匹配?
标签:10,keyword,16,ip,interface,LoopBack0,2021,IP,print 来源: https://blog.csdn.net/qq_37316868/article/details/120801673