Installing the App in Nautobot¶
Here you will find detailed instructions on how to install and configure the App within your Nautobot environment.
Prerequisites¶
- The app is compatible with Nautobot 3.0.0 and higher.
- Databases supported: PostgreSQL, MySQL
Note
Please check the dedicated page for a full compatibility matrix and the deprecation policy.
Access Requirements¶
The Operational Compliance app requires the Nautobot Plugin Nornir App because it connects to devices to collect data. It is included as a dependency, but you will still need to configure Nornir in your Nautobot environment.
For the app to work, your devices in Nautobot must have:
- A Platform assigned (used to match devices to the correct Command Parsers)
- A reachable IP address (primary IP)
- Credentials configured via Nornir (see the Nautobot Plugin Nornir documentation)
Install Guide¶
The app is distributed as a Python package (nautobot-operational-compliance) which can be installed by Python package managers (e.g. pip, poetry, uv etc.) from an authorized private repository.
Important
Nautobot Operational Compliance is commercial (licensed) software. To obtain access to the Network To Code private package repository, please contact us through the customer portal. Then review the instructions on how to set up the repository in your Python package manager of choice.
To ensure Nautobot Operational Compliance is automatically re-installed during future upgrades, create a file named local_requirements.txt (if not already existing) in the Nautobot root directory (alongside requirements.txt) and list the nautobot-operational-compliance package:
Configuration¶
Once installed, the app needs to be enabled in your Nautobot configuration. Add the following to your nautobot_config.py file:
- Append
"nautobot_operational_compliance"to thePLUGINSlist. - Append the
"nautobot_operational_compliance"dictionary to thePLUGINS_CONFIGdictionary and override any defaults.
# In your nautobot_config.py
PLUGINS = [
"nautobot_plugin_nornir", # Required dependency
"nautobot_operational_compliance",
]
PLUGINS_CONFIG = {
"nautobot_plugin_nornir": {
"use_config_context": {"secrets": False, "connection_options": True},
"connection_options": {
"napalm": {
"extras": {
"optional_args": {"global_delay_factor": 1},
},
},
"netmiko": {
"extras": {
"global_delay_factor": 1,
},
},
},
"nornir_settings": {
"credentials": "nautobot_plugin_nornir.plugins.credentials.settings_vars.CredentialsSettingsVars",
"runner": {
"plugin": "threaded",
"options": {
"num_workers": 20,
},
},
},
},
"nautobot_operational_compliance": {
"MOCK_DEVICE_CONNECTIONS": False, # Set to True for demos/testing
}
}
Note
The Nautobot Plugin Nornir configuration above is a basic example. You may need to adjust the connection options based on your specific network devices and authentication methods. For more detailed configuration options, refer to the Nautobot Plugin Nornir documentation.
Post-Install Steps¶
Once the Nautobot configuration is updated, run the Post Upgrade command (nautobot-server post_upgrade) to run migrations and clear any cache:
Then restart (if necessary) the Nautobot services which may include:
- Nautobot
- Nautobot Workers
- Nautobot Scheduler
App Configuration¶
The app behavior can be controlled with the following list of settings:
| Key | Example | Default | Description |
|---|---|---|---|
MOCK_DEVICE_CONNECTIONS |
True |
False |
When set to True, uses mock device connections instead of real network connections. Useful for demos, testing, or local development environments. |
Optional: Creating a Test Device via Script
If you don't already have a device in Nautobot to test with, you can use the following script to create one. This example creates a Cisco IOS Catalyst 8000 device from the Cisco DevNet Sandbox, but you can adjust it for any platform supported by Nornir.
from nautobot.dcim.models import Device, DeviceType, Manufacturer, Platform, Role, Location, LocationType, Status, Interface, IPAddress, Namespace, Prefix
from django.contrib.contenttypes.models import ContentType
from nautobot.core.models import ColorChoices
import netaddr
def create_catalyst_8000_device():
"""Create a Cisco IOS Catalyst 8000 device for testing."""
# Create or get manufacturer
cisco, _ = Manufacturer.objects.get_or_create(name="Cisco")
# Create or get device type for Catalyst 8000
catalyst_8000, _ = DeviceType.objects.get_or_create(
model="Catalyst 8000",
defaults={
"manufacturer": cisco,
"part_number": "Catalyst 8000"
}
)
# Create or get platform
ios_platform, _ = Platform.objects.get_or_create(
name="cisco_ios",
network_driver="cisco_ios",
defaults={"manufacturer": cisco}
)
# Create or get role
device_ct = ContentType.objects.get_for_model(Device)
router_role, _ = Role.objects.get_or_create(
name="Router",
defaults={"color": ColorChoices.COLOR_BLUE}
)
router_role.content_types.set([device_ct])
router_role.validated_save()
# Create or get location type and location
site_type, _ = LocationType.objects.get_or_create(name="Site")
site_type.content_types.set([device_ct])
site_type.save()
status_active, _ = Status.objects.get_or_create(name="Active")
status_active.content_types.set([
ContentType.objects.get_for_model(Device),
ContentType.objects.get_for_model(Location)
])
location, _ = Location.objects.get_or_create(
name="Test Lab",
location_type=site_type,
defaults={"status": status_active}
)
# Create the device
device, created = Device.objects.get_or_create(
name="catalyst-8000",
defaults={
"device_type": catalyst_8000,
"platform": ios_platform,
"role": router_role,
"location": location,
"status": status_active,
}
)
if created:
print(f"Created device: {device.name}")
else:
print(f"Device already exists: {device.name}")
# Create management interface and assign IP
mgmt_interface, _ = Interface.objects.get_or_create(
device=device,
name="GigabitEthernet0/0/0",
defaults={"status": status_active}
)
# Create IP address
global_namespace, _ = Namespace.objects.get_or_create(name="Global")
Prefix.objects.get_or_create(
prefix="10.10.20.0/24",
namespace=global_namespace,
defaults={"status": status_active}
)
ip_addr, _ = IPAddress.objects.get_or_create(
address=netaddr.IPNetwork("10.10.20.48/32"),
namespace=global_namespace,
defaults={"status": status_active}
)
# Assign IP to interface
mgmt_interface.ip_addresses.set([ip_addr])
mgmt_interface.save()
# Set as primary IP
device.primary_ip4 = ip_addr
device.save()
print(f"Device {device.name} configured with IP {ip_addr}")
return device