Table of Contents

Nornir filter inventory gives the capability to limit the execution of automation scripts on a specific network device or group of network devices.

In this section we will learn about two different types of Nornir filter, basic filtering using the filter method and advanced filtering using the F object.

Filter Devices by Nornir Filter Function

Depending on the type of configuration, we usually run the automation script on a limited number of network devices. Nornir inventory filtering feature allows you to restrict the network devices that the automation script needs to run on.

There are a few types of Nornir filters. You can see the details and configuration examples of the filters in these links. Link1 and Link2.

We discuss two of the Nornir filter methods.

Nornir Filter Features to filter Inventory Devices
Nornir Filter Features to filter Inventory Devices

One is basic filter where you can filter network devices based on a specific device attribute or a logical AND of some attributes.

The second type is advanced filtering where we can filter devices using complex logical operation of device attributes like AND, OR, NOT, CONTAIN, LESS THAT OR EQUAL and GREATER THAN OR EQUAL.

Configure Device Attributes in Nornir Inventory Files

To start using the Nornir filter function, we first need to configure some attributes for each network device in nornir inventory file.

The device attribute can be anything that can be used to filter devices. Some examples are attributed which are based on physical location, based on device type if it is a router or a switch, based on topological layer of the device if used in access layer or in the core, based on AS number or any others Attributes that can help you filter devices.

Here as an example, I have used four attributes for each device, “type” which shows the type of the device, “city” is the physical location of the device, “core” which shows if it is a core router, and “as” which show the AS number of the device.

All these attributes are configured through adding a “data” field in “hosts.yaml” inventory file

majid@devnet:~/devnet/pyhton_nornir/2023/7.nornir_filter_inventory$ cat hosts.yaml
---

R1:
  hostname: "192.168.2.91"
  groups:
    - cisco
  data:
    type: router
    city: babolsar
    core: False
    as_number: 65001

R2:
  hostname: "192.168.2.92"
  groups:
    - cisco
  data:
    type: switch
    city: munich
    core: True
    as_number: 65002

R3:
  hostname: "192.168.200.101"
  groups:
    - juniper
  data:
    type: switch
    city: frankfurt
    core: True
    as_number: 65002

There are three routers, “R1”, “R2” and “R3” devices in inventory files. For each device, these four attributes are configured.

Since I really only have one device, “R1”, in my lab, I will use the filter in a way to always select “R1” to run the automation script.

In other inventory files, “groups.yaml” and “defaults.yaml”, I have not configured any attributes, but these attributes are also allowed to be configured at the group level or as default attributes.

majid@devnet:~/devnet/pyhton_nornir/2023/7.nornir_filter_inventory$ cat groups.yaml
---

cisco:
  platform: ios

juniper:
  platform: junos

majid@devnet:~/devnet/pyhton_nornir/2023/7.nornir_filter_inventory$ cat defaults.yaml
---

username: "rayka"
password: "rayka-co.com"
platform: "ios"

Nornir basic Filtering using "filter" Method

This is the first script which use basic nornir filter method to filter devices based on attributes.

In this script we use the Nornir Netmiko plugin to send monitoring commands to network devices, but it can also be other Nornir plugins like Nornir Scrapli or Nornir Napalm plugins.

from nornir import InitNornir
from nornir_netmiko.tasks import netmiko_send_command
from nornir_utils.plugins.functions import print_result

nr = InitNornir(config_file="config.yaml")

def nornir_basic_filtering_using_filter_method_example(task):
    task.run(task=netmiko_send_command, command_string="show ip int brief | exc unass")

nr_filter = nr.filter(type="router", city="babolsar")
results=nr_filter.run(task=nornir_basic_filtering_using_filter_method_example)

The only difference in this script is that before executing the function via the “nr” variable initialized by Nornir, we first filter devices with the “filter” method. Then the function is executed through the new filtered initialized nornir variable.

In this filter example, we only run the script on “router” devices located in “babolsar” since the type attribute is configured as “router” and the city attribute is configured as “babolsar”.

The only device matching both attributes is R1. Then it is expected that the script will be run only on router R1.

majid@devnet:~/devnet/pyhton_nornir/2023/7.nornir_filter_inventory$ python3 8.1.nornir_basic_filtering_using_filter_method.py
nornir_basic_filtering_using_filter_method_example******************************
* R1 ** changed : False ********************************************************
vvvv nornir_basic_filtering_using_filter_method_example ** changed : False vvvvv INFO
---- netmiko_send_command ** changed : False ----------------------------------- INFO
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       192.168.2.91    YES NVRAM  up                    up

^^^^ END nornir_basic_filtering_using_filter_method_example ^^^^^^^^^^^^^^^^^^^^

Nornir advanced Filtering using F object

This is the second script which uses advanced nornir filtering features using F object. F object is part of nornir core functions.

To use the F-Object, we need to import it into the script’s header first, then we are allowed to filter devices based on the F-Object’s capabilities.

from nornir import InitNornir
from nornir_netmiko.tasks import netmiko_send_command
from nornir_utils.plugins.functions import print_result
from nornir.core.filter import F

nr = InitNornir(config_file="config.yaml")

def nornir_advanced_filtering_using_F_object_example(task):
    task.run(task=netmiko_send_command, command_string="show ip int brief | exc unass")

nr_filter = nr.filter( (F(type="router") | F(city="babolsar")) & ~F(core="True") & F(as__le="65001") & F(city__contains="bol") )
results=nr_filter.run(task=nornir_advanced_filtering_using_F_object_example)
print_result(results)

There is no logic behind this filter that we use in this script. It is just an example to use some important capabilities of F object.

In the first parentheses, we filter the devices with router type OR those that are located in babolsar. Then we choose between those devices which are NOT core routers AND the as-number is LESS THAN OR EQUAL to 65001 AND the location of the device contains the word “bol”.

As you see, the example is not so reasonable. I have filtered in a way that device R1 is finally selected.

Then the filtered nornir initialized variable is used to call the function based on the nornir netmiko plugin to send monitoring commands to network devices.

The monitoring command is expected to run only on router R1. Let’s check and see the result.

majid@devnet:~/devnet/pyhton_nornir/2023/7.nornir_filter_inventory$ python3 8.2.nornir_advanced_filtering_using_F_object.py
nornir_advanced_filtering_using_F_object_example********************************
* R1 ** changed : False ********************************************************
vvvv nornir_advanced_filtering_using_F_object_example ** changed : False vvvvvvv INFO
---- netmiko_send_command ** changed : False ----------------------------------- INFO
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       192.168.2.91    YES NVRAM  up                    up

^^^^ END nornir_advanced_filtering_using_F_object_example ^^^^^^^^^^^^^^^^^^^^^^

you can download nornir filer scripts from this link.

Back to: CLI based Network Automation using Python Nornir > Nornir Inventory Filter

Leave a Reply

Your email address will not be published. Required fields are marked *


Post comment