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.
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.