Nautobot Inventory
The Nautobot inventory plugin pulls device information from a Nautobot instance via its REST API. This allows Tom to use Nautobot as the source of truth for network devices.
When to Use
If you have Nautobot, use it. A proper source of truth is preferable to an NMS like SolarWinds, and certainly better than maintaining YAML files by hand.
Requirements
- Nautobot instance (1.x or 2.x)
- API token with read access to devices
pynautobotlibrary (included in Tom's dependencies)
Configuration
Controller Config
# tom_controller_config.yaml
inventory_type: nautobot
# Plugin settings
plugin_nautobot_url: "https://nautobot.example.com"
plugin_nautobot_token: "your-api-token"
# Credential mapping
plugin_nautobot_credential_source: custom_field # or: config_context
plugin_nautobot_credential_field: credential_id # field name or config context path
plugin_nautobot_default_credential: default # fallback credential ID
# Adapter/driver mapping (optional - defaults work for most setups)
plugin_nautobot_adapter_source: custom_field # or: config_context
plugin_nautobot_adapter_field: "" # empty = use default
plugin_nautobot_default_adapter: netmiko
plugin_nautobot_driver_source: custom_field # or: config_context
plugin_nautobot_driver_field: "" # empty = use default
plugin_nautobot_default_driver: cisco_ios
# Optional: Filter which devices to include
plugin_nautobot_status_filter: ["Active"]
plugin_nautobot_role_filter: []
plugin_nautobot_location_filter: []
plugin_nautobot_tag_filter: []
Or via environment variables:
TOM_PLUGIN_NAUTOBOT_URL=https://nautobot.example.com
TOM_PLUGIN_NAUTOBOT_TOKEN=your-api-token
TOM_PLUGIN_NAUTOBOT_CREDENTIAL_SOURCE=custom_field
TOM_PLUGIN_NAUTOBOT_CREDENTIAL_FIELD=credential_id
Field Mapping
Tom needs to know the credential, adapter, and driver for each device. Each field can be sourced independently from either a custom field or config context.
Settings Per Field
| Field | Source Setting | Field/Path Setting | Default Setting |
|---|---|---|---|
| Credential | credential_source |
credential_field |
default_credential |
| Adapter | adapter_source |
adapter_field |
default_adapter |
| Driver | driver_source |
driver_field |
default_driver |
- Source:
custom_fieldorconfig_context - Field: Custom field name (e.g.,
credential_id) or config context path (e.g.,tom.credential_id) - Default: Fallback value when field is empty or not found
Option 1: Custom Fields
Create custom fields in Nautobot:
- Go to Extensibility > Custom Fields
- Create custom fields:
credential_id(Text) - requiredtom_adapter(Text) - optionaltom_driver(Text) - optional- Content Types: dcim | device
- Set values on each device
Configure Tom:
plugin_nautobot_credential_source: custom_field
plugin_nautobot_credential_field: credential_id
plugin_nautobot_default_credential: default
plugin_nautobot_adapter_source: custom_field
plugin_nautobot_adapter_field: tom_adapter # or empty to use default
plugin_nautobot_default_adapter: netmiko
plugin_nautobot_driver_source: custom_field
plugin_nautobot_driver_field: tom_driver # or empty to use default
plugin_nautobot_default_driver: cisco_ios
Option 2: Config Context
Use Nautobot config context for all Tom settings (no custom fields required):
plugin_nautobot_credential_source: config_context
plugin_nautobot_credential_field: tom.credential_id
plugin_nautobot_adapter_source: config_context
plugin_nautobot_adapter_field: tom.adapter
plugin_nautobot_driver_source: config_context
plugin_nautobot_driver_field: tom.driver
In Nautobot, add config context to devices:
{
"tom": {
"credential_id": "lab_creds",
"adapter": "netmiko",
"driver": "cisco_ios"
}
}
Config context paths support nesting (e.g., tom.network.credential_id).
Option 3: Mixed Sources
You can mix sources - for example, credential from custom field, driver from config context:
plugin_nautobot_credential_source: custom_field
plugin_nautobot_credential_field: credential_id
plugin_nautobot_driver_source: config_context
plugin_nautobot_driver_field: tom.driver
Minimal Setup
If all devices use the same adapter/driver, just configure credentials:
plugin_nautobot_credential_source: custom_field
plugin_nautobot_credential_field: credential_id
plugin_nautobot_default_adapter: netmiko
plugin_nautobot_default_driver: cisco_ios
Leave adapter_field and driver_field empty (or omit them) to use defaults.
Device Filtering
Filter which devices Tom includes in its inventory:
# Only include Active and Planned devices
plugin_nautobot_status_filter: ["Active", "Planned"]
# Only include specific roles
plugin_nautobot_role_filter: ["Edge Router", "Core Switch"]
# Only include specific locations
plugin_nautobot_location_filter: ["NYC-DC1", "SFO-DC2"]
# Only include devices with specific tags
plugin_nautobot_tag_filter: ["production", "tom-managed"]
Leave a filter empty ([]) to disable it. Multiple values in a filter use OR logic; multiple filters use AND logic.
Host/IP Resolution
Tom determines the device IP in this order:
- primary_ip4 - IPv4 address (without prefix)
- primary_ip6 - IPv6 address (without prefix)
- Device name - Falls back to using the device name as hostname
Ensure your devices have primary IPs assigned in Nautobot for reliable connectivity.
Example: Complete Setup
1. Nautobot Setup
Create a custom field for credential mapping:
- Name: credential_id
- Type: Text
- Assign to devices
Assign primary IPs to devices.
2. Tom Configuration
# tom_controller_config.yaml
inventory_type: nautobot
plugin_nautobot_url: "https://nautobot.example.com"
plugin_nautobot_token: "abc123def456"
plugin_nautobot_credential_source: custom_field
plugin_nautobot_credential_field: credential_id
plugin_nautobot_default_credential: default
plugin_nautobot_default_adapter: netmiko
plugin_nautobot_default_driver: cisco_ios
plugin_nautobot_status_filter: ["Active"]
3. Store Credentials
Credentials referenced by credential_id must exist in your credential store:
# Using Vault
uv run credload.py put default -u admin -p defaultpass
uv run credload.py put lab_creds -u labuser -p labpass
4. Test
# List all devices from Nautobot
curl "http://localhost:8000/api/inventory/export" \
-H "X-API-Key: your-api-key"
# Query a specific device
curl -X POST "http://localhost:8000/api/device/router1/send_command" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{"command": "show version", "wait": true}'
Settings Reference
| Setting | Default | Description |
|---|---|---|
url |
(required) | Nautobot URL |
token |
(required) | API token |
credential_source |
custom_field |
custom_field or config_context |
credential_field |
credential_id |
Field name or config context path |
default_credential |
default |
Fallback credential ID |
adapter_source |
custom_field |
custom_field or config_context |
adapter_field |
"" |
Field name or config context path (empty = use default) |
default_adapter |
netmiko |
netmiko or scrapli |
driver_source |
custom_field |
custom_field or config_context |
driver_field |
"" |
Field name or config context path (empty = use default) |
default_driver |
cisco_ios |
Netmiko/Scrapli driver name |
default_port |
22 |
SSH port |
status_filter |
[] |
Filter by device status |
role_filter |
[] |
Filter by device role |
location_filter |
[] |
Filter by location |
tag_filter |
[] |
Filter by tags |
Troubleshooting
"400" Errors from Nautobot
Filter values must exactly match what exists in Nautobot (case-sensitive). Nautobot uses title case for status values: Active, Planned, Staged, Failed, Inventory, Decommissioning, Offline.
Use empty filters to disable filtering and see all devices:
plugin_nautobot_status_filter: []
Device Not Using Expected Driver
Check the order of precedence:
1. If driver_field is set and device has a value, that's used
2. Otherwise default_driver is used
To debug, export inventory and check what Tom sees:
curl "http://localhost:8000/api/inventory/export" -H "X-API-Key: your-key"