银狐NetDevOps-网络运维python指南之自动生成yaml文件+华为nornir批量操作

科技银狐

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进行跑批操作。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容