FFun

Nornir interacts with many devices and has it’s own inventory. FFun is an extension that uses Nornir’s built-in filtering capabilities to narrow down tasks execution to certain hosts/devices.

Filtering order:

FO -> FB -> FC -> FR -> FG -> FP -> FL -> FN

Note

If multiple filters provided, hosts must pass all checks - AND logic - to succeed.

FFun filters overview

FO - Filter Object

Filter using Nornir Filter Object

Examples:

# Platform ios and hostname 192.168.217.7:
filtered_hosts = FFun(NornirObj, FO={"platform": "ios", "hostname": "192.168.217.7"})

# Host with name R1 or R2:
filtered_hosts = FFun(NornirObj, FO={"name__any": ["R1", "R2"])

# Location B1 or location B2:
filtered_hosts = FFun(NornirObj, FO=[{"location": "B1"}, {"location": "B2"}])

# Location B1 and platform ios or any host at location B2:
filtered_hosts = FFun(NornirObj, FO=[{"location": "B1", "platform": "ios"}, {"location": "B2"}])

FB - Filter gloB

Filter hosts by name using Glob Patterns matching fnmatchcase module:

# Match R1, R2, R# hostnames but not R11 or R4:
filtered_hosts = FFun(NornirObj, FB="R[123]")

# Match R1, R2, and SW1 but not R11 or R4 or eSW1 using list of patterns:
filtered_hosts = FFun(NornirObj, FB=["R[12]", "SW*"])

# Match R1, R2, and SW1 but not R11 or R4 or eSW1 using comma separated list of patterns:
filtered_hosts = FFun(NornirObj, FB="R[12], SW*")

If list of patterns provided, host matching at least one pattern will pass this check.

FC - Filter Contains Any

Filter hosts by checking if their name contains any of the string patterns:

# Match core-switch-1 but not switch-1:
filtered_hosts = FFun(NornirObj, FC="core-switch")

# Match R1, R2, and SW1 but not ER33 or CR4 using list of patterns:
filtered_hosts = FFun(NornirObj, FC=["R1", "R2", "SW"])

# Match R1, R2, and SW1 but not ER33 or CR4 using comma separated list of patterns:
filtered_hosts = FFun(NornirObj, FC="R1, R2, SW")

If list of patterns provided, host matching at least one pattern will pass this check.

FR - Filter Regex

Filter hosts by checking if their name contains any of regular expression patterns:

# Match core-switch-1 but not switch-1:
filtered_hosts = FFun(NornirObj, FR=".+core-switch.+")

# Match R1, R2, and SW1 but not ER33 or CR4 using list of patterns:
filtered_hosts = FFun(NornirObj, FR=["^R1$", "^R2$", "^SW$"])

If list of patterns provided, host matching at least one pattern will pass this check.

FG - Filter Group

Filter hosts by group returning all hosts that belongs to given group:

# return hosts that belong to 'lab' group only
filtered_hosts = FFun(NornirObj, FG="lab")

FP - Filter Prefix

Filter hosts by checking if hosts hostname is part of at least one of given IP Prefixes:

# return hosts with hostnames in 192.168.217.0/29, 192.168.2.0/24 ranges
filtered_hosts = FFun(NornirObj, FP="192.168.217.0/29, 192.168.2.0/24")

If host’s inventory hostname is IP, will use it as is, if it is FQDN, will attempt to resolve it to obtain IP address, if DNS resolution fails, host fails the check.

FL - Filter List

Match only hosts with names in provided list:

filtered_hosts = FFun(NornirObj, FL="R1, R2")

FN - Filter Negate

Negate matching results if FN argument set to True:

# will match all hosts except R1 and R2
filtered_hosts = FFun(NornirObj, FL="R1, R2", FN=True)

FFun passes through all the Fx functions filtering hosts normally, FN function called at the end to form a set of non matched hosts, that set used with FL function to provide final match result.

FFun sample usage

Example how to invoke FFun filtering:

import pprint
import yaml
from nornir import InitNornir
from nornir_netmiko import netmiko_send_command
from nornir_salt.plugins.functions import FFun

inventory_data = '''
hosts:
  R1:
    hostname: 192.168.1.151
    platform: ios
    groups: [lab]
    data:
      role: core
      site: B1
  SW1:
    hostname: 192.168.2.144
    platform: nxos_ssh
    groups: [lab, pod1]
    data:
      role: access
      site: B3

groups:
  lab:
    username: cisco
    password: cisco
  pod1:
    username: cisco@
    password: cisco
'''

inventory_dict = yaml.safe_load(inventory_data)

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

filtered_hosts = FFun(NornirObj, FB="R*", FG="lab", FP="192.168.1.0/24", FO={"role": "core"})

pprint.pprint(filtered_hosts.dict()["inventory"]["hosts"])

# should print:
# {'R1': {'connection_options': {},
#         'data': {'role': 'core', 'site': 'B1'},
#         'groups': ['lab'],
#         'hostname': '192.168.1.151',
#         'name': 'R1',
#         'password': 'cisco',
#         'platform': 'ios',
#         'port': None,
#         'username': 'cisco'}}

result = filtered_hosts.run(
    task=netmiko_send_command,
    command_string="show clock"
)

FFun return

Nornir object with filtered hosts to further execute tasks against.

FFun reference

nornir_salt.plugins.functions.FFun.FFun(nr, check_if_has_filter=False, **kwargs)

Inventory filters dispatcher function.

Parameters
  • nr – Nornir object

  • kwargs – Dictionary with filtering parameters e.g. {“FB”: “host1*”, “FL”: [“host1”, “host2”]}

  • check_if_has_filter – (bool) default is False, if True, returns tuple (filtered_hosts, has_filter), where has_filter is boolean set to True if any of Fx filters provided

  • FO – (str) Nornir Filter object dictionary

  • FB – (str or list) glob pattern or comma separate list of patterns to filter based on hosts’ names

  • FC – (str or list) pattern or comma separate list of patterns to check for containment in hostname

  • FR – (str or list) regex pattern or list of patterns to filter based on hosts’ names

  • FG – (str) Name of inventory group to return only hosts that part of it

  • FP – (str) string, comma separated list of IPv4 or IPv6 prefixes e.g. 102.168.1.0/24

  • FL – (str) string, comma separated list of hosts’ names to return

  • FN – (bool) default is False, if True, will negate match results to opposite set of hosts