Skip to main content

NetBox iDRAC Inventory Plugin

A NetBox plugin that synchronizes Dell PowerEdge server hardware inventory into NetBox by querying each server's iDRAC management interface via the Redfish API.


Features

  • One-to-one Dell server record linked to a NetBox Device. Adding a Dell server creates the Device for you (its name defaults to the host part of the iDRAC FQDN); the record stores the iDRAC address, service tag, BIOS version and iDRAC firmware. The device type is set from the iDRAC-reported model on the first sync.
  • Hardware component inventory — CPUs, DIMMs, disks, storage controllers and power supplies are discovered and stored as DellComponent objects.
  • Health status — the iDRAC Status.Health of the server (rolled up) and of each component is mapped to a colored health badge (OK / Warning / Critical), so a failed PSU or disk is visible at a glance and filterable.
  • iDRAC management IP — the iDRAC's own NIC is modelled as a mgmt-only iDRAC interface (with its MAC), the iDRAC IPv4 is created in IPAM and set as the device's out-of-band IP (oob_ip).
  • Native network modelling — each physical network adapter is created as a NetBox Module (with a matching ModuleType) installed in the device's ModuleBay for its slot, and each physical port becomes an Interface with its MAC address and link speed. Ports are matched to an existing interface by MAC address first, falling back to name — so a device that already had interfaces before being onboarded (under whatever names/cables were there previously) gets reconciled onto its real Dell port name in place, rather than getting a duplicate interface. The NUMA node the adapter's PCIe lanes are wired to (from Dell's CPUAffinity, converted from Dell's 1-indexed CPU socket to a 0-indexed NUMA node) is stored in the numa_node custom field on the ModuleBay.
  • Module bays from the device type — every module bay the Dell model's device type defines is created on the device, including empty slots you can fill by hand. An adapter goes into the bay whose position matches its slot (NIC.Slot.2 → PCIe-2, PCIe-Gen3-2, PCIE2 or slot-2; NIC.Integrated.1 → inic-1, NDC-1 or OCP-1; NIC.Embedded.1 → enic-1); without a matching bay it gets one named after its FQDD.
  • LLDP discovery — the LLDP neighbour reported by iDRAC for each connected port (remote switch + remote port) is stored in the lldp_remote_chassis and lldp_remote_port custom fields on the interface. These, and numa_node, are created automatically on first migrate.
  • Firmware inventory — the Redfish UpdateService/FirmwareInventory is read on each sync and the installed version is written to matching components (by FQDD), covering parts whose own resource omits a version.
  • Sync-on-demand — trigger a sync from the NetBox UI (single server or a bulk Sync from iDRAC action on the server list) or via the REST API (POST .../servers/<id>/sync/); sync runs as a background job.
  • Scheduled sync — set sync_interval_minutes > 0 to register a recurring system job that fans out one sync job per Dell server, so the RQ workers run them in parallel and one unreachable iDRAC never stalls the fleet.
  • Network discovery — define a Scan Range (CIDR / range / hosts); a discovery job probes each iDRAC and imports it, attaching to an existing device with the same service tag when one exists (no duplicate) or creating a new one. New devices get the range's site as a default and are flagged on the Site Review page so it can be confirmed or corrected per device — handy when one iDRAC subnet spans several sites.
  • Full REST API at /api/plugins/idrac-inventory/ (servers + components).
  • GraphQL queries dell_server / dell_server_list / dell_component / dell_component_list exposed through NetBox's Strawberry schema.
  • Credentials — a global iDRAC password comes from PLUGINS_CONFIG / environment; an optional per-device password (when machines differ) is stored encrypted at rest (Fernet, keyed on NetBox SECRET_KEY) and is never returned by the API.

Compatibility

Plugin version NetBox version
0.3.6+ 4.1 – 4.7
0.2.x – 0.3.5 4.1 – 4.6
0.1.x 4.1 or later

NetBox 4.6+ requires API_TOKEN_PEPPERS in your NetBox configuration (a core NetBox requirement, not a plugin one).

Requires Python 3.10+.


Installation

1. Install the package

pip install netbox-idrac-inventory

2. Add to configuration.py

PLUGINS = [
    "netbox_idrac_inventory",
]

PLUGINS_CONFIG = {
    "netbox_idrac_inventory": {
        # iDRAC credentials used when a DellServer has no per-device username set.
        "idrac_default_username": "root",
        # Prefer setting the password via an environment variable rather than
        # committing it to the config file.  The plugin checks the env var
        # IDRAC_DEFAULT_PASSWORD before falling back to this value.
        "idrac_default_password": "",
        # Set to True (and provide a valid CA bundle) in production.
        "idrac_verify_ssl": False,
        # HTTP request timeout in seconds for iDRAC Redfish calls.
        "idrac_timeout": 30,
        # When True, the sync writes the iDRAC service tag to Device.serial
        # in NetBox so the physical device record stays up to date.
        "update_device_serial": True,
        # When True, the sync creates a mgmt-only "iDRAC" interface with the
        # iDRAC IP and sets it as the device's out-of-band IP.
        "manage_idrac_interface": True,
        # Minutes between automatic syncs of every Dell server (0 = disabled,
        # sync stays manual). Read at worker startup — restart the RQ worker
        # after changing it.
        "sync_interval_minutes": 0,
        # Optional list of prefixes that iDRAC addresses and scan targets
        # must fall within, e.g. ["10.116.0.0/16"]. Empty = no restriction.
        # Strongly recommended: see "Credentials and security" below.
        "allowed_networks": [],
    }
}

3. Apply database migrations

python manage.py migrate

Usage

Add a Dell server

Two ways:

  • From scratch — go to Plugins → iDRAC Inventory → Dell Servers → Add. Enter the iDRAC address, a device name (left blank, it defaults to the host part of the iDRAC FQDN, e.g. host01.ipmi.example.com → host01), a site and a role. The plugin creates the Device (with a placeholder device type, replaced by the real model on the first sync) and links it.
  • From an existing device — on a Device page, use the iDRAC Inventory panel's Add button; the new record is attached to that device instead of creating a new one. If the device already has an interface named "iDRAC" with an IP assigned (common for a device onboarded before this plugin, already cabled and documented), the iDRAC address field is pre-filled from it.

Optionally set a per-device iDRAC username; otherwise the plugin default is used.

Trigger a sync

  • UI: open the DellServer (or its Device) page and click Sync from iDRAC. The sync runs as a NetBox background job; refresh to see the result in sync_status / sync_message.

  • REST API:

    curl -X POST \
      -H "Authorization: Token <your-token>" \
      https://netbox.example.com/api/plugins/idrac-inventory/servers/42/sync/
    

    Returns HTTP 202 with the background job ID:

    {
      "job_id": 123,
      "job_url": "https://netbox.example.com/api/core/jobs/123/",
      "message": "Sync job enqueued for my-server-01 (SVC00042)."
    }
    

    Triggering a sync requires the change permission on Dell servers (on top of NetBox's standard POST-to-add API permission mapping).

Discover servers from a range

Under Plugins → iDRAC Inventory → Scan Ranges → Add, define one or more targets (one per line or comma-separated): a CIDR (10.0.0.0/24), a range (10.0.0.10-20) or single hosts, plus the site and role for created devices. Click Run scan (or POST .../scan-ranges/<id>/run/). For each reachable iDRAC the discovery attaches to an existing device with the same service tag (its site is left unchanged), or creates one, then syncs it.

Newly-created devices land with the range's site as a best-effort default only — useful when one iDRAC management subnet spans several NetBox sites and a single range can't be right for every host. Each such device is flagged for review; go to Plugins → iDRAC Inventory → Dell Servers → Site Review to confirm or correct the site per device.

REST API overview

Base path: /api/plugins/idrac-inventory/

Method Endpoint Description
GET /servers/ List all Dell servers
POST /servers/ Create a Dell server record
GET /servers/<id>/ Retrieve a Dell server
PATCH /servers/<id>/ Update a Dell server
DELETE /servers/<id>/ Delete a Dell server
POST /servers/<id>/sync/ Enqueue an iDRAC sync job
GET /components/ List all components
GET /components/<id>/ Retrieve a component
GET/POST /scan-ranges/ List / create scan ranges
POST /scan-ranges/<id>/run/ Enqueue a discovery job

The per-device / per-range idrac_password can be set via POST/PATCH; it is write-only (encrypted before storage, never present in any response) and a blank or absent value keeps the stored one.

Full OpenAPI schema is available at /api/schema/ in your NetBox instance.

GraphQL

query {
  dell_server_list {
    id
    service_tag
    model
    sync_status
    device { name }
  }
}

query {
  dell_server(id: 42) {
    bios_version
    idrac_firmware
    last_synced
  }
}

Credentials and security

  • At sync time the plugin resolves the password in this order:
    1. The per-device idrac_password (or a scan range's), when set.
    2. Environment variable IDRAC_DEFAULT_PASSWORD (recommended default for production — set it in your process manager / secrets manager).
    3. PLUGINS_CONFIG["netbox_idrac_inventory"]["idrac_default_password"].
  • Per-device password — when servers don't share one password, set it on the DellServer (or scan range). It is encrypted at rest with a key derived from NetBox's SECRET_KEY (Fernet), is write-only in the form and the API, and is never returned by the REST or GraphQL API. If you only have one shared password, leave these blank and use the global default above.
  • SECRET_KEY rotation — rotate per Django's documented procedure (put the old key in SECRET_KEY_FALLBACKS) and stored passwords keep working. If a stored password can no longer be decrypted, the sync fails with a clear message instead of silently retrying with the global default (which could trip the iDRAC's account lockout); re-enter the password to recover.
  • The per-device idrac_username overrides idrac_default_username likewise.
  • In production, set idrac_verify_ssl: true and provide a trusted CA bundle so TLS certificates are validated.

Restricting where syncs may connect

Anyone with change permission on Dell servers or scan ranges chooses which address the plugin connects to — and the sync presents the configured iDRAC credentials to that address. A malicious or compromised account could point a record at a host it controls and capture the global default password. To contain this:

  • set allowed_networks to the management prefixes your iDRACs live in; syncs and scans to any address (or DNS name resolving) outside them are refused;
  • grant change_dellserver / change_dellscanrange sparingly, like any credential-bearing automation;
  • enable idrac_verify_ssl so credentials are never sent over unverified TLS.

Development

Quick start with Docker

A self-contained NetBox stack (NetBox + worker + Postgres + Redis) with the plugin pre-installed lives under dev/. See dev/README.md:

cd dev
cp .env.example .env      # set IDRAC_USERNAME / IDRAC_PASSWORD
docker compose up --build # NetBox at http://localhost:8000 (admin / admin)

Migrations

The plugin ships its schema migration (migrations/0001_initial.py), so a plain python manage.py migrate is all that is needed. The LLDP custom fields on dcim.Interface are not a migration — they are created idempotently by a post_migrate signal (see signals.py) so they stay correct across NetBox versions. If you change the models, regenerate with python manage.py makemigrations netbox_idrac_inventory and commit the result.

Running tests

Tests must run inside the NetBox Django environment:

# From the NetBox source root with the plugin installed:
python manage.py test netbox_idrac_inventory
# or, with the dev stack running:
docker compose exec netbox \
  /opt/netbox/venv/bin/python /opt/netbox/netbox/manage.py test netbox_idrac_inventory

Project layout

netbox_idrac_inventory/
  api/
    serializers.py     # NetBoxModelSerializer subclasses
    views.py           # NetBoxModelViewSet subclasses + sync action
    urls.py            # NetBoxRouter registration
  graphql/
    types.py           # Strawberry-django type definitions
    schema.py          # Root query class + schema list
  idrac/
    client.py          # IdracClient — Redfish wrapper (sushy), plain dicts
    sync.py            # sync_server() — iDRAC -> NetBox reconcile logic
    discovery.py       # discover_range() — scan a range and import iDRACs
  migrations/
    0001_initial.py    # DellServer / DellComponent schema
  templates/netbox_idrac_inventory/   # detail pages + Device-page panel
  tests/
    test_models.py     # Model unit tests
    test_idrac.py      # Sync engine + network/LLDP tests (fake client)
    test_api.py        # REST API tests (NetBox APIViewTestCases)
    test_forms.py      # Device-creating form + password handling
    test_discovery.py  # Target expansion + discovery engine
    test_utils.py      # Address helpers + encryption fail-closed
    test_views.py      # Bulk sync action
  __init__.py          # PluginConfig (settings) + post_migrate hook
  choices.py           # SyncStatusChoices, ComponentTypeChoices
  models.py            # DellServer, DellComponent, DellScanRange
  forms.py             # Forms (DellServerForm creates/links the Device)
  tables.py            # DellServerTable, DellComponentTable
  filtersets.py        # DellServerFilterSet, DellComponentFilterSet
  views.py             # CRUD views + DellServerSyncView
  urls.py              # UI URL routes
  navigation.py        # Plugin menu
  template_content.py  # Dell panel on the Device page
  jobs.py              # DellSyncJob + enqueue_sync()
  signals.py           # post_migrate: create LLDP custom fields
  utils.py             # default_device_name(), get_or_create_manufacturer()

Metadata

Release files for netbox-idrac-inventory 0.3.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for netbox-idrac-inventory 0.3.8
File Size Uploaded
netbox_idrac_inventory-0.3.8.tar.gz 82.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for netbox-idrac-inventory 0.3.8
File Interpreter ABI Platform
netbox_idrac_inventory-0.3.8-py3-none-any.whl Python 3 none any Details

Total release size: 175.7 kB

Release files / netbox_idrac_inventory-0.3.8.tar.gz

Download URL netbox_idrac_inventory-0.3.8.tar.gz
Size 82.9 kB
Tags Source
SHA-256 checksum
How to use checksums
c59d8dffaf4df37ee03ac4e76d63da0551b35e9c9018a461981bab286bcde639
BLAKE2b-256 checksum
How to use checksums
8583e399c894d9444f936a1c8d1310a80a2f772e3d0e81be5f1cf0ae43b598ed
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / netbox_idrac_inventory-0.3.8-py3-none-any.whl

Download URL netbox_idrac_inventory-0.3.8-py3-none-any.whl
Size 92.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1f763191ea0561d26d5a64c92d002af76c4b23508e4d6972e6a329fb240f7d83
BLAKE2b-256 checksum
How to use checksums
4273b2e86553abda70aaffda1449a64504cccd06eaa76c7dffc166840978fac0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

0.3.9

2 release files

This release

0.3.8 This release

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page