Many of us are running networks that have thousands of devices and those devices need backed up. Oxidized is one of many projects that aims to provide vendor agnostic configuration backups and, as a past Oxidized contributor, I feel this is one of the few OSS projects that compelled me to start sending patches to the community.
The same can be said about Netbox. If you're in the networking community recently, you have certainly heard of Netbox. It is truly one of the best platforms available for DCIM and the plugin architecture makes it one of my favorite pieces of software to work on.
So how we do leverage these two fantastic pieces of software to work together? Oxidized official documentation shows several backends available: https://github.com/ytti/oxidized/blob/master/docs/Sources.md
- CSV
- DB
- HTTP
For option 1, we could write a Netbox webhook to update the file on Oxidized anytime someone changes a Netbox device. https://demo.netbox.dev/static/docs/additional-features/webhooks/ This event-driven architecture is a step above polling for changes on a set period of time, but its error prone and requires some complexity in maintaining an API gateway, the Webhook, and the CSV.
For option 2, we basically can do the same thing but now we can have the benefits of a database. Things like multi-source db updates, transactions, backups, and data consistency become a little easier, but we are still requiring the complexity of the webhooks, API gateway and now an additional database.
For option 3, we could leverage the HTTP backend to natively call Netbox's REST API. This would remove all the complexity and additional components while continuing to be just as up to date as the EDI solution. Using the oxidized documentation link above, we can see an example HTTP backend below.
source:
default: http
http:
url: https://url/api
scheme: https
delimiter: !ruby/regexp /:/
user: username
pass: password
read_timeout: 120
map:
name: hostname
model: os
username: username
password: password
vars_map:
enable: enable
headers:
X-Auth-Token: 'somerandomstring'
Note: the documentation says that Netbox will create one device per object returned by the API call.
With our template and understanding the Netbox and Oxidized requirements, we can formulate a configuration to integrate the two.
source:
default: http
http:
url: https://netbox/api/dcim/devices/?status=active&role_id=1&role_id=3&manufacturer_id=1
scheme: https
delimiter: !ruby/regexp /:/
headers:
Authorization: Token [token-here]
map:
name: name
model: device_type.manufacturer.name
ip: name
insecure: true
secure: false
hosts_location: results
A few important notes:
- Oxidized needs a URL endpoint to call for the devices. Here is where we apply some filters to get only the devices we want. For instance, the example above filters for devices that are Active, Role=1, and Manufacturer=1
- Oxidized needs an API token to authenticate with Netbox and pull the data. This section is the "headers" part of the config and needs to be exactly in the following format: "Token [token]"
- Oxidized needs to know which fields in the response to map to the Oxidized fields. This is contained in the "map" section of the config.
- Oxidized needs to know which object in the HTTP response contains the objects that need to be pulled into Oxidized. This is the "hosts_location" field. Netbox will return JSON with each device contained in an array called "results".This is the basis for the object creation in Oxidized
Happy Netboxing!