Nornir 过滤inventory

过滤inventory

到目前为止,我们已经看到,nr.inventory.hostsnr.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}

进阶筛选

有时您需要更多的高级过滤。对于这些情况,您有两种选择:

  1. 使用过滤器功能。
  2. 使用过滤器对象。

过滤功能

filter_func参数使您可以运行自己的代码来过滤host。函数签名很简单,my_func(host)其中host是Host类型的对象,它必须返回TrueFalse指示您是否要托管。

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用来检查元素是否存在或字符串是否具有特定的子字符串。

觉得文章有用?

点个广告表达一下你的爱意吧 !😁