其他分享
首页 > 其他分享> > 2021-10-16

2021-10-16

作者:互联网

NetDevOps实践(一)华为CE交换机:基线检查——本机发往日志服务器的IP与设备的LoopBack 0下的IP进行对比

本文说明:

1、本篇文章部分借鉴了弈心《网路行者》实验思想,推荐移步阅读。
2、特别鸣谢:朱嘉盛,在我初学Python的道路上给予无私的帮助。以及他专栏内的文章给了我不少的灵感。
3、感谢现工作中同组的同事。

文章目录


前言

作为一名网络工程师,少不了每天跟路由器、交换机及他们的配置打交道。当我们在对设备进行基线检查时,我们大可以将设备配置进行导出,然后用notepad打开搜索关键字进行“人肉”比对。然而,这仅仅适用于小规模的网络拓扑,而面对稍微大一点的网络架构,我们将有可能会对100台、1000台甚至上万台设备进行相关的基线检查时,“人肉”核验的效率显得十分低下。下面我将用Python程序对不同的交换机的配置进行基线检查。

提示:以下是本篇文章正文内容,下面案例可供参考

一、需求

  1. 基线检查:核验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
#
  1. 如果需要检查多个交换机的配置文件,请在编写该Python文件的文件夹中新建一个文件夹用于存储交换机的配置文件。
    图1

二、思考与实践

笔者在实践中,一开始是利用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()方法对文件进行读取。

第一部分的程序执行结果如下图所示:
图2

Ⅱ.如何提取配置中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. 本文使用了不少的方法,为了加深印象,在这里我并提出几个问题。(1) 如何将字符串转换成列表?(2)如何将列表转换成字符串?(3)正则模块之中,可以运用什么方法进行关键词匹配?

本文作者为Python初学者,若对程序有疑问,请在文章下方留言。大手勿喷,谢谢。

标签:10,keyword,16,ip,interface,LoopBack0,2021,IP,print
来源: https://blog.csdn.net/qq_37316868/article/details/120801673