
Product
Introducing Webhook Events for Alert Changes
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.
inventory-monitor
Advanced tools
A comprehensive NetBox plugin for asset management with semi-automatic discovery processes. This plugin extends NetBox with powerful inventory tracking capabilities, including asset lifecycle management, probe monitoring, contract tracking, and RMA (Return Merchandise Authorization) processing.
classDiagram
class AssetType {
+CharField name
+SlugField slug
+CharField description
+ColorField color
}
class Asset {
+CharField serial*
+CharField partnumber
+CharField description
+CharField assignment_status
+CharField lifecycle_status
+PositiveIntegerField quantity
+DecimalField price
+CharField currency
+CharField project
+CharField vendor
+DateField warranty_start
+DateField warranty_end
+GenericForeignKey assigned_object
+ForeignKey type
+ForeignKey order_contract
+TextField comments
+is_recently_probed()
+get_related_probes()
+delete() throws ValidationError
}
class AssetService {
+DateField service_start
+DateField service_end
+DecimalField service_price
+CharField service_currency
+CharField service_category
+CharField service_category_vendor
+ForeignKey asset
+ForeignKey contract
}
class Contract {
+CharField name
+CharField name_internal
+CharField type
+DecimalField price
+CharField currency
+DateField signed
+DateField accepted
+DateField invoicing_start
+DateField invoicing_end
+TextField comments
+ForeignKey contractor
+ForeignKey parent
+clean() validates price/currency
}
class Contractor {
+CharField name
+CharField company
+CharField address
+ForeignKey tenant
}
class Invoice {
+CharField name
+CharField project
+DecimalField price
+CharField currency
+DateField invoicing_start
+DateField invoicing_end
+ForeignKey contract
}
class Probe {
+DateTimeField time
+DateTimeField creation_time
+CharField name
+CharField serial
+CharField part
+CharField category
+CharField device_descriptor
+CharField site_descriptor
+CharField location_descriptor
+TextField description
+TextField comments
+JSONField discovered_data
+ForeignKey device
+ForeignKey site
+ForeignKey location
+is_recently_probed()
}
class RMA {
+CharField rma_number
+CharField original_serial
+CharField replacement_serial
+CharField status
+DateField date_issued
+DateField date_replaced
+TextField comments
+ForeignKey asset
}
class ExternalInventory {
+CharField external_id
+CharField inventory_number
+CharField name
+CharField serial_number
+CharField person_id
+CharField person_name
+CharField location_code
+CharField location
+CharField department_code
+CharField project_code
+CharField user_name
+TextField user_note
+CharField split_asset
+CharField status
+ManyToManyField assets
+get_status_color()
+get_status_display()
}
AssetType --> Asset : "type"
Asset --> AssetService : "asset"
Asset --> RMA : "asset"
Asset --> Probe : "serial match"
Asset --> ExternalInventory : "M2M assets"
Contract --> Asset : "order_contract"
Contract --> AssetService : "contract"
Contractor --> Contract : "contractor"
Contract --> Invoice : "contract"
Contract --> Contract : "parent (subcontract)"
ExternalInventory --> Asset : "assets"
Asset --> Site : "assigned_object"
Asset --> Location : "assigned_object"
Asset --> Rack : "assigned_object"
Asset --> Device : "assigned_object"
Asset --> Module : "assigned_object"
All models have optimized __str__ methods designed for human readability and easy searching without relying on primary keys. The format is intuitive and includes contextual information relevant to each model type.
Design Principles:
(parentheses) for clarity[brackets]String Representation Examples:
| Model | Format | Example |
|---|---|---|
| Asset | partnumber [serial] (vendor) | PROD-123 [SN12345] (Dell) |
| Probe | serial - name | SN12345 - Server-01 |
| Contractor | name (company) [tenant] | John Doe (ACME Corp) [Tenant1] |
| Contract | name (internal_name) [Sub: parent] via contractor | Main Contract (MC-001) via ACME Corp |
| Invoice | name (contract_name) [project] price currency | Invoice-Q1 (Main Contract) [PRJ-001] 5000.00 EUR |
| AssetService | asset_serial (contract_name) [category] | SN12345 (Service Contract) [Maintenance] |
| RMA | RMA#number asset_serial [status] | RMA#12345 PROD-123 [SN12345] [Approved] |
| AssetType | name (description) | Server (High-performance computing) |
| ExternalInventory | inventory_number name [SN: serial] β person_name | INV-001 Server Hardware [SN: ABC123] β John Smith |
Search Optimization: These representations are optimized for text-based searching in:
The absence of primary key prefixes makes searching by name, serial number, or other identifying fields significantly easier.
Most models in the Inventory Monitor plugin include a description field that provides additional context and details. These descriptions are automatically displayed in form choice fields (dropdowns) thanks to NetBox's built-in JavaScript functionality.
Models with Description Fields:
How It Works: When you're selecting from a choice field in a form (e.g., selecting an Asset Type, selecting a Contract, or selecting a linked Probe record), the description field is automatically shown as secondary text below the primary identifier in the dropdown. This makes it easier to identify and select the correct item without having to navigate to the detail page.
Example:
Asset Type Dropdown:
βββββββββββββββββββββββββββββββββββββββ
β #1: Server β
β High-performance computing β β Description shown in gray
β β
β #2: Network Equipment β
β Networking devices β β Description shown in gray
βββββββββββββββββββββββββββββββββββββββ
String Representations: All models use optimized string representations for human readability and searchability (see String Representations & Readability section above):
The central model representing physical or logical inventory items.
Key Fields:
serial: Unique identifier for the asset (required)partnumber: Manufacturer part numberdescription: Asset descriptionassignment_status: Current assignment status (reserved, deployed, loaned, stocked)lifecycle_status: Lifecycle stage (new, in_stock, in_use, in_maintenance, retired, disposed)assigned_object: Generic foreign key to NetBox objects (Device, Site, Location, Rack, Module)type: Link to AssetType for categorizationorder_contract: Associated purchase contractproject: Project identifiervendor: Vendor namequantity: Number of items (default: 1, must be β₯ 0)price: Asset purchase price (DecimalField, nullable, must be β₯ 0)currency: Price currency (CharField, nullable - required only when price is set and non-zero)warranty_start/end: Warranty period trackingcomments: Additional notesSpecial Features:
is_recently_probed() methodorder_contract (prevents orphaned contract references). User must clear the contract first. Also prevents deletion when linked to external inventory items.Discovery and monitoring data collection points populated by external scripts (e.g., SNMP discovery tools).
Key Fields:
time: Timestamp of the probe data collection (last probe time)creation_time: Timestamp when the probe was first discovered (first discovery)serial: Device serial number - links to Asset via serial number matchingname: Device name or descriptionpart: Part number or model identifiercategory: Probe type/category classificationdevice_descriptor, site_descriptor, location_descriptor: Context information from discoverydevice, site, location: Foreign keys to actual NetBox objects (if resolved)description: Additional discovery informationcomments: User notes about the probediscovered_data: JSON field for flexible data storage from external toolsFeatures:
is_recently_probed() method for status indicatorsNote: Probe data is populated by external discovery scripts, not generated by the plugin itself.
Business relationship management with full currency support.
Contractor Features:
name: Contractor/vendor name (required)company: Company legal nameaddress: Business addressdescription: Contractor description and notestenant: Optional NetBox tenant association for multi-tenant deploymentscomments: Additional contractor informationContract Features:
name: Contract identifier (required)name_internal: Internal reference name (required)type: Contract type (supply, order, service, other)description: Contract description and terms summaryprice: Contract value (DecimalField, nullable)currency: Contract currency (CharField, nullable - required only when price > 0)signed: Date contract was signedaccepted: Date contract was acceptedinvoicing_start/end: Invoicing period datescontractor: Foreign key to Contractor/Vendorparent: Self-referential FK for subcontracts (one level only)comments: Contract notesValidation Rules:
invoicing_start must not be after invoicing_endcontract_type returns "subcontract" vs "contract"Invoice Tracking:
Complete RMA workflow management with serial number tracking.
Key Fields:
rma_number: RMA reference number (unique when provided, optional for draft RMAs)asset: Foreign key to Asset being returned/replaced (required)original_serial: Serial number of the failed/returned hardwarereplacement_serial: Serial number of the replacement hardwarestatus: RMA status (pending, shipped, received, investigating, approved, rejected, completed)date_issued: When the RMA was createddate_replaced: When the replacement was installed/receivedissue_description: Description of the issue with the asset (required)vendor_response: Vendor response/resolution detailsKey Features:
rma_number supports NULL values for draft RMAs, enforces uniqueness only on non-empty values (via UniqueConstraint)original_serial auto-populated from asset when RMA createdstr_no_pk() to avoid ID duplication in string representationService and maintenance contract tracking with multi-currency support.
Key Fields:
service_start: Service contract start dateservice_end: Service contract end dateservice_price: Service cost (DecimalField, nullable)service_currency: Service currency (CharField, nullable - required only when service_price > 0)service_category: Service category/type classificationservice_category_vendor: Vendor for the service categorydescription: Service scope and terms descriptionasset: Foreign key to Asset being servicedcontract: Foreign key to related Contractcomments: Service notesFeatures:
str_no_pk() to avoid ID duplication when both asset and contract are linkedIntegration with external inventory management systems.
Key Fields:
external_id: Unique identifier from external systeminventory_number: Asset number from external systemname: Item name or descriptionserial_number: Serial or production numberperson_id/person_name: Responsible person informationlocation_code/location: Location informationdepartment_code: Department codeproject_code: Project codeuser_name/user_note: User information and notessplit_asset: Whether this is a split/shared assetstatus: Current status code (configurable via plugin settings)assets: Many-to-many relationship with Assets (handles splits and mappings)Features:
get_status_color() and get_status_display() for UI renderingpip install inventory-monitor
git clone https://github.com/CESNET/inventory-monitor-plugin.git
cd inventory-monitor-plugin
pip install .
configuration.py:PLUGINS = [
"inventory_monitor",
]
python manage.py migrate
sudo systemctl restart netbox netbox-rq
Version 12.0.0 brings full NetBox v4 compatibility with significant internal changes:
None - this version maintains full backward compatibility with existing data and APIs.
NetBox v4 API Update (ObjectType Migration)
Starting with NetBox v4, the plugin has been updated to use NetBox's new ObjectType API instead of Django's deprecated ContentType. This is an internal change with no user-facing impact:
Technical Details:
The following components have been updated for NetBox v4 compatibility:
ObjectType for assigned object handlingPlugin Compatibility Fix
The plugin now properly handles tag field reverse accessor conflicts when multiple inventory plugins are installed simultaneously. All models now use unique related_name values for their tags fields to prevent Django's fields.E304 reverse accessor clash errors.
pip install --upgrade inventory-monitor
sudo systemctl restart netbox netbox-rq
After upgrading, verify that:
Configure the plugin in your NetBox configuration.py:
PLUGINS_CONFIG = {
"inventory_monitor": {
# Probe Status Settings
"probe_recent_days": 7, # Days to consider probe "recent"
# Currency Settings
"currencies": [
("CZK", "Czech Koruna", "KΔ"),
("EUR", "Euro", "β¬"),
("USD", "US Dollar", "$"),
("GBP", "British Pound", "Β£"),
("JPY", "Japanese Yen", "Β₯"),
],
"default_currency": "EUR", # Default currency for new records
# External Inventory Status Configuration (Optional)
"external_inventory_status_config": {
"1": {"label": "Active", "color": "success"},
"0": {"label": "Pending Activation", "color": "warning"},
"2": {"label": "Decommissioned", "color": "danger"},
},
# Custom tooltip template for status display (Optional)
"external_inventory_tooltip_template": "<span class='badge text-bg-{color}'>{code}</span> {label}",
}
}
probe_recent_days (default: 7): Number of days to consider a probe "recent". Affects visual indicators and status badges.currencies (default: see example above): List of available currencies for all financial models (Assets, Contracts, Invoices, AssetServices). Each item is a tuple of (currency_code, display_name, symbol).
currency_code: Currency identifier (e.g., "EUR", "USD", "CZK") - no length restrictionsdisplay_name: Human-readable name shown in formssymbol: Currency symbol for display (e.g., "β¬", "$", "KΔ") - optional (if omitted, currency code is used)default_currency (default: "EUR"): Default currency code used when creating new records. Must match one of the codes in the currencies list.Price and Currency Validation:
price = None: No pricing information - currency optionalprice = 0: Free/no charge - currency optionalprice > 0: Actual cost - currency required and validated in model's clean() methodexternal_inventory_status_config (optional): Maps status codes to display labels and Bootstrap colors. If not configured, status displays as-is without special formatting.external_inventory_tooltip_template (optional, default: "<span class='badge text-bg-{color}'>{code}</span> {label}"): Template string for formatting status tooltipsStatus Configuration Structure:
{
"status_code": {
"label": "Human readable label",
"color": "bootstrap_color_class" # primary, secondary, success, danger, warning, info, light, dark
}
}
Template Variables:
{code}: The status code{label}: The display label from configuration{color}: The Bootstrap color classHow it works:
get_status_color() and get_status_display() methodsFor file attachments, install and configure netbox-attachments:
pip install netbox-attachments
The plugin provides several configurable choice fields that can be customized via NetBox's FIELD_CHOICES configuration. This allows you to replace default choices or extend them with additional options.
Asset Model:
inventory_monitor.Asset.assignment_status: Assignment status (Reserved, Deployed, Loaned, Stocked)inventory_monitor.Asset.lifecycle_status: Lifecycle status (New, In Stock, In Use, In Maintenance, Retired, Disposed)Contract Model:
inventory_monitor.Contract.type: Contract type (Supply, Order, Service, Other)RMA Model:
inventory_monitor.RMA.status: RMA status (Pending, Shipped to Vendor, Received by Vendor, Under Investigation, Approved, Rejected, Completed)Asset Assignment Status (inventory_monitor.Asset.assignment_status):
[
('reserved', 'Reserved', 'cyan'),
('deployed', 'Deployed', 'green'),
('loaned', 'Loaned', 'blue'),
('stocked', 'Stocked', 'gray'),
]
Asset Lifecycle Status (inventory_monitor.Asset.lifecycle_status):
[
('new', 'New', 'green'),
('in_stock', 'In Stock', 'blue'),
('in_use', 'In Use', 'cyan'),
('in_maintenance', 'In Maintenance', 'orange'),
('retired', 'Retired', 'red'),
('disposed', 'Disposed', 'gray'),
]
Contract Type (inventory_monitor.Contract.type):
[
('supply', 'Supply Contract', 'green'),
('order', 'Order', 'red'),
('service', 'Service Contract', 'orange'),
('other', 'Other', 'blue'),
]
RMA Status (inventory_monitor.RMA.status):
[
('pending', 'Pending', 'yellow'),
('shipped', 'Shipped to Vendor', 'blue'),
('received', 'Received by Vendor', 'blue'),
('investigating', 'Under Investigation', 'blue'),
('approved', 'Approved', 'green'),
('rejected', 'Rejected', 'red'),
('completed', 'Completed', 'green'),
]
Replace Asset Assignment Status choices (in configuration.py):
FIELD_CHOICES = {
'inventory_monitor.Asset.assignment_status': (
('reserved', 'Reserved for Order', 'info'),
('active', 'Active/Deployed', 'success'),
('storage', 'In Storage', 'warning'),
('disposal', 'Pending Disposal', 'danger'),
)
}
Extend (append to) Asset Lifecycle Status choices:
FIELD_CHOICES = {
'inventory_monitor.Asset.lifecycle_status+': (
('quarantine', 'Quarantine', 'dark'),
('damaged', 'Damaged', 'danger'),
)
}
Replace Contract Type choices:
FIELD_CHOICES = {
'inventory_monitor.Contract.type': (
('purchase', 'Purchase Agreement', 'success'),
('maintenance', 'Maintenance Contract', 'info'),
('warranty', 'Warranty', 'primary'),
('lease', 'Lease Agreement', 'warning'),
)
}
Extend RMA Status choices:
FIELD_CHOICES = {
'inventory_monitor.RMA.status+': (
('refund', 'Refunded', 'success'),
('warranty_claim', 'Warranty Claim', 'info'),
)
}
Available Colors: blue, indigo, purple, pink, red, orange, yellow, green, teal, cyan, gray, black, white
Alternatively, Bootstrap semantic colors are also supported: primary, secondary, success, danger, warning, info, light, dark
For more information on NetBox field choice configuration, see the NetBox documentation.
After installation, the plugin adds an "Inventory Monitor" section to the NetBox navigation menu with the following sections:
The plugin provides visual feedback for probe status:
Assets can be assigned to any NetBox object using GenericForeignKey:
The plugin provides a dedicated form (AssetExternalInventoryAssignmentForm) for managing the many-to-many relationship between Assets and External Inventory items. This form:
_post_clean() to avoid validating price/currency when only managing external inventory relationshipsclean_fields() instead of full_clean() - Prevents cross-field validation errors for fields not in the formThis specialized form prevents validation errors like 'AssetExternalInventoryAssignmentForm' has no field named 'currency' that would occur if the full Asset model validation ran.
The plugin follows NetBox plugin best practices:
Asset ββ Probe (via serial number matching)
Asset β AssetType
Asset β Contract (order_contract)
Asset β GenericForeignKey (assigned to Device, Site, Location, Rack, Module)
Asset ββ RMA (via serial numbers: original_serial, replacement_serial)
Asset ββ ExternalInventory (many-to-many via assets field)
Asset β AssetService (via asset ForeignKey)
Contract β Contractor (via contractor ForeignKey)
Contract β Contract (parent, self-referential for hierarchical contracts)
Contract β Invoice (via contract ForeignKey)
Contract β AssetService (via contract ForeignKey)
ExternalInventory ββ Asset (many-to-many relationship)
ExternalInventory β RMA (matched via external_id for display)
select_related() and prefetch_related() in views and tables# Recommended approach - use helper functions
from inventory_monitor.settings import (
get_probe_recent_days,
get_currency_choices,
get_external_inventory_status_config_safe,
get_external_inventory_tooltip_template,
)
days = get_probe_recent_days()
currencies = get_currency_choices()
status_config, is_configured = get_external_inventory_status_config_safe()
tooltip_template = get_external_inventory_tooltip_template()
# Alternative approach - direct settings access
from inventory_monitor.settings import get_plugin_settings
settings = get_plugin_settings()
days = settings.get("probe_recent_days", 7)
This project is licensed under the MIT License. See the LICENSE file for more details.
FAQs
Asset Management with semi-auto discovery processes
We found that inventory-monitor demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.

Security News
ENISA has become a CVE Program Root, giving the EU a central authority for coordinating vulnerability reporting, disclosure, and cross-border response.

Product
Socket now scans OpenVSX extensions, giving teams early detection of risky behaviors, hidden capabilities, and supply chain threats in developer tools.