python

Nornir文档翻译----第一节 主机清单

2022-03-20  本文已影响0人  Bless_H

Inventory

Inventory是nornir非常的重要的组件,Inventory由三部分组成hosts、groups、defaults
hosts.yaml

---
host1.cmh:
    hostname: 127.0.0.1
    port: 2201
    username: vagrant
    password: vagrant
    platform: linux
    groups:
        - cmh
    data:
        site: cmh
        role: host
        type: host
        nested_data:
            a_dict:
                a: 1
                b: 2
            a_list: [1, 2]
            a_string: "asdasd"

host2.cmh:
    hostname: 127.0.0.1
    port: 2202
    username: vagrant
    password: vagrant
    platform: linux
    groups:
        - cmh
    data:
        site: cmh
        role: host
        type: host
        nested_data:
            a_dict:
                b: 2
                c: 3
            a_list: [1, 2]
            a_string: "qwe"

spine00.cmh:
    hostname: 127.0.0.1
    username: vagrant
    password: vagrant
    port: 12444
    platform: eos
    groups:
        - cmh
    data:
        site: cmh
        role: spine
        type: network_device

spine01.cmh:
    hostname: 127.0.0.1
    username: vagrant
    password: ""
    platform: junos
    port: 12204
    groups:
        - cmh
    data:
        site: cmh
        role: spine
        type: network_device

leaf00.cmh:
    hostname: 127.0.0.1
    username: vagrant
    password: vagrant
    port: 12443
    platform: eos
    groups:
        - cmh
    data:
        site: cmh
        role: leaf
        type: network_device
        asn: 65100

leaf01.cmh:
    hostname: 127.0.0.1
    username: vagrant
    password: ""
    port: 12203
    platform: junos
    groups:
        - cmh
    data:
        site: cmh
        role: leaf
        type: network_device
        asn: 65101

host1.bma:
    groups:
        - bma
    platform: linux
    data:
        site: bma
        role: host
        type: host

host2.bma:
    groups:
        - bma
    platform: linux
    data:
        site: bma
        role: host
        type: host

spine00.bma:
    hostname: 127.0.0.1
    username: vagrant
    password: vagrant
    port: 12444
    platform: eos
    groups:
        - bma
    data:
        site: bma
        role: spine
        type: network_device

spine01.bma:
    hostname: 127.0.0.1
    username: vagrant
    password: ""
    port: 12204
    platform: junos
    groups:
        - bma
    data:
        site: bma
        role: spine
        type: network_device

leaf00.bma:
    hostname: 127.0.0.1
    username: vagrant
    password: vagrant
    port: 12443
    platform: eos
    groups:
        - bma
    data:
        site: bma
        role: leaf
        type: network_device

leaf01.bma:
    hostname: 127.0.0.1
    username: vagrant
    password: wrong_password
    port: 12203
    platform: junos
    groups:
        - bma
    data:
        site: bma
        role: leaf
        type: network_device

groups.yaml

---
global:
    data:
        domain: global.local
        asn: 1

eu:
    data:
        asn: 65100

bma:
    groups:
        - eu
        - global

cmh:
    data:
        asn: 65000
        vlans:
          100: frontend
          200: backend

可以通过Host对象来查看简要格式

from nornir.core.inventory import Host
import json
print(json.dumps(Host.schema(), indent=4))

输出:
{
    "name": "str",
    "connection_options": {
        "$connection_type": {
            "extras": {
                "$key": "$value"
            },
            "hostname": "str",
            "port": "int",
            "username": "str",
            "password": "str",
            "platform": "str"
        }
    },
    "groups": [
        "$group_name"
    ],
    "data": {
        "$key": "$value"
    },
    "hostname": "str",
    "port": "int",
    "username": "str",
    "password": "str",
    "platform": "str"
}

groups.yaml和host基本保持一样的格式

访问Iventory

可以通过inventory属性来访问:

from nornir import InitNornir
nr = InitNornir(config_file="config.yaml")
print(nr.inventory.hosts)

输出:
{'host1.cmh': Host: host1.cmh, 
'host2.cmh': Host: host2.cmh, 
'spine00.cmh': Host: spine00.cmh,
 'spine01.cmh': Host: spine01.cmh,
 'leaf00.cmh': Host: leaf00.cmh, 
'leaf01.cmh': Host: leaf01.cmh, 
'host1.bma': Host: host1.bma, 
'host2.bma': Host: host2.bma, 
'spine00.bma': Host: spine00.bma,
 'spine01.bma': Host: spine01.bma,
 'leaf00.bma': Host: leaf00.bma, 
'leaf01.bma': Host: leaf01.bma}

inventory有两个类似字典的属性,hosts和groups,可以用相同的方式来访问host和groups

print(nr.inventory.groups)

输出:
{'global': Group: global,
 'eu': Group: eu,
 'bma': Group: bma, 
'cmh': Group: cmh}

Hosts和groups同样是类似字典格式的对象:

host = nr.inventory.hosts['host1.cmh']
print(host.keys())
print(host['asn'])

输出:
dict_keys(['site', 'role', 'type', 'nested_data', 'asn', 'vlans', 'domain'])
65000

继承模块

下面我们举例看下继承模块是如何工作的,我们再看下goups文件:

---
global:
    data:
        domain: global.local
        asn: 1

eu:
    data:
        asn: 65100

bma:
    groups:
        - eu
        - global

cmh:
    data:
        asn: 65000
        vlans:
          100: frontend
          200: backend

leaf01.bma属于bma组,并且bma又属于eu和global. spine00.cmh属于cmh,但是cmh并不属于其他人组

数据解析是通过递归迭代出所有的父组中的数据,查看是否包含data这个字段。例如:

leaf01_bma = nr.inventory.hosts["leaf01.bma"]
leaf01_bma["domain"]  # 来自global组

输出:
'global.local'

leaf01_bma["asn"]  # 来自eu组
输出:
65100

如果你不想通过迭代的方式去获取数据,那可以使用data这个属性来获取数据。
可以通过keys()来看下data属性的key值,没有继承groups和defaults中的数据。

print(leaf01_cmh.data.keys())
print(leaf01_cmh.data["domain"])

输出:
dict_keys(['site', 'role', 'type', 'asn'])
Traceback (most recent call last):
  File "/mnt/c/Users/BlessLiu/Project/nornir_learn2/learn_inventory.py", line 23, in <module>
    print(leaf01_cmh.data["domain"])
KeyError: 'domain'

筛选inventory

我们已经看到了通过nr.inventory.hosts和nr.inventory.groups像是字典对象,我们可以直接迭代出hosts和groups中的所有的一个属性。

现在我们可以看下如果通过一些有趣的筛选基于他们的属性来做一些操作。

print(nr.filter(site="cmh").inventory.hosts.keys())

输出:
dict_keys(['host1.cmh', 'host2.cmh', 'spine00.cmh', 'spine01.cmh', 'leaf00.cmh', 'leaf01.cmh'])
print(nr.filter(site="cmh",role="spine").inventory.hosts.keys())

输出:
dict_keys(['spine00.cmh', 'spine01.cmh'])
nr.filter(site="cmh").filter(role="spine").inventory.hosts.keys()

输出:
dict_keys(['spine00.cmh', 'spine01.cmh'])
print(nr.inventory.children_of_group('bma'))

输出:
{Host: spine00.bma, Host: leaf01.bma, Host: spine01.bma, Host: host1.bma, Host: leaf00.bma, Host: host2.bma}

高级筛选

有时候你需要一些高级筛选。对于这些情况你有两个选择:

  1. 使用一个筛选函数。
  2. 使用一个筛选对象。

筛选函数

    filter_func参数可以让你运行自己的代码去筛选hosts,函数名就像my_func(host)一样简单,host是Host类型的一个对象,并且
这个函数必须返回True或者False以标识是否需要这个host。

def has_long_name(host):
    return len(host.name) == 11

print(nr.filter(filter_func=has_long_name).inventory.hosts.keys())

筛选对象

  你可以通过筛选对象来逐渐地创建一个复杂的筛选。我们看下它是怎么工作的:

#引入F对象
from nornir.core.filter import F

#在cmh中的host
cmh = nr.filter(F(groups__contains="cmh"))
print(cmh.inventory.hosts.keys())

输出:
dict_keys(['host1.cmh', 'host2.cmh', 'spine00.cmh', 'spine01.cmh', 'leaf00.cmh', 'leaf01.cmh'])

#在cmh的spines
cmh_and_spine = nr.filter(F(groups__contains="cmh") & F(role="spine"))
print(cmh_and_spine.inventory.hosts.keys())

输出:
dict_keys(['spine00.cmh', 'spine01.cmh'])

#在cmh但不是spines的host
cmh_and_not_spine = nr.filter(F(groups__contains="cmh") & ~F(role="spine"))
print(cmh_and_not_spine.inventory.hosts.keys())

输出:
dict_keys(['host1.cmh', 'host2.cmh', 'leaf00.cmh', 'leaf01.cmh'])

  你还可以访问嵌套在内部的数据,甚至dicts/lists/strings包含的元素。同样我们来几个例子:

nested_string_asd = nr.filter(F(nested_data__a_string__contains="asd"))
print(nested_string_asd.inventory.hosts.keys())'

输出:
dict_keys(['host1.cmh'])

a_dict_element_equals = nr.filter(F(nested_data__a_dict__c=3))
print(a_dict_element_equals.inventory.hosts.keys())

输出:
dict_keys(['host2.cmh'])

a_list_contains = nr.filter(F(nested_data__a_list__contains=2))
print(a_list_contains.inventory.hosts.keys())

输出:
dict_keys(['host1.cmh', 'host2.cmh'])

上一篇下一篇

猜你喜欢

热点阅读