Skip to content

Inventory

The Nautobot ORM inventory is rather static in nature at this point. The user has the ability to define the default data. The native capabilities include.

  • Providing an object called within the obj key that is a Nautobot Device object instance.
  • Provide additional keys for hostname, name, id, type, location, role, config_context, and custom_field_data.
  • Provide grouping for global, location, role, type, and manufacturer based on their names (more details below).
  • Provide credentials for NAPALM, Netmiko, and Scrapli.
  • Link to the credential class as defined by the nornir_settings['settings'] definition.

Enabling the use of Config Context:

PLUGINS_CONFIG = {
    "nautobot_plugin_nornir": {
        "allowed_location_types": ["Site"],
        "denied_location_types": ["Region"],
        "use_config_context": {
            "connection_options": True
        },
    }
}

Local Device Config Context:

{
    "nautobot_plugin_nornir": {
        "connection_options": {
            "napalm": {
                "extras": {
                    "optional_args": {
                        "global_delay_factor": 5
                    }
                }
            }
        }
    }
}

Device Type Config Context:

---
_metadata:
  name: spine
  weight: 1000
  description: Group Definitions for device type SPINE
  is_active: true
  device-roles:
    - name: spine
nautobot_plugin_nornir:
  connection_options:
    napalm:
    extras:
        optional_args:
        global_delay_factor: 5

Inventory Groupings

The inventory provides natural groupings of the following.

  • "global"
  • "location__{device.location.name}"
  • "location__{device.location.parent.name}"
  • "role__{device.role.name}"
  • "type__{device.device_type.model}"
  • "manufacturer__{device.device_type.manufacturer.name}"

As an example, if you had manufacturer of cisco and arista, there will automatically be groups call manufacturer__cisco and manufacturer__arista.

All allowed locations from locations tree will be included as groups. If the device is assigned to the location of US-East, and it has the parent location of US, there will be groups called location__US and location__US-East. Allowed or denied locations can be tuned by specifying allowed_location_types or denied_location_types in the PLUGINS_CONFIG settings.

Using the Inventory

The inventory provides a series of parameters that you can use, similar to any Nornir inventory. The specific parameters provided are:

queryset: QuerySet = None
filters: Dict = None
credentials_class: str = "nautobot_plugin_nornir.plugins.credentials.env_vars.CredentialsEnvVars"
credentials_params: Dict = None
params: Dict = None
defaults: Dict = None

The most important part about the inventory is providing a valid queryset. This defines what is in scope for your environment. Ideally, the code that interacts with the inventory (via jobs, a plugin, or other custom code) would take some parameters to filter the queryset. In the below illustrative example we simply use the full inventory:

from nautobot.dcim.models import Device

from nornir import InitNornir
from nornir.core.plugins.inventory import InventoryPluginRegister

from nautobot_plugin_nornir.plugins.inventory.nautobot_orm import NautobotORMInventory

InventoryPluginRegister.register("nautobot-inventory", NautobotORMInventory)

qs = Device.objects.all()
data = {"company": "acme"}

nr = InitNornir(
    runner={"options": {"num_workers": 20}},
    logging={"enabled": False},
    inventory={
        "plugin": "nautobot-inventory",
        "options": {
            "credentials_class": "nautobot_plugin_nornir.plugins.credentials.env_vars.CredentialsEnvVars",
            "params": {"use_fqdn": True, "fqdn": "acme.com"},
            "queryset": qs,
            "defaults": data,
        },
    },
)

print(nr)

To illustrate this further, included is an example in which we filter the queryset further. This pattern while simple can be used to provide query capabilities within a specific Nornir play vs another one.

from nautobot.dcim.models import Device
from nautobot.dcim.filters import DeviceFilterSet

from nornir import InitNornir
from nornir.core.plugins.inventory import InventoryPluginRegister

from nautobot_plugin_nornir.plugins.inventory.nautobot_orm import NautobotORMInventory

InventoryPluginRegister.register("nautobot-inventory", NautobotORMInventory)

def get_qs(location=None):
    query = {}
    if location:
        query["location__name"] = location
    base_qs = Device.objects.all()
    return DeviceFilterSet(data=query, queryset=base_qs).qs

qs = get_qs("acme")
data = {"company": "acme"}

nr = InitNornir(
    runner={"options": {"num_workers": 20}},
    logging={"enabled": False},
    inventory={
        "plugin": "nautobot-inventory",
        "options": {
            "credentials_class": "nautobot_plugin_nornir.plugins.credentials.env_vars.CredentialsEnvVars",
            "params": {"use_fqdn": True, "fqdn": "acme.com"},
            "queryset": qs,
            "defaults": data,
        },
    },
)

print(nr)