Keeping Data Clean
Scenario: your support contracts need some rules:
- contract numbers follow your format;
- a contract number is unique per vendor (different vendors may reuse a number);
- an end date is never before its start date;
- active contracts must have an end date.
You'll use: validation regexes, required fields, unique and check constraints, and NetBox's CUSTOM_VALIDATORS setting.
Before You Start
- The Support Contract type from A self-contained object type exists, with a few contracts.
- Your user can change Custom Object Type fields and add constraints. Step 5 needs access to NetBox's
configuration.py.
Steps
1. Check the Contract Number Format
- On the Support Contract type's page, open the Fields tab and edit Contract number.
- Set Validation regex to
^[A-Z]+-[0-9]+$and save. - Try saving a contract with the number
acme 1001. The form shows "Values must match this regex" under Contract number.
Existing values aren't rechecked when you add a regex; it applies the next time each contract is saved.
2. Make Contract Numbers Unique per Vendor
- On the type's page, click Add and choose Constraint.
- Set Name to
unique_number_per_vendorand Type to Unique. - Under Fields, choose Vendor and Contract number, and enable Case-insensitive, so
AcmeandACMEcount as the same vendor. - Click Create. If existing contracts already break the rule, NetBox says so ("Existing Support Contract objects already have duplicate values for these fields.") and doesn't create the constraint.
- Try adding a contract with vendor
ACMEand the number of an existing Acme contract. It's rejected with "Support Contract with this Contract number and Vendor already exists." The same number with vendorGlobexis accepted.
3. Require the End Date After the Start Date
-
Add another constraint with Name
end_after_startand Type Check. -
Set Rule to:
[{"field": "end_date", "lookup": "gt", "value": {"field": "start_date"}}] -
Set Error message to
The end date must be after the start date.and click Create. The Constraints tab describes the rule as "End date is greater than Start date". -
Try saving a contract that ends before it starts. Your error message is shown. A contract with no end date is still accepted: a comparison with an empty value passes.
4. Require an End Date on Active Contracts
- Add a check constraint named
active_needs_end_date. - Set Condition to
[{"field": "status", "lookup": "exact", "value": "active"}], so the rule only applies to active contracts. - Set Rule to
[{"field": "end_date", "lookup": "isnull", "value": false}]. - Set Error message to
Active contracts need an end date.and click Create. - Try saving an active contract with no end date, then a pending one. Only the active one is rejected.
5. Add a Rule with a Custom Validator (Optional)
Constraints cover comparisons between fields. For other rules, NetBox's CUSTOM_VALIDATORS setting applies to custom objects too, keyed by the type's slug:
-
In
configuration.py, add (the key ends with the type's slug):CUSTOM_VALIDATORS = { 'netbox_custom_objects.support-contracts': [ {'vendor': {'min_length': 2}}, ], } -
Restart NetBox.
-
Try saving a contract with a one-letter vendor. It's rejected with "Custom validation failed for vendor", followed by the validator's message.
6. Check That Every Path Is Covered
Repeat one rejected change through the REST API and through a CSV import. The same rules apply: the REST API returns 400 Bad Request with the same message, and the import is rejected without creating anything.
Result
Invalid contracts are rejected in the UI, the REST API and imports.
See Also
- Constraints for every lookup and option.
- Field Attributes for Required, Must be unique and validation settings.
Bulk Importing and Editing
1. Click Support Contracts in the navigation menu, then Import. 2. Scroll down to Field Options. It lists each field's column name, with a check mark for req...
Linking to NetBox Objects
1. Go to Custom Objects > Custom Object Types and click Add. 2. Set Internal name to staticroute, Display name (singular) to Static Route and Display name (p...