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