Skip to content

Overview

Consumables are user-defined assets that fall below the threshold of devices that need to be tracked individually, items such as network cables, transceivers, etc. Once consumables are defined, they are assigned to a storage location and are available to be checked out and assigned to a device.

Consumable Type vs. Consumable vs. Consumable Pool

Consumables are made up of three models, which together allow you to create categories of consumables (Consumable Type), specific consumable products (Consumable), and physical consumable assets available to be used in datacenters (Consumable Pool).

Consumable Type

A Consumable Type is a generic category of consumable, not a specific product, and include things like cables, transceivers, screws, labels, etc. Genric, Cable, and Transceiver Consumable Types are included with the Consumables plugin by default, and additional types can be added as needed. Consumable Types are the basis for all other consumables, each Consumable must be assigned a Consumable Type. Basic rule of thumb is that a category of product should be a Consumable Type, but if the product you're adding has a Manufacturer or Product ID it should be a Consumable.

Defining a Consumable Type

Add new consumable type

Consumable Types utilize JSON Schemas to allow for unique, detailed information to be stored for individual Consumables. The JSON schema is used to display an editor on the forms that makes adding and editing data in a consistent way more convenient. On the backend, there is validation on both the schema and the details to ensure that the input data is valid for that Consumable Type.

The JSON form utilizes JSON Editor to display the JSON schema in an easy to update form. JSON Editor has support for JSON Schema versions 3 and 4.

Important

In order to simplify displaying data, $ref definitions are not currently supported.

The JSON Editor supports an extra attribute, propertyOrder, that will sort the properties in that order. The Consumables app also utilizes this field to order fields when displaying to the end user. The closer to 0 the number is, the higher in the form it will be displayed.

The Consumables app has an added feature that if you need to use units, e.g. m, ft, etc., you can use name for the integer and name_unit for the units. Those fields will then be combined when displayed to the user, e.g. 1 ft.

Tip

As you're editing the schema for a Consumable Type, you can click the Update Schema button in the Form Preview panel of the form to see how the schema translates to a web form at any point. Add new consumable type

Sample JSON Schema
{
    "title": "Demo Consumable",
    "type": "object",
    "required": [
        "str1",
        "choice1",
        "int1",
        "array1"
    ],
    "properties": {
        "str1": {
            "title": "String 1",
            "type": "string"
        },
        "choice1": {
            "title": "Choice 1",
            "type": "string",
            "enum": [
                "option-1",
                "option-2",
                "option-3"
            ],
            "options": {
                "enum_titles": [
                    "Option 1",
                    "Option 2",
                    "Option 3"
                ]
            }
        },
        "int1": {
            "title": "Integer 1",
            "type": "integer",
            "minimum": 0,
            "maximum": 42
        },
        "array1": {
            "title": "Array 1",
            "type": "array",
            "format": "table",
            "items": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string"
                    }
                }
            }
        }
    }
}
Example Type Creation

When adding a new Consumable Type, it may be advantageous to use Choice Fields already built in to Nautobot (Colors, Cable Types, Port Types, etc.), this can be done via the ORM or updating signals.py.

Info

signals.py has some helpers to make it easier to convert a built-in choice to a JSON object.

Below is an example of a Rack Consumable Type that could be added to signals.py, triggering its creation at the post-migration step when installing/upgrading the Consumables app.

# signals.py
from nautobot.dcim.choices import RackTypeChoices, RackWidthChoices

from nautobot_consumables.models import ConsumableType


def post_migrate_create_defaults(sender, apps, **kwargs):  # pylint: disable=W0613
    """Callback function for post_migrate() -- create default Statuses."""

    # Existing post-migrate steps here

    rack_schema = {
        "type": "object",
        "title": "Rack Details",
        "properties": {
            "rack_type": create_json_schema_type("Rack Type", RackTypeChoices.as_dict(), 10),
            "rack_width": create_json_schema_type("Rack Width", RackWidthChoices.as_dict(), 20),
            "rack_units": {
                "title": "Rack Units",
                "type": "integer",
                "minimum": 1,
                "maximum": 100,
                "propertyOrder": 30,
            },
            "height": {
                "title": "Height",
                "type": "integer",
                "minimum": 1,
                "maximum": 144,
                "propertyOrder": 40
            },
            "height_unit": {
                "title": "Height Unit",
                "type": "string",
                "enum": ["m", "cm", "ft", "in"],
                "options": {"enum_titles": ["Meters", "Centimeters", "Feet", "Inches"]},
                "propertyOrder": 50,
            },
            "width": {
                "title": "Width",
                "type": "integer",
                "minimum": 1,
                "maximum": 144,
                "propertyOrder": 40
            },
            "width_unit": {
                "title": "Height Unit",
                "type": "string",
                "enum": ["m", "cm", "ft", "in"],
                "options": {"enum_titles": ["Meters", "Centimeters", "Feet", "Inches"]},
                "propertyOrder": 50,
            },
        }
    }

    ConsumableType.objects.update_or_create(name="Rack", slug="rack", defaults={"schema": rack_schema})

Consumable

A Consumable represents a physical consumable that has a manufacturer, product ID, type, etc., and is used to create a Consumable Pool. This allows for standardization between projects so that you don't wind up with 42 different variations of the same product. Typical Consumables would be things like a 15' Red Cat6A patch cable, 200 yard roll of Velcro strapping, or an LX SFP+ module.

Add new consumable type

Info

When adding a new Consumable, the details form will dynamically updated for the schema of the chosen Consumable Type. Once a Consumable is created, its Consumable Type cannot be changed, and when editing an existing consumable the form will prevent you from changing the selection.

Consumable Pool

Consumables Pools are the available physical assets represented by a Consumable. When adding a new Consumable Pool, a Consumable is selected along with the storage location, and quantity.

Add new consumable type

Info

Once created, the base consumable of a pool cannot be changed, but the quantity and storage location can be updated. Note that changing the storage location will cause any checked out consumables from the pool to be checked back in.

Consumable Detail Inheritance

When creating a Consumable Type, a detailed JSON schema is created for that type.

When creating a Consumable, it is associated with a Consumable Type, and the JSON schema is used to construct the form with options for the product.

Updating the schema of a Consumable Type will not change any existing Consumables based on that type.

Consumable Pools can be moved between locations, but doing so will cause all checked out consumables to be checked back in.

Checking Out Consumables

Consumable Pools are assigned to locations, and define the number of those consumables available in that location. Once consumables are put into use, e.g. hosts and switches are cabled up, the consumables in use need to be checked out. Checked Out Consumables track the quantity in use by each device, and decrease the number available in the pool, for proper inventory tracking.

Filtering

The Consumables app extends the filter set for Locations to allow filtering based on the presence of Consumable Pools at a given location. In the UI, the filter is available under the Advanced tab when filtering. Choose Has Consumable Pools for the field, is null for the lookup type, and then choose either Yes or No to filter for locations that to or do not have Consumable Pools assigned to them.

The filter can also be used by attaching a query parameter to the request URL for the location list. The parameter for filtering by available project consumables is nautobot_consumables_has_pools, set the parameter value to either True or False.

http://nautobot.server/dcim/locations/?nautobot_consumables_has_pools=True