Nornir文档翻译----第七节 过滤的深入研究

Filtering Deep Dive

这篇教程中我们将探索nornir过滤的能力并且证明为什么nornir是最好的inventory管理框架。

这篇教程将会演示一些通用的网络使用案例以及nornir是如何精确的锁定到主机或者主机组。

Tutorial Inventory

首先,我们初始化我们的nornir inventory。

# Import modules
from nornir import InitNornir
from nornir.core.filter import F

# Initialise nornir
nr = InitNornir(config_file="filtering_deep_dive/config.yaml")

接下来我们看下我们教程的hosts.yaml文件。不要被这个inventory的大小或者内容搞的不知所措,我们将会在接下来的教程中探索更多的细节。

---
lab-csr-011.lab.norn.local:
    hostname: lab-csr-011.lab.norn.local
    groups:
        - ios
        - lab
        - mel
    data:
        mgmt_ip: 10.0.0.16
        vendor: cisco
        device_type: router
        os_version: 16.6.4
        site_code: mel

dfjt-r001.lab.norn.local:
    hostname: dfjt-r001.lab.norn.local
    groups:
        - ios
        - lab
        - bcn
    data:
        mgmt_ip: 10.0.0.1
        vendor: cisco
        device_type: router
        os_version: 16.6.3
        site_code: bcn

lab-arista-01.lab.norn.local:
    hostname: lab-arista-01.lab.norn.local
    groups:
        - eos
        - lab
        - mtl
    data:
        mgmt_ip: 10.0.0.11
        vendor: arista
        device_type: switch
        os_version: 4.22.0F
        site_code: mtl

lab-arista-02.lab.norn.local:
    hostname: lab-arista-02.lab.norn.local
    groups:
        - eos
        - lab
        - mel
    data:
        mgmt_ip: 10.0.0.18
        vendor: arista
        device_type: switch
        os_version: 4.23.2F
        site_code: mel

lab-junos-01.lab.norn.local:
    hostname: lab-junos-01.lab.norn.local
    groups:
        - junos
        - lab
        - mtl
    data:
        mgmt_ip: 10.0.0.15
        vendor: juniper
        device_type: router
        os_version: 18.4R2-S5
        site_code: mtl

lab-nxos-01.lab.norn.local:
    hostname: lab-nxos-01.lab.norn.local
    groups:
        - nxos
        - lab
        - mtl
    data:
        mgmt_ip: 10.0.0.14
        vendor: cisco
        device_type: switch
        os_version: 9.3(6)
        site_code: mtl

lab-paloalto-01.lab.djft.local:
    hostname: lab-paloalto-01.lab.djft.local
    groups:
        - panos
        - lab
        - mel
    data:
        mgmt_ip: 10.0.0.21
        vendor: palo alto
        device_type: firewall
        os_version: 10.0.3
        site_code: mel

lab-paloalto-02.lab.norn.local:
    hostname: lab-paloalto-02.lab.norn.local
    groups:
        - panos
        - lab
        - bcn
    data:
        mgmt_ip: 10.0.0.22
        vendor: palo alto
        device_type: firewall
        os_version: 9.1.3-h1
        site_code: bcn

lab-junos-06.lab.norn.local:
    hostname: lab-junos-06.lab.norn.local
    groups:
        - junos
        - lab
        - mel
    data:
        mgmt_ip: 10.0.0.23
        vendor: juniper
        device_type: switch
        os_version: 18.4R2-S5
        site_code: mel

prd-csr-01.prd.norn.local:
    hostname: prd-csr-01.prd.norn.local
    groups:
        - ios
        - prod
        - mel
    data:
        mgmt_ip: 10.0.16.16
        vendor: cisco
        device_type: router
        os_version: 16.6.4
        site_code: mel

dfjt-r001.prd.norn.local:
    hostname: dfjt-r001.prd.norn.local
    groups:
        - ios
        - prod
        - mel
    data:
        mgmt_ip: 10.0.16.1
        vendor: cisco
        device_type: router
        os_version: 16.6.3
        site_code: mel

prd-arista-01.prd.norn.local:
    hostname: prd-arista-01.prd.norn.local
    groups:
        - eos
        - prod
        - mel
    data:
        mgmt_ip: 10.0.16.11
        vendor: arista
        device_type: switch
        os_version: 4.21.1F
        site_code: mel

prd-arista-02.prd.nron.local:
    hostname: prd-arista-02.prd.norn.local
    groups:
        - eos
        - prod
        - mel
    data:
        mgmt_ip: 10.0.16.18
        vendor: arista
        device_type: switch
        os_version: 4.23.1F
        site_code: mel

prd-junos-01.prd.norn.local:
    hostname: prd-junos-01.prd.norn.local
    groups:
        - junos
        - prod
        - mel
    data:
        mgmt_ip: 10.0.16.15
        vendor: juniper
        device_type: router
        os_version: 15.1R7-S6
        site_code: mel

prd-nxos-01.prd.norn.local:
    hostname: prd-nxos-01.prd.norn.local
    groups:
        - nxos_ssh
        - prod
        - mel
    data:
        mgmt_ip: 10.0.16.14
        vendor: cisco
        device_type: switch
        os_version: 7.0(3)
        site_code: mel

prd-paloalto-01.prd.norn.local:
    hostname: prd-paloalto-01.prd.norn.local
    groups:
        - panos
        - prod
        - mel
    data:
        mgmt_ip: 10.0.16.21
        vendor: palo alto
        device_type: firewall
        os_version: 10.0.3
        site_code: mel

prd-paloalto-02.prd.norn.local:
    hostname: prd-paloalto-02.prd.norn.local
    groups:
        - panos
        - prod
        - mel
    data:
        mgmt_ip: 10.0.16.22
        vendor: palo alto
        device_type: firewall
        os_version: 9.1.6
        site_code: mel

prd-junos-06.prd.norn.local:
    hostname: prd-junos-06.prd.norn.local
    groups:
        - junos
        - prod
        - mel
    data:
        mgmt_ip: 10.0.16.23
        vendor: juniper
        device_type: switch
        os_version: 12.1R3-S4
        site_code: mel

tst-csr-01.tst.norn.local:
    hostname: tst-csr-01.tst.norn.local
    groups:
        - ios
        - test
        - mel
    data:
        mgmt_ip: 10.0.32.16
        vendor: cisco
        device_type: router
        os_version: 16.6.4
        site_code: mel

dfjt-r001.tst.norn.local:
    hostname: dfjt-r001.tst.norn.local
    groups:
        - ios
        - test
        - mel
    data:
        mgmt_ip: 10.0.32.1
        vendor: cisco
        device_type: router
        os_version: 15.1.4
        site_code: mel

tst-arista-01.tst.norn.local:
    hostname: tst-arista-01.tst.norn.local
    groups:
        - eos
        - test
        - ptl
    data:
        mgmt_ip: 10.0.32.11
        vendor: arista
        device_type: switch
        os_version: 4.21.1F
        site_code: ptl

tstt-arista-02.tst.norn.local:
    hostname: tstt-arista-02.tst.norn.local
    groups:
        - eos
        - test
        - ptl
    data:
        mgmt_ip: 10.0.32.18
        vendor: arista
        device_type: switch
        os_version: 4.21.1F
        site_code: ptl

tst-junos-01.tst.norn.local:
    hostname: tst-junos-01.tst.norn.local
    groups:
        - junos
        - test
        - ptl
    data:
        mgmt_ip: 10.0.32.15
        vendor: juniper
        device_type: router
        os_version: 15.1R7-S6
        site_code: ptl

tst-nxos-01.tst.norn.local:
    hostname: tst-nxos-01.tst.norn.local
    groups:
        - nxos
        - test
        - chc
    data:
        mgmt_ip: 10.0.32.14
        vendor: cisco
        device_type: switch
        os_version: 7.0(4)
        site_code: chc

tst-paloalto-01.tst.norn.local:
    hostname: tst-paloalto-01.tst.norn.local
    groups:
        - panos
        - test
        - chc
    data:
        mgmt_ip: 10.0.32.21
        vendor: palo alto
        device_type: firewall
        os_version: 10.0.3
        site_code: chc

tst-paloalto-02.tst.norn.local:
    hostname: tst-paloalto-02.tst.norn.local
    groups:
        - panos
        - test
        - chc
    data:
        mgmt_ip: 10.0.32.22
        vendor: palo alto
        device_type: firewall
        os_version: 8.0.8
        site_code: chc

tst-junos-06.tst.norn.local:
    hostname: tst-junos-06.tst.norn.local
    groups:
        - junos
        - test
        - chc
    data:
        mgmt_ip: 10.0.32.23
        vendor: juniper
        device_type: switch
        os_version: 12.1R3-S4
        site_code: chc
Next, let’s look at our tutorial groups.yaml file. There are a mixture of group types in here.

Some appear to be based on network operating systems, some on operating environments and others based on physical location.

nornir has no pre-conceived ideas or limits on group composition or structures:

[23]:
%cat filtering_deep_dive/inventory/groups.yaml
---
ios:
    platform: ios
    data:
        vendor: cisco
junos:
    platform: junos
    data:
        vendor: juniper
eos:
    platform: eos
    data:
        vendor: arista
nxos:
    platform: nxos
    data:
        vendor: cisco
nxos_ssh:
    platform: nxos_ssh
    data:
        vendor: cisco
panos:
    platform: paloalto_panos
    data:
        vendor: palo alto
lab:
    data:
        sla: 70
        production: false
prod:
    data:
        sla: 90
        production: true
test:
    data:
        sla: 80
        production: false
mel:
    data:
        full_name: Melbourne
        country: Australia
        region: apac
        hemisphere: southern
        site_type: primary
hbt:
    data:
        full_name: Hobart
        country: Australia
        region: apac
        hemisphere: southern
        site_type: tertiary
chc:
    data:
        full_name: Christchurch
        country: New Zealand
        region: apac
        hemisphere: southern
        site_type: secondary
ptl:
    data:
        full_name: Port Louis
        country: Mauritius
        region: amea
        hemisphere: southern
        site_type: primary
mtl:
    data:
        full_name: Montreal
        country: Canada
        region: amer
        hemisphere: northern
        site_type: primary
bcn:
    data:
        full_name: Barcelona
        country: Spain
        region: amea
        hemisphere: northern
        site_type: primary

接下来我们看下这个教程groups.yaml,这里有一些混合的组合。有些是基于网络设备操作系统的,有些是基于操作环境,有些是基于物理位置的。
nornir没有任何预置的想法或者限制在group组件或架构上。

Customer inventory data

在我们进行过滤之前,介绍一些关于自定义数据的概念是很重要的。

nornir允许你去填充自定义数据在hosts或者groups对象的data键中,无论你选择什么key/value数据结构。你可以为这些keys其任何名字去适配的业务需要。

首先,我们看下从原始的hosts.yaml和groups.yaml中摘取的一个host和一个group。

%cat filtering_deep_dive/inventory/hosts_extract.yaml

---
lab-csr-011.lab.norn.local:
    hostname: lab-csr-011.lab.norn.local
    groups:
        - ios
        - lab
        - mel
    data:  # Anything under this key is custom data
        mgmt_ip: 10.0.0.16  # This is custom data
        vendor: cisco  # So is this
        device_type: router  # Same as this
        os_version: 16.6.4  # Also this too
        site_code: mel  # Yes, and also this

%cat filtering_deep_dive/inventory/groups_extract.yaml


---
mel:
    data:  # Anything under this key is custom data
        full_name: Melbourne  # This is custom data
        country: Australia  # So is this
        region: apac  # Same as this
        hemisphere: southern  # Also this too
        site_type: primary  # Yes, and also this

如你所见在上面的两个例子中,你可以通过你喜欢的自定数据来记录信息。上面这些例子是在data中的一个“胖”数据结构,你还可以嵌套数据结构来适配你的需要。

在下面的例子中,我们拿到了mgmt_ip的值是10.0.0.16,并且我们重新调整数据结构,把他调整到了mgmt这个key中,这样方便以后的扩展。

%cat filtering_deep_dive/inventory/hosts_extract_alternate.yaml

---
lab-csr-011.lab.norn.local:
    hostname: lab-csr-011.lab.norn.local
    groups:
        - ios
        - lab
        - mel
    data:  # Anything under this key is custom data
        ip_addresses:
            mgmt: 10.0.0.16  # Alternate way of managing mgmt_ip data
        vendor: cisco
        device_type: router
        os_version: 16.6.4
        site_code: mel

随着时间的推移,你需要存储的自定义数据需要改变,理想情况下你会随着业务的增长丰富你的数据。

在下面的例子中,一些关于节点的键/值对关联在location这个key下。这意味着即使一些代码影响现有的数据结构也不需要去重构。

%cat filtering_deep_dive/inventory/groups_extract_alternate.yaml

---
mel:
   data:  # Anything under this key is custom data
       full_name: Melbourne
       country: Australia
       region: apac
       hemisphere: southern
       site_type: primary
       location:  # New location data is stored about the site
           address: 1 Wurundjeri Street
           suburb: Northcote
           zip_code: 3070

View host/group data

在我们返回过滤之前,我们将会展示如何访问哪些可访问的或者归属于host和group的所有数据。

首先,我们将初始化nornir然后过滤一个单独的host lab-csr-011.lab.norn.local:

from nornir import InitNornir
from nornir.core.filter import F


# Initialise nornir
nr = InitNornir(config_file="filtering_deep_dive/config.yaml")
# 输出inventory中host的数量
print(f"Number of hosts in entire inventory: {len(nr.inventory.hosts)}")
#  通过标准的python方法访问 host lab-csr-011.lab.norn.local
single_host = nr.inventory.hosts['lab-csr-011.lab.norn.local']
# 输出这个host
print(f"Single host: {single_host}")


输出:
Number of hosts in entire inventory: 27
Single host: lab-csr-011.lab.norn.local
# Import the JSON module
import json
# Dump the dictionary, assign to variable
single_host_data = json.dumps(single_host.dict(), indent=2)
# Print seperator
print("=" * 50)
# Print header and host data structure
print(f"Displaying information for host: {single_host}")
print(f"{single_host_data}")
# Print seperator
print("=" * 50)

如上所见,所有相关的数据都可以在后面的代码中查看和使用。无论你使用JSON或者YAML,数据结构是相同的。

下面是一些展示一些key的数据的例子:

print(f"Displaying data for host: {single_host}")
# Access the site_code value, nested under the data key
single_host_site_code = single_host.dict()["data"]["site_code"]
print(f"Site code is: {single_host_site_code}")
# Access the platform value
single_host_platform = single_host.dict()["platform"]
print(f"Platform is: {single_host_platform}")
# Access the os_version value, nested under the data key
single_host_os_version = single_host.dict()["data"]["os_version"]
print(f"OS Version is: {single_host_os_version}")


输出:
Displaying data for host: lab-csr-011.lab.norn.local
Site code is: mel
Platform is: None
OS Version is: 16.6.4

Filtering Types

nornir提供三种类型的过滤能力:

  • 通过filter方法实现基础或中级过滤
  • 通过F对象实现高级过滤
  • 通过filter函数实现高级过滤

大家应该注意到filter方法可以解决的过滤需求F对象都可以解决,但是F对象还可以解决filter方法解决的过滤需求。这个教程会团所两个过滤方法,这样你可以理解他们的使用他们使用的案例、限制、权衡。

Basic Filtering

让我们探索filter方法,它可以用在简单、直接的过滤需求中。我们将重新初始化教程开始时的nornir仓库。


# Import modules
from nornir import InitNornir
from nornir.core.filter import F

# Initialise nornir
nr = InitNornir(config_file="filtering_deep_dive/config.yaml")
# Informational printouts
print(f"There are {len(nr.inventory.hosts)} hosts in this tutorial inventory.")
print(f"There are {len(nr.inventory.groups)} groups in this tutorial inventory.")

#output
There are 27 hosts in this tutorial inventory.
There are 15 groups in this tutorial inventory.

基础的filter方法允许去过滤主机或主机组的任何键。下面的例子中我们过滤一个单独的主机:

# Assign filter value to a variable for usage
filter_query = "lab-arista-02.lab.norn.local"
# Filter inventory for all hostnames which equal the filter value
target_hosts = nr.filter(hostname=filter_query)
print(f"Filtering entire inventory on {filter_query} ...")
print(f"Total results found: {len(target_hosts.inventory.hosts)}")
# Iterate over filtered results and printout information
for host, data in target_hosts.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Hostname: {data.hostname}"
    )
Filtering entire inventory on lab-arista-02.lab.norn.local ...
Total results found: 1
Host: lab-arista-02.lab.norn.local - Hostname: lab-arista-02.lab.norn.local

Host-based basic filters

让我们看一些更有用的案例,我们直接过滤host的属性,例如:

  • 通过vendor过滤
  • 通过device_type过滤
  • 通过mgmt_ip过滤
# Import modules
from nornir import InitNornir
# Initialise nornir
nr = InitNornir(config_file="filtering_deep_dive/config.yaml")

# Use Case 1 - filter hosts by platform
# Assign platform to variable for later usage
platform="junos"
# Execute filter based on platform
target_hosts = nr.filter(platform=platform)
# Print seperator and header
print("=" * 50)
print(f"The hosts which have platform {platform} are:")
# Iterate over filtered results and printout information
for host, data in target_hosts.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Platform: {data.platform}"
    )
# Print total and seperator
print(f"Total: {len(target_hosts.inventory.hosts.items())}")
print("=" * 50)

# Use Case 2 - filter hosts by production equals false
# Assign production equals false to variable for later usage
production = False
# Execute filter based on production
target_hosts = nr.filter(production=production)
# Print seperator and header
print("=" * 50)
print(f"The hosts which have production boolean value of {production} are:")
# Iterate over filtered results and printout information
for host, data in target_hosts.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Production: {data['production']}"
    )
# Print total and seperator
print(f"Total: {len(target_hosts.inventory.hosts.items())}")
print("=" * 50)


# Use Case 3 - filter hosts by site_type of tertiary
# Assign site_type of secondary to variable for later usage
site_type="secondary"
# Execute filter based on site_type
target_hosts = nr.filter(site_type=site_type)
# Print seperator and header
print("=" * 50)
print(f"The hosts which have site_type of {site_type} are:")
# Iterate over filtered results and printout information
for host, data in target_hosts.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Site Type: {data['site_type']}"
    )
# Print total and seperator
print(f"Total: {len(target_hosts.inventory.hosts.items())}")
print("=" * 50)

#output

==================================================
The hosts which have platform junos are:
Host: lab-junos-01.lab.norn.local - Platform: junos
Host: lab-junos-06.lab.norn.local - Platform: junos
Host: prd-junos-01.prd.norn.local - Platform: junos
Host: prd-junos-06.prd.norn.local - Platform: junos
Host: tst-junos-01.tst.norn.local - Platform: junos
Host: tst-junos-06.tst.norn.local - Platform: junos
Total: 6
==================================================
==================================================
The hosts which have production boolean value of False are:
Host: lab-csr-011.lab.norn.local - Production: False
Host: dfjt-r001.lab.norn.local - Production: False
Host: lab-arista-01.lab.norn.local - Production: False
Host: lab-arista-02.lab.norn.local - Production: False
Host: lab-junos-01.lab.norn.local - Production: False
Host: lab-nxos-01.lab.norn.local - Production: False
Host: lab-paloalto-01.lab.djft.local - Production: False
Host: lab-paloalto-02.lab.norn.local - Production: False
Host: lab-junos-06.lab.norn.local - Production: False
Host: tst-csr-01.tst.norn.local - Production: False
Host: dfjt-r001.tst.norn.local - Production: False
Host: tst-arista-01.tst.norn.local - Production: False
Host: tstt-arista-02.tst.norn.local - Production: False
Host: tst-junos-01.tst.norn.local - Production: False
Host: tst-nxos-01.tst.norn.local - Production: False
Host: tst-paloalto-01.tst.norn.local - Production: False
Host: tst-paloalto-02.tst.norn.local - Production: False
Host: tst-junos-06.tst.norn.local - Production: False
Total: 18
==================================================
==================================================
The hosts which have site_type of secondary are:
Host: tst-nxos-01.tst.norn.local - Site Type: secondary
Host: tst-paloalto-01.tst.norn.local - Site Type: secondary
Host: tst-paloalto-02.tst.norn.local - Site Type: secondary
Host: tst-junos-06.tst.norn.local - Site Type: secondary
Total: 4
==================================================

Intermediate filtering

我们可以通过连续过滤的filter方法来细化过滤的结果并且获得指定的设备。

在下面的例子中,我们将通过输出一个过滤的结果,并且把它用于后面的filter中,逐渐地在最后找到一台思科的Christchurch设备。

# Import modules
from nornir import InitNornir
# Initialise nornir
nr = InitNornir(config_file="filtering_deep_dive/config.yaml")
# Filter all devices for Cisco devices
cisco_devices = nr.filter(vendor="cisco")
# Print seperator and header
print("=" * 50)
print("All cisco devices")
# Iterate over filtered results and printout information
for host, data in cisco_devices.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Vendor: {data['vendor']}"
    )
# Print total and seperator
print(f"Total: {len(cisco_devices.inventory.hosts.items())}")
print("=" * 50)
# Filter all Cisco devices for Cisco switches
cisco_switches = cisco_devices.filter(device_type="switch")
# Print seperator and header
print("=" * 50)
print("All cisco switches")
# Iterate over filtered results and printout information
for host, data in cisco_switches.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Device Type: {data['device_type']}"
    )
# Print total and seperator
print(f"Total: {len(cisco_switches.inventory.hosts.items())}")
print("=" * 50)
# Filter all Cisco switches for Christchurch switches
chc_cisco_switches = cisco_switches.filter(full_name="Christchurch")
# Print seperator and header
print("=" * 50)
print("All Christchuch cisco switches")
# Iterate over filtered results and printout information
for host, data in chc_cisco_switches.inventory.hosts.items():
    print(
        f"Host: {host} \n"
        + " " * 8 + f"- Vendor: {data['vendor']}\n"
        + " " * 8 + f"- Device Type: {data['device_type']}\n"
        + " " * 8 + f"- Site Name: {data['full_name']}"
    )
# Print total and seperator
print(f"Total: {len(chc_cisco_switches.inventory.hosts.items())}")
print("=" * 50)

#output
==================================================
All cisco devices
Host: lab-csr-011.lab.norn.local - Vendor: cisco
Host: dfjt-r001.lab.norn.local - Vendor: cisco
Host: lab-nxos-01.lab.norn.local - Vendor: cisco
Host: prd-csr-01.prd.norn.local - Vendor: cisco
Host: dfjt-r001.prd.norn.local - Vendor: cisco
Host: prd-nxos-01.prd.norn.local - Vendor: cisco
Host: tst-csr-01.tst.norn.local - Vendor: cisco
Host: dfjt-r001.tst.norn.local - Vendor: cisco
Host: tst-nxos-01.tst.norn.local - Vendor: cisco
Total: 9
==================================================
==================================================
All cisco switches
Host: lab-nxos-01.lab.norn.local - Device Type: switch
Host: prd-nxos-01.prd.norn.local - Device Type: switch
Host: tst-nxos-01.tst.norn.local - Device Type: switch
Total: 3
==================================================
==================================================
All Christchuch cisco switches
Host: tst-nxos-01.tst.norn.local
        - Vendor: cisco
        - Device Type: switch
        - Site Name: Christchurch
Total: 1

Advanced filtering

最强大的过滤方式是通过F对象实现的,正如上面介绍的,F对象可以实现所有形式的过滤。

这一节中我们将介绍:

  • F对象的运算符
  • F对象的操作符
  • filter_func函数

F对象有三个如下所示的运算符:

运算符 描述
~ NOT
& AND
| OR

在执行的代码中,我们将展示如何使用这些运算符:

# Import modules
from nornir import InitNornir
from nornir.core.filter import F
# Initialise nornir
nr = InitNornir(config_file="filtering_deep_dive/config.yaml")
# Use Case 1 - NOT operator
# Filter for NOT equals platform of "junos"
not_junos = nr.filter(~F(platform__eq="junos"))
# Print seperator and header
print("=" * 50)
print("All non-junos devices - using NOT operator")
# Iterate over filtered results and printout information
for host, data in not_junos.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Platform: {data.platform}"
    )
# Print total and seperator
print(f"Total: {len(not_junos.inventory.hosts.items())}")
print("=" * 50)
# Use Case 2 - AND operator
# Filter for platform equals "nxos" AND device_type equals "switch"
nxos_switches = nr.filter(F(platform__eq="nxos") & F(device_type__eq="switch"))
# Print seperator and header
print("=" * 50)
print("All nxos switches - using AND operator")
# Iterate over filtered results and printout information
for host, data in nxos_switches.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Platform: {data.platform} "
        + f"- Device Type: {data['device_type']}"
    )
# Print total and seperator
print(f"Total: {len(nxos_switches.inventory.hosts.items())}")
print("=" * 50)
# Use Case 3 - OR operator
# Filter for site code equals "ptl" OR site code equals "chc"
ptl_or_chc_devices = nr.filter(
    F(site_code__eq="ptl") | F(site_code__eq="chc")
)
print("=" * 50)
print("All ptl or chc site code devices - using OR operator")
# Iterate over filtered results and printout information
for host, data in ptl_or_chc_devices.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Site Code: {data['site_code']}"
    )
# Print total and seperator
print(f"Total: {len(ptl_or_chc_devices.inventory.hosts.items())}")
print("=" * 50)

#output:

==================================================
All non-junos devices - using NOT operator
Host: lab-csr-011.lab.norn.local - Platform: ios
Host: dfjt-r001.lab.norn.local - Platform: ios
Host: lab-arista-01.lab.norn.local - Platform: eos
Host: lab-arista-02.lab.norn.local - Platform: eos
Host: lab-nxos-01.lab.norn.local - Platform: nxos
Host: lab-paloalto-01.lab.djft.local - Platform: paloalto_panos
Host: lab-paloalto-02.lab.norn.local - Platform: paloalto_panos
Host: prd-csr-01.prd.norn.local - Platform: ios
Host: dfjt-r001.prd.norn.local - Platform: ios
Host: prd-arista-01.prd.norn.local - Platform: eos
Host: prd-arista-02.prd.nron.local - Platform: eos
Host: prd-nxos-01.prd.norn.local - Platform: nxos_ssh
Host: prd-paloalto-01.prd.norn.local - Platform: paloalto_panos
Host: prd-paloalto-02.prd.norn.local - Platform: paloalto_panos
Host: tst-csr-01.tst.norn.local - Platform: ios
Host: dfjt-r001.tst.norn.local - Platform: ios
Host: tst-arista-01.tst.norn.local - Platform: eos
Host: tstt-arista-02.tst.norn.local - Platform: eos
Host: tst-nxos-01.tst.norn.local - Platform: nxos
Host: tst-paloalto-01.tst.norn.local - Platform: paloalto_panos
Host: tst-paloalto-02.tst.norn.local - Platform: paloalto_panos
Total: 21
==================================================
==================================================
All nxos switches - using AND operator
Host: lab-nxos-01.lab.norn.local - Platform: nxos - Device Type: switch
Host: tst-nxos-01.tst.norn.local - Platform: nxos - Device Type: switch
Total: 2
==================================================
==================================================
All ptl or chc site code devices - using OR operator
Host: tst-arista-01.tst.norn.local - Site Code: ptl
Host: tstt-arista-02.tst.norn.local - Site Code: ptl
Host: tst-junos-01.tst.norn.local - Site Code: ptl
Host: tst-nxos-01.tst.norn.local - Site Code: chc
Host: tst-paloalto-01.tst.norn.local - Site Code: chc
Host: tst-paloalto-02.tst.norn.local - Site Code: chc
Host: tst-junos-06.tst.norn.local - Site Code: chc
Total: 7
==================================================

F object operations

F对象有如下11种操作符:

运算符 描述 类型
eq 等于 字符串、整型
ge 大于等于 整型
gt 大于 整型
le 小于等于 整型
lt 小于 整型
contains 包含 字符串
startswith 开始于 字符串
endswith 结束于 字符串
any 任何一个之中 字符串
has_parent_group 有一个父组 字符串
in 在其中【感觉和any区别不大】 字符串
all 所有 列表

在下面的代码重,我们将展示如何使用这些操作符:

# Import modules
from nornir import InitNornir
from nornir.core.filter import F
# Initialise nornir
nr = InitNornir(config_file="filtering_deep_dive/config.yaml")
# Use Case 1 - eq operation
# Filter for equals platform of "junos"
junos_devices = nr.filter(F(platform__eq="junos"))
# Print seperator and header
print("=" * 50)
print("All junos devices - using eq operation")
# Iterate over filtered results and printout information
for host, data in junos_devices.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Platform: {data.platform}"
    )
# Print total and seperator
print(f"Total: {len(junos_devices.inventory.hosts.items())}")
print("=" * 50)
# Use Case 2 - ge operation
# Filter for sla greater than or equal to 80
sla_eighty_or_greater = nr.filter(F(sla__ge=80))
# Print seperator and header
print("=" * 50)
print("All devices with SLA greater than or equal to 80 - using gt operation")
# Iterate over filtered results and printout information
for host, data in sla_eighty_or_greater.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- SLA: {data['sla']}"
    )
# Print total and seperator
print(f"Total: {len(sla_eighty_or_greater.inventory.hosts.items())}")
print("=" * 50)
# Use Case 3 - gt operation
# Filter for sla greater than 79
sla_more_than_seventy_nine = nr.filter(F(sla__gt=79))
# Print seperator and header
print("=" * 50)
print("All devices with SLA greater than 79 - using gt operation")
# Iterate over filtered results and printout information
for host, data in sla_more_than_seventy_nine.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- SLA: {data['sla']}"
    )
# Print total and seperator
print(f"Total: {len(sla_more_than_seventy_nine.inventory.hosts.items())}")
print("=" * 50)
# Use Case 4 - le operation
# Filter for sla lesser than or equal to 80
sla_eighty_or_lesser = nr.filter(F(sla__le=80))
# Print seperator and header
print("=" * 50)
print("All devices with SLA less than or equal to 80 - using le operation")
# Iterate over filtered results and printout information
for host, data in sla_eighty_or_lesser.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- SLA: {data['sla']}"
    )
# Print total and seperator
print(f"Total: {len(sla_eighty_or_lesser.inventory.hosts.items())}")
print("=" * 50)
# Use Case 4 - lt operation
# Filter for sla lesser than 80
sla_less_than_eighty = nr.filter(F(sla__lt=80))
# Print seperator and header
print("=" * 50)
print("All devices with SLA less than 80 - using lt operation")
# Iterate over filtered results and printout information
for host, data in sla_less_than_eighty.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- SLA: {data['sla']}"
    )
# Print total and seperator
print(f"Total: {len(sla_less_than_eighty.inventory.hosts.items())}")
print("=" * 50)

#output

==================================================
All junos devices - using eq operation
Host: lab-junos-01.lab.norn.local - Platform: junos
Host: lab-junos-06.lab.norn.local - Platform: junos
Host: prd-junos-01.prd.norn.local - Platform: junos
Host: prd-junos-06.prd.norn.local - Platform: junos
Host: tst-junos-01.tst.norn.local - Platform: junos
Host: tst-junos-06.tst.norn.local - Platform: junos
Total: 6
==================================================
==================================================
All devices with SLA greater than or equal to 80 - using gt operation
Host: prd-csr-01.prd.norn.local - SLA: 90
Host: dfjt-r001.prd.norn.local - SLA: 90
Host: prd-arista-01.prd.norn.local - SLA: 90
Host: prd-arista-02.prd.nron.local - SLA: 90
Host: prd-junos-01.prd.norn.local - SLA: 90
Host: prd-nxos-01.prd.norn.local - SLA: 90
Host: prd-paloalto-01.prd.norn.local - SLA: 90
Host: prd-paloalto-02.prd.norn.local - SLA: 90
Host: prd-junos-06.prd.norn.local - SLA: 90
Host: tst-csr-01.tst.norn.local - SLA: 80
Host: dfjt-r001.tst.norn.local - SLA: 80
Host: tst-arista-01.tst.norn.local - SLA: 80
Host: tstt-arista-02.tst.norn.local - SLA: 80
Host: tst-junos-01.tst.norn.local - SLA: 80
Host: tst-nxos-01.tst.norn.local - SLA: 80
Host: tst-paloalto-01.tst.norn.local - SLA: 80
Host: tst-paloalto-02.tst.norn.local - SLA: 80
Host: tst-junos-06.tst.norn.local - SLA: 80
Total: 18
==================================================
==================================================
All devices with SLA greater than 79 - using gt operation
Host: prd-csr-01.prd.norn.local - SLA: 90
Host: dfjt-r001.prd.norn.local - SLA: 90
Host: prd-arista-01.prd.norn.local - SLA: 90
Host: prd-arista-02.prd.nron.local - SLA: 90
Host: prd-junos-01.prd.norn.local - SLA: 90
Host: prd-nxos-01.prd.norn.local - SLA: 90
Host: prd-paloalto-01.prd.norn.local - SLA: 90
Host: prd-paloalto-02.prd.norn.local - SLA: 90
Host: prd-junos-06.prd.norn.local - SLA: 90
Host: tst-csr-01.tst.norn.local - SLA: 80
Host: dfjt-r001.tst.norn.local - SLA: 80
Host: tst-arista-01.tst.norn.local - SLA: 80
Host: tstt-arista-02.tst.norn.local - SLA: 80
Host: tst-junos-01.tst.norn.local - SLA: 80
Host: tst-nxos-01.tst.norn.local - SLA: 80
Host: tst-paloalto-01.tst.norn.local - SLA: 80
Host: tst-paloalto-02.tst.norn.local - SLA: 80
Host: tst-junos-06.tst.norn.local - SLA: 80
Total: 18
==================================================
==================================================
All devices with SLA less than or equal to 80 - using le operation
Host: lab-csr-011.lab.norn.local - SLA: 70
Host: dfjt-r001.lab.norn.local - SLA: 70
Host: lab-arista-01.lab.norn.local - SLA: 70
Host: lab-arista-02.lab.norn.local - SLA: 70
Host: lab-junos-01.lab.norn.local - SLA: 70
Host: lab-nxos-01.lab.norn.local - SLA: 70
Host: lab-paloalto-01.lab.djft.local - SLA: 70
Host: lab-paloalto-02.lab.norn.local - SLA: 70
Host: lab-junos-06.lab.norn.local - SLA: 70
Host: tst-csr-01.tst.norn.local - SLA: 80
Host: dfjt-r001.tst.norn.local - SLA: 80
Host: tst-arista-01.tst.norn.local - SLA: 80
Host: tstt-arista-02.tst.norn.local - SLA: 80
Host: tst-junos-01.tst.norn.local - SLA: 80
Host: tst-nxos-01.tst.norn.local - SLA: 80
Host: tst-paloalto-01.tst.norn.local - SLA: 80
Host: tst-paloalto-02.tst.norn.local - SLA: 80
Host: tst-junos-06.tst.norn.local - SLA: 80
Total: 18
==================================================
==================================================
All devices with SLA less than 80 - using lt operation
Host: lab-csr-011.lab.norn.local - SLA: 70
Host: dfjt-r001.lab.norn.local - SLA: 70
Host: lab-arista-01.lab.norn.local - SLA: 70
Host: lab-arista-02.lab.norn.local - SLA: 70
Host: lab-junos-01.lab.norn.local - SLA: 70
Host: lab-nxos-01.lab.norn.local - SLA: 70
Host: lab-paloalto-01.lab.djft.local - SLA: 70
Host: lab-paloalto-02.lab.norn.local - SLA: 70
Host: lab-junos-06.lab.norn.local - SLA: 70
Total: 9
==================================================

# Use Case 5 - contains operation
# Filter for a platform that contains "nos" in it.
# i.e match "paloalto_panos" or "junos" but not "nxos"
network_nos = nr.filter(F(platform__contains="nos"))
# Print seperator and header
print("=" * 50)
print("All devices contain 'nos' in platform - using contain operation")
# Iterate over filtered results and printout information
for host, data in network_nos.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Platform: {data.platform}"
    )
# Print total and seperator
print(f"Total: {len(network_nos.inventory.hosts.items())}")
print("=" * 50)
# Use Case 6 - startswith operation
# Filter for a platform that starts with "am".
# i.e match "amer", "amea" but not "apac"
am_devs = nr.filter(F(region__startswith="am"))
# Print seperator and header
print("=" * 50)
print("All devices starts with 'am' in region - using startswith operation")
# Iterate over filtered results and printout information
for host, data in am_devs.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Platform: {data['region']}"
    )
# Print total and seperator
print(f"Total: {len(am_devs.inventory.hosts.items())}")
print("=" * 50)
# Use Case 7 - endswith operation
# Filter for a platform that ends with "l".
# i.e match "mtl", "mel" or "ptl", but not "chc", "hbt" or "bcn"
l_site_code_devs = nr.filter(F(site_code__endswith="l"))
# Print seperator and header
print("=" * 50)
print("All devices ends with 'l' in site code - using endswith operation")
# Iterate over filtered results and printout information
for host, data in l_site_code_devs.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Platform: {data['site_code']}"
    )
# Print total and seperator
print(f"Total: {len(l_site_code_devs.inventory.hosts.items())}")
print("=" * 50)
# Use Case 8 - any operation
# Filter for a platform that is any of elements in our cisco_platforms
# list
cisco_platforms = ["catos", "ios", "iosxe", "iosxr", "nxos"]
cisco_devs = nr.filter(F(platform__any=cisco_platforms))
# Print seperator and header
print("=" * 50)
print(f"All devices which contains {cisco_platforms} - using contains operation")
# Iterate over filtered results and printout information
for host, data in cisco_devs.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Platform: {data.platform}"
    )
# Print total and seperator
print(f"Total: {len(cisco_devs.inventory.hosts.items())}")
print("=" * 50)
# Use Case 9 - has_parent_group operation
# Filter for any hosts which have the parent group of test
test_devs  = nr.filter(F(has_parent_group="test"))
# Print seperator and header
print("=" * 50)
print(f"All devices which has parent group of test - using has_parent_group operation")
# Iterate over filtered results and printout information
for host, data in test_devs.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Production: {data['production']}"
    )
# Print total and seperator
print(f"Total: {len(test_devs.inventory.hosts.items())}")
print("=" * 50)
# Use Case 10 - in operation
# Filter for a platform that is in one of elements in our non_cisco_platforms
# list
# NOTE: Not sure how different this is to the "any" operation in case you
# were wondering too.
non_cisco_platforms = ["eos", "paloalto_panos", "junos"]
non_cisco_devs = nr.filter(F(platform__in=non_cisco_platforms))
# Print seperator and header
print("=" * 50)
print(f"All devices which are in the list {non_cisco_platforms} - using in operation")
# Iterate over filtered results and printout information
for host, data in non_cisco_devs.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Platform: {data.platform}"
    )
# Print total and seperator
print(f"Total: {len(non_cisco_devs.inventory.hosts.items())}")
print("=" * 50)
# Use Case 11 - all operation
# Filter for a device which has all groups
all_groups = ["eos","prod", "mel"]
eos_prod_mel = nr.filter(F(groups__all=all_groups))
# Print seperator and header
print("=" * 50)
print(f"All devices which all the groups {all_groups} - using all operation")
# Iterate over filtered results and printout information
for host, data in eos_prod_mel.inventory.hosts.items():
    print(
        f"Host: {host} "
        + f"- Groups: {data.groups}"
    )
# Print total and seperator
print(f"Total: {len(eos_prod_mel.inventory.hosts.items())}")
print("=" * 50)

#output
==================================================
All devices contain 'nos' in platform - using contain operation
Host: lab-junos-01.lab.norn.local - Platform: junos
Host: lab-paloalto-01.lab.djft.local - Platform: paloalto_panos
Host: lab-paloalto-02.lab.norn.local - Platform: paloalto_panos
Host: lab-junos-06.lab.norn.local - Platform: junos
Host: prd-junos-01.prd.norn.local - Platform: junos
Host: prd-paloalto-01.prd.norn.local - Platform: paloalto_panos
Host: prd-paloalto-02.prd.norn.local - Platform: paloalto_panos
Host: prd-junos-06.prd.norn.local - Platform: junos
Host: tst-junos-01.tst.norn.local - Platform: junos
Host: tst-paloalto-01.tst.norn.local - Platform: paloalto_panos
Host: tst-paloalto-02.tst.norn.local - Platform: paloalto_panos
Host: tst-junos-06.tst.norn.local - Platform: junos
Total: 12
==================================================
==================================================
All devices starts with 'am' in region - using startswith operation
Host: dfjt-r001.lab.norn.local - Platform: amea
Host: lab-arista-01.lab.norn.local - Platform: amer
Host: lab-junos-01.lab.norn.local - Platform: amer
Host: lab-nxos-01.lab.norn.local - Platform: amer
Host: lab-paloalto-02.lab.norn.local - Platform: amea
Host: tst-arista-01.tst.norn.local - Platform: amea
Host: tstt-arista-02.tst.norn.local - Platform: amea
Host: tst-junos-01.tst.norn.local - Platform: amea
Total: 8
==================================================
==================================================
All devices ends with 'l' in site code - using endswith operation
Host: lab-csr-011.lab.norn.local - Platform: mel
Host: lab-arista-01.lab.norn.local - Platform: mtl
Host: lab-arista-02.lab.norn.local - Platform: mel
Host: lab-junos-01.lab.norn.local - Platform: mtl
Host: lab-nxos-01.lab.norn.local - Platform: mtl
Host: lab-paloalto-01.lab.djft.local - Platform: mel
Host: lab-junos-06.lab.norn.local - Platform: mel
Host: prd-csr-01.prd.norn.local - Platform: mel
Host: dfjt-r001.prd.norn.local - Platform: mel
Host: prd-arista-01.prd.norn.local - Platform: mel
Host: prd-arista-02.prd.nron.local - Platform: mel
Host: prd-junos-01.prd.norn.local - Platform: mel
Host: prd-nxos-01.prd.norn.local - Platform: mel
Host: prd-paloalto-01.prd.norn.local - Platform: mel
Host: prd-paloalto-02.prd.norn.local - Platform: mel
Host: prd-junos-06.prd.norn.local - Platform: mel
Host: tst-csr-01.tst.norn.local - Platform: mel
Host: dfjt-r001.tst.norn.local - Platform: mel
Host: tst-arista-01.tst.norn.local - Platform: ptl
Host: tstt-arista-02.tst.norn.local - Platform: ptl
Host: tst-junos-01.tst.norn.local - Platform: ptl
Total: 21
==================================================
==================================================
All devices which contains ['catos', 'ios', 'iosxe', 'iosxr', 'nxos'] - using contains operation
Host: lab-csr-011.lab.norn.local - Platform: ios
Host: dfjt-r001.lab.norn.local - Platform: ios
Host: lab-nxos-01.lab.norn.local - Platform: nxos
Host: prd-csr-01.prd.norn.local - Platform: ios
Host: dfjt-r001.prd.norn.local - Platform: ios
Host: tst-csr-01.tst.norn.local - Platform: ios
Host: dfjt-r001.tst.norn.local - Platform: ios
Host: tst-nxos-01.tst.norn.local - Platform: nxos
Total: 8
==================================================
==================================================
All devices which has parent group of test - using has_parent_group operation
Host: tst-csr-01.tst.norn.local - Production: False
Host: dfjt-r001.tst.norn.local - Production: False
Host: tst-arista-01.tst.norn.local - Production: False
Host: tstt-arista-02.tst.norn.local - Production: False
Host: tst-junos-01.tst.norn.local - Production: False
Host: tst-nxos-01.tst.norn.local - Production: False
Host: tst-paloalto-01.tst.norn.local - Production: False
Host: tst-paloalto-02.tst.norn.local - Production: False
Host: tst-junos-06.tst.norn.local - Production: False
Total: 9
==================================================
==================================================
All devices which are in the list ['eos', 'paloalto_panos', 'junos'] - using in operation
Host: lab-arista-01.lab.norn.local - Platform: eos
Host: lab-arista-02.lab.norn.local - Platform: eos
Host: lab-junos-01.lab.norn.local - Platform: junos
Host: lab-paloalto-01.lab.djft.local - Platform: paloalto_panos
Host: lab-paloalto-02.lab.norn.local - Platform: paloalto_panos
Host: lab-junos-06.lab.norn.local - Platform: junos
Host: prd-arista-01.prd.norn.local - Platform: eos
Host: prd-arista-02.prd.nron.local - Platform: eos
Host: prd-junos-01.prd.norn.local - Platform: junos
Host: prd-paloalto-01.prd.norn.local - Platform: paloalto_panos
Host: prd-paloalto-02.prd.norn.local - Platform: paloalto_panos
Host: prd-junos-06.prd.norn.local - Platform: junos
Host: tst-arista-01.tst.norn.local - Platform: eos
Host: tstt-arista-02.tst.norn.local - Platform: eos
Host: tst-junos-01.tst.norn.local - Platform: junos
Host: tst-paloalto-01.tst.norn.local - Platform: paloalto_panos
Host: tst-paloalto-02.tst.norn.local - Platform: paloalto_panos
Host: tst-junos-06.tst.norn.local - Platform: junos
Total: 18
==================================================
==================================================
All devices which all the groups ['eos', 'prod', 'mel'] - using all operation
Host: prd-arista-01.prd.norn.local - Groups: [Group: eos, Group: prod, Group: mel]
Host: prd-arista-02.prd.nron.local - Groups: [Group: eos, Group: prod, Group: mel]
Total: 2
==================================================

Filter functions

Filter函数是一个强的过滤方法,它可以通过一个python脚本来过滤你的nornir主机库。

用这个方法,你可以写复杂的过滤逻辑并在在另外一个函数种管理,并且当你需要时调用它。

在这个用例中我们将介绍一些用正则表达式分析hostname的案例,然后再其他的函数中调用。这只是很多用途中的一种,希望它可以帮助你激发想象力。

# Import modules
from nornir import InitNornir
from nornir.core.filter import F
import re
# Initialise nornir
nr = InitNornir(config_file="filtering_deep_dive/config.yaml")
"""
Below are some example filter functions, which we will call in later functions
"""

def even_device_naming_convention(host):
    """
    Helper filter function to filter hosts based targeting
    host names which have even number names.
    Examples:
        - lab-junos-08.prd.norn.local
        - lab-arista-22.tst.norn.local
        - lab-nxos-64.lab.norn.local
    :param host: The host you want to filter on
    :return bool: True if it matches, False if it doesn't match
    """
    # Perform regex match on host name and return boolean
    if re.match(".+\-[0-9][2,4,6,8,0].+", host.name):
        return True
    else:
        return False


def device_name_convention(host):
    """
    Helper filter function to filter hosts based targeting
    host names which a specified naming convention
    Examples:
        - lab-junos-08.tst.norn.local
        - lab-arista-22.prd.norn.local
        - lab-nxos-01.lab.norn.local
    :param host: The host you want to filter on
    :return bool: True if it matches, False if it doesn't match
    """
    # Perform regex match on host name and return boolean
    if re.match("\w{3}\-\w+\-\d{2}.\w{3}.norn.local", host.name):
        return True
    else:
        return False


def non_device_name_convention(host):
    """
    Helper filter function to filter hosts based targeting
    host names which do NOT match a specified naming convention
    Examples:
        - lab-junos-08.tstt.norn.local
        - dfjt-arista-22.prd.norn.local
        - lab-nxos-001.lab.nron.local
    :param host: The host you want to filter on
    :return bool: True if does not match, False if it matches the convention
    """
    # Perform regex match on host name and return boolean
    if re.match("\w{3}\-\w+\-\d{2}.\w{3}.norn.local", host.name):
        return False
    else:
        return True


def filter_functions(nr):
    """
    An example of wrapping filter functions to retrieve some more complex
    filtering queries.

    Three use cases are shown:
        - Use Case 1 - Filter inventory for "even" numbered devices.
        - Use Case 2 - Filter inventory for device which meet
        the naming convention.
        - Use Case 3 - Filter inventory for device which DO NOT meet
        the naming convention.

    :param nr: An initialised Nornir inventory, used for processing.
    """
    # We use the 'filter_func' option to run our entire inventory through the python
    # function called 'even_device_naming_convention'
    even_device_name_hosts = nr.filter(filter_func=even_device_naming_convention)
    # Print seperator and header
    print("=" * 50)
    print("The hosts which match the even device naming convention are:")
    # Iterate over filtered results and printout information
    for host, data in even_device_name_hosts.inventory.hosts.items():
        print(f"Host: {host} ")
    # Print total and seperator
    print(f"Total: {len(even_device_name_hosts.inventory.hosts.items())}")
    print("=" * 50)
    # Use Case 2 - Devices which match the naming convention
    # We use the 'filter_func' option to run our entire inventory through the python
    # function called 'device_name_convention'
    compliant_naming_convention_hosts = nr.filter(filter_func=device_name_convention)
    # Print seperator and header
    print("=" * 50)
    print("The hosts which match the device naming convention are:")
    # Iterate over filtered results and printout information
    for host, data in compliant_naming_convention_hosts.inventory.hosts.items():
        print(f"Host: {host} ")
    # Print total and seperator
    print(f"Total: {len(compliant_naming_convention_hosts.inventory.hosts.items())}")
    print("=" * 50)
    # Use Case 2 - Devices which DO NOT match the naming convention
    # We use the 'filter_func' option to run our entire inventory through the python
    # function called 'non_device_name_convention'
    non_compliant_naming_convention_hosts = nr.filter(filter_func=non_device_name_convention)
    # Print seperator and header
    print("=" * 50)
    print("The hosts which DO NOT match the device naming convention are:")
    # Iterate over filtered results and printout information
    for host, data in non_compliant_naming_convention_hosts.inventory.hosts.items():
        print(f"Host: {host} ")
    # Print total and seperator
    print(f"Total: {len(non_compliant_naming_convention_hosts.inventory.hosts.items())}")
    print("=" * 50)


# Call wrapper function
filter_functions(nr)

#output
==================================================
The hosts which match the even device naming convention are:
Host: lab-arista-02.lab.norn.local
Host: lab-paloalto-02.lab.norn.local
Host: lab-junos-06.lab.norn.local
Host: prd-arista-02.prd.nron.local
Host: prd-paloalto-02.prd.norn.local
Host: prd-junos-06.prd.norn.local
Host: tstt-arista-02.tst.norn.local
Host: tst-paloalto-02.tst.norn.local
Host: tst-junos-06.tst.norn.local
Total: 9
==================================================
==================================================
The hosts which match the device naming convention are:
Host: lab-arista-01.lab.norn.local
Host: lab-arista-02.lab.norn.local
Host: lab-junos-01.lab.norn.local
Host: lab-nxos-01.lab.norn.local
Host: lab-paloalto-02.lab.norn.local
Host: lab-junos-06.lab.norn.local
Host: prd-csr-01.prd.norn.local
Host: prd-arista-01.prd.norn.local
Host: prd-junos-01.prd.norn.local
Host: prd-nxos-01.prd.norn.local
Host: prd-paloalto-01.prd.norn.local
Host: prd-paloalto-02.prd.norn.local
Host: prd-junos-06.prd.norn.local
Host: tst-csr-01.tst.norn.local
Host: tst-arista-01.tst.norn.local
Host: tst-junos-01.tst.norn.local
Host: tst-nxos-01.tst.norn.local
Host: tst-paloalto-01.tst.norn.local
Host: tst-paloalto-02.tst.norn.local
Host: tst-junos-06.tst.norn.local
Total: 20
==================================================
==================================================
The hosts which DO NOT match the device naming convention are:
Host: lab-csr-011.lab.norn.local
Host: dfjt-r001.lab.norn.local
Host: lab-paloalto-01.lab.djft.local
Host: dfjt-r001.prd.norn.local
Host: prd-arista-02.prd.nron.local
Host: dfjt-r001.tst.norn.local
Host: tstt-arista-02.tst.norn.local
Total: 7
==================================================

Conclusion

感谢已经关注这个教程。如果你已经阅读完了,我确定你会同意nornir过滤的强大和
无限可能性。

我们基本覆盖了基础、中级和高级的过滤通过网络自动化的一些用例。希望可以给你一些撬动这个feature上的想法和灵感。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容