銀狐NetDevOps-網(wǎng)絡(luò)運維python指南之自動生成yaml文件+華為nornir批量操作

科技銀狐

01 前言

前段時間分享了華為NETCONF結(jié)合協(xié)程gevent,在大規(guī)模數(shù)據(jù)中心自動化批量操作的方法,不過我忽略了兩個問題文虏,一個是協(xié)程gevent的加入會讓排錯難度大幅提升节视,導(dǎo)致很多小伙伴自己應(yīng)用時無限掉坑被逼瘋,第二是gevent在windows環(huán)境下總會出現(xiàn)莫名其妙的問題益楼,而很多使用者對linux又不算熟悉猾漫,最終導(dǎo)致很多人使用gevent并不順利。

秉著簡單易用的原則感凤,我重新研究了下nornir這個專為網(wǎng)絡(luò)而生的模塊悯周,個人感覺3000臺以下網(wǎng)絡(luò)設(shè)備的簡單跑批操作使用nr就可以了。相比于ansible來說這個模塊在效率和靈活性上都有質(zhì)的飛躍陪竿,相比協(xié)程+api的方式又簡單了許多禽翼,相比單獨的netmiko模塊又有更多的優(yōu)化。所以中小規(guī)模企業(yè)推薦直接使用nornir族跛。nornir的基礎(chǔ)知識王印老師(知乎@弈心)已經(jīng)做過介紹闰挡,華為安裝的一些坑朱嘉盛老師也介紹過,這些內(nèi)容直接在知乎搜索即可礁哄,我就不重復(fù)介紹了长酗。

雖然nr模塊確實非常好用,但從實踐的角度我發(fā)現(xiàn)一個問題桐绒,就是從現(xiàn)有的資料來看并不適合大規(guī)模跑批操作夺脾,因為網(wǎng)上分享的內(nèi)容(包括官方案例)都有一個問題,就是nr模塊強依賴hosts.yaml這個文件茉继,但沒人強調(diào)如何大批量導(dǎo)入資產(chǎn)信息到這個yaml文件內(nèi)咧叭,如果你有1000臺設(shè)備,按照yaml格式一個一個輸入到y(tǒng)aml文件里手都要斷了烁竭,所以我手寫了一個自動生成hosts.yaml+nr跑批的py腳本菲茬,這樣在大規(guī)模場景下更加實用。

02 實現(xiàn)邏輯

  1. 簡化hosts.yaml內(nèi)部配置,只保存設(shè)備名稱和IP地址(yaml內(nèi)的hostname)生均,用戶名听想、密碼、platform全放在defaults.yaml中马胧,不使用group.yaml(想使用也可以汉买,因為我這個內(nèi)容主要是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內(nèi)容(excel內(nèi)容如下:),形成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必須導(dǎo)入
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內(nèi)容自動生成hosts.yaml文件舔痕,再使用nr進行跑批操作
#===========================================================
if __name__ == '__main__':
    main()

執(zhí)行結(jié)果(示例我就執(zhí)行了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,比如要根據(jù)已知內(nèi)容生成{'SHM-RO4-POD2-1': {'hostname': '10.13.0.224'}}邢笙,那我們就用for循環(huán)遍歷excel內(nèi)容啸如,然后以A列為key,hostname:B列內(nèi)容作為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內(nèi)容以標準yaml格式寫入hosts.yaml文件,注意需要加參數(shù)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)

主函數(shù)很簡單帘不,調(diào)用生成yaml文件的方法,然后使用Nornir進行跑批操作铛纬。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末厌均,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子告唆,更是在濱河造成了極大的恐慌,老刑警劉巖晶密,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件擒悬,死亡現(xiàn)場離奇詭異,居然都是意外死亡稻艰,警方通過查閱死者的電腦和手機懂牧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人僧凤,你說我怎么就攤上這事畜侦。” “怎么了躯保?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵旋膳,是天一觀的道長。 經(jīng)常有香客問我途事,道長验懊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任尸变,我火速辦了婚禮义图,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘召烂。我一直安慰自己碱工,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布奏夫。 她就那樣靜靜地躺著怕篷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪桶蛔。 梳的紋絲不亂的頭發(fā)上匙头,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機與錄音仔雷,去河邊找鬼蹂析。 笑死,一個胖子當(dāng)著我的面吹牛碟婆,可吹牛的內(nèi)容都是我干的电抚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼竖共,長吁一口氣:“原來是場噩夢啊……” “哼蝙叛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起公给,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤借帘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后淌铐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肺然,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年腿准,在試婚紗的時候發(fā)現(xiàn)自己被綠了际起。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖街望,靈堂內(nèi)的尸體忽然破棺而出校翔,到底是詐尸還是另有隱情,我是刑警寧澤灾前,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布防症,位于F島的核電站,受9級特大地震影響豫柬,放射性物質(zhì)發(fā)生泄漏告希。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一烧给、第九天 我趴在偏房一處隱蔽的房頂上張望燕偶。 院中可真熱鬧,春花似錦础嫡、人聲如沸指么。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伯诬。三九已至,卻和暖如春巫财,著一層夾襖步出監(jiān)牢的瞬間盗似,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工平项, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留赫舒,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓闽瓢,卻偏偏與公主長得像接癌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子扣讼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容