Table of Contents

Nornir Netbox Inventory is another solution for inventory management in Nornir based network automation.

In the previous section, we installed Netbox and added inventory information.

In this section, we read netbox inventory information through Nornir and then send monitoring commands to network devices that have already been read from the netbox inventory.

Nornir Netbox Inventory Configuration

From the beginning of the course until now we have always used and configured “SimpleInventory” in the Nornir configuration file which uses “hosts.yaml”, “groups.yaml” and “defaults.yaml” to retrieve inventory information of network devices such as IP address, platform, device group membership and credentials to connect to network devices.

Nornir Simple versus Netbox Inventory Configuration
Nornir Simple versus Netbox Inventory Configuration

But in order to use Netbox as Nornir inventory source, we need to modify the Nornir config file so that it can use netbox instead of simple inventory file to get the necessary information.

Before we can use netbox as an inventory file, we need to install the netbox plugin through the python pip package manager. The plugin can be installed with “python3 -m pip install nornir-netbox” command.

python3 -m pip install nornir-netbox

Then we are allowed to change the type of the inventory to “NetBoxInventory2” instead of “SimpleInventory” in the Nornir configuration file.

# nornir old configuration
majid@devnet:~/devnet/pyhton_nornir/2023/11.netbox$ cat ../10.jinja2_template/config.yaml
---

inventory:
  plugin: SimpleInventory
  options:
    host_file: "hosts.yaml"
    group_file: "groups.yaml"
    defaults_file: "defaults.yaml"

runner:
  plugin: threaded
  options:
    num_workers: 10
# nornir new configuration to use netbox inventory
majid@devnet:~/devnet/pyhton_nornir/2023/11.netbox$ cat config.yaml
---

inventory:
  plugin: NetBoxInventory2
  options:
    nb_url: "http://127.0.0.1:8000"
    nb_token: "0123456789abcdef0123456789abcdef01234567"
    ssl_verify: false

runner:
  plugin: threaded
  options:
    num_workers: 10

Additionally we need to give the IP address and port number to access the Netbox API.

To authenticate the access to the netbox through the API, we also configure API token which can be achieved from Netbox web interface, admin section menus and “API Tokens” option.

Netbox API Tokens
Netbox API Tokens

Since we’re not using a valid SSL certificate for the demonstration, we’ll configure it not to perform SSL verification.

I have provided two scripts to show nornir netbox inventory capability.

In the first script, we only read inventory data from netbox and print them in the screen.

In the second script, we use inventory information retrieved from netbox to connect and send command to the network devices.

Nornir Script Example to Get Netbox Inventory Information

This is the first script in which only import InitNornir from nornir library. The “rptint” from “rich” library is used to show the output in a nicer format and is not required.

from nornir import InitNornir
from rich import print as rprint

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

# it is not recommended to store username and password in automation script.
# in the next script we use environment variables to read the username and password.
nr.inventory.defaults.username = "rayka"
nr.inventory.defaults.password = "rayka-co.ir"

def get_inventory_from_netbox(task):
    rprint(f"device name: {task.host}")
    rprint(f"device IP address: {task.host.hostname}")
    rprint(f"device platform: {task.host.platform}")
    rprint(f"device inventory data: {task.host.data}")

nr.run(task=get_inventory_from_netbox)

In this script we store the username and password in the automation secret itself, which is not recommended.

In the next script, we’ll export the username and password as an environment variables before running the script, and then read them from the environment variable in the automation script.

In the next step we print the inventory information, the name of the device, the IP address of the device, platform of the device and some other Information stored in netbox inventory through “data” key word.

Do not forget that the address of netbox inventory source is already defined in nornir configuration file.

Now let’s run the script and see the result.

majid@devnet:~/devnet/pyhton_nornir/2023/11.netbox$ python3 11.1.get_inventory_from_netbox.py
device name: R1
device IP address: 192.168.2.91
device platform: ios
device inventory data: {'id': 3, 'url': 'http://127.0.0.1:8000/api/dcim/devices/3/', 'display': 'R1', 'name':
'R1', 'device_type': {'id': 3, 'url': 'http://127.0.0.1:8000/api/dcim/device-types/3/', 'display': 'ios',
'manufacturer': {'id': 3, 'url': 'http://127.0.0.1:8000/api/dcim/manufacturers/3/', 'display': 'cisco', 'name':
'cisco', 'slug': 'cisco'}, 'model': 'ios', 'slug': 'ios'}, 'device_role': {'id': 3, 'url':
'http://127.0.0.1:8000/api/dcim/device-roles/3/', 'display': 'router', 'name': 'router', 'slug': 'router'},
'tenant': None, 'platform': {'id': 3, 'url': 'http://127.0.0.1:8000/api/dcim/platforms/3/', 'display': 'ios',
'name': 'ios', 'slug': 'ios'}, 'serial': '', 'asset_tag': None, 'site': {'id': 3, 'url':
'http://127.0.0.1:8000/api/dcim/sites/3/', 'display': 'central_office', 'name': 'central_office', 'slug':
'central_office'}, 'location': None, 'rack': None, 'position': None, 'face': None, 'parent_device': None,
'status': {'value': 'active', 'label': 'Active'}, 'airflow': None, 'primary_ip': {'id': 3, 'url':
'http://127.0.0.1:8000/api/ipam/ip-addresses/3/', 'display': '192.168.2.91/24', 'family': 4, 'address':
'192.168.2.91/24'}, 'primary_ip4': {'id': 3, 'url': 'http://127.0.0.1:8000/api/ipam/ip-addresses/3/', 'display':
'192.168.2.91/24', 'family': 4, 'address': '192.168.2.91/24'}, 'primary_ip6': None, 'cluster': None,
'virtual_chassis': None, 'vc_position': None, 'vc_priority': None, 'description': '', 'comments': '',
'local_context_data': None, 'tags': [], 'custom_fields': {}, 'config_context': {}, 'created':
'2023-02-08T22:03:28.880181Z', 'last_updated': '2023-02-12T01:37:18.679146Z'}

As you can see, besides the network device name and IP address, there are some other inventory information keys in the inventory, but there are no value displayed because we have not configured them.

Use Netbox Inventory to Connect and Send Command to Network Devices

This is the second script to send show command to network devices.

import os
from nornir import InitNornir
from nornir_scrapli.tasks import send_command
from nornir_utils.plugins.functions import print_result

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

# before running the script export username and password in environment variables in automation machine
#majid@devnet:$ export USERNAME='rayka'
#majid@devnet:$ export PASSWORD='rayka-co.com'

# read username and password from environment variables and storethem into nornir username and password variables
nr.inventory.defaults.username = os.environ['USERNAME']
nr.inventory.defaults.password = os.environ['PASSWORD']

# you can any other methods to not store clear text password in automation script
# like  public key authentication, sysargv, GPG or getpass, ...

def use_netbox_as_nornir_inventory_source(task):
    task.run(task=send_command, command="show ip interface brief")

results = nr.run(task=use_netbox_as_nornir_inventory_source)
print_result(results)

We use nornir scrapli to send “show ip interface brief” command.

But before we run the script, we export the username and password in the environment variables. Then in the automation script we read the username and password from the environment variables and store them in the nornir username and password variables using the “os.environ” function.

This way we don’t need to store the username and password in the automation script itself.

Of course this is not the only method, not to store clear username and password in automation script.

In the lessons 17 to 20 we have introduced and demonstrated “getpass”, “sysargv”, “gpg” and “PKI” methods.

Now let’s run the script and see the result.

majid@devnet:~/devnet/pyhton_nornir/2023/11.netbox$ python3 11.2.netbox_send_command.py
netbox_send_command*************************************************************
* R1 ** changed : False ********************************************************
vvvv netbox_send_command ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO
---- send_command ** changed : False ------------------------------------------- INFO
Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1       192.168.2.91    YES NVRAM  up                    up
GigabitEthernet2       unassigned      YES NVRAM  administratively down down
GigabitEthernet3       unassigned      YES NVRAM  administratively down down
^^^^ END netbox_send_command ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

As we expected, the “show ip interface” command runs on the managed device and returns the result.

you can download the scripts related to nornir netbox plugin from this link.

Back to: CLI based Network Automation using Python Nornir > Netbox as Inventory Source in Network Automation

Leave a Reply

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


Post comment