美文网首页银狐NetDevOps
银狐NetDevOps-网络运维python指南之自动生成yam

银狐NetDevOps-网络运维python指南之自动生成yam

作者: 科技银狐 | 来源:发表于2021-06-24 20:26 被阅读0次
    科技银狐

    01 前言

    前段时间分享了华为NETCONF结合协程gevent,在大规模数据中心自动化批量操作的方法,不过我忽略了两个问题,一个是协程gevent的加入会让排错难度大幅提升,导致很多小伙伴自己应用时无限掉坑被逼疯,第二是gevent在windows环境下总会出现莫名其妙的问题,而很多使用者对linux又不算熟悉,最终导致很多人使用gevent并不顺利。

    秉着简单易用的原则,我重新研究了下nornir这个专为网络而生的模块,个人感觉3000台以下网络设备的简单跑批操作使用nr就可以了。相比于ansible来说这个模块在效率和灵活性上都有质的飞跃,相比协程+api的方式又简单了许多,相比单独的netmiko模块又有更多的优化。所以中小规模企业推荐直接使用nornir。nornir的基础知识王印老师(知乎@弈心)已经做过介绍,华为安装的一些坑朱嘉盛老师也介绍过,这些内容直接在知乎搜索即可,我就不重复介绍了。

    虽然nr模块确实非常好用,但从实践的角度我发现一个问题,就是从现有的资料来看并不适合大规模跑批操作,因为网上分享的内容(包括官方案例)都有一个问题,就是nr模块强依赖hosts.yaml这个文件,但没人强调如何大批量导入资产信息到这个yaml文件内,如果你有1000台设备,按照yaml格式一个一个输入到yaml文件里手都要断了,所以我手写了一个自动生成hosts.yaml+nr跑批的py脚本,这样在大规模场景下更加实用。

    02 实现逻辑

    1. 简化hosts.yaml内部配置,只保存设备名称和IP地址(yaml内的hostname),用户名、密码、platform全放在defaults.yaml中,不使用group.yaml(想使用也可以,因为我这个内容主要是HUAWEI,没有第二个厂商,所以不需要)。
    config.yaml
    
    ---
    inventory:
        plugin: SimpleInventory
        options:
            host_file: "hosts.yaml"
            defaults_file: "defaults.yaml"
    runner:
        plugin: threaded
        options:
            num_workers: 20
    
    
    defaults.yaml
    
    ---
    username: user
    password: pass
    platform: huawei_vrpv8
    
    
    1. 读取excel内容(excel内容如下:),形成dict,在用dict专为yaml文件,生成hosts.yaml,再使用nornir进行跑批操作。

    03 代码示例

    #!/usr/bin/env python
    #coding: utf-8
    
    import os
    from pprint import pprint
    from ruamel import yaml
    #ruamel.yaml用来读写yaml文件
    from openpyxl import Workbook
    from openpyxl import load_workbook
    from collections import defaultdict
    #使用defaultdict必须导入
    from nornir import InitNornir
    from nornir_netmiko import netmiko_send_command
    from nornir_utils.plugins.functions import print_result,print_title
    
    def read_device_excel():
        current_path = os.path.abspath(".")
        devices_filename = current_path + "/info02.xlsx"
        wb1 = load_workbook(devices_filename)
        ws1 = wb1.get_sheet_by_name("device list")
        device_dict = defaultdict(dict)
    
        for cow_num in range(2,ws1.max_row+1):
            device_dict[ws1["a"+str(cow_num)].value.strip()]["hostname"]=ws1["b"+str(cow_num)].value.strip()
        return (dict(device_dict))
    
    def dict_to_yaml(yaml_file):
        device_dict = read_device_excel()
        with open(yaml_file, 'w', encoding='utf-8') as file:
            file.write("---\\n")
            yaml.dump(device_dict, file, Dumper=yaml.RoundTripDumper)
    
    def main():
        current_path = os.path.abspath(".")
        yaml_path = os.path.join(current_path, "hosts.yaml")
        dict_to_yaml(yaml_path)
    
        nr = InitNornir(config_file="config.yaml", dry_run=True)
        results = nr.run(netmiko_send_command, command_string='disp ver') 
        print_result(results)
    
    #===========================================================
    # 读取excel内容自动生成hosts.yaml文件,再使用nr进行跑批操作
    #===========================================================
    if __name__ == '__main__':
        main()
    
    

    执行结果(示例我就执行了1台)

    netmiko_send_command************************************************************
    * SHM-RO4-POD2-1 ** changed : False ********************************************
    vvvv netmiko_send_command ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO
    Huawei Versatile Routing Platform Software
    VRP (R) software, Version 8.150 (CE6851HI V200R002C50SPC018T)
    Copyright (C) 2012-2017 Huawei Technologies Co., Ltd.
    HUAWEI CE6851-48S6Q-HI uptime is 1476 days, 2 hours, 26 minutes
    
    CE6851-48S6Q-HI(Master) 1 : uptime is  1476 days, 2 hours, 25 minutes
            StartupTime 2017/06/09   14:44:20
    Memory    Size    : 2048 M bytes
    Flash     Size    : 1024 M bytes
    CE6851-48S6Q-HI version information
    1\. PCB    Version : CEM48S6QP04    VER B
    2\. MAB    Version : 1
    3\. Board  Type    : CE6851-48S6Q-HI
    4\. CPLD1  Version : 103
    5\. CPLD2  Version : 103
    6\. BIOS   Version : 383
    ^^^^ END netmiko_send_command ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    

    04 代码详解

    def read_device_excel():
        current_path = os.path.abspath(".")
        devices_filename = current_path + "/info02.xlsx"
        wb1 = load_workbook(devices_filename)
        ws1 = wb1.get_sheet_by_name("device list")
        device_dict = defaultdict(dict)
    
        for cow_num in range(2,ws1.max_row+1):
            device_dict[ws1["a"+str(cow_num)].value.strip()]["hostname"]=ws1["b"+str(cow_num)].value.strip()
        return (dict(device_dict))
    
    

    看过我分享的都比较熟悉上面的代码了,就不做介绍了,主要说下defaultdict(dict),这个可以用作嵌套dict,比如要根据已知内容生成{'SHM-RO4-POD2-1': {'hostname': '10.13.0.224'}},那我们就用for循环遍历excel内容,然后以A列为key,hostname:B列内容作为value,生成嵌套dict。

    def dict_to_yaml(yaml_file):
        device_dict = read_device_excel()
        with open(yaml_file, 'w', encoding='utf-8') as file:
            file.write("---\\n")
            yaml.dump(device_dict, file, Dumper=yaml.RoundTripDumper)
    
    

    使用yaml.dump()方法将dict内容以标准yaml格式写入hosts.yaml文件,注意需要加参数Dumper=yaml.RoundTripDumper。

    生成的hosts.yaml

    ---
    SHM-RO4-POD2-1:
      hostname: 10.13.0.224
    SHM-RO4-POD2-2:
      hostname: 10.13.0.225
    SHM-RO4-POD2-3:
      hostname: 10.13.0.226
    SHM-RO4-POD2-4:
      hostname: 10.13.0.227
    
    
    def main():
        current_path = os.path.abspath(".")
        yaml_path = os.path.join(current_path, "hosts.yaml")
        dict_to_yaml(yaml_path)
    
        nr = InitNornir(config_file="config.yaml", dry_run=True)
        results = nr.run(netmiko_send_command, command_string='disp ver') 
        # results = nr.run(task=napalm_get, getters=["facts"])   #napalm API不好用
        print_result(results)
    
    

    主函数很简单,调用生成yaml文件的方法,然后使用Nornir进行跑批操作。

    相关文章

      网友评论

        本文标题:银狐NetDevOps-网络运维python指南之自动生成yam

        本文链接:https://www.haomeiwen.com/subject/vwygyltx.html