Lab 03 - Filtering the Inventory File¶
Once multiple devices and groups have been defined in the inventory, there are going to be times where only a specific device or a group of devices need to be targeted.
In the next few examples, the filter function will be used to filter the host key for a specific host and the children_of_group method can be used to filter groups. For more advanced filtering on groups the F object which is inside the core.filter package is used.
Task 1 - Basic Filters¶
To only individually target devices, the filter function can be used with the name key as an argument and a value of the device hostname.
Step 1¶
Create a variable for each host that needs to be filtered and use the filter function to specify the name of each device.
>>>
>>> from nornir import InitNornir
>>> from rich import print
>>>
>>> nr = InitNornir(config_file="nornir_configuration/napalm_configuration.yml")
>>>
>>> csr1 = nr.filter(name="csr1")
>>> csr2 = nr.filter(name="csr2")
>>> csr3 = nr.filter(name="csr3")
>>>
Step 2¶
Use the hosts object to print out a dictionary output of the devices stored in each variable defined on the previous step.
>>>
>>> print(csr1.inventory.hosts.keys())
dict_keys(['csr1'])
>>> print(csr2.inventory.hosts.keys())
dict_keys(['csr2'])
>>> print(csr3.inventory.hosts.keys())
dict_keys(['csr3'])
>>>
Step 3¶
This step does not use the filter function. Still, a basic way of filtering groups can be accomplished by using the children_of_group function, and it will return all the devices inside the specified group, including the children's devices nested inside the parent groups.
Create a variable for cisco_group and arista_group. Inside each variable, use the children_of_group() function with the string name of the group. After defining the variables, print them out to view how it returns all the devices that belong to that group, including the nested devices.
>>>
>>> cisco_group = nr.inventory.children_of_group("cisco")
>>>
>>> print(cisco_group)
{Host: csr3, Host: nxos-spine2, Host: nxos-spine1, Host: csr1, Host: csr2}
>>>
>>> arista_group = nr.inventory.children_of_group("arista")
>>>
>>> print(arista_group)
{Host: eos-spine1, Host: eos-leaf1, Host: eos-spine2, Host: eos-leaf2}
>>>
Step 4¶
Create a variable for iosxe_group and use the children_of_group function to filter out all devices inside the iosxe group. Use the same logic to view all the other devices that are part of the parent cisco group.
>>>
>>> iosxe_group = nr.inventory.children_of_group("iosxe")
>>>
>>> print(iosxe_group)
{Host: csr1, Host: csr2, Host: csr3}
>>>
>>> cisco_group = nr.inventory.children_of_group("cisco")
>>>
>>> print(cisco_group)
{Host: csr3, Host: nxos-spine2, Host: nxos-spine1, Host: csr1, Host: csr2}
Step 5¶
You can also filter on the various attributes from the inventory, such as platform:
>>>
>>> print(nr.filter(platform="ios").inventory.hosts)
{'csr1': Host: csr1, 'csr2': Host: csr2, 'csr3': Host: csr3}
>>>
>>> print(nr.filter(platform="eos").inventory.hosts)
{'eos-leaf1': Host: eos-leaf1, 'eos-leaf2': Host: eos-leaf2, 'eos-spine1': Host: eos-spine1, 'eos-spine2': Host: eos-spine2}
>>>
Task 2 - Advanced Filters¶
For more advanced filtering, the F object can be imported to filter out more specific data. In the next few examples, the F object will be used to filter out devices inside specified groups.
Data can be accessed by separating the elements in the path with two underscores __. Then you can use __contains to check if an element exists or if a string has a particular substring.
Step 1¶
Import the F object found inside the nornir.core.filter package. Then create a variable for each group that will be filtered and use the filter function with the F object to look up only the members of a particular group.
>>>
>>>
>>> from nornir.core.filter import F
>>>
>>> iosxe = nr.filter(F(groups__contains="iosxe"))
>>>
>>> nxos = nr.filter(F(groups__contains="nxos"))
>>>
>>> cisco = nr.filter(F(groups__contains="cisco"))
>>>
>>> eos_leaves = nr.filter(F(groups__contains="eos-leaves"))
>>>
>>> eos_spines = nr.filter(F(groups__contains="eos-spines"))
>>>
>>> arista = nr.filter(F(groups__contains="arista"))
>>>
Step 2¶
Print out each filtered object, to return the devices inside each group.
>>> print(iosxe.inventory.hosts.keys())
dict_keys(['csr1', 'csr2', 'csr3'])
>>>
>>> print(nxos.inventory.hosts.keys())
dict_keys(['nxos-spine1', 'nxos-spine2'])
>>>
>>> print(cisco.inventory.hosts.keys())
dict_keys([])
>>>
>>> print(eos_leaves.inventory.hosts.keys())
dict_keys(['eos-leaf1', 'eos-leaf2'])
>>>
>>> print(eos_spines.inventory.hosts.keys())
dict_keys(['eos-spine1', 'eos-spine2'])
>>>
>>> print(arista.inventory.hosts.keys())
dict_keys([])
>>>
Note: You will notice that the filter returns empty host lists for the
ciscoandaristagroups - this is because these parent groups have no hosts directly belonging to them. The hosts they inherit from their children groups (e.g.iosxeforcisco) are not returned here.
Step 3¶
Groups can be filtered based on the string provided and the ~ symbol can be used to filter out the opposite.
Create three different variables using not_in_<group_name> to filter out the opposite of the group provided as a string. Use the ~ symbol to get the opposite output of what is being filtered.
>>>
>>> not_in_iosxe = nr.filter(~F(groups__contains="iosxe"))
>>>
>>> not_in_nxos = nr.filter(~F(groups__contains="nxos"))
>>>
>>> not_in_cisco = nr.filter(~F(groups__contains="cisco"))
>>>
Step 4¶
Print out each filtered object, to return the devices inside each group.
>>>
>>> print(not_in_iosxe.inventory.hosts.keys())
dict_keys(['nxos-spine1', 'nxos-spine2', 'eos-leaf1', 'eos-leaf2', 'eos-spine1', 'eos-spine2'])
>>>
>>> print(not_in_nxos.inventory.hosts.keys())
dict_keys(['csr1', 'csr2', 'csr3', 'eos-leaf1', 'eos-leaf2', 'eos-spine1', 'eos-spine2'])
>>>
>>> print(not_in_cisco.inventory.hosts.keys())
dict_keys(['csr1', 'csr2', 'csr3', 'nxos-spine1', 'nxos-spine2', 'eos-leaf1', 'eos-leaf2', 'eos-spine1', 'eos-spine2'])
>>>