CLI tool
Solvik/netbox-agent avatar
Solvik/netbox-agent

netbox-agent: write your rack into NetBox from dmidecode

Netbox agent to run on your infrastructure's servers

395 stars97 forksPythonApache-2.0

At a glance

What is it?
netbox-agent is a per-server Python program that reads standard Linux tools, dmidecode and lldpd among them, and writes what it finds into NetBox as devices, blades, interfaces, IPs and cabling. It is built for fleets where the documentation lags the hardware, and it exposes narrow update commands so you can correct one slice of an inventory without re-registering the machine.
Who is it for?
Adopt netbox-agent if your NetBox instance is missing hardware that is already racked, because it is built to generate an existing inventory from the machines themselves and then keep it current on a schedule. Do not adopt it as a replacement for a proper discovery service with a database of its own, since it is a script that reads local tools and writes to an API.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 10 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 4, 2026, and from our analysis. They are not legal advice.

Editorial analysis

It reads the machine, not an inventory file

The aim is stated plainly: create hardware automatically in NetBox based on standard tools, among them dmidecode, lldpd and parsing under /sys. The goal is to generate an existing infrastructure on NetBox and then keep it up to date by running the agent again.

That framing matters because it is the opposite of the usual assumption. You are not importing a list you prepared; each server reports itself. The feature list follows from that: virtual machines, servers, chassis and blades from dmidecode; physical, bonding and vlan interfaces with IPv4 and IPv6 addresses; an IPMI interface when one is found; VLANs created or matched and then associated to interfaces.

Two of the features are the ones most projects would build separately. Automatic cabling maps a server's interface to a switch's interface using LLDP, so the topology in NetBox comes from what the switches actually advertise rather than from a spreadsheet. Local inventory records CPU, GPU, RAM, RAID cards and the physical disks behind those RAID cards as NetBox inventory items, with PSU creation and power consumption reporting based on vendor tools.

It also links the virtual layer to the physical one, associating hypervisor devices to the virtualization cluster and virtual machines to the hypervisor device.

Configuration precedence is documented, which is rare

The agent runs from a shell and takes its configuration from a file or from environment variables, and the precedence is written down rather than left to be discovered: command line arguments, which may themselves point at a config file, take precedence over environment variables, which take precedence over the default config file, which takes precedence over the built-in defaults.

The shipped example file shows the shape:

yaml
netbox:
  url: 'http://netbox.internal.company.com'
  token: supersecrettoken

network:
  ignore_interfaces: "(dummy.*|docker.*)"
  ignore_ips: (127\.0\.0\..*)
  lldp: true

Two lines in that example are commented out and both matter in practice. ssl_verify: false disables certificate checking, and ssl_ca_certs_file points at a CA bundle when you use the system's certificates. A commented #device: chassis_ block marks the NetBox role defaults, which tells you the agent can be pointed at different NetBox roles per device.

The two regexes at the top of the network block are how you keep container plumbing out of your source-of-truth inventory, and the lldp switch is what turns automatic cabling on.

Register everything, or correct one slice

Installation is a single pip line:

bash
pip3 install netbox-agent

A full registration run points at a config file and asks for everything:

bash
netbox_agent -c /etc/netbox_agent.yaml --register

The log output is the best documentation of what it creates. It reports creating a chassis blade by serial, then creating the blade itself on that chassis, then setting the device's new slot, then finding an interface missing and creating it, then creating the NIC with its MAC address, and finally creating an IP address on the bridge interface it just created.

What makes this usable on a live rack is that you do not have to run the full registration to fix one thing. You can update network, inventory, location or PSUs individually, and the README shows that shape: add an address to an interface at the shell, then

bash
netbox_agent -c /etc/netbox_agent.yaml --update-network
netbox_agent --update-inventory

which produce a single new IP record and a single new disk entry. For a fleet, that is the difference between a nightly full run and a set of small corrections you can run without a maintenance window.

Blades need a vendor class and sometimes a regex

Blade handling is the part with the most vendor-specific logic. Each vendor class has an is_blade method, which is what later drives Device creation through NetBox's parent and child feature, so a compute blade becomes a child of its chassis rather than a peer. The get_blade_slot method returns the name of the Device Bay the blade occupies.

Some vendors do not report the blade slot in dmidecode at all, and for those the configuration file offers a slot_location regex feature. That is a workaround in the honest sense: you describe where the slot number comes from when the hardware will not say.

Blade expansions are the other case. Some blade servers carry extra hardware in a neighbouring expansion blade, such as a GPU expansion or a drive bay expansion. By default that hardware is associated with the blade server itself, which is usually what you want in a capacity model. If you would rather see the expansion as its own device, there is a --expansion-as-device command line parameter or an expansion_as_device setting in the configuration file.

The hardware list in the README starts with virtual machines on Hyper-V, VMware, VirtualBox, AWS and GCP, then vendor sections, and the Dell entry is the one visible in the copy available here, covering PowerEdge MX7000 blades.

Drive attributes need seven fields registered before you can use them

Disks behind RAID controllers are the richest data source and the most demanding to set up. The agent can read extended attributes such as the drive's physical or logical identifier, its logical drive RAID type, size and consistency, and write them as custom fields in NetBox.

Custom fields have to exist before anything can be written to them, so you create seven of them as DCIM inventory items of type Text: mount_point, pd_identifier, vd_array, vd_consistency, vd_device, vd_raid_type and vd_size. Only then does the feature activate, through the --process-virtual-drives parameter or process_virtual_drives set to true.

The underlying data comes from the vendor tools the requirements list under inventory: hpassacli, storcli and omreport.

One behaviour is stated and worth internalising: in the current implementation the disk attributes are not updated. If a disk with the correct serial number is found, it is considered up to date. The escape hatch is --force-disk-refresh, which removes all existing disks before repopulating them with the correct parsing, and --dump-disks-map writes the physical to virtual disk map out as JSON when you want to inspect or automate it yourself.

Anycast IPs loop unless you change the IP mode

The default behaviour is to assign an interface to an IP. With two servers sharing an anycasted address, running the agent in update mode on both would only trigger the same interface assignment over and over.

The fix is on the NetBox side rather than in the agent: set the IP's mode to Anycast, and the agent will create another IP record when it finds the address already present on another server instead of fighting over it.

This is the kind of bug that only shows up in a real deployment. The agent is doing exactly what it was told, and the ambiguity lives in what an IP record means when two machines legitimately answer for one address.

If you are adopting this agent anywhere with anycast addresses, do it before the first fleet-wide update run rather than after, because the loop is harmless in a single-machine trial and noisy in a scheduled job.

Cabling comes from LLDP, and VLANs are created or matched

Two smaller behaviours are easy to miss and expensive to reinvent.

Automatic cabling uses LLDP to associate a server's interface with a switch's interface, which means the link in NetBox comes from the switch's own advertisements. The lldp: true setting in the network block turns it on. When a switch does not run an LLDP agent, that link simply does not appear, so it is worth knowing which of your switches are silent before you conclude the cabling is wrong.

VLAN handling is create-or-get: the agent creates the VLAN in NetBox if it is not there and then associates it to the interfaces that use it. That is the behaviour you want in a rack where switches and NetBox were configured by different people, because it converges rather than failing on a duplicate.

Interfaces are filtered before any of this happens, through ignore_interfaces and ignore_ips regexes, which is where you keep dummy and docker interfaces and loopback addresses out of your inventory.

Apache-2.0, exact pins, and a test run that stops at the first failure

The package is netbox-agent at version 1.2.0, authored by Solvik Blum, under Apache-2.0, requiring Python 3.8 or newer with classifiers up to 3.13. Every dependency is pinned exactly: pynetbox 7.4.1, netaddr 1.3.0, netifaces2 0.0.22, pyyaml 6.0.2, jsonargparse 4.36.0, python-slugify 8.0.4, packaging 24.2 and distro 1.9.0. requirements.txt repeats the same list.

Two inconsistencies are worth noting if you are debugging an install. The README's requirements list names python3-netifaces while the pinned dependency is netifaces2, and the project URL in the packaging metadata points at github.com/solvik/netbox_agent rather than the repository you are reading.

The test configuration is strict in a way that shows the project's intent. Pytest runs with coverage on the netbox_agent package, term-missing and XML reports, --no-cov-on-fail, and -x, which stops the run at the first failure. Ruff is configured at a 99 character line length with an ignore list that includes F841 twice, which is a small sign of list editing by hand rather than by tool.

Maintenance is healthy and active. The last push was on 2026-10-01, after releases 1.2.0 in January 2026, v1.1.0 in January 2025 and v1.0.0 in October 2024, with the newest tag dropping the v prefix its older ones used. renovate.json is present for dependency updates and rpmenv.json for packaging.

Editorial conclusion

Adopt netbox-agent if your NetBox instance is missing hardware that is already racked, because it is built to generate an existing inventory from the machines themselves and then keep it current on a schedule. Do not adopt it as a replacement for a proper discovery service with a database of its own, since it is a script that reads local tools and writes to an API. Verify first that the vendor tooling you need is installed, that the custom fields for drive attributes exist before you enable that phase, and that you set anycast IPs to Anycast mode before running it in update mode across a fleet.

Frequently asked questions

What does netbox-agent need in order to run?

NetBox 3.7 or newer and Python 3.8 or newer, the Python packages pynetbox, netaddr, netifaces and jsonargparse, and the system tools ethtool, dmidecode, ipmitool, lldpd and lshw. Inventory of disks behind RAID controllers additionally needs hpassacli, storcli or omreport.

How do I install and configure netbox-agent?

Install it with pip3 install netbox-agent. Configuration comes from a YAML file or from environment variables, with command line arguments taking precedence over environment variables, which take precedence over the default config file, which takes precedence over the built-in defaults.

Can netbox-agent update only part of an inventory?

Yes. Alongside the full --register run there are targeted updates for network, inventory, location and PSUs, so you can add an address at the shell and then run --update-network, or swap a disk and run --update-inventory, without re-registering the whole machine.

Why does netbox-agent loop on anycast IPs?

By default the agent assigns an interface to an IP, so two servers sharing an anycasted address in update mode would keep reassigning the interface to each other. Set the NetBox IP's mode to Anycast and the agent creates another IP record instead of fighting over the existing one.

How do I get RAID disk attributes into NetBox?

Register seven custom fields as DCIM inventory items of type Text first, then enable the feature with --process-virtual-drives or process_virtual_drives set to true. The data comes from hpassacli, storcli or omreport, and --force-disk-refresh exists because disk attributes are otherwise considered up to date once the serial number matches.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. README
  4. Releases
  5. Solvik/netbox-agent on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/solvik-netbox-agent.svg)](https://hysenlabs.com/projects/solvik-netbox-agent)