python网络设备信息自动化采集\对比

一、背景
最近在实施变更时需要采集多台设备信息,用于在实施完毕后对设备状态进行检查。由于人工采集比较耗时,在网上找了一下没找到自动采集的脚本,就用python写了个网络设备信息自动化信息采集脚本,在实施变更前后抓取相关设备信息,实施完成后自动对比前后变化情况。

二、使用提示
1、将设备信息填写在dev_ins.csv表格(表格内容见下图),只支持ssh,思科设备需要输入enable的在enpass列输入enable密码,不需要则不写

2、需要采集信息命令在对应设备下方填写

3、第一条命令为将设备修改全部输出不限制输出行数,否则输出信息不完整

4、目前只适配了Cisco_IOS、H3C_SW、H3C_FW,如有其他设备需求可自行增加
在表格增加相关命令,在代码修改如下变量(fac\cmd),cmdread[9] 数字9与表格列数相对应(从0开始数)
在代码中修改如下变量:

    if fac == "H3C_SW":
        for cmdread in islice(cmd_file, 1, None):
            cmd += cmdread[9] + chr(10)

5、csv表格内不要写中文

6、csv表格与脚本需要放在同一个文件夹执行

7、第一次采集与第二次采集时间如果不是同一天,在信息比对时需要修改文件名称为同一天

8、第一次采集与第二次采集信息比对时,是通过csv表格里面的IP地址来确认比对对象

9、测试环境python3.9

构造如下csv表格:
构造一个如图的dev_ins.csv表格,和脚本放在同一个文件夹

完整代码如下:

import csv
import os
import paramiko
import time
import sys
import difflib
import datetime
from itertools import islice
from datetime import datetime, date, timedelta


now = str(date.today())
filename = 'dev_ins.csv'  # 设备信息、执行命令表格名称
path_before = 'C:/check/collect_info/' + now + '/' + 'before'  # 第一次采集信息保存路径
path_after = 'C:/check/collect_info/' + now + '/' + 'after'  # 第二次采集信息保存路径
path_compare = 'C:/check/result_comp/'  # 第一次第二次采集信息比对结果保存路径


def check_path():
    isExists_before = os.path.exists(path_before)
    isExists_after = os.path.exists(path_after)
    isExists = os.path.exists(path_compare)
    if not isExists_before:
        os.makedirs(path_before)
    if not isExists_after:
        os.makedirs(path_after)
    if not isExists:
        os.makedirs(path_compare)


def ssh_login():
    cache = []
    global host
    global fac
    global login
    global user
    global passw
    global enpass
    global ssh
    global channel
    set_interval_time()
    print('开始采集设备信息....')
    cmd_file = csv.reader(open(filename, 'r', encoding='UTF-8'))
    for line in islice(cmd_file, 1, None):
        if line[0] != "":
            cache.append(line[0:6])
    for hostread in cache:
        host = hostread[0]
        fac = hostread[1]
        login = hostread[2]
        user = hostread[3]
        passw = hostread[4]
        enpass = hostread[5]
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        try:
            ssh.connect(hostname=host, port=22, username=user, password=passw, timeout=3)
        except BaseException as e:
            print('{0} 登录失败,请确认账户密码\网络连通性!!!'.format(host), e, '\n')
            log = host + '登录失败,请确认账户密码\网络连通性!!!\t' + str(e) + '\t' + str(datetime.now())+'\n'
            with open(path_before + '/' + 'faillog.txt', "a+", encoding='UTF-8') as rfile:
                rfile.write(log)
            continue
        channel = ssh.invoke_shell()
        print(host + '    ' + 'collecting' + '    ' + 'information' + '    ' + 'start')
        collect_info()
        format_txt()
    print('信息采集完成,保存路径:{0}/'.format(file_save_path))
    input('按任意键返回菜单')


def collect_info():
    cmd = ''
    global cmdread
    channel.send(chr(13))
    cmd_file = csv.reader(open(filename, 'r', encoding='UTF-8'))
    if fac == "Cisco_IOS":
        # 如果dev_ins.csv表格中enpass列不为空则输入enable密码
        if enpass:
            channel.send('enable' + chr(13))
            channel.send(enpass + chr(13))
        for cmdread in islice(cmd_file, 1, None):  # 读取表格中的命令到cmd变量
            cmd += cmdread[8] + chr(10)
        ssh_exec(cmd)  # 执行cmd命令
    if fac == "H3C_SW":
        for cmdread in islice(cmd_file, 1, None):
            cmd += cmdread[9] + chr(10)
        ssh_exec(cmd)
    if fac == "H3C_FW":
        for cmdread in islice(cmd_file, 1, None):
            cmd += cmdread[10] + chr(10)
        ssh_exec(cmd)
    ssh.close()
    return


def ssh_exec(cmd):
    global file_save_path
    if flage == 1:
        file_save_path = path_before
    elif flage == 2:
        file_save_path = path_after
    if cmd:
        channel.send(cmd)
        time.sleep(interval_time)  # 执行cmd命令后等待结果输出,时间间隔设置太短会导致输出不完整,
                                   # 程序就结束了,通常配置不是太多的情况下3S内即可
        output = channel.recv(4096000).decode(encoding='gbk')  # 输出结果里面包含中文,编码用的gbk
        if cmdread[8] not in output:  # 检查最后一条命令是否在输出结果里面
            print('采集配置不完整,请调大间隔时间后重试。')
            sys.exit()
    with open(file_save_path + '/' + host + ".txt", "a+", encoding='gbk') as rfile:
        rfile.write(output)
    print(host + '    ' + 'collecting' + '    ' + 'information' + '    ' + 'stop' + '\n')


def set_interval_time():
    global interval_time
    fla = 0
    interval_time = 2
    answer = input('是否修改命令执行间隔时间(默认为{0}s)y/n:'.format(interval_time))
    while True:
        if fla == 1:
            break
        if answer == 'y':
            try:
                interval_time = float(input('请输入间隔时间(s):'))
            except BaseException:
                print('输入有误,请重新输入!')
            else:
                fla = 1
        else:
            fla = 1
    return


def format_txt():  # 输出结果空行太多,将空行去掉
    global comp_path
    if flage == 1:
        comp_path = path_before
    elif flage == 2:
        comp_path = path_after
    with open(comp_path + '/' + host + '.txt', "r", encoding='gbk') as rfile:
        line = rfile.read()
        line = line.replace('\n', '&')
        with open(comp_path + '/' + host + '.txt', "w", encoding='gbk') as dfile:
            line = line.replace('&&&', '\n')
            line = line.replace('&&', '\n')
            line = line.replace('&', '\n')
            dfile.write(line)
    return


def comp_read_file(file_name):
    try:
        file_desc = open(file_name, 'r', encoding='utf-8')
        text = file_desc.read().splitlines()
        file_desc.close()
        return text
    except IOError as error:
        print('文件读取失败,请确认文件是否存在!{0}'.format(error))
        input('按任意键退出。')
    sys.exit()


def comp_file(file1, file2):
    global result_fiel
    if file1 == "" or file2 == "":
        print('文件不存在,请先收集信息!\n第一个文件的路径:{0}, 第二个文件的路径:{1} .'.format(file1, file2))
        sys.exit()
    text1_lines = comp_read_file(file1)
    text2_lines = comp_read_file(file2)
    diff = difflib.HtmlDiff()
    result = diff.make_file(text1_lines, text2_lines, context=True, charset='utf-8')  
    today = str(date.today())
    result_fiel = path_compare + comp_ip + '-' + today + '.html'
    try:
        with open(path_compare + '/' + comp_ip + '-' + today + '.html', 'w', encoding='UTF-8') as result_file:  # 输出检查结果
            result_file.write(result)
    except IOError as error:
        print('写入错误:{0}'.format(error))


def compare():
    cache = []
    global comp_ip
    host_file = csv.reader(open(filename, 'r', encoding='UTF-8'))
    for line in islice(host_file, 1, None):
        if line[0] != "":
            cache.append(line[0])
    print("开始对比设备信息....")
    for comp_ip in cache:
        today = str(date.today())
        path_today = 'C:/check/collect_info/' + today + '/'
        file_before = path_today + 'before' + '/' + comp_ip + '.txt'
        file_after = path_today + 'after' + '/' + comp_ip + '.txt'
        print('正在检查:' + comp_ip)
        print('文件1名称:' + file_before)
        print('文件2名称:' + file_after + '\n')
        comp_file(file_before, file_after)
    print("对比完毕,结果见附件:{0}".format(result_fiel))
    input('按任意键返回菜单')


def menu():
    print('==============网络设备基线配置采集===============')
    print('(请确认需要采集设备信息是否已导入dev_ins.csv表格)')
    print('1、实施前设备配置、状态信息采集')
    print('2、实施后设备配置、状态信息采集')
    print('3、对比实施前后设备配置、状态')
    print('0、退出')
    print('==============================================')


def main():
    check_path()
    global flage
    while True:
        menu()
        try:
            flage = int(input('请选择:'))
        except BaseException:
            continue
        if flage == 1 or flage == 2:
            ssh_login()
        elif flage == 3:
            compare()
        elif flage == 0:
            break
        else:
            continue
    return


if __name__ == "__main__":
    main()


  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
网络设备配置采集是指通过使用Python编写的网络爬虫脚本,自动从网络设备中提取配置信息。这样可以节省人工采集的时间,并且可以在实施变更前后对比设备配置的变化情况。\[1\] 在Python中,可以使用BeautifulSoup库来解析HTML或XML,从网页中提取所需的数据。这个库提供了强大的API和多种解析方式,可以方便地从网页中提取设备配置信息。\[2\] 网络爬虫是一种按照一定规则自动抓取网页信息的程序或脚本。它可以根据网页的链接地址自动获取网页内容。网络爬虫可以用于搜索引擎的数据采集、金融数据采集、商品数据采集、竞争对手的客户数据采集等多种用途。\[3\] 因此,通过编写Python网络爬虫脚本,可以实现自动采集网络设备的配置信息。这样可以提高效率,并且可以方便地对比设备配置的变化情况。 #### 引用[.reference_title] - *1* [python网络设备信息自动化采集\对比](https://blog.csdn.net/weixin_41748039/article/details/126306627)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Python 网络爬虫与数据采集(一)](https://blog.csdn.net/weixin_45529272/article/details/122755705)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值