过滤inventory
到目前为止,我们已经看到,nr.inventory.hosts
和nr.inventory.groups
有类似字典的对象,我们可以用遍历所有的host和group或直接访问任何特定的一个。现在,我们将看到如何进行花式过滤,从而使我们能够基于host的属性对host组进行操作。
筛选host的更简单方法是按对进行。例如:<key, value>
nr.filter(site="cmh").inventory.hosts.keys()
dict_keys(['host1.cmh', 'host2.cmh', 'spine00.cmh', 'spine01.cmh', 'leaf00.cmh', 'leaf01.cmh'])
您还可以使用多个<key, value>对进行过滤:
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'])
或者:
cmh = nr.filter(site="cmh")
cmh.filter(role="spine").inventory.hosts.keys()
dict_keys(['spine00.cmh', 'spine01.cmh'])
cmh.filter(role="leaf").inventory.hosts.keys()
dict_keys(['leaf00.cmh', 'leaf01.cmh'])
您还可以获取group的子group:
nr.inventory.children_of_group("eu")
{Host: host1.bma,
Host: host2.bma,
Host: leaf00.bma,
Host: leaf01.bma,
Host: spine00.bma,
Host: spine01.bma}
进阶筛选
有时您需要更多的高级过滤。对于这些情况,您有两种选择:
- 使用过滤器功能。
- 使用过滤器对象。
过滤功能
该filter_func
参数使您可以运行自己的代码来过滤host。函数签名很简单,my_func(host)
其中host是Host类型的对象,它必须返回True
或False
指示您是否要托管。
def has_long_name(host): return len(host.name) == 11 nr.filter(filter_func=has_long_name).inventory.hosts.keys()
dict_keys(['spine00.cmh','spine01.cmh','spine00.bma','spine01.bma'])
# Or a lambda function nr.filter(filter_func=lambda h: len(h.name) == 9).inventory.hosts.keys()
dict_keys(['host1.cmh','host2.cmh','host1.bma','host2.bma'])
筛选对象
您还可以使用过滤器对象以增量方式创建复杂的查询对象。让我们通过示例看看它是如何工作的:
# first you need to import the F object from nornir.core.filter import F
# hosts in group cmh 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'])
# devices running either linux or eos linux_or_eos = nr.filter(F(nornir_nos="linux") | F(nornir_nos="eos")) print(linux_or_eos.inventory.hosts.keys())
dict_keys([])
# spines in cmh 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 devices that are not spines 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'])
您还可以访问嵌套数据,甚至检查dict / 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'])
通过使用两个下划线分隔路径中的元素,基本上可以访问任何嵌套数据__
。然后,您可以__contains
用来检查元素是否存在或字符串是否具有特定的子字符串。