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中的所有的一个属性。
现在我们可以看下如果通过一些有趣的筛选基于他们的属性来做一些操作。
- 最简单的筛选使用过key, value对来进行,例如:
print(nr.filter(site="cmh").inventory.hosts.keys())
输出:
dict_keys(['host1.cmh', 'host2.cmh', 'spine00.cmh', 'spine01.cmh', 'leaf00.cmh', 'leaf01.cmh'])
- 你可以设置多个key,value对:
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'])
- 可以通过筛选出属于一个group的host:
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}
高级筛选
有时候你需要一些高级筛选。对于这些情况你有两个选择:
- 使用一个筛选函数。
- 使用一个筛选对象。
筛选函数
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'])
网友评论