* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in fr [Manual Sync]
12% of minimum 1% reviewed source file: 'django.po'
on 'fr'.
Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
* Translate django.po in pt [Manual Sync]
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in de [Manual Sync]
78% of minimum 1% reviewed source file: 'django.po'
on 'de'.
Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
* Translate django.po in tr [Manual Sync]
7% of minimum 1% reviewed source file: 'django.po'
on 'tr'.
Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
* Translate django.po in ru [Manual Sync]
30% of minimum 1% reviewed source file: 'django.po'
on 'ru'.
Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
* Translate django.po in zh [Manual Sync]
16% of minimum 1% reviewed source file: 'django.po'
on 'zh'.
Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
---------
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
* Allowed configuration of Sentry send_default_pii parameter.
Also changed default value of send_default_pii to False to avoid sending sensitive data to Sentry.
Closes#16802
* Order alphabetically & link to Sentry parameter documentation
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Extend STORAGE_BACKEND config to support Swift
Requires django-storage-swift >= 1.4.0 when used.
Bug: T310717
Change-Id: I67cf439e9152608cbba3a3de4173d54ba5fbddc2
* Update system.md from suggestions
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Update settings.py from suggestions
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Update system.md from suggestions 2
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Remove SWIFT storage from configuration_example.py
* Load swift config as global instead of monkey path
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Do not delete all search indexes when reindexing specific models
* Clear all indexes only if neither --lazy nor a list of models are
specified for "manage.py reindex"
* Otherwise, clear the index for a model immediately before rebuilding
it
* Separated clearing from re-indexing the search cache
* I replaced `append` with `insert` into menu.py to make the admin section appear last in the navigation menu.
* Clean up ordering logic
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Was added to searching support languages other than English for object types(s).
* Fix SearchForm field label translation
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Added `help_text` to ColorField.
* Addressed PR comment to remove the redundant help_text from all the forms where ColorField was used.
* Add space before example value
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in pt
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in fr [Manual Sync]
12% of minimum 1% reviewed source file: 'django.po'
on 'fr'.
Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
* Translate django.po in pt [Manual Sync]
100% reviewed source file: 'django.po'
on 'pt'.
* Translate django.po in ru [Manual Sync]
30% of minimum 1% reviewed source file: 'django.po'
on 'ru'.
Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
* Translate django.po in de [Manual Sync]
75% of minimum 1% reviewed source file: 'django.po'
on 'de'.
Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
* Translate django.po in tr [Manual Sync]
7% of minimum 1% reviewed source file: 'django.po'
on 'tr'.
Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
---------
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
* Fixes#15717: Allow VM with Site to Cluster without Site
* Fixes#15717: Allow VM with Site to Cluster without Site
* Fixes#15717: Allow VM with Site to Cluster without Site
* Fixes#15717: Allow VM with Site to Cluster without Site
* Fixes#15717: Allow VM with Site to Cluster without Site
* Added dropdown for Saved Filters.
* Added dropdown for Saved Filters.
* Added dropdown for Saved Filters.
* Fixed linter issues in savedFiltersSelect.ts
* Fixed linter issues in netbox.ts
* Fixed linter issues in netbox.ts
* Removed the blue tag with the filters when saved filters is selected.
* Adjusts in table_controls_htmx.html to vertical height of the Quick Search match to the dropdown.
* Adjusts in table_controls_htmx.html to vertical height of the Quick Search match to the dropdown.
* Adjusts in table_controls_htmx.html to vertical height of the Quick Search match to the dropdown.
* Minor adjusts in savedFiltersSelect.ts
* Addressed PR comment.
* Addressed PR comment.
* Addressed PR comment.
* Omit saved filters from 'applied filters'; clean up form widget
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Closes#15794: Make "related objects" dynamic
Instead of hardcoding relationships between models for the detail view,
they are now dynamically generated.
* Fix related models call
* Remove extra related models hook
Instead of providing a rarely used hook method, additional related
models can now be passed directly to the lookup method.
* Fix relations view for ASNs
ASNs have ManyToMany relationships and therefore can't used automatic
resolving. Explicit relations have been restored as before.
* Add method call keywords for clarification
* Cleanup related models
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Translate django.po in de [Manual Sync]
74% of minimum 1% reviewed source file: 'django.po'
on 'de'.
Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
* Translate django.po in de [Manual Sync]
74% of minimum 1% reviewed source file: 'django.po'
on 'de'.
Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
* Translate django.po in ru [Manual Sync]
30% of minimum 1% reviewed source file: 'django.po'
on 'ru'.
Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
* Translate django.po in pt [Manual Sync]
2% of minimum 1% reviewed source file: 'django.po'
on 'pt'.
Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
* Translate django.po in fr [Manual Sync]
12% of minimum 1% reviewed source file: 'django.po'
on 'fr'.
Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
* Translate django.po in tr [Manual Sync]
7% of minimum 1% reviewed source file: 'django.po'
on 'tr'.
Sync of partially translated files:
untranslated content is included with an empty translation
or source language content depending on file format
---------
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
* Created "convert_byte_size" method to convert the memory and disk size according to unit informed.
Changed "get_extra_context" method from "ClusterView" to use the method above and convert all the disks and memories from VMs to normalize the units.
* Changed decimal size for memory_sum and disk_sum
* Added test for convert_byte_size.
* Fixed
* Addressed PR comments.
Changed humanize_megabytes in helpers.py
* Addressed PR comments.
Changed humanize_megabytes in helpers.py
* Linter issues for helpers.py
* Changed humanize_megabytes
* Changed humanize_megabytes
* Changed humanize_megabytes
* Added the title to display the value in MB when mouseover.
* Addressed PR comment.
* Addressed PR comment.
* Rewrite sizing logic
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* 16050 Show script python_class name and description
* 16050 change to use Meta.description
* 16050 change to use Meta.description
* 16050 remove module name customization from docs
* Fixes: #16083 - Add font-variant-ligatures setting to disable ligatures on chromium
* Fix comment
* Disable ligatures on input fields
* Condense rules & apply to all elements
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Fix row highlighting
* Minor fix for VMInterfaces
* Move duplicated dicts into inheritable meta class
* Add CableTerminationTable.Meta class for inheritance of the row_attrs to each descendant Meta class.
* 16145 script api use module.script name instead of pk
* 16145 fix test
* 16145 allow both pk and script name
* 16145 update doc string
* Simplify retrieval logic
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Fixes#15962: support Redis Unix sockets
* Clean up language & remove obsolete note
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* 14953 fix serializers when using add_related_count
* 14953 update comments
* Set default=0 for annotated count fields
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Translate django.po in ja
100% translated source file: 'django.po'
on 'ja'.
* Translate django.po in uk
100% translated source file: 'django.po'
on 'uk'.
* Translate django.po in de
100% translated source file: 'django.po'
on 'de'.
* Translate django.po in zh
100% translated source file: 'django.po'
on 'zh'.
---------
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
* add USE_I18N setting
* change setting name to ENABLE_TRANSLATION
* raise a warning in the UI when translation is disabled
* Misc cleanup
* Rename to TRANSLATION_ENABLED for consistency with other settings
---------
Co-authored-by: Anton Myasnikov <anton.myasnikov@nordigy.ru>
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Closes#16090: Show NetBox version if plugin validation fails
* Shorten error message
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* slim-select-pagination-bug-fix : fixed several bugs related to slim
select search box gui element
1. If user enters a search text in the filter text box, the user will
not be able to scroll to the next page. That is the user will only be
able to see the first page of returned item with a none empty search
string.
2. User will not be able to select an item returned from search query
if user clicks reload after a dynami search. When the user is able
to load a second page, the user will be able to select an item from
the third+ page if previous bug is fixed.
* Recompile static assets
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* slim-select-pagination-bug-fix : fixed several bugs related to slim
select search box gui element
1. If user enters a search text in the filter text box, the user will
not be able to scroll to the next page. That is the user will only be
able to see the first page of returned item with a none empty search
string.
2. User will not be able to select an item returned from search query
if user clicks reload after a dynami search. When the user is able
to load a second page, the user will be able to select an item from
the third+ page if previous bug is fixed.
* Recompile static assets
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* 15802 change table anchor color
* 15802 make link color lighter
* 15802 lighten table color
* 15802 add comment
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* 15831 monkeypatch LDAP _mirror_group function for NB4
* 15831 monkeypatch LDAP _mirror_group function for NB4
* 15831 monkeypatch LDAP _mirror_group function for NB4
* Move the modified _mirror_groups() method to a separate module to retain license
* 15831 fix import
* 15831 fix import
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Fix cable edit form with single unterminated cable
* Minor tweaks
* Instead of skipping HTMX, override the template & move form template to an "htmx" template
* Use HTMXSelect widget for A/B type selection
* Infer A/B termination types from POST data
* Fix saving cable which results in resetting of the termination type fields
* Condense view logic
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Fixes#15812: Add Date(Time)Var for scripts to allow much easier date input
* Extend tests for invalid data
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Closes#14690: Pretty-format JSON fields in the config form
* Revert changes
* Use our own JSONField for config parameters for pretty editor outputs
* Compare identity instead of equality
* 15761 filter IKEAProposals on IKEAPolicy detail view
* Add test for ike_policy filter
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* 5509 add content type data to model tests create and update
* 5509 update use cf form data
* 5509 update tests to use CustomFieldTypeChoices
* 5509 update tests to check custom fields
* Simplify custom fields used for testing
* Move custom field data functions to testing.utils
* Move validate_custom_field_data() into assertInstanceEqual()
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Introduce the isodate(), isotime(), and isodatetime() template filters
* Display the relative time on mouse hover
* Render journal entry times in ISO 8601 format
* Use ISO 8601 format when displaying dates & times in a table
* Standardize the use of DateTimeColumn across all tables
* Fix typos in migration-v4.md
* Replace typing.List with list
typing.List is deprecated since Python 3.9
* Also replace typing.List with list in graphql-api.md
* Added SECURE_HSTS_SECONDSm SECURE_HSTS_INCLUDE_SUBDOMAINS, and SECURE_HSTS_PRELOAD to settings.py
* Addressed some PR comments.
* Apply suggestions from code review
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* add example showing how to order results.
This addresses issue 15622 by building off filtering example to
show how to order results on a named field.
* Apply suggestions from code review
---------
Co-authored-by: Frank Clements <fclements@scoore.net>
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Update documentation for plugins index.md
You should restart netbox-rq workers if you added a plugin. Otherwise you can't load modules from plugin to custom scripts later.
* Update docs/plugins/index.md
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Enable HTMX boosting
* Refactor HTMX properties for tables
* Fix dashboard object list widget
* Disable scrolling to page content
* Fix initialization of TomSelect dropdowns after HTMX loading
* Replace formaction properties with hx-post
* Fix quick search field on object list view
* Reinitialize copy-to-clipboard buttons upon HTMX load
* Disable scrolling effect for intra-page navigation
* Introduce user preference for toggling HTMX navigation
* Enable HTMX navigation only when selected by user
* Pass htmx_navigation context
* Fix display of confirmation form when deleting an object
* Disable HTMX boosting for rack elevation SVG downloads
* Fix dyanmic form rendering
* Introduce htmx_boost template tag; enable HTMX for user menu
* Use out-of-band sap to update footer stamp
* Fix display of toasts after form submission
* Fix user preference selection
* Misc cleanup
* Rename render_partial() to htmx_partial()
* Add docstring to htmx_boost template tag
* Disable HTMX for user preferences form to force a full page refresh on changes
* Fixes: #13722 - Correct range expansion code when a numeric set is used
* Correct to my own suggestion
* Clean up logic
* Simplify range detection
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Fix left padding of login button in top menu
* Relocate "add" buttons for embedded object tables
* Remove unused data template block & getNetboxData() utility function
* Remove bottom margin from last <p> element in rendered Markdown inside a table cell
* Prevent TomSelect from initializing on <select> elements with a size
* Fix styling of dropdown menu button for circuit commit rate
* Change .color-block to display: inline-block
* Delete unused static asset
* Improve contrast between menu group headings & items
* Remove custom color for attr-table row headings
* Fix border color of copy-to-clipboard button
* Fix toast text color in dark mode
* Fix rack elevation label/image toggles
* Increase border radius for small buttons
* Fix object selector
* Rename sequences & indexes after renaming users table
* Migrate from auth.Group to a custom group model
* Delete original groups from auth_group table
* Update object & multi-object custom fields referencing the Group model
* Fix ContentType resolution
* Clean up obsolete logic for view/serializer resolution
- Introduces the Script model to represent individual Python classes within a ScriptModule file
- Automatically migrates jobs & event rules
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Added Last Login to user/profile GUI and user api output
* Update netbox/templates/account/profile.html
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Update netbox/templates/account/profile.html
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Update netbox/templates/users/user.html
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Fixes: #14058 - Limits platform selection to manufacturer and platforms with no manufacturer
* Apply suggestions from code review
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Introduce RelatedObjectCountField
* Introduce get_annotations_for_serializer() and enable dynamic annotations
* Add RelatedObjectCountFields to serializers; remove static annotations from querysets
* Remove annotations cleanup logic from BriefModeMixin
* Annotate type for RelatedObjectCountField
* Remove redundant field on TagSerializer
* Add missing reverse relationship for power feeds to rack
* Refactor RelatedObjectCountField to take a single relationship name
* Enable dynamic field inclusion for REST API serializers
* Recurse through nested serializer when resolving prefetches
* Remove obsolete calls to prefetch_related() for API views
* Remove support for brief_prefetch_fields viewset attribute
* Rename query parameter
* Fixes#15133: Fix FHRP group representation on assignments endpoint under brief mode (#15134)
* Fixes#15133: Fix FHRP group representation on assignments endpoint under brief mode
* Update API test
* Restore get_queryset() on BriefModeMixin, minus prefetch logic
* get_prefetches_for_serializer() should reference serializer field source if set
* Initial work on #13283
* Enable passing TomSelect HTML template attibutes on DynamicModelChoiceField
* Merge disabled_indicator into option_attrs
* Add support for annotating a numeric count on dropdown options
* Annotate parent object on relevant fields
* Improve rendering of color options
* Improve rendering of color options
* Rename option_attrs to context
* Expose option context on ObjectVar for custom scripts
* Document dropdown context variables
* Experimenting
* Remove testing resources
* Replace ApiSelect with TomSelect
* Add color support
* Add clear button
* Clear cached options when searching dynamic selects
* Add support for static parameters
* Refactor TomSelect implementation
* Add dynamic parameter support
* Limit number of options to 100
* Remove redundant api_url definitions for user model
* Add support for disabled indicator
* Remove obsolete value-field attr on dynamic select widgets
* Remove obsolete fetch_trigger kwarg from dynamic model choice widgets
* Remove obsolete empty_label kwarg from dynamic model choice widgets
* Add support for API path variables
* Add support for setting a 'null' option
* Annotate depth for recursive hierarchies
* Misc cleanup
* Remove obsolete APISelect code
* Remove slim-select & just-debounce-it
* Clean up type validation
* Closes#14237: Clear child selections on change to parent selection
* Use an MD icon for the clear button
* Use an MD icon for the clear button
* Explain why noUnusedParameters is disabled
* Fixes: #14840 - Forces API to use proxy model
* Update tests to use proxy model
* Revert "Update tests to use proxy model"
This reverts commit 1d784cfe5d.
* Revert "Fixes: #14840 - Forces API to use proxy model"
This reverts commit df85cc967c.
* More realistic change to resole issue with netboxusers-list
* Revert "More realistic change to resole issue with netboxusers-list"
This reverts commit 15df8082aa.
* Fixes: #14840 - Better fix for netboxusers-list
* Swap model for serializer from proxy model
Clean up spacing for nav pills
Markdown fields should default to using monospace font
Wrap action buttons in object page header
Fix page link style for non-HTMX paginators
Clean up styling of Markdown preview widget
Fix spacing around placeholder text for empty panel tables
Remove obsolete templates
Tweak checkbox input spacing
Fix toggling of clear button for quick search
Fix positioning of quick search filter dropdown
Fix positioning of 'highlight device' button
Fix styling for custom field group names
Widen buttons on nav menu items
Restyle the login page
Fix active nav-pill background color in dark mode
Fix spacing around 'map' button for sites
* Fixes#14572 - Constrains JobView (and related views) badge to specific named job
* Adjust report views to resolve same problem
* Fixed PEP8 error
* Update netbox/templates/extras/script/base.html
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Move function to method on PythonModuleMixin
* Update netbox/extras/views.py
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Update netbox/extras/views.py
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Update netbox/extras/views.py
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Update netbox/extras/views.py
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Update to mixin and view
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Fixes#14755: ValueError in web UI after REST API accepts invalid custom-field choice-set data
* PR Comments Addressed
* Set max_length=2 on extra_choices items; remove custom validation logic
* Move test for invalid choices to CustomFieldChoiceSetTest
* Omit unused imports
---------
Co-authored-by: julio.oliveira <julio.oliveira@alertmedia.com>
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* fixes user delete when they have a bookmark #14851
* Include migration for user field
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Introduce custom form widget templates to apply CSS classes
* Apply both mandatory and optional CSS classes to form widgets
* Omit required & placeholder attrs
* Move annotation of field validation failures to CSS
* Remove BootstrapMixin class
* Remove obsolete ComponentTemplateImportForm class
* Remove obsolete custom forms for login & password change
* Clean up obsolete accommodations for 'required' widget attr
* Remove dark mode styling
* Condense & rename light mode stylesheet
* Upgrade to Bootstrap 5.3.2
* Swap out Bootstrap for Tabler; remove custom styling
* Update base page layout for Tabler
* Update login page
* Bump node to v18
* Update button styles
* Update object list view
* Tweak navbar size
* Clean up dashboard widgets
* Ditch separate stylesheet for print media
* Remove simplebar
* Remove obsolete sidebar styling
* Clean up object view template
* Clean up object edit template
* Standardize primary button sizing
* Clean up object list styling
* Add buttons for add & import to navigation menu
* Fix global search bar
* Fix slim-select form widget styling
* Fix toast styling
* Set base fonts
* Clean up paginator styling
* Clean up navigation menu group headings
* Clean up footer links
* Clean up card styles
* Move SVG styles to a designated directory
* Restructure SCSS files
* Remove obsolete/redundant dependencies
* Fix icon spacing
* Update background color classes
* Tweak banner & footer styling and spacing
* Fix badge background colors in table content
* Bump @types/bootstrap to 5.2.10
* Clean up form layouts
* Fix object selector button style
* Fix icon padding inside small buttons
* Fix icon & badge spacing inside buttons and tabs
* Hide paginator for empty pages
* Fix hover color for list items (Tabler bug #1694)
* Fix width of checkbox column in empty tables
* Clean up bulk edit template
* Fix border color of reslug button
* Package & serve Google fonts locally
* Fix tab styling
* Reduce vetical space at top of dashboard
* Remove obsolete content-wrapper template block
* Fix icon spacing in dropdown menu items
* Fix color label sizing
* Separate bulk delete form & object list into tabs
* Fix styling of filter group headings
* Fix styling for object changelog & journal views
* Standardize ordering & styling of action buttons
* Fix designation of active menu item
* Automatically expand menu section containing the active link
* Clean up nav menu styling
* Remove button colors; hide buttons except on hover/active
* Highlight menu group containing the active item
* Update & standardize alert styling
* Refactor base templates to ensure consistent display of header content
* Tweak styling for links inside badges
* Clean up top menu
* Fix JSON/YAML toggles for config context data
* Fix object template header
* Constrain tabs to container-xl; tweak header margins
* Fix object identifier styling
* Fix positioning of card header buttons
* Remove padding from HTMX tables inside cards
* Ensure consistent use of row headings in attribute tables
* Remove padding surrounding tables inside cards
* Remove obsolete CSS classes
* Misc cleanup of old styling
* Refactor 'controls' template block; ditch old classes
* Fix login button sizing
* Limit object edit form width
* Append asterisk to required form field labels
* Remove obsolete styling
* Remove obsolete styling
* Fix position of progress bar outside label
* Fix alignment of delete button in report/script lists
* Fix <pre> styling
* Clean up page headers
* Replace SVG icons with Material Design icons
* Restore dark mode togle functionality
* Fix top navbar background color under dark mode
* Rebuild static assets
DH group 15 was not selectable in the UI, and I strongly suspect this
patch will fix that, as that particular choices was missing in
`choices.py`.
Signed-off-by: Jorik Jonker <jorik@kippendief.biz>
Fixes#14793
* Change references to admin UI to Admin menu
* Change also for reports and custom scripts
* Minor tweaks to help text flow better
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit updates the cable rendering logic to fix
both issue #14722 and #13922. Before, objects, terminations
and cables where drawn in the svg without context of each
other.
Now the following changes are applied:
- Hosts and Terminations are where possible sorted alphabetically
- Terminations and Cables are visually connected, and if necessary not in a vertical line
- Terminations and Hosts are visually aligning
- Cable Tooltips contain more information
* Fix validation when primary IP is moved.
* Fix views test
* Work on excluding assigned_objects
* Modify clean() on model and form to properly catch error
* Fix test failure
* Fix test to check for PK
* Remove model_form check
* Usability improvements for object selector:
* Adds preselected filters
* Applies the filter on selection instead of requiring the search button to be pushed
* Declare selector_fields on base form class
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* 14147 Prevent logging to Change Log when no changes are made
* 14147 add test
* 14147 add exclude_fields to serialize_object
* 14147 make skip empty default to True
* 14147 remove override of to_objectchange
* Misc cleanup
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* fixes client ip detection for v6
* adds test for get_client_ip
* Employ urlparse() to strip port numbers from IPs
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* initial work to render hierarchical region #13735
* adds site display #13735
* cleanup #13735
* adds display region tag #13735
* refactored region hierarchy #13735
* refactored region hierarchy #13735
* renamed display_region to nested_tree #13735
* Make render_tree suitable for generic use
* Remove errant item from __all__
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Fixed password was not hashed on REST API update
* When we updated a user password with a REST API call the password was
stored in clear in plain text in the database.
* Following code review
* Move test on UserTest class
* Call `super().update()` in overriding `update` method
* Return directly the result of `super().update()`
In PR #13958 (commit 8224644) _get_report was modified to do the call on the variable without changing the call later on.
This commit fixes that and removes the call on the variable.
Signed-off-by: Josef Johansson <josef@oderland.se>
* Move L2VPN and L2VPNTermination models from ipam to vpn
* Move L2VPN resources from ipam to vpn
* Extend migration to update content types
* Misc cleanup
- Introduces a new `vpn` app with the following models:
- Tunnel
- TunnelTermination
- IKEProposal
- IKEPolicy
- IPSecProposal
- IPSecPolicy
- IPSecProfile
* Move ConfigRevision model & write migrations
* Move ConfigRevision resources from extras to core
* Extend migration to update original content type for ConfigRevision
* 8356 add virtual disk model
* 8356 add supplemental forms
* 8356 add menu
* 8356 cleanup views
* 8356 virtual machine tab
* 8356 migrations
* 8356 vm disk tables
* 8356 cleanup
* 8356 graphql
* 8356 graphql
* 8356 add components button
* 8356 bulk add on virtualmachine
* 8356 bulk add fixes
* 8356 api tests
* 8356 news tests add rename
* 8356 VirtualDiskCreateForm
* 8356 fix test
* 8356 add todo to remove disk from vm
* 8356 review changes
* 8356 fix test
* 8356 deprecate disk field
* 8356 review changes
* 8356 fix test
* 8356 fix test
* Simplify view actions
* 8356 review changes
* 8356 split trans tag
* 8356 add total virtual disk size to api
* 8356 add virtual disk list to virtual machine detail view
* 8356 move virtual disk size to property
* 8356 revert property
* Tweak display of deprecated disk field
* 8356 render single disk field
* 8356 update serializer
* 8356 model property
* 8356 fix test
* 8356 review changes
* Revert disk space annotation
* Use existing disk field to store aggregate virtual disk size
* Introduce abstract ComponentModel for VM components
* Add search index for VirtualDisk
* Misc cleanup
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Closes#13794: Dynamically populate related objects list under tenant view
* get_related_models() should sort models alphabetically by default
* Reference Meta.related_objects instead of calling get_fields()
* WIP
* Add display_attrs for all indexers
* Linkify object attributes
* Clean up prefetch logic
* Use tooltips for display attributes
* Simplify template code
* Introduce get_indexer() utility function
* Add to examples in docs
* Use tooltips to display long strings
* adds unit to the power port draw #13587
* review changes #13587
* moved units to header #13587
* Abbreviate unit for consistency with e.g. PowerFeedTable available_power column
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Add primary_ip4 and primary_ip6 filters for VirtualMachine and VirtualDeviceContext filtersets (#13936)
* Add PrimaryIPFilterSet to __all__
---------
Co-authored-by: Artem I. Kotik <artem.i.kotik@ringcentral.com>
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Add manufacturer for filters in the virtual machine and device #12741
* reverse the filtersets of device and vm
* revert the filtersets of vm
* add advance selector in platform
* remove manufacture from imports
* show objects that would be deleted by cascade
* some items were not showing (eg ips on devices)
* dont include the item being deleted in the list of related items
* Revert "dont include the item being deleted in the list of related items"
This reverts commit 298a7860b2.
* cleanup
- migrate code to use collector directly instead of the NestedObjects wrapper from admin.utils
- adjust object names and text output
* requested adjustments
* remove comma from end of list
* linting
* refactor, add accordion
* migrate to defaultdict, use title for capitalisation of accordian titles
* Misc cleanup
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Closes#12135: Prevent the deletion of interfaces with children
* Change PROTECT to RESTRICT
* Extend handle_protectederror() to also handle RestrictedError
* Fix string translation
* Update migrations
* Support bulk removal of parent interfaces via UI if all children are included
* Add support for the bulk deletion of restricted objects via REST API
* Initial work on #13381
* Fix backend type display in table column
* Fix data source type choices during bulk edit
* Misc cleanup
* Move backend utils from core app to netbox
* Move backend type validation from serializer to model
* 13230 add exclusion flag to device type
* 13230 forms, detail views
* 13230 add tests
* 13230 extraneous model field
* 13230 extraneous form field
* Update netbox/dcim/forms/bulk_edit.py
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* 13230 review feedback
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* 12216 add color to model
* 12216 add forms, serializers for color
* 12216 color to detail view, add type to svg
* 12216 add color to svg
* 12216 review changes
* Move extras.plugins to netbox.plugins & add deprecation warnings
* Move plugin template tags from extras to utilities
* Move plugins tests from extras to netbox
* Add TODO reminders for v4.0
* 14025 fix script name checking
* 14025 fix script name checking
* 14025 add file extension validation and simplify get logic
* 14025 match start of string with regex
* 14025 backout changes to model_forms
* 14025 add filepatch checking to reports
* Catch AssertionError's in signals. Handle accordingly
* Alter cable logic to handle certain additional path types.
* Fix failures and add test
* More tests
* Remove not needed tests, add additional tests
* Finish tests, correct some behaviour
* Add check for mid-span device not allowed condition
* Remove excess import
* Remove logging import
* Remove logging import
* Minor tweaks based on Arthur's feedback
* Update netbox/dcim/tests/test_cablepaths.py
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Update netbox/dcim/models/cables.py
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Changes to account for required SVG rendering changes and based on feedback
* More tweaks for cable path checking
* Improve handling of links with multi-terminations
* Improved SVG rendering of multiple rear ports (with positions) per path trace. Include asymmetric path detection
* Include missing assert to ensure links are same type.
* Clean up tests
* Remove unused objects from tests
* Changes requested to tests and update comments/doctstrings
* Fix parent reference
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Update VLANGroup bulk edit form to support all scope types
* Fixes#13843: Fix scope assignment for VLAN groups during bulk edit
* Add missed static file
* Restore graphiql static assets
* 12685 use markdown for custom fields added to form
* 13809 change markdown to use utilities
* Add help_text for CustomField description indicating Markdown support
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Fixes#11209 - Do not add available ips when IPAddressTable sort preferences are saved
* Refine check to account scenario right after clearing ordering string
* Introduce get_table_ordering() utility to determine intended ordering given a request
* Apply fix to VLAN ranges as well
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Adding documentation to 6-LDAP to display how to allow Active Directory logins with or without the user UPN suffix.
* Correcting misspellings and clarifying explanations
* Updating sections to include sample template
* Misc revisions
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* adds csv dialect detection to bulk import view #13239
* adds sane delimiters for dialect detection #13239
* adds csv delimiter tests #13239
* adds csv delimiter on the form
* pass delimiter to clean_csv method #13239
* fix tests for csv import #13239
* fix tests for csv import #13239
* fix tests for csv import #13239
* fix tests for csv import #13239
* Improve auto-detection of import data format
* Misc cleanup
* Include tab as a supported delimiting character for auto-detection
* Move delimiting chars to a separate constant for easy reference
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Fixes: #13682 - Fix custom field exceptions and validation
* Add tests
* Remove default setting for multi-select/multi-object and return slice of choices and annotate.
* Remove redundant default choice valiadtion; introduce values property on CustomFieldChoiceSet
* Refactor test
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* adds interface rename button on the list page #13444
* adds rename view on all device components #13564
* Condense component views to a single template
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Add `vc_interfaces` flag to control interface queryset
* Fix test failure
* Add new filters instead of using undocumented query params
* Cleanup filterset, add test
* Rename filter and re-introduce virtual_chassis filtering method (required)
* Fix test
* Adjust tests to more accurately provide coverage
* Add breaking change note
* Misc cleanup
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* 12489 use htmx for site view locations and non-racked-devices
* 12489 remove now unused queries in context
* adds device type and role to device component filter #12015
* Revert "Fixes #12463: Fix the association of completed jobs with reports & scripts in the REST API"
This reverts commit a29a07ed26.
* 12489 update nonracked_devices on rack and location templates
* 12489 fix whitespace issue
* Undo errant commits
* 12489 update site id in templates
* 12489 remove nonracked_devices include
* 12489 add has_position filter
* Use empty lookup for position field
* Remove non-racked devices list from rack view (was moved to a tab)
* Clean up location and device tables
* Restore plugins block on rack template
---------
Co-authored-by: Abhimanyu Saharan <desk.abhimanyu@gmail.com>
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
* adds parent filter on iprange #13313
* lint fix
* adds filterset test
* Filter should match both start & end of IP range
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
Anonymous git clones (in GitLab) require the username and password not
to be set in order to successfully clone. This patch will define clone
args only, if the username passed is not empty.
* adds config template to vm model #12461
* Add translation tags; collapse config data
* i18n cleanup
* Establish parity with DeviceRenderConfigView
* Move config_template field to RenderConfigMixin
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Fixes#12639 - Make sure name expansions throws a validation error on decrementing ranges
* Fix pep8
* Also fail on equal start & end values
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* 13319 add documentation for internationalization
* 13319 add verbose name to model
* 13319 fix typo
* Flesh out developer doc for i18n
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Schema generation is working
* Added option to either dump to a file or the console
* Moving schema file and utilizing settings definition for file paths
* Cleaning up the imports and fixing a few pythonic issues
* Tweak command flags
* Clean up choices mapping
* Misc cleanup
* Rename & move template file
* Move management command from extras to dcim
* Update release checklist
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* exposes all models in device context data #12814
* added app namespaces to the context data
* revert object to device in context data
* moved context to render method of ConfigTemplate
* removed print
* Include only registered models; permit passed context data to overwrite apps
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* adds standardized list API for scripts and reports #13037
* adds standardized list API for scripts and reports #13037
* adds standardized list API for scripts and reports #13037
* adds module name to the display #13037
* replaces device_role with role on device model #6391
* fixes lint issue #6391
* revert the database user
* revert test_runner comment
* changes as per review
* Update references to device_role column in UserConfigs
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* adds custom field on webhook model #11936
* adds tags on webhook model #11936
* Remove extraneous import; revert change to NetBoxModelForm (no longer needed)
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Initial work on custom field choice sets
* Rename choices to extra_choices (prep for #12194)
* Remove CustomField.choices
* Add & update tests
* Clean up table columns
* Add order_alphanetically boolean for choice sets
* Introduce ArrayColumn for choice lists
* Show dependent custom fields on choice set view
* Update custom fields documentation
* Introduce ArrayWidget for more convenient editing of choices
* Incorporate PR feedback
* Misc cleanup
* Initial work on predefined choices for custom fields
* Misc cleanup
* Add IATA airport codes
* #13241: Add support for custom field choice labels
* Restore ArrayColumn
* Misc cleanup
* Change extra_choices back to a nested ArrayField to preserve choice ordering
* Hack to bypass GraphQL API test utility absent support for nested ArrayFields
* Add Brazilian power outlet standard to choices.py
* Eliminate possible name conflict
* Rename group and add IEC 60906-1 plug type
* Update choices.py
Add Brazilian power port standard
* initial oob_ip support for devices
* add primary ip and oob ip checkmark to ip address view
* add oob ip to device view and device edit view
* pep8
* make is_oob_ip and is_primary_ip generic for other models
* refactor oob_ip
* fix oob ip signal
* string capitalisation
* Misc cleanup
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
Move admin views for users, groups, and object permissions from the admin site to the NetBox frontend
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* fixes form rendering when scheduling_enabled is disabled #13096
* Remove requires_input property from BaseScript; render form consistently
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* adds copy content button #12499
* adds newline
* Omit hash mark from target string
* Clean up HTML element IDs
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Fixes#11335: Default manager for ObjectChange should filter by installed apps
* Employ canonical model discovery mechanism
* Move filtering logic to valid_models() queryset method
* fixed import to avoid content type does not exist
* Cleanup
---------
Co-authored-by: Abhimanyu Saharan <desk.abhimanyu@gmail.com>
Partially revert 41c92483a0 to restore
bulk edit with m2m fields. The m2m cleaned_data yields a empty queryset
when nothing is selected. By setting the m2m relation unless set null is
checked even when nothing is selected the m2m relation is always
cleared.
This commit only sets the m2m relation when a selection is made.
* Initial work on #11541
* Merge migrations
* Limit tags by object type during assignment
* Add tests for object type validation
* Fix form field parameters
* 12175 add rack starting unit
* 12175 rack starting unit to svg
* verify devices can still fit if change rack starting_unit
* 12175 fix migration
* 12175 fix typo and test
* 12175 fix test
* 12175 fix max height calc display
* Misc cleanup & fixes
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* 12794 change User ref to get_user_model
* 12794 call get_user_model once in tests
* 12794 call get_user_model once in tests
* 12794 use settings.AUTH_USER_MODEL for FK reference
* Issue #12622: Fix creating Prefix using VLAN without site
* Issue #12622: Fix importing Prefix using VLAN without site
This commit also adds tests to verify the import changes implemented
in this commit.
* Issue #12622: Cleanup code to filter allowed VLANs on a prefix import
* Closes#12622: Switch to VLAN selector dialog when creating Prefix
* fixes incorrectly handled type error when list of objects is found in data #9876
* fixes incorrectly handled type error when list of objects is found in data #9876
* fixes incorrectly handled type error when list of objects is found in data #9876
* adds device type and role to device component filter #12015
* changes as per review
* Add filterset tests for device type & role filters
---------
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
* 7503 do device validate-create in serial
* 7503 fix single instance
* 7503 atomic transaction
* 7503 fix return data for bulk operations
* 7503 add test
* Move sequential creation logic to a mixin
---------
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
* adds hide-if-unset to custom field #12597
* moved hide logic from template to python
* fix indentation
* Update logic for omit_hidden under get_custom_fields()
* Update docs
* Account for False values
---------
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
* Closes#11619: Allow VLANs without a site during multi-port edits
This commit allows users to be able to select VLANs without a site assignment
during bulk interfaces edits under Devices > DEVICE COMPONENTS > Interfaces.
Prior to this commit, only VLANs that were assigned the same site as the device
were available for selection.
* Replace 'null' with FILTERS_NULL_CHOICE_VALUE constant
---------
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
* adds rq retry options #12327
* Clean up docs; disable retries of failed jobs by default
* Pass a Retry object only if RQ_RETRY_MAX is non-zero
---------
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
* Convert power draw/max draw to PositiveIntegerField
* Closes#11017: Increase maximum power draw
* Rename migration file for clarity
---------
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
* 12468 disallow double underscores in custom field names
* 12468 disallow double underscores in custom field names
* 12468 review changes
* 12468 correct migration
* 12468 use inverse match
* 12468 use inverse match
* Add test for invalid custom field names
---------
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
* Add REMOTE_AUTH_AUTOCREATE_GROUPS
When REMOTE_AUTH_AUTOCREATE_GROUPS is True, Netbox will create groups
referenced in the REMOTE_AUTH_GROUP_HEADER that don't exist in the
database.
Closes#7671
* Fix naming of parameter
Apply the fix requested by kkthxbye-code in https://github.com/netbox-community/netbox/pull/8603
---------
Co-authored-by: Lars Kellogg-Stedman <lars@oddbit.com>
* moves related ips to a tab #12233
* Refactor IP address templates to use a base template
---------
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
* adds tooltip on custom field #12131
* adds description field check
* fixed field name
* updated code to match the panel
* added escape filter on description
* 11670: Add optional weight to DeviceType import
This is 1 of 2 commits to address issue #11670
To maintain consistency, the import design of the DeviceType weight follows the
same pattern used for importing weight and weight units in DCIM Racks.
* Closes#11670: Add weight to ModuleType import
This is commit 2 of 2 to address and close#11670.
To maintain consistency, the import design of the ModuleType weight follows the
same pattern used for importing weight and weight units in DCIM Racks.
* Merge tests; misc cleanup
---------
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
* replaced device type weight with device total weight #12286
* replaced device type weight with device total weight #12286
* Update netbox/templates/dcim/device.html
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Fixes: #11715 - Fix Parent Prefix table display of global vrf prefixes that are **not** containers.
* Combine AND into a single Q object
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* adds description to elevation device tooltip #11801
* changes as per review
* changes as per review
* Rearrange attrs, add headings, and update docstring
---------
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
* 12363 update paragraph spacing on journal table
* 12363 make css rule generic
* 12363 change p tag to only effect last-child
* 12363 change p table spacing to .5em
* 12363 move comment
* Fixes: #10757 - Change interface assignment to use new selector. Perform the same change to the NAT assignment as well.
* Remove nat_vrf from form and remove query_params that are not required anymore
* enable markdown in custom field descriptions
* Closes#10759: Enable markdown support for custom field descriptions
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* Intial. 2 ways the racknavigation displayed
* show active rack in dropdown
* auto hide/show when viewport reduces
* Dropdown only
* Update links to use get_absolute_url()
---------
Co-authored-by: Pieter Lambrecht <pieter.lambrecht@sentia.com>
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
* #12278 add serializer for ipaddressfield to remove spectacular warnings
* #12278 add ipaddressfieldserializer to nested serializers
* #12278 fix to_internal_value to_representation in serializer
* #12278 to_internal_value is called before validation! need to raise validation error if incorrect format
* #12278 to_internal_value needs to return value doh
* #12278 move IPAddressField to field_serializers
* #12278 remove old import
* 12278 remove validator
* Clean up base modules
* Clean up forms modules
* Clean up templatetags modules
* Replace custom simplify_decimal filter with floatformat
* Misc cleanup
* Merge ReturnURLForm into ConfirmationForm
* Clean up import statements for utilities.forms
* Fix field class references in docs
* 11432 make device field on interface read-only on api edit call
* 11432 make device field on interface read-only on api edit call
* 11432 extend serializer change to mixin
* 11432 add readonlydevicemixin to template serializers
* 11432 change subclass ordering
* 11432 fix device_type for template serializers
* 11432 DRY
* 11432 DRY
* 11432 make internal var
* 11432 change to model-level validation
* 11432 fix fk accessor
* Clean up validation error messages
---------
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
* 11091 add permission to allow user to create api tokens for other users
* 11091 update docs
* 11091 fix for test
* 11091 fix for test
* 11091 test case for invalid token creation
* 11091 add test for permission grant
* Cleanup & fix serializer validation
---------
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
* added group and user model to object_type
* Update netbox/utilities/utils.py
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* 12074 fix full clean
* 12074 move device location setting to save from clean
* 12074 fix set location only if present in rack
* Update base.py
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
* start() and terminate() methods on Job should call save()
* Fix display of associated jobs
* Introduce get_latest_jobs() method on JobsMixin
* Update messaging when no reports/scripts exist
* Catch ImportErrors when rendering report/script lists
* Fix loading of nested modules
* Fix URLs for nested scripts/reports
* Reference database object by GFK when running scripts & reports via UI
* Reference database object by GFK when running scripts & reports via API
* Remove old enqueue_job() method
* Enable filtering jobs by object
* Introduce ObjectJobsView
* Add tabbed views for report & script jobs
* Add object_id to JobSerializer
* Move generic relation to JobsMixin
* Clean up old naming
* Add suppport for REMOTE_AUTH_BACKEND as iterable
* Closes#11977: Support for multiple auth backends
* Tweak list casting
---------
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
* Add suppport for REMOTE_AUTH_BACKEND as iterable
* Closes#11977: Support for multiple auth backends
* Tweak list casting
---------
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
* WIP
* WIP
* WIP
* Make object selector functional
* Replace extraneous form fields with selector widgets
* Avoid overlap with filterset field names
* Show checkmarks next to visibile filters
* Update results automatically when searching
* Include selector for device/VM component parent fields
* Use selector for filtering VLAN group/site
* Limit selector to 100 results
* MarkdownWidget
* Change border and color of active markdown tab
* Fix template name typo
* Add render markdown endpoint
* Static assets for markdown widget
* widget style fix and unique ids based on name
* Replace SmallTextArea with SmallMarkdownWidget
* Clear innerHTML before swapping
* render markdown directly in template
* change render markdown view path
* remove small markdown widget
* Simplify rendering logic
* Use a form to clean input Markdown data
---------
Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
* Fixes#11470: Validation and user friendly message on invalid address query param
* Update invalid input handling to return empty set instead of raising exception
* Move ASN to a separate module
* Move ASNField from dcim to ipam
* Introduce ASNRange model
* Add relationship from ASN to ASNRange
* Add an available-asns API endpoint
* Add RIR assignment for ASNRange
* Add standard tests
* Move child ASNs to a tabbed view
* Remove FK on ASN to ASNRange
* Add tests for provisioning available ASNs
* Add docs for ASNRange
* Replace masonry with gridstack
* Initial work on dashboard widgets
* Implement function to save dashboard layout
* Define a default dashboard
* Clean up widgets
* Implement widget configuration views & forms
* Permit merging dict value with existing dict in user config
* Add widget deletion view
* Enable HTMX for widget configuration
* Implement view to add dashboard widgets
* ObjectCountsWidget: Identify models by app_label & name
* Add color customization to dashboard widgets
* Introduce Dashboard model to store user dashboard layout & config
* Clean up utility functions
* Remove hard-coded API URL
* Use fixed grid cell height
* Add modal close button
* Clean up dashboard views
* Rebuild JS
* WIP
* Add config_template field to Device
* Pre-fetch referenced templates
* Correct up_to_date callable
* Add config_template FK to Device
* Update & merge migrations
* Add config_template FK to Platform
* Add tagging support for ConfigTemplate
* Catch exceptions when rendering device templates in UI
* Refactor ConfigTemplate.render()
* Add support for returning plain text content
* Add ConfigTemplate model documentation
* Add feature documentation for config rendering
* WIP
* WIP
* Add git sync
* Fix file hashing
* Add last_synced to DataSource
* Build out UI & API resources
* Add status field to DataSource
* Add UI control to sync data source
* Add API endpoint to sync data sources
* Fix display of DataSource job results
* DataSource password should be write-only
* General cleanup
* Add data file UI view
* Punt on HTTP, FTP support for now
* Add DataSource URL validation
* Add HTTP proxy support to git fetcher
* Add management command to sync data sources
* DataFile REST API endpoints should be read-only
* Refactor fetch methods into backend classes
* Replace auth & git branch fields with general-purpose parameters
* Fix last_synced time
* Render discrete form fields for backend parameters
* Enable dynamic edit form for DataSource
* Register DataBackend classes in application registry
* Add search indexers for DataSource, DataFile
* Add single & bulk delete views for DataFile
* Add model documentation
* Convert DataSource to a primary model
* Introduce pre_sync & post_sync signals
* Clean up migrations
* Rename url to source_url
* Clean up filtersets
* Add API & filterset tests
* Add view tests
* Add initSelect() to HTMX refresh handler
* Render DataSourceForm fieldsets dynamically
* Update compiled static resources
* Closes#11592: Expose FILE_UPLOAD_MAX_MEMOMORY_SIZE as a setting
* change configuration settings to alphabetic order
* Small example and documentation
---------
Co-authored-by: aron bergur jóhannsson <aronnemi@gmail.com>
* Fixes#11459 - Allow using null in conditions
- Update docs to reflect this
- Change docs example from primary_ip to primary_ip4 as computed properties are not serialized when queuing webhooks
* Update netbox/extras/conditions.py
---------
Co-authored-by: Simon Toft <SITO@telenor.dk>
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
### Fixes: #11582
Not sure if this is the correct fix or not. The reason that the custom field errors were not shown is that messages.html only shows non_field_errors if the form passed to the context is named form. This is probably an issue in more places, but not sure how to make it generic. A change to messages.html would also need to support formsets.
Any input appreciated @jeremystretch or @arthanson
* Fixes#11032 - Replication fields broken in custom validation
* Use getattr instead of hasattr to make sure custom validation is triggered as normal
---------
Co-authored-by: kkthxbye-code <>
* Added buttons to edit cables
* Revert change that did not address this branch
* Consolidated buttons
* moved back trace button / added permission checks
* reverted disabled trace button
* Added 100base-fx (aka fast ethernet over fiber optic)
* Added 100BASE-T1 (single pair fast ethernet) as well as 100BASE‑LFX (fast ethernet over fiber, non standard)
* Update choices.py
Updated the placing of the 100base-fx and lfx choices
* Update netbox/dcim/choices.py
Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
* Closes#11150: Add a filter for device.primary_ip4 and primary_ip6
* Tweaked tests to query for multiple IDs
Co-authored-by: jeremystretch <jstretch@ns1.com>
* Allow re-assigning InventoryItem components
* Refactor logic for finding initial component assignment on InventoryItems
* PEP8 fix
* Fix wrong HTML causing tab list to extend past the end of the parent row
* Tweak form field labels
Co-authored-by: jeremystretch <jstretch@ns1.com>
* Make sure we bail out if field validation failed when importing modules
* Tweak form validation logic
Co-authored-by: jeremystretch <jstretch@ns1.com>
* Adds replication and adoption for module import
* Moves common Module form clean logic to new class
* Adds tests for replication and adoption for module import
* Fix test
Co-authored-by: jeremystretch <jstretch@ns1.com>
* Add interval to JobResult
* Accept a recurrence interval when executing scripts & reports
* Cleaned up jobs list display
* Schedule next job only if a reference start time can be determined
* Improve validation for scheduled jobs
* Show the Provider of the NetworkProvider
* Clean up form fields
Co-authored-by: Pieter Lambrecht <pieter.lambrecht@sentia.com>
Co-authored-by: jeremystretch <jstretch@ns1.com>
* 10653 log failed login attempts on INFO
* 10653 use signal to log failed login attempts
* 10653 use signal to log failed login attempts
* Update netbox/users/signals.py
Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
* Update netbox/users/apps.py
Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
* Fixes: #10356 Add interface type and cable for backplane connections
* Allow Backplone for front and readports , too.
* Correct tyo in port definition
* pep8 fix (blank lines)
* Remove port type and changed name/description of backplane cable
* Omit backplane cable type
Co-authored-by: Patrick Hurrelmann <patrick.hurrelmann@nfon.com>
Co-authored-by: jeremystretch <jstretch@ns1.com>
* Added Colors to SVG for Front and Reaer Ports
Fix for feature request 10904 thanks to @TheZackCodec
* Simplify termination color resolution
Co-authored-by: jeremystretch <jstretch@ns1.com>
* WIP
* Convert checkout() context manager to a class
* Misc cleanup
* Drop unique constraint from Change model
* Extend staging tests
* Misc cleanup
* Incorporate M2M changes
* Don't cancel wipe out creation records when an object is deleted
* Rename Change to StagedChange
* Add documentation for change staging
* Work on #7854
* Move to new URL scheme.
* Fix PEP8 errors
* Fix PEP8 errors
* Add GraphQL and fix primary_ip missing
* Fix PEP8 on GQL Type
* Fix missing NestedSerializer.
* Fix missing NestedSerializer & rename VDC to VDCs
* Fix migration
* Change Validation for identifier
* Fix missing migration
* Rebase to feature
* Post-review changes
* Remove VDC Type
* Remove M2M Enforcement logic
* Interface related changes
* Add filter fields to filterset for Interface filter
* Add form field to filterset form for Interface filter
* Add VDC display to interface detail template
* Remove VirtualDeviceContextTypeChoices
* Accommodate recent changes in feature branch
* Add tests
Add missing search()
* Update tests, and fix model form
* Update test_api
* Update test_api.InterfaceTest create_data
* Fix issue with tests
* Update interface serializer
* Update serializer and tests
* Update status to be required
* Remove error message for constraint
* Remove extraneous import
* Re-ordered devices menu to place VDC below virtual chassis
* Add helptext for `identifier` field
* Fix breadcrumb link
* Remove add interface link
* Add missing tenant and status fields
* Changes to tests as per Jeremy
* Change for #9623
Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
* Update filterset form for status field
* Remove Rename View
* Change tabs to spaces
* Update netbox/dcim/tables/devices.py
Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
* Update netbox/dcim/tables/devices.py
Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
* Fix tenant in bulk_edit
* Apply suggestions from code review
Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
* Add status field to table.
* Re-order table fields.
Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
* 8853 hide api token
* 8853 hide key on edit
* 8853 add key display
* 8853 cleanup html
* 8853 make token view accessible only once on POST
* Clean up display of tokens in views
* Honor ALLOW_TOKEN_RETRIEVAL in API serializer
* Add docs & tweak default setting
* Include token key when provisioning with user credentials
Co-authored-by: jeremystretch <jstretch@ns1.com>
* 7961 add csv bulk update
* temp checkin - blocked
* 7961 bugfix and cleanup
* 7961 change to id, add docs
* 7961 add tests cases
* 7961 fix does not exist validation error
* 7961 fix does not exist validation error
* 7961 update tests
* 7961 update tests
* 7961 update tests
* 7961 update tests
* 7961 update tests
* 7961 update tests
* 7961 update tests
* 7961 update tests
* 7961 update tests
* 7961 make test cases more explicit
* 7961 make test cases more explicit
* 7961 make test cases more explicit
* 7961 make test cases more explicit
* 7961 make test cases more explicit
* 7961 make test cases more explicit
* 7961 make test cases more explicit
* 7961 optimize loading csv test data
* 7961 update tests remove redundant code
* 7961 avoid MPTT issue in test cases
* Initial work on new search backend
* Clean up search backends
* Return only the most relevant result per object
* Clear any pre-existing cached entries on cache()
* #6003: Implement global search functionality for custom field values
* Tweak field weights & document guidance
* Extend search() to accept a lookup type
* Move get_registry() out of SearchBackend
* Enforce object permissions when returning search results
* Add indexers for remaining models
* Avoid calling remove() on non-cacheable objects
* Use new search backend by default
* Extend search backend to filter by object type
* Clean up search view form
* Enable specifying lookup logic
* Add indexes for value field
* Remove object type selector from search bar
* Introduce SearchTable and enable HTMX for results
* Enable pagination
* Remove legacy search backend
* Cleanup
* Use a UUID for CachedValue primary key
* Refactoring search methods
* Define max search results limit
* Extend reindex command to support specifying particular models
* Add clear() and size to SearchBackend
* Optimize bulk caching performance
* Highlight matched portion of field value
* Performance improvements for reindexing
* Started on search tests
* Cleanup & docs
* Documentation updates
* Clean up SearchIndex
* Flatten search registry to register by app_label.model_name
* Clean up search backend classes
* Clean up RestrictedGenericForeignKey and RestrictedPrefetch
* Resolve migrations conflict
* change IP address accessor to parent object
* set IP assigned check to link to interface
* Fix Assigned not being orderable
Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
Co-authored-by: Craig Pund <cpund@iuhealth.org>
Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
As discussed in #10639, all three `COOKIE_PATH`s should be set accordingly with the netbox-`BASE_PATH` to improve coexistance with other Django-projects probably hosted on the same Host
* 10643 add fieldset to device role for improved add/edit form display
* 10643 update other forms
* 10643 update other forms
* Specify fieldsets for additional models
Co-authored-by: jeremystretch <jstretch@ns1.com>
* Added JobResult form filtersets
* Change housekeeping cleanup delete from `_raw_delete` to `delete` to make sure scheduled tasks are cancelled
* Change default sort of JobResult table to -created
* Added `delete` override to `JobResult` to remove scheduled tasks from RQ when a JobResult is deleted
* Updated js/css dist files. Will need to be redone when develop is merged to feature.
* Add javascript to disable empty form fields
* add js cleanGetUrl
* use addEventListener submit
* use addEventListener
* update collectstatics
* Use FormData to remove empty fields
* optimeze ts-ignore
* update ts-ignore comment
* oneline of ts-ignore
* one line of ts-ingnore
* fix tsc errors by adding types (as per kkthxbye)
Co-authored-by: Pieter Lambrecht <pieter.lambrecht@sentia.com>
* 10348 add decimal custom field
* 10348 fix tests
* 10348 add documentation
* Rearrange custom fields to be ordered consistently
* Rename number_field to integer_field for clarity
* Clean up validation logic
* Apply suggested changes from PR
* Store decimal custom field values natively
* Fix filter test
* Update custom field model migrations to use new encoder
Co-authored-by: jeremystretch <jstretch@ns1.com>
* #9045 - remove legacy fields from Provider
* Add safegaurd for legacy data to migration
* 9045 remove fields from forms and tables
* Update unrelated tests to use ASN model instead of Provider
* Fix migrations collision
Co-authored-by: jeremystretch <jstretch@ns1.com>
* Initial work on #10247
* Continued work on #10247
* Clean up component creation tests
* Move valdiation of replicated field to form
* Clean up ordering of fields in component creation forms
* Omit fieldset header if none
* Clean up ordering of fields in component template creation forms
* View tests should not move component templates to new device type
* Define replication_fields on VMInterfaceCreateForm
* Clean up expandable field help texts
* Update comments
* Update component bulk update forms & views to support new replication fields
* Fix ModularDeviceComponentForm parent class
* Fix bulk creation of VM interfaces (thanks @kkthxbye-code!)
Closes: #9906
- Adds `color` field to front and rearport template import forms
- Adds `color` field to `to_yaml` export for front and rearport
templates
Prefetch the Tenant Group in views which allows its table to be configured
by the user. This decreases the amount of database queries that are required
to fetch the data.
Configure the prefetch to also include the Tenant Group, avoids additional
database queries when the Tenant Group column is to be rendered.
NOTE: If no personalisation of the global search tables should be done,
this commit can be reverted.
Replaces all usages of the TenantColumn with the new TenancyColumnsMixin.
This enables the user to add a column for Tenant Group on all tables which
also has a column for Tenant.
Works the same as the existing TenantColumn, but displats the Tenant Group of
the Tenant.
Views should prefetch the Tenants Group for this to be efficient in large
tables.
* Closes#9396 - Added ability to query modules by module bay & installed_modules for module bay REST API endpoint
* Closes#9396 - Added ability to query modules by module bay & installed_modules for module bay REST API endpoint
* Closes#9396 - Added ability to query modules by module bay & installed_modules for module bay REST API endpoint
**Looking for help?** NetBox has a vast, active community of fellow users that may be able to provide assistance. Just [start a discussion](https://github.com/netbox-community/netbox/discussions/new) right here on GitHub! Or if you'd prefer to chat, join us live in the `#netbox` channel on the [NetDev Community Slack](https://netdev.chat/)!
If you encounter any issues installing or using NetBox, try one of the
following resources to get assistance. Please **do not** open a GitHub issue
except to report bugs or request features.
<div align="center">
<h3>
:bug: <a href="#bug-reporting-bugs">Report a bug</a> ·
:bulb: <a href="#bulb-feature-requests">Suggest a feature</a> ·
:arrow_heading_up: <a href="#arrow_heading_up-submitting-pull-requests">Submit a pull request</a>
</h3>
<h3>
:jigsaw: <a href="#jigsaw-creating-plugins">Create a plugin</a> ·
:rescue_worker_helmet: <a href="#rescue_worker_helmet-become-a-maintainer">Become a maintainer</a> ·
GitHub's discussions are the best place to get help or propose rough ideas for
new functionality. Their integration with GitHub allows for easily cross-
referencing and converting posts to issues as needed. There are several
categories for discussions:
In her book [Working in Public](https://www.amazon.com/Working-Public-Making-Maintenance-Software/dp/0578675862), Nadia Eghbal defines four production models for open source projects, categorized by contributor and user growth: federations, clubs, toys, and stadiums. The NetBox project fits her definition of a stadium very well:
* **General** - General community discussion
* **Ideas** - Ideas for new functionality that isn't yet ready for a formal
feature request
***Q&A** - Request help with installing or using NetBox
> Stadiums are projects with low contributor growth and high user growth. While they may receive casual contributions, their regular contributor base does not grow proportionately to their users. As a result, they tend to be powered by one or a few developers.
### Slack
The bulk of NetBox's development is carried out by a handful of core maintainers, with occasional contributions from collaborators in the community. We find the stadium analogy very useful in conveying the roles and obligations of both contributors and users.
For real-time chat, you can join the **#netbox** Slack channel on [NetDev Community](https://netdev.chat/).
Unfortunately, the Slack channel does not provide long-term retention of chat
history, so try to avoid it for any discussions would benefit from being
preserved for future reference.
If you're a contributor, actively working on the center stage, you have an obligation to produce quality content that will benefit the project as a whole. Conversely, if you're in the audience consuming the work being produced, you have the option of making requests and suggestions, but must also recognize that contributors are under no obligation to act on them.
## Reporting Bugs
NetBox users are welcome to participate in either role, on stage or in the crowd. We ask only that you acknowledge the role you've chosen and respect the roles of others.
* First, ensure that you're running the [latest stable version](https://github.com/netbox-community/netbox/releases)
of NetBox. If you're running an older version, it's possible that the bug has
already been fixed.
### General Tips for Working on GitHub
*Next, check the GitHub [issues list](https://github.com/netbox-community/netbox/issues)
to see if the bug you've found has already been reported. If you think you may
be experiencing a reported issue that hasn't already been resolved, please
click "add a reaction" in the top right corner of the issue and add a thumbs
up (+1). You might also want to add a comment describing how it's affecting your
installation. This will allow us to prioritize bugs based on how many users are
affected.
*Register for a free [GitHub account](https://github.com/signup) if you haven't already.
* You can use [GitHub Markdown](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax) for formatting text and adding images.
* To help mitigate notification spam, please avoid "bumping" issues with no activity. (To vote an issue up or down, use a :thumbsup: or :thumbsdown: reaction.)
* Please avoid pinging members with `@` unless they've previously expressed interest or involvement with that particular issue.
* Familiarize yourself with [this list of discussion anti-patterns](https://github.com/bradfitz/issue-tracker-behaviors) and make every effort to avoid them.
* When submitting an issue, please be as descriptive as possible. Be sure to
provide all information request in the issue template, including:
## :bug: Reporting Bugs
* The environment in which NetBox is running
* The exact steps that can be taken to reproduce the issue
* Expected and observed behavior
* Any error messages generated
* Screenshots (if applicable)
:warning: Bug reports are used to call attention to some unintended or unexpected behavior in NetBox, such as when an error occurs or when the result of taking some action is inconsistent with the documentation. **Bug reports may not be used to suggest new functionality**; please see "feature requests" below if that is your goal.
*Please avoid prepending any sort of tag (e.g. "[Bug]") to the issue title.
The issue will be reviewed by a maintainer after submission and the appropriate
labels will be applied for categorization.
*First, ensure that you're running the [latest stable version](https://github.com/netbox-community/netbox/releases) of NetBox. If you're running an older version, it's likely that the bug has already been fixed.
*Keep in mind that we prioritize bugs based on their severity and how much
work is required to resolve them. It may take some time for someone to address
your issue.
*Next, search our [issues list](https://github.com/netbox-community/netbox/issues?q=is%3Aissue) to see if the bug you've found has already been reported. If you come across a bug report that seems to match, please click "add a reaction" in the top right corner of the issue and add a thumbs up (:thumbsup:). This will help draw more attention to it. Any comments you can add to provide additional information or context would also be much appreciated.
* If you can't find any existing issues (open or closed) that seem to match yours, you're welcome to [submit a new bug report](https://github.com/netbox-community/netbox/issues/new?label=type%3A+bug&template=bug_report.yaml). Be sure to complete the entire report template, including detailed steps that someone triaging your issue can follow to confirm the reported behavior. (If we're not able to replicate the bug based on the information provided, we'll ask for additional detail.)
* Some other tips to keep in mind:
* Error messages and screenshots are especially helpful.
* Don't prepend your issue title with a label like `[Bug]`; the proper label will be assigned automatically.
* Ensure that your reproduction instructions don't reference data in our [demo instance](https://demo.netbox.dev/), which gets rebuilt nightly.
* Verify that you have GitHub notifications enabled and are subscribed to your issue after submitting.
* We appreciate your patience as bugs are prioritized by their severity, impact, and difficulty to resolve.
* For more information on how bug reports are handled, please see our [issue
* First, check the GitHub [issues list](https://github.com/netbox-community/netbox/issues)
to see if the feature you're requesting is already listed. (Be sure to search
closed issues as well, since some feature requests have been rejected.) If the
feature you'd like to see has already been requested and is open, click "add a
reaction" in the top right corner of the issue and add a thumbs up (+1). This
ensures that the issue has a better chance of receiving attention. Also feel
free to add a comment with any additional justification for the feature.
(However, note that comments with no substance other than a "+1" will be
deleted. Please use GitHub's reactions feature to indicate your support.)
* First, check the GitHub [issues list](https://github.com/netbox-community/netbox/issues?q=is%3Aissue) to see if the feature you have in mind has already been proposed. If you happen to find an open feature request that matches your idea, click "add a reaction" in the top right corner of the issue and add a thumbs up (:thumbsup:). This ensures that the issue has a better chance of receiving attention. Also feel free to add a comment with any additional justification for the feature.
*Before filing a new feature request, consider raising your idea in a
first. Feedback you receive there will help validate and shape the proposed
feature before filing a formal issue.
*If you have a rough idea that's not quite ready for formal submission yet, start a [GitHub discussion](https://github.com/netbox-community/netbox/discussions) instead. This is a great way to test the viability and narrow down the scope of a new feature prior to submitting a formal proposal, and can serve to generate interest in your idea from other community members.
*Good feature requests are very narrowly defined. Be sure to thoroughly
describe the functionality and data model(s) being proposed. The more effort
you put into writing a feature request, the better its chance is of being
implemented. Overly broad feature requests will be closed.
*Once you're ready, submit a feature request [using this template](https://github.com/netbox-community/netbox/issues/new?label=type%3A+feature&template=feature_request.yaml). Be sure to provide sufficient context and detail to convey exactly what you're proposing and why. The stronger your use case, the better chance your proposal has of being accepted.
*When submitting a feature request on GitHub, be sure to include all
information requested by the issue template, including:
*Some other tips to keep in mind:
* Don't prepend your issue title with a label like `[Feature]`; the proper label will be assigned automatically.
* Try to anticipate any likely questions about your proposal and provide that information proactively.
* Verify that you have GitHub notifications enabled and are subscribed to your issue after submitting.
* You're welcome to volunteer to implement your FR, but don't submit a pull request until it has been approved.
* A detailed description of the proposed functionality
* A use case for the feature; who would use it and what value it would add
to NetBox
* A rough description of changes necessary to the database schema (if
applicable)
* Any third-party libraries or other resources which would be involved
* For more information on how feature requests are handled, please see our [issue intake policy](https://github.com/netbox-community/netbox/wiki/Issue-Intake-Policy).
* Please avoid prepending any sort of tag (e.g. "[Feature]") to the issue
title. The issue will be reviewed by a moderator after submission and the
appropriate labels will be applied for categorization.
## :arrow_heading_up: Submitting Pull Requests
*For more information on how feature requests are handled, please see our
*[Pull requests](https://docs.github.com/en/pull-requests) (a feature of GitHub) are used to propose changes to NetBox's code base. Our process generally goes like this:
* A user opens a new issue (bug report or feature request)
* A maintainer triages the issue and may mark it as needing an owner
* The issue's author can volunteer to own it, or someone else can
* A maintainer assigns the issue to whomever volunteers
* The issue owner submits a pull request that will resolve the issue
* A maintainer reviews and merges the pull request, closing the issue
## Submitting Pull Requests
* It's very important that you not submit a pull request until a relevant issue has been opened **and** assigned to you. Otherwise, you risk wasting time on work that may ultimately not be needed.
*If you're interested in contributing to NetBox, be sure to check out our
documentation for tips on setting up your development environment.
*New pull requests should generally be based off of the `develop` branch, rather than `master`. The `develop` branch is used for ongoing development, while `master` is used for tracking stable releases. (If you're developing for an upcoming minor release, use `feature` instead.)
*Be sure to open an issue **before** starting work on a pull request, and
discuss your idea with the NetBox maintainers before beginning work. This will
help prevent wasting time on something that might we might not be able to
implement. When suggesting a new feature, also make sure it won't conflict with
any work that's already in progress.
*In most cases, it is not necessary to add a changelog entry: A maintainer will take care of this when the PR is merged. (This helps avoid merge conflicts resulting from multiple PRs being submitted simultaneously.)
*Once you've opened or identified an issue you'd like to work on, ask that it
be assigned to you so that others are aware it's being worked on. A maintainer
will then mark the issue as "accepted."
*Any pull request which does _not_ relate to an **accepted** issue will be closed.
* All new functionality must include relevant tests where applicable.
* When submitting a pull request, please be sure to work off of the `develop`
branch, rather than `master`. The `develop` branch is used for ongoing
development, while `master` is used for tagging stable releases.
* In most cases, it is not necessary to add a changelog entry: A maintainer will
take care of this when the PR is merged. (This helps avoid merge conflicts
resulting from multiple PRs being submitted simultaneously.)
* All code submissions should meet the following criteria (CI will enforce
these checks):
* Python syntax is valid
* All tests pass when run with `./manage.py test`
* PEP 8 compliance is enforced, with the exception that lines may be
*All code submissions must meet the following criteria (CI will enforce these checks where feasible):
* Consist entirely of original work
* Python syntax is valid
* All tests pass when run with `./manage.py test`
*PEP 8 compliance is enforced, with the exception that lines may be
greater than 80 characters in length
## Commenting
> [!CAUTION]
> Any contributions which include AI-generated or reproduced content will be rejected.
Only comment on an issue if you are sharing a relevant idea or constructive
feedback. **Do not** comment on an issue just to show your support (give the
top post a :+1: instead) or ask for an ETA. These comments will be deleted to
reduce noise in the discussion.
* Some other tips to keep in mind:
* If you'd like to volunteer for someone else's issue, please post a comment on that issue letting us know. (This will allow the maintainers to assign it to you.)
* Check out our [developer docs](https://docs.netbox.dev/en/stable/development/getting-started/) for tips on setting up your development environment.
* All new functionality must include relevant tests where applicable.
## Issue Lifecycle
## :jigsaw: Creating Plugins
New issues are handled according to our [issue intake policy](https://github.com/netbox-community/netbox/wiki/Issue-Intake-Policy).
Maintainers will assign label(s) and/or close new issues as the policy
dictates. This helps ensure a productive development environment and avoid
accumulating a large backlog of work.
Do you have an idea for something you'd like to build in NetBox, but might not be right for the core project? NetBox includes a powerful and extensive [plugins framework](https://docs.netbox.dev/en/stable/plugins/) that enables users to develop their own custom data models and integrations.
The core maintainers group has chosen to make use of GitHub's [Stale bot](https://github.com/apps/stale)
to aid in issue management.
Check out our [plugin development tutorial](https://github.com/netbox-community/netbox-plugin-tutorial) to get started!
* Issues will be marked as stale after 60 days of no activity.
* If the stable label is not removed in the following 30 days, the issue will
be closed automatically.
* Any issue bearing one of the following labels will be exempt from all Stale
bot actions:
*`status: accepted`
*`status: blocked`
*`status: needs milestone`
## :rescue_worker_helmet: Become a Maintainer
It is natural that some new issues get more attention than others. The stale
bot helps bring renewed attention to potentially valuable issues that may have
been overlooked. **Do not** comment on an issue that has been marked stale in
an effort to circumvent the bot: Doing so will not remove the stale label.
(Stale labels can be removed only by maintainers.)
We're always looking for motivated individuals to join the maintainers team and help drive NetBox's long-term development. Some of our most sought-after skills include:
## Maintainer Guidance
* Python development with a strong focus on the [Django](https://www.djangoproject.com/) framework
* Expertise working with PostgreSQL databases
* Javascript & TypeScript proficiency
* A knack for web application design (HTML & CSS)
* Familiarity with git and software development best practices
* Excellent attention to detail
* Working experience in the field of network operations & engineering
* Maintainers are expected to contribute at least four hours per week to the
project on average. This can be employer-sponsored or individual time, with
the understanding that all contributions are submitted under the Apache 2.0
license and that your employer may not make claim to any contributions.
Contributions include code work, issue management, and community support. All
development must be in accordance with our [development guidance](https://docs.netbox.dev/en/stable/development/).
We generally ask that maintainers dedicate around four hours of work to the project each week on average, which includes both hands-on development and project management tasks such as issue triage. Maintainers are also encouraged (but not required) to attend our bi-weekly Zoom call to catch up on recent items.
* Maintainers are expected to attend (where feasible) our biweekly ~30-minute
sync to review agenda items. This meeting provides opportunity to present and
discuss pressing topics. Meetings are held as virtual audio/video conferences.
Interested? You can contact our lead maintainer, Jeremy Stretch, at jeremy@netbox.dev or on the [NetDev Community Slack](https://netdev.chat/). We'd love to have you on the team!
* Maintainers with no substantial recorded activity in a 60-day period will be
removed from the project.
## :heart: Other Ways to Contribute
You don't have to be a developer to contribute to NetBox: There are plenty of other ways you can add value to the community! Below are just a few examples:
* Help answer questions and provide feedback in our [GitHub discussions](https://github.com/netbox-community/netbox/discussions) and on [Slack](https://netdev.chat/).
* Write a blog article or record a YouTube video demonstrating how NetBox is used at your organization.
* Help grow our [library of device & module type definitions](https://github.com/netbox-community/devicetype-library).
NetBox exists to empower network engineers. Since its release in 2016, it has become the go-to solution for modeling and documenting network infrastructure for thousands of organizations worldwide. As a successor to legacy IPAM and DCIM applications, NetBox provides a cohesive, extensive, and accessible data model for all things networked. By providing a single robust user interface and programmable APIs for everything from cable maps to device configurations, NetBox serves as the central source of truth for the modern network.
NetBox is an infrastructure resource modeling (IRM) tool designed to empower
network automation, used by thousands of organizations around the world.
Initially conceived by the network engineering team at
[DigitalOcean](https://www.digitalocean.com/), NetBox was developed specifically
to address the needs of network and infrastructure engineers. It is intended to
function as a domain-specific source of truth for network operations.
<p align="center">
<a href="#netboxs-role">NetBox's Role</a> |
<a href="#why-netbox">Why NetBox?</a> |
<a href="#getting-started">Getting Started</a> |
<a href="#get-involved">Get Involved</a> |
<a href="#screenshots">Screenshots</a>
</p>
Myriad infrastructure components can be modeled in NetBox, including:
<p align="center">
<img src="docs/media/screenshots/home-light.png" width="600" alt="NetBox user interface screenshot" />
</p>
* Hierarchical regions, site groups, sites, and locations
* Racks, devices, and device components
* Cables and wireless connections
* Power distribution
* Data circuits and providers
* Virtual machines and clusters
* IP prefixes, ranges, and addresses
* VRFs and route targets
* FHRP groups (VRRP, HSRP, etc.)
* AS numbers
* VLANs and scoped VLAN groups
* Organizational tenants and contacts
## NetBox's Role
In addition to its extensive built-in models and functionality, NetBox can be
customized and extended through the use of:
NetBox functions as the **source of truth** for your network infrastructure. Its job is to define and validate the _intended state_ of all network components and resources. NetBox does not interact with network nodes directly; rather, it makes this data available programmatically to purpose-built automation, monitoring, and assurance tools. This separation of duties enables the construction of a robust yet flexible automation system.
NetBox also features a complete REST API as well as a GraphQL API for easily
integrating with other tools and systems.
The diagram above illustrates the recommended deployment architecture for an automated network, leveraging NetBox as the central authority for network state. This approach allows your team to swap out individual tools to meet changing needs while retaining a predictable, modular workflow.
NetBox runs as a web application atop the [Django](https://www.djangoproject.com/)
Python framework with a [PostgreSQL](https://www.postgresql.org/) database. For a
complete list of requirements, see `requirements.txt`. The code is available [on GitHub](https://github.com/netbox-community/netbox).
## Why NetBox?
The complete documentation for NetBox can be found at [docs.netbox.dev](https://docs.netbox.dev/). A public demo instance is available at https://demo.netbox.dev.
### Comprehensive Data Model
<div align="center">
<h4>Thank you to our sponsors!</h4>
Racks, devices, cables, IP addresses, VLANs, circuits, power, VPNs, and lots more: NetBox is built for networks. Its comprehensive and thoroughly inter-linked data model provides for natural and highly structured modeling of myriad network primitives that just isn't possible using general-purpose tools. And there's no need to waste time contemplating how to build out a database: Everything is ready to go upon installation.
NetBox strives to meet a singular goal: Provide the best available solution for making network infrastructure programmatically accessible. Unlike "all-in-one" tools which awkwardly bolt on half-baked features in an attempt to check every box, NetBox is committed to its core function. NetBox provides the best possible solution for modeling network infrastructure, and provides rich APIs for integrating with tools that excel in other areas of network automation.
### Discussion
### Extensible and Customizable
* [GitHub Discussions](https://github.com/netbox-community/netbox/discussions) - Discussion forum hosted by GitHub; ideal for Q&A and other structured discussions
* [Slack](https://netdev.chat/) - Real-time chat hosted by the NetDev Community; best for unstructured discussion or just hanging out
No two networks are exactly the same. Users are empowered to extend NetBox's native data model with custom fields and tags to best suit their unique needs. You can even write your own plugins to introduce entirely new objects and functionality!
### Installation
### Flexible Permissions
Please see [the documentation](https://docs.netbox.dev/) for
instructions on installing NetBox. To upgrade NetBox, please download the
[latest release](https://github.com/netbox-community/netbox/releases) and
run `upgrade.sh`.
NetBox includes a fully customizable permission system, which affords administrators incredible granularity when assigning roles to users and groups. Want to restrict certain users to working only with cabling and not be able to change IP addresses? Or maybe each team should have access only to a particular tenant? NetBox enables you to craft roles as you see fit.
### Providing Feedback
### Custom Validation & Protection Rules
The best platform for general feedback, assistance, and other discussion is our
To report a bug or request a specific feature, please open a GitHub issue using
the [appropriate template](https://github.com/netbox-community/netbox/issues/new/choose).
The data you put into NetBox is crucial to network operations. In addition to its robust native validation rules, NetBox provides mechanisms for administrators to define their own custom validation rules for objects. Custom validation can be used both to ensure new or modified objects adhere to a set of rules, and to prevent the deletion of objects which don't meet certain criteria. (For example, you might want to prevent the deletion of a device with an "active" status.)
If you are interested in contributing to the development of NetBox, please read
our [contributing guide](CONTRIBUTING.md) prior to beginning any work.
### Device Configuration Rendering
### Screenshots
NetBox can render user-created Jinja2 templates to generate device configurations from its own data. Configuration templates can be uploaded individually or pulled automatically from an external source, such as a git repository. Rendered configurations can be retrieved via the REST API for application directly to network devices via a provisioning tool such as Ansible or Salt.
")
### Custom Scripts
")
Complex workflows, such as provisioning a new branch office, can be tedious to carry out via the user interface. NetBox allows you to write and upload custom scripts that can be run directly from the UI. Scripts prompt users for input and then automate the necessary tasks to greatly simplify otherwise burdensome processes.

### Automated Events

Users can define event rules to automatically trigger a custom script or outbound webhook in response to a NetBox event. For example, you might want to automatically update a network monitoring service whenever a new device is added to NetBox, or update a DHCP server when an IP range is allocated.

### Comprehensive Change Logging
### Related projects
NetBox automatically logs the creation, modification, and deletion of all managed objects, providing a thorough change history. Changes can be attributed to the executing user, and related changes are grouped automatically by request ID.
Please see [our wiki](https://github.com/netbox-community/netbox/wiki/Community-Contributions)
for a list of relevant community projects.
> [!NOTE]
> A complete list of NetBox's myriad features can be found in [the introductory documentation](https://docs.netbox.dev/en/stable/introduction/).
## Getting Started
* Just want to explore? Check out [our public demo](https://demo.netbox.dev/) right now!
* The [official documentation](https://docs.netbox.dev) offers a comprehensive introduction.
* Check out [our wiki](https://github.com/netbox-community/netbox/wiki/Community-Contributions) for even more projects to get the most out of NetBox!
Looking for a managed solution? Check out <strong><a href="https://netboxlabs.com/netbox-cloud/">NetBox Cloud</a></strong> or <strong><a href="https://netboxlabs.com/netbox-enterprise/">NetBox Enterprise</a></strong>!
</p>
## Get Involved
* Follow [@NetBoxOfficial](https://twitter.com/NetBoxOfficial) on Twitter!
* Join the conversation on [the discussion forum](https://github.com/netbox-community/netbox/discussions) and [Slack](https://netdev.chat/)!
* Already a power user? You can [suggest a feature](https://github.com/netbox-community/netbox/issues/new?assignees=&labels=type%3A+feature&template=feature_request.yaml) or [report a bug](https://github.com/netbox-community/netbox/issues/new?assignees=&labels=type%3A+bug&template=bug_report.yaml) on GitHub.
* Contributions from the community are encouraged and appreciated! Check out our [contributing guide](CONTRIBUTING.md) to get started.
* [Share your idea](https://plugin-ideas.netbox.dev/) for a new plugin, or [learn how to build one](https://github.com/netbox-community/netbox-plugin-tutorial) yourself!
Per the terms of the Apache 2 license, NetBox is offered "as is" and without any guarantee or warranty pertaining to its operation. While every reasonable effort is made by its maintainers to ensure the product remains free of security vulnerabilities, users are ultimately responsible for conducting their own evaluations of each software release.
## Recommendations
Administrators are encouraged to adhere to industry best practices concerning the secure operation of software, such as:
* Do not expose your NetBox installation to the public Internet
* Do not permit multiple users to share an account
* Enforce minimum password complexity requirements for local accounts
* Prohibit access to your database from clients other than the NetBox application
* Keep your deployment updated to the most recent stable release
## Reporting a Suspected Vulnerability
If you believe you've uncovered a security vulnerability and wish to report it confidentially, you may do so via email. Please note that any reported vulnerabilities **MUST** meet all the following conditions:
* Affects the most recent stable release of NetBox, or a current beta release
* Affects a NetBox instance installed and configured per the official documentation
* Is reproducible following a prescribed set of instructions
Please note that we **DO NOT** accept reports generated by automated tooling which merely suggest that a file or file(s) _may_ be vulnerable under certain conditions, as these are most often innocuous.
If you believe that you've found a vulnerability which meets all of these conditions, please [submit a draft security advisory](https://github.com/netbox-community/netbox/security/advisories/new) on GitHub. For any security concerns regarding NetBox deployed via Docker, please see the [netbox-docker](https://github.com/netbox-community/netbox-docker) project.
### Bug Bounties
As NetBox is provided as free open source software, we do not offer any monetary compensation for vulnerability or bug reports, however your contributions are greatly appreciated.
All primary objects in NetBox support journaling. A journal is a collection of human-generated notes and comments about an object maintained for historical context. It supplements NetBox's change log to provide additional information about why changes have been made or to convey events which occur outside NetBox. Unlike the change log, in which records typically expire after a configurable period of time, journal entries persist for the life of their associated object.
Each journal entry has a selectable kind (info, success, warning, or danger) and a user-populated `comments` field. Each entry automatically records the date, time, and associated user upon being created.
NetBox supports integration with the [NAPALM automation](https://github.com/napalm-automation/napalm) library. NAPALM allows NetBox to serve a proxy for operational data, fetching live data from network devices and returning it to a requester via its REST API. Note that NetBox does not store any NAPALM data locally.
The NetBox UI will display tabs for status, LLDP neighbors, and configuration under the device view if the following conditions are met:
* Device status is "Active"
* A primary IP has been assigned to the device
* A platform with a NAPALM driver has been assigned
* The authenticated user has the `dcim.napalm_read_device` permission
!!! note
To enable this integration, the NAPALM library must be installed. See [installation steps](../../installation/3-netbox/#napalm) for more information.
Below is an example REST API request and response:
```no-highlight
GET /api/dcim/devices/1/napalm/?method=get_environment
{
"get_environment": {
...
}
}
```
!!! note
To make NAPALM requests via the NetBox REST API, a NetBox user must have assigned a permission granting the `napalm_read` action for the device object type.
## Authentication
By default, the [`NAPALM_USERNAME`](../configuration/dynamic-settings.md#napalm_username) and [`NAPALM_PASSWORD`](../configuration/dynamic-settings.md#napalm_password) configuration parameters are used for NAPALM authentication. They can be overridden for an individual API call by specifying the `X-NAPALM-Username` and `X-NAPALM-Password` headers.
The list of supported NAPALM methods depends on the [NAPALM driver](https://napalm.readthedocs.io/en/latest/support/index.html#general-support-matrix) configured for the platform of a device. Because there is no granular mechanism in place for limiting potentially disruptive requests, NetBox supports only read-only [get](https://napalm.readthedocs.io/en/latest/support/index.html#getters-support-matrix) methods.
## Multiple Methods
It is possible to request the output of multiple NAPALM methods in a single API request by passing multiple `method` parameters. For example:
```no-highlight
GET /api/dcim/devices/1/napalm/?method=get_ntp_servers&method=get_ntp_peers
{
"get_ntp_servers": {
...
},
"get_ntp_peers": {
...
}
}
```
## Optional Arguments
The behavior of NAPALM drivers can be adjusted according to the [optional arguments](https://napalm.readthedocs.io/en/latest/support/index.html#optional-arguments). NetBox exposes those arguments using headers prefixed with `X-NAPALM-`. For example, the SSH port is changed to 2222 in this API call:
A webhook may include a set of conditional logic expressed in JSON used to control whether a webhook triggers for a specific object. For example, you may wish to trigger a webhook for devices only when the `status` field of an object is "active":
```json
{
"and":[
{
"attr":"status.value",
"value":"active"
}
]
}
```
For more detail, see the reference documentation for NetBox's [conditional logic](../reference/conditions.md).
## Webhook Processing
When a change is detected, any resulting webhooks are placed into a Redis queue for processing. This allows the user's request to complete without needing to wait for the outgoing webhook(s) to be processed. The webhooks are then extracted from the queue by the `rqworker` process and HTTP requests are sent to their respective destinations. The current webhook queue and any failed webhooks can be inspected in the admin UI under System > Background Tasks.
A request is considered successful if the response has a 2XX status code; otherwise, the request is marked as having failed. Failed requests may be retried manually via the admin UI.
## Troubleshooting
To assist with verifying that the content of outgoing webhooks is rendered correctly, NetBox provides a simple HTTP listener that can be run locally to receive and display webhook requests. First, modify the target URL of the desired webhook to `http://localhost:9000/`. This will instruct NetBox to send the request to the local server on TCP port 9000. Then, start the webhook receiver service from the NetBox root directory:
```no-highlight
$ python netbox/manage.py webhook_receiver
Listening on port http://localhost:9000. Stop with CONTROL-C.
```
You can test the receiver itself by sending any HTTP request to it. For example:
```no-highlight
$ curl -X POST http://localhost:9000 --data '{"foo": "bar"}'
```
The server will print output similar to the following:
Note that `webhook_receiver` does not actually _do_ anything with the information received: It merely prints the request headers and body for inspection.
Now, when the NetBox webhook is triggered and processed, you should see its headers and content appear in the terminal where the webhook receiver is listening. If you don't, check that the `rqworker` process is running and that webhook events are being placed into the queue (visible under the NetBox admin UI).
@@ -73,7 +73,7 @@ You should be redirected to Microsoft's authentication portal. Enter the usernam
If successful, you will be redirected back to the NetBox UI, and will be logged in as the AD user. You can verify this by navigating to your profile (using the button at top right).
This user account has been replicated locally to NetBox, and can now be assigned groups and permissions within the NetBox admin UI.
This user account has been replicated locally to NetBox, and can now be assigned groups and permissions.
@@ -67,4 +67,4 @@ You should be redirected to Okta's authentication portal. Enter the username/ema
If successful, you will be redirected back to the NetBox UI, and will be logged in as the Okta user. You can verify this by navigating to your profile (using the button at top right).
This user account has been replicated locally to NetBox, and can now be assigned groups and permissions within the NetBox admin UI.
This user account has been replicated locally to NetBox, and can now be assigned groups and permissions.
Local user accounts and groups can be created in NetBox under the "Authentication and Authorization" section of the administrative user interface. This interface is available only to users with the "staff" permission enabled.
Local user accounts and groups can be created in NetBox under the "Authentication" section in the "Admin" menu. This section is available only to users with the "staff" permission enabled.
At a minimum, each user account must have a username and password set. User accounts may also denote a first name, last name, and email address. [Permissions](../permissions.md) may also be assigned to users and/or groups within the admin UI.
At a minimum, each user account must have a username and password set. User accounts may also denote a first name, last name, and email address. [Permissions](../permissions.md) may also be assigned to individual users and/or groups as needed.
Another option for remote authentication in NetBox is to enable HTTP header-based user assignment. The front end HTTP server (e.g. nginx or Apache) performs client authentication as a process external to NetBox, and passes information about the authenticated user via HTTP headers. By default, the user is assigned via the `REMOTE_USER` header, but this can be customized via the `REMOTE_AUTH_HEADER` configuration parameter.
Optionally, user profile information can be supplied by `REMOTE_USER_FIRST_NAME`, `REMOTE_USER_LAST_NAME` and `REMOTE_USER_EMAIL` headers. These are saved to the user's profile during the authentication process. These headers can be customized like the `REMOTE_USER` header.
!!! warning Verify Header Compatibility
Some WSGI servers may drop headers which contain unsupported characters. For instance, gunicorn v22.0 and later silently drops HTTP headers containing underscores. This behavior can be disabled by changing gunicorn's [`header_map`](https://docs.gunicorn.org/en/stable/settings.html#header-map) setting to `dangerous`.
NetBox supports single sign-on authentication via the [python-social-auth](https://github.com/python-social-auth) library. To enable SSO, specify the path to the desired authentication backend within the `social_core` Python package. Please see the complete list of [supported authentication backends](https://github.com/python-social-auth/social-core/tree/master/social_core/backends) for the available options.
Most remote authentication backends require some additional configuration through settings prefixed with `SOCIAL_AUTH_`. These will be automatically imported from NetBox's `configuration.py` file. Additionally, the [authentication pipeline](https://python-social-auth.readthedocs.io/en/latest/pipeline.html) can be customized via the `SOCIAL_AUTH_PIPELINE` parameter.
Most remote authentication backends require some additional configuration through settings prefixed with `SOCIAL_AUTH_`. These will be automatically imported from NetBox's `configuration.py` file. Additionally, the [authentication pipeline](https://python-social-auth.readthedocs.io/en/latest/pipeline.html) can be customized via the `SOCIAL_AUTH_PIPELINE` parameter. (NetBox's default pipeline is defined in `netbox/settings.py` for your reference.)
NetBox supports native integration with [Sentry](https://sentry.io/) for automatic error reporting. To enable this functionality, set `SENTRY_ENABLED` to True and define your unique [data source name (DSN)](https://docs.sentry.io/product/sentry-basics/concepts/dsn-explainer/) in `configuration.py`.
Setting `SENTRY_ENABLED` to False will disable the Sentry integration.
### Assigning Tags
You can optionally attach one or more arbitrary tags to the outgoing error reports if desired by setting the `SENTRY_TAGS` parameter:
```python
SENTRY_TAGS={
"custom.foo":"123",
"custom.bar":"abc",
}
```
!!! warning "Reserved tag prefixes"
Avoid using any tag names which begin with `netbox.`, as this prefix is reserved by the NetBox application.
### Testing
Once the configuration has been saved, restart the NetBox service.
To test Sentry operation, try generating a 404 (page not found) error by navigating to an invalid URL, such as `https://netbox/404-error-testing`. (Be sure that debug mode has been disabled.) After receiving a 404 response from the NetBox server, you should see the issue appear shortly in Sentry.
NetBox includes a `housekeeping` management command that should be run nightly. This command handles:
* Clearing expired authentication sessions from the database
* Deleting changelog records older than the configured [retention time](../configuration/dynamic-settings.md#changelog_retention)
* Deleting job result records older than the configured [retention time](../configuration/dynamic-settings.md#jobresult_retention)
* Deleting changelog records older than the configured [retention time](../configuration/miscellaneous.md#changelog_retention)
* Deleting job result records older than the configured [retention time](../configuration/miscellaneous.md#job_retention)
* Check for new NetBox releases (if [`RELEASE_CHECK_URL`](../configuration/miscellaneous.md#release_check_url) is set)
This command can be invoked directly, or by using the shell script provided at `/opt/netbox/contrib/netbox-housekeeping.sh`. This script can be linked from your cron scheduler's daily jobs directory (e.g. `/etc/cron.daily`) or referenced directly within the cron configuration file.
This command can be invoked directly, or by using the shell script provided at `/opt/netbox/contrib/netbox-housekeeping.sh`.
## Scheduling
### Using Cron
This script can be linked from your cron scheduler's daily jobs directory (e.g. `/etc/cron.daily`) or referenced directly within the cron configuration file.
On Debian-based systems, be sure to omit the `.sh` file extension when linking to the script from within a cron directory. Otherwise, the task may not run.
The `housekeeping` command can also be run manually at any time: Running the command outside scheduled execution times will not interfere with its operation.
### Using Systemd
First, create symbolic links for the systemd service and timer files. Link the existing service and timer files from the `/opt/netbox/contrib/` directory to the `/etc/systemd/system/` directory:
NetBox v2.9 introduced a new object-based permissions framework, which replaces Django's built-in permissions model. Object-based permissions enable an administrator to grant users or groups the ability to perform an action on arbitrary subsets of objects in NetBox, rather than all objects of a certain type. For example, it is possible to grant a user permission to view only sites within a particular region, or to modify only VLANs with a numeric ID within a certain range.
NetBox employs a new object-based permissions framework, which replaces Django's built-in permissions model. Object-based permissions enable an administrator to grant users or groups the ability to perform an action on arbitrary subsets of objects in NetBox, rather than all objects of a certain type. For example, it is possible to grant a user permission to view only sites within a particular region, or to modify only VLANs with a numeric ID within a certain range.
{!models/users/objectpermission.md!}
A permission in NetBox represents a relationship shared by several components:
* Object type(s) - One or more types of object in NetBox
* User(s)/Group(s) - One or more users or groups of users
* Action(s) - The action(s) that can be performed on an object
* Constraints - An arbitrary filter used to limit the granted action(s) to a specific subset of objects
At a minimum, a permission assignment must specify one object type, one user or group, and one action. The specification of constraints is optional: A permission without any constraints specified will apply to all instances of the selected model(s).
## Actions
There are four core actions that can be permitted for each type of object within NetBox, roughly analogous to the CRUD convention (create, read, update, and delete):
* **View** - Retrieve an object from the database
* **Add** - Create a new object
* **Change** - Modify an existing object
* **Delete** - Delete an existing object
In addition to these, permissions can also grant custom actions that may be required by a specific model or plugin. For example, the `run` permission for scripts allows a user to execute custom scripts. These can be specified when granting a permission in the "additional actions" field.
!!! note
Internally, all actions granted by a permission (both built-in and custom) are stored as strings in an array field named `actions`.
## Constraints
Constraints are expressed as a JSON object or list representing a [Django query filter](https://docs.djangoproject.com/en/stable/ref/models/querysets/#field-lookups). This is the same syntax that you would pass to the QuerySet `filter()` method when performing a query using the Django ORM. As with query filters, double underscores can be used to traverse related objects or invoke lookup expressions. Some example queries and their corresponding definitions are shown below.
All attributes defined within a single JSON object are applied with a logical AND. For example, suppose you assign a permission for the site model with the following constraints.
```json
{
"status":"active",
"region__name":"Americas"
}
```
The permission will grant access only to sites which have a status of "active" **and** which are assigned to the "Americas" region.
To achieve a logical OR with a different set of constraints, define multiple objects within a list. For example, if you want to constrain the permission to VLANs with an ID between 100 and 199 _or_ a status of "reserved," do the following:
```json
[
{
"vid__gte":100,
"vid__lt":200
},
{
"status":"reserved"
}
]
```
Additionally, where multiple permissions have been assigned for an object type, their collective constraints will be merged using a logical "OR" operation.
### User Token
When defining a permission constraint, administrators may use the special token `$user` to reference the current user at the time of evaluation. This can be helpful to restrict users to editing only their own journal entries, for example. Such a constraint might be defined as:
```json
{
"created_by":"$user"
}
```
The `$user` token can be used only as a constraint value, or as an item within a list of values. It cannot be modified or extended to reference specific user attributes.
### Default Permissions
While permissions are typically assigned to specific groups and/or users, it is also possible to define a set of default permissions that are applied to _all_ authenticated users. This is done using the [`DEFAULT_PERMISSIONS`](../configuration/security.md#default_permissions) configuration parameter. Note that statically configuring permissions for specific users or groups is **not** supported.
By default, NetBox stores uploaded files (such as image attachments) in its media directory. To fully replicate an instance of NetBox, you'll need to copy both the database and the media files.
!!! note
These operations are not necessary if your installation is utilizing a [remote storage backend](../../configuration/optional-settings/#storage_backend).
These operations are not necessary if your installation is utilizing a [remote storage backend](../configuration/system.md#storage_backend).
This is a mapping of models to [custom validators](../customization/custom-validation.md) that have been defined locally to enforce custom validation logic. An example is provided below:
```python
CUSTOM_VALIDATORS={
"dcim.site":[
{
"name":{
"min_length":5,
"max_length":30
}
},
"my_plugin.validators.Validator1"
],
"dim.device":[
"my_plugin.validators.Validator1"
]
}
```
---
## FIELD_CHOICES
Some static choice fields on models can be configured with custom values. This is done by defining `FIELD_CHOICES` as a dictionary mapping model fields to their choices. Each choice in the list must have a database value and a human-friendly label, and may optionally specify a color. (A list of available colors is provided below.)
The choices provided can either replace the stock choices provided by NetBox, or append to them. To _replace_ the available choices, specify the app, model, and field name separated by dots. For example, the site model would be referenced as `dcim.Site.status`. To _extend_ the available choices, append a plus sign to the end of this string (e.g. `dcim.Site.status+`).
For example, the following configuration would replace the default site status choices with the options Foo, Bar, and Baz:
```python
FIELD_CHOICES={
'dcim.Site.status':(
('foo','Foo','red'),
('bar','Bar','green'),
('baz','Baz','blue'),
)
}
```
Appending a plus sign to the field identifier would instead _add_ these choices to the ones already offered:
```python
FIELD_CHOICES={
'dcim.Site.status+':(
...
)
}
```
The following model fields support configurable choices:
*`circuits.Circuit.status`
*`dcim.Device.status`
*`dcim.Location.status`
*`dcim.Module.status`
*`dcim.PowerFeed.status`
*`dcim.Rack.status`
*`dcim.Site.status`
*`dcim.VirtualDeviceContext.status`
*`extras.JournalEntry.kind`
*`ipam.IPAddress.status`
*`ipam.IPRange.status`
*`ipam.Prefix.status`
*`ipam.VLAN.status`
*`virtualization.Cluster.status`
*`virtualization.VirtualMachine.status`
*`wireless.WirelessLAN.status`
The following colors are supported:
*`blue`
*`indigo`
*`purple`
*`pink`
*`red`
*`orange`
*`yellow`
*`green`
*`teal`
*`cyan`
*`gray`
*`black`
*`white`
---
## PROTECTION_RULES
!!! tip "Dynamic Configuration Parameter"
This is a mapping of models to [custom validators](../customization/custom-validation.md) against which an object is evaluated immediately prior to its deletion. If validation fails, the object is not deleted. An example is provided below:
This parameter controls the content and layout of user's default dashboard. Once the dashboard has been created, the user is free to customize it as they please by adding, removing, and reconfiguring widgets.
This parameter must specify an iterable of dictionaries, each representing a discrete dashboard widget and its configuration. The follow widget attributes are supported:
*`widget`: Dotted path to the Python class (required)
*`width`: Default widget width (between 1 and 12, inclusive)
*`height`: Default widget height, in rows
*`title`: Widget title
*`color`: Color of the widget's title bar, specified by name
*`config`: Dictionary mapping of any widget configuration parameters
A brief example configuration is provided below.
```python
DEFAULT_DASHBOARD=[
{
'widget':'extras.ObjectCountsWidget',
'width':4,
'height':3,
'title':'Organization',
'config':{
'models':[
'dcim.site',
'tenancy.tenant',
'tenancy.contact',
]
}
},
{
'widget':'extras.ObjectCountsWidget',
'width':4,
'height':3,
'title':'IPAM',
'color':'blue',
'config':{
'models':[
'ipam.prefix',
'ipam.iprange',
'ipam.ipaddress',
]
}
},
]
```
## DEFAULT_USER_PREFERENCES
!!! tip "Dynamic Configuration Parameter"
This is a dictionary defining the default preferences to be set for newly-created user accounts. For example, to set the default page size for all users to 100, define the following:
```python
DEFAULT_USER_PREFERENCES={
"pagination":{
"per_page":100
}
}
```
For a complete list of available preferences, log into NetBox and navigate to `/user/preferences/`. A period in a preference name indicates a level of nesting in the JSON data. The example above maps to `pagination.per_page`.
---
## PAGINATE_COUNT
!!! tip "Dynamic Configuration Parameter"
Default: 50
The default maximum number of objects to display per page within each list of objects.
---
## POWERFEED_DEFAULT_AMPERAGE
!!! tip "Dynamic Configuration Parameter"
Default: 15
The default value for the `amperage` field when creating new power feeds.
---
## POWERFEED_DEFAULT_MAX_UTILIZATION
!!! tip "Dynamic Configuration Parameter"
Default: 80
The default value (percentage) for the `max_utilization` field when creating new power feeds.
---
## POWERFEED_DEFAULT_VOLTAGE
!!! tip "Dynamic Configuration Parameter"
Default: 120
The default value for the `voltage` field when creating new power feeds.
---
## RACK_ELEVATION_DEFAULT_UNIT_HEIGHT
!!! tip "Dynamic Configuration Parameter"
Default: 22
Default height (in pixels) of a unit within a rack elevation. For best results, this should be approximately one tenth of `RACK_ELEVATION_DEFAULT_UNIT_WIDTH`.
---
## RACK_ELEVATION_DEFAULT_UNIT_WIDTH
!!! tip "Dynamic Configuration Parameter"
Default: 220
Default width (in pixels) of a unit within a rack elevation.
This setting enables debugging. Debugging should be enabled only during development or troubleshooting. Note that only
clients which access NetBox from a recognized [internal IP address](#internal_ips) will see debugging tools in the user
interface.
!!! warning
Never enable debugging on a production system, as it can expose sensitive data to unauthenticated users and impose a
substantial performance penalty.
---
## DEVELOPER
Default: False
This parameter serves as a safeguard to prevent some potentially dangerous behavior, such as generating new database schema migrations. Additionally, enabling this setting disables the debug warning banner in the UI. Set this to `True`**only** if you are actively developing the NetBox code base.
These configuration parameters are primarily controlled via NetBox's admin interface (under Admin > Extras > Configuration Revisions). These setting may also be overridden in `configuration.py`; this will prevent them from being modified via the UI.
A list of permitted URL schemes referenced when rendering links within NetBox. Note that only the schemes specified in this list will be accepted: If adding your own, be sure to replicate all of the default values as well (excluding those schemes which are not desirable).
---
## BANNER_TOP
## BANNER_BOTTOM
Setting these variables will display custom content in a banner at the top and/or bottom of the page, respectively. HTML is allowed. To replicate the content of the top banner in the bottom banner, set:
```python
BANNER_TOP='Your banner text'
BANNER_BOTTOM=BANNER_TOP
```
---
## BANNER_LOGIN
This defines custom content to be displayed on the login page above the login form. HTML is allowed.
---
## CHANGELOG_RETENTION
Default: 90
The number of days to retain logged changes (object creations, updates, and deletions). Set this to `0` to retain
changes in the database indefinitely.
!!! warning
If enabling indefinite changelog retention, it is recommended to periodically delete old entries. Otherwise, the database may eventually exceed capacity.
---
## JOBRESULT_RETENTION
Default: 90
The number of days to retain job results (scripts and reports). Set this to `0` to retain
job results in the database indefinitely.
!!! warning
If enabling indefinite job results retention, it is recommended to periodically delete old entries. Otherwise, the database may eventually exceed capacity.
---
## CUSTOM_VALIDATORS
This is a mapping of models to [custom validators](../customization/custom-validation.md) that have been defined locally to enforce custom validation logic. An example is provided below:
```python
CUSTOM_VALIDATORS={
"dcim.site":[
{
"name":{
"min_length":5,
"max_length":30
}
},
"my_plugin.validators.Validator1"
],
"dim.device":[
"my_plugin.validators.Validator1"
]
}
```
---
## DEFAULT_USER_PREFERENCES
This is a dictionary defining the default preferences to be set for newly-created user accounts. For example, to set the default page size for all users to 100, define the following:
```python
DEFAULT_USER_PREFERENCES={
"pagination":{
"per_page":100
}
}
```
For a complete list of available preferences, log into NetBox and navigate to `/user/preferences/`. A period in a preference name indicates a level of nesting in the JSON data. The example above maps to `pagination.per_page`.
---
## ENFORCE_GLOBAL_UNIQUE
Default: False
By default, NetBox will permit users to create duplicate prefixes and IP addresses in the global table (that is, those which are not assigned to any VRF). This behavior can be disabled by setting `ENFORCE_GLOBAL_UNIQUE` to True.
---
## GRAPHQL_ENABLED
Default: True
Setting this to False will disable the GraphQL API.
---
## MAINTENANCE_MODE
Default: False
Setting this to True will display a "maintenance mode" banner at the top of every page. Additionally, NetBox will no longer update a user's "last active" time upon login. This is to allow new logins when the database is in a read-only state. Recording of login times will resume when maintenance mode is disabled.
This specifies the URL to use when presenting a map of a physical location by street address or GPS coordinates. The URL must accept either a free-form street address or a comma-separated pair of numeric coordinates appended to it.
---
## MAX_PAGE_SIZE
Default: 1000
A web user or API consumer can request an arbitrary number of objects by appending the "limit" parameter to the URL (e.g. `?limit=1000`). This parameter defines the maximum acceptable limit. Setting this to `0` or `None` will allow a client to retrieve _all_ matching objects at once with no limit by specifying `?limit=0`.
---
## NAPALM_USERNAME
## NAPALM_PASSWORD
NetBox will use these credentials when authenticating to remote devices via the supported [NAPALM integration](../additional-features/napalm.md), if installed. Both parameters are optional.
!!! note
If SSH public key authentication has been set up on the remote device(s) for the system account under which NetBox runs, these parameters are not needed.
---
## NAPALM_ARGS
A dictionary of optional arguments to pass to NAPALM when instantiating a network driver. See the NAPALM documentation for a [complete list of optional arguments](https://napalm.readthedocs.io/en/latest/support/#optional-arguments). An example:
```python
NAPALM_ARGS={
'api_key':'472071a93b60a1bd1fafb401d9f8ef41',
'port':2222,
}
```
Some platforms (e.g. Cisco IOS) require an argument named `secret` to be passed in addition to the normal password. If desired, you can use the configured `NAPALM_PASSWORD` as the value for this argument:
```python
NAPALM_USERNAME='username'
NAPALM_PASSWORD='MySecretPassword'
NAPALM_ARGS={
'secret':NAPALM_PASSWORD,
# Include any additional args here
}
```
---
## NAPALM_TIMEOUT
Default: 30 seconds
The amount of time (in seconds) to wait for NAPALM to connect to a device.
---
## PAGINATE_COUNT
Default: 50
The default maximum number of objects to display per page within each list of objects.
---
## PREFER_IPV4
Default: False
When determining the primary IP address for a device, IPv6 is preferred over IPv4 by default. Set this to True to prefer IPv4 instead.
---
## RACK_ELEVATION_DEFAULT_UNIT_HEIGHT
Default: 22
Default height (in pixels) of a unit within a rack elevation. For best results, this should be approximately one tenth of `RACK_ELEVATION_DEFAULT_UNIT_WIDTH`.
---
## RACK_ELEVATION_DEFAULT_UNIT_WIDTH
Default: 220
Default width (in pixels) of a unit within a rack elevation.
Set to True to enable automatic error reporting via [Sentry](https://sentry.io/).
!!! note
The `sentry-sdk` Python package is required to enable Sentry integration.
---
## SENTRY_SAMPLE_RATE
Default: 1.0 (all)
The sampling rate for errors. Must be a value between 0 (disabled) and 1.0 (report on all errors).
---
## SENTRY_SEND_DEFAULT_PII
Default: False
Maps to the Sentry SDK's [`send_default_pii`](https://docs.sentry.io/platforms/python/configuration/options/#send-default-pii) parameter. If enabled, certain personally identifiable information (PII) is added.
!!! warning "Sensitive data"
If you enable this option, be aware that sensitive data such as cookies and authentication tokens will be logged.
---
## SENTRY_TAGS
An optional dictionary of tag names and values to apply to Sentry error reports.For example:
```
SENTRY_TAGS = {
"custom.foo": "123",
"custom.bar": "abc",
}
```
!!! warning "Reserved tag prefixes"
Avoid using any tag names which begin with `netbox.`, as this prefix is reserved by the NetBox application.
---
## SENTRY_TRACES_SAMPLE_RATE
Default: 0 (disabled)
The sampling rate for transactions. Must be a value between 0 (disabled) and 1.0 (report on all transactions).
!!! warning "Consider performance implications"
A high sampling rate for transactions can induce significant performance penalties. If transaction reporting is desired, it is recommended to use a relatively low sample rate of 10% to 20% (0.1 to 0.2).
NetBox's local configuration is stored in `$INSTALL_ROOT/netbox/netbox/configuration.py` by default. An example configuration is provided as `configuration_example.py`. You may copy or rename the example configuration and make changes as appropriate. NetBox will not run without a configuration file. While NetBox has many configuration settings, only a few of them must be defined at the time of installation: these are defined under "required settings" below.
## Configuration File
NetBox's configuration file contains all the important parameters which control how NetBox functions: database settings, security controls, user preferences, and so on. While the default configuration suffices out of the box for most use cases, there are a few [required parameters](./required-parameters.md) which **must** be defined during installation.
The configuration file is loaded from `$INSTALL_ROOT/netbox/netbox/configuration.py` by default. An example configuration is provided at `configuration_example.py`, which you may copy to use as your default config. Note that a configuration file must be defined; NetBox will not run without one.
!!! info "Customizing the Configuration Module"
A custom configuration module may be specified by setting the `NETBOX_CONFIGURATION` environment variable. This must be a dotted path to the desired Python module. For example, a file named `my_config.py` in the same directory as `settings.py` would be referenced as `netbox.my_config`.
For the sake of brevity, the NetBox documentation refers to the configuration file simply as `configuration.py`.
To keep things simple, the NetBox documentation refers to the configuration file simply as `configuration.py`.
Some configuration parameters may alternatively be defined either in `configuration.py` or within the administrative section of the user interface. Settings which are "hard-coded" in the configuration file take precedence over those defined via the UI.
Some configuration parameters are primarily controlled via NetBox's admin interface (under Admin > Extras > Configuration Revisions). These are noted where applicable in the documentation. These settings may also be overridden in `configuration.py` to prevent them from being modified via the UI. A complete list of supported parameters is provided below:
NetBox will email details about critical errors to the administrators listed here. This should be a list of (name, email) tuples. For example:
```python
ADMINS=[
['Hank Hill','hhill@example.com'],
['Dale Gribble','dgribble@example.com'],
]
```
---
## BANNER_BOTTOM
!!! tip "Dynamic Configuration Parameter"
Sets content for the bottom banner in the user interface.
---
## BANNER_LOGIN
!!! tip "Dynamic Configuration Parameter"
This defines custom content to be displayed on the login page above the login form. HTML is allowed.
---
## BANNER_MAINTENANCE
!!! tip "Dynamic Configuration Parameter"
This adds a banner to the top of every page when maintenance mode is enabled. HTML is allowed.
---
## BANNER_TOP
!!! tip "Dynamic Configuration Parameter"
Sets content for the top banner in the user interface.
!!! tip
If you'd like the top and bottom banners to match, set the following:
```python
BANNER_TOP = 'Your banner text'
BANNER_BOTTOM = BANNER_TOP
```
---
## CENSUS_REPORTING_ENABLED
Default: True
Enables anonymous census reporting. To opt out of census reporting, set this to False.
This data enables the project maintainers to estimate how many NetBox deployments exist and track the adoption of new versions over time. Census reporting effects a single HTTP request each time a worker starts. The only data reported by this function are the NetBox version, Python version, and a pseudorandom unique identifier.
---
## CHANGELOG_RETENTION
!!! tip "Dynamic Configuration Parameter"
Default: 90
The number of days to retain logged changes (object creations, updates, and deletions). Set this to `0` to retain
changes in the database indefinitely.
!!! warning
If enabling indefinite changelog retention, it is recommended to periodically delete old entries. Otherwise, the database may eventually exceed capacity.
---
## CHANGELOG_SKIP_EMPTY_CHANGES
Default: True
If enabled, a change log record will not be created when an object is updated without any changes to its existing field values.
!!! note
The object's `last_updated` field will always reflect the time of the most recent update, regardless of this parameter.
---
## DATA_UPLOAD_MAX_MEMORY_SIZE
Default: `2621440` (2.5 MB)
The maximum size (in bytes) of an incoming HTTP request (i.e. `GET` or `POST` data). Requests which exceed this size will raise a `RequestDataTooBig` exception.
---
## DJANGO_ADMIN_ENABLED
Default: False
Setting this to True installs the `django.contrib.admin` app and enables the [Django admin UI](https://docs.djangoproject.com/en/5.0/ref/contrib/admin/). This may be necessary to support older plugins which do not integrate with the native NetBox interface.
---
## ENFORCE_GLOBAL_UNIQUE
!!! tip "Dynamic Configuration Parameter"
Default: True
By default, NetBox will prevent the creation of duplicate prefixes and IP addresses in the global table (that is, those which are not assigned to any VRF). This validation can be disabled by setting `ENFORCE_GLOBAL_UNIQUE` to False.
---
## FILE_UPLOAD_MAX_MEMORY_SIZE
Default: `2621440` (2.5 MB)
The maximum amount (in bytes) of uploaded data that will be held in memory before being written to the filesystem. Changing this setting can be useful for example to be able to upload files bigger than 2.5MB to custom scripts for processing.
---
## GRAPHQL_ENABLED
!!! tip "Dynamic Configuration Parameter"
Default: True
Setting this to False will disable the GraphQL API.
---
## JOB_RETENTION
!!! tip "Dynamic Configuration Parameter"
Default: 90
The number of days to retain job results (scripts and reports). Set this to `0` to retain job results in the database indefinitely.
!!! warning
If enabling indefinite job results retention, it is recommended to periodically delete old entries. Otherwise, the database may eventually exceed capacity.
---
## MAINTENANCE_MODE
!!! tip "Dynamic Configuration Parameter"
Default: False
Setting this to True will display a "maintenance mode" banner at the top of every page. Additionally, NetBox will no longer update a user's "last active" time upon login. This is to allow new logins when the database is in a read-only state. Recording of login times will resume when maintenance mode is disabled.
This specifies the URL to use when presenting a map of a physical location by street address or GPS coordinates. The URL must accept either a free-form street address or a comma-separated pair of numeric coordinates appended to it. Set this to `None` to disable the "map it" button within the UI.
---
## MAX_PAGE_SIZE
!!! tip "Dynamic Configuration Parameter"
Default: 1000
A web user or API consumer can request an arbitrary number of objects by appending the "limit" parameter to the URL (e.g. `?limit=1000`). This parameter defines the maximum acceptable limit. Setting this to `0` or `None` will allow a client to retrieve _all_ matching objects at once with no limit by specifying `?limit=0`.
---
## METRICS_ENABLED
Default: False
Toggle the availability Prometheus-compatible metrics at `/metrics`. See the [Prometheus Metrics](../integrations/prometheus-metrics.md) documentation for more details.
---
## PREFER_IPV4
!!! tip "Dynamic Configuration Parameter"
Default: False
When determining the primary IP address for a device, IPv6 is preferred over IPv4 by default. Set this to True to prefer IPv4 instead.
---
## QUEUE_MAPPINGS
Allows changing which queues are used internally for background tasks.
```python
QUEUE_MAPPINGS = {
'webhook': 'low',
'report': 'high',
'script': 'high',
}
```
If no queue is defined the queue named `default` will be used.
---
## RELEASE_CHECK_URL
Default: None (disabled)
This parameter defines the URL of the repository that will be checked for new NetBox releases. When a new release is detected, a message will be displayed to administrative users on the home page. This can be set to the official repository (`'https://api.github.com/repos/netbox-community/netbox/releases'`) or a custom fork. Set this to `None` to disable automatic update checks.
!!! note
The URL provided **must** be compatible with the [GitHub REST API](https://docs.github.com/en/rest).
---
## RQ_DEFAULT_TIMEOUT
Default: `300`
The maximum execution time of a background task (such as running a custom script), in seconds.
---
## RQ_RETRY_INTERVAL
Default: `60`
This parameter controls how frequently a failed job is retried, up to the maximum number of times specified by `RQ_RETRY_MAX`. This must be either an integer specifying the number of seconds to wait between successive attempts, or a list of such values. For example, `[60, 300, 3600]` will retry the task after 1 minute, 5 minutes, and 1 hour.
---
## RQ_RETRY_MAX
Default: `0` (retries disabled)
The maximum number of times a background task will be retried before being marked as failed.
NetBox will email details about critical errors to the administrators listed here. This should be a list of (name, email) tuples. For example:
```python
ADMINS=[
['Hank Hill','hhill@example.com'],
['Dale Gribble','dgribble@example.com'],
]
```
---
## AUTH_PASSWORD_VALIDATORS
This parameter acts as a pass-through for configuring Django's built-in password validators for local user accounts. If configured, these will be applied whenever a user's password is updated to ensure that it meets minimum criteria such as length or complexity. An example is provided below. For more detail on the available options, please see [the Django documentation](https://docs.djangoproject.com/en/stable/topics/auth/passwords/#password-validation).
The base URL path to use when accessing NetBox. Do not include the scheme or domain name. For example, if installed at https://example.com/netbox/, set:
```python
BASE_PATH='netbox/'
```
---
## CORS_ORIGIN_ALLOW_ALL
Default: False
If True, cross-origin resource sharing (CORS) requests will be accepted from all origins. If False, a whitelist will be used (see below).
---
## CORS_ORIGIN_WHITELIST
## CORS_ORIGIN_REGEX_WHITELIST
These settings specify a list of origins that are authorized to make cross-site API requests. Use
`CORS_ORIGIN_WHITELIST` to define a list of exact hostnames, or `CORS_ORIGIN_REGEX_WHITELIST` to define a set of regular
expressions. (These settings have no effect if `CORS_ORIGIN_ALLOW_ALL` is True.) For example:
```python
CORS_ORIGIN_WHITELIST=[
'https://example.com',
]
```
---
## CSRF_TRUSTED_ORIGINS
Default: `[]`
Defines a list of trusted origins for unsafe (e.g. `POST`) requests. This is a pass-through to Django's [`CSRF_TRUSTED_ORIGINS`](https://docs.djangoproject.com/en/4.0/ref/settings/#std:setting-CSRF_TRUSTED_ORIGINS) setting. Note that each host listed must specify a scheme (e.g. `http://` or `https://).
```python
CSRF_TRUSTED_ORIGINS = (
'http://netbox.local',
'https://netbox.local',
)
```
---
## DEBUG
Default: False
This setting enables debugging. Debugging should be enabled only during development or troubleshooting. Note that only
clients which access NetBox from a recognized [internal IP address](#internal_ips) will see debugging tools in the user
interface.
!!! warning
Never enable debugging on a production system, as it can expose sensitive data to unauthenticated users and impose a
substantial performance penalty.
---
## DEVELOPER
Default: False
This parameter serves as a safeguard to prevent some potentially dangerous behavior, such as generating new database schema migrations. Set this to `True` **only** if you are actively developing the NetBox code base.
---
## DOCS_ROOT
Default: `$INSTALL_ROOT/docs/`
The filesystem path to NetBox's documentation. This is used when presenting context-sensitive documentation in the web UI. By default, this will be the `docs/` directory within the root NetBox installation path. (Set this to `None` to disable the embedded documentation.)
---
## EMAIL
In order to send email, NetBox needs an email server configured. The following items can be defined within the `EMAIL` configuration parameter:
* `SERVER` - Hostname or IP address of the email server (use `localhost` if running locally)
* `PORT` - TCP port to use for the connection (default: `25`)
* `USERNAME` - Username with which to authenticate
* `PASSSWORD` - Password with which to authenticate
* `USE_SSL` - Use SSL when connecting to the server (default: `False`)
* `USE_TLS` - Use TLS when connecting to the server (default: `False`)
* `SSL_CERTFILE` - Path to the PEM-formatted SSL certificate file (optional)
* `SSL_KEYFILE` - Path to the PEM-formatted SSL private key file (optional)
* `TIMEOUT` - Amount of time to wait for a connection, in seconds (default: `10`)
* `FROM_EMAIL` - Sender address for emails sent by NetBox
!!! note
The `USE_SSL` and `USE_TLS` parameters are mutually exclusive.
Email is sent from NetBox only for critical events or if configured for [logging](#logging). If you would like to test the email server configuration, Django provides a convenient [send_mail()](https://docs.djangoproject.com/en/stable/topics/email/#send-mail) function accessible within the NetBox shell:
```no-highlight
# python ./manage.py nbshell
>>> from django.core.mail import send_mail
>>> send_mail(
'Test Email Subject',
'Test Email Body',
'noreply-netbox@example.com',
['users@example.com'],
fail_silently=False
)
```
---
## EXEMPT_VIEW_PERMISSIONS
Default: Empty list
A list of NetBox models to exempt from the enforcement of view permissions. Models listed here will be viewable by all users, both authenticated and anonymous.
List models in the form `<app>.<model>`. For example:
```python
EXEMPT_VIEW_PERMISSIONS = [
'dcim.site',
'dcim.region',
'ipam.prefix',
]
```
To exempt _all_ models from view permission enforcement, set the following. (Note that `EXEMPT_VIEW_PERMISSIONS` must be an iterable.)
```python
EXEMPT_VIEW_PERMISSIONS = ['*']
```
!!! note
Using a wildcard will not affect certain potentially sensitive models, such as user permissions. If there is a need to exempt these models, they must be specified individually.
---
## FIELD_CHOICES
Some static choice fields on models can be configured with custom values. This is done by defining `FIELD_CHOICES` as a dictionary mapping model fields to their choices. Each choice in the list must have a database value and a human-friendly label, and may optionally specify a color. (A list of available colors is provided below.)
The choices provided can either replace the stock choices provided by NetBox, or append to them. To _replace_ the available choices, specify the app, model, and field name separated by dots. For example, the site model would be referenced as `dcim.Site.status`. To _extend_ the available choices, append a plus sign to the end of this string (e.g. `dcim.Site.status+`).
For example, the following configuration would replace the default site status choices with the options Foo, Bar, and Baz:
```python
FIELD_CHOICES = {
'dcim.Site.status': (
('foo', 'Foo', 'red'),
('bar', 'Bar', 'green'),
('baz', 'Baz', 'blue'),
)
}
```
Appending a plus sign to the field identifier would instead _add_ these choices to the ones already offered:
```python
FIELD_CHOICES = {
'dcim.Site.status+': (
...
)
}
```
The following model fields support configurable choices:
* `circuits.Circuit.status`
* `dcim.Device.status`
* `dcim.PowerFeed.status`
* `dcim.Rack.status`
* `dcim.Site.status`
* `extras.JournalEntry.kind`
* `ipam.IPAddress.status`
* `ipam.IPRange.status`
* `ipam.Prefix.status`
* `ipam.VLAN.status`
* `virtualization.VirtualMachine.status`
The following colors are supported:
* `blue`
* `indigo`
* `purple`
* `pink`
* `red`
* `orange`
* `yellow`
* `green`
* `teal`
* `cyan`
* `gray`
* `black`
* `white`
---
## HTTP_PROXIES
Default: None
A dictionary of HTTP proxies to use for outbound requests originating from NetBox (e.g. when sending webhook requests). Proxies should be specified by schema (HTTP and HTTPS) as per the [Python requests library documentation](https://2.python-requests.org/en/master/user/advanced/). For example:
```python
HTTP_PROXIES = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
}
```
---
## INTERNAL_IPS
Default: `('127.0.0.1', '::1')`
A list of IP addresses recognized as internal to the system, used to control the display of debugging output. For
example, the debugging toolbar will be viewable only when a client is accessing NetBox from one of the listed IP
addresses (and [`DEBUG`](#debug) is true).
---
## LOGGING
By default, all messages of INFO severity or higher will be logged to the console. Additionally, if [`DEBUG`](#debug) is False and email access has been configured, ERROR and CRITICAL messages will be emailed to the users defined in [`ADMINS`](#admins).
The Django framework on which NetBox runs allows for the customization of logging format and destination. Please consult the [Django logging documentation](https://docs.djangoproject.com/en/stable/topics/logging/) for more information on configuring this setting. Below is an example which will write all INFO and higher messages to a local file:
```python
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': '/var/log/netbox.log',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'INFO',
},
},
}
```
### Available Loggers
* `netbox.<app>.<model>` - Generic form for model-specific log messages
* `netbox.auth.*` - Authentication events
* `netbox.api.views.*` - Views which handle business logic for the REST API
* `netbox.views.*` - Views which handle business logic for the web UI
---
## LOGIN_PERSISTENCE
Default: False
If true, the lifetime of a user's authentication session will be automatically reset upon each valid request. For example, if [`LOGIN_TIMEOUT`](#login_timeout) is configured to 14 days (the default), and a user whose session is due to expire in five days makes a NetBox request (with a valid session cookie), the session's lifetime will be reset to 14 days.
Note that enabling this setting causes NetBox to update a user's session in the database (or file, as configured per [`SESSION_FILE_PATH`](#session_file_path)) with each request, which may introduce significant overhead in very active environments. It also permits an active user to remain authenticated to NetBox indefinitely.
---
## LOGIN_REQUIRED
Default: False
Setting this to True will permit only authenticated users to access any part of NetBox. By default, anonymous users are permitted to access most data in NetBox but not make any changes.
---
## LOGIN_TIMEOUT
Default: 1209600 seconds (14 days)
The lifetime (in seconds) of the authentication cookie issued to a NetBox user upon login.
---
## MEDIA_ROOT
Default: $INSTALL_ROOT/netbox/media/
The file path to the location where media files (such as image attachments) are stored. By default, this is the `netbox/media/` directory within the base NetBox installation path.
---
## METRICS_ENABLED
Default: False
Toggle the availability Prometheus-compatible metrics at `/metrics`. See the [Prometheus Metrics](../additional-features/prometheus-metrics.md) documentation for more details.
---
## PLUGINS
Default: Empty
A list of installed [NetBox plugins](../../plugins/) to enable. Plugins will not take effect unless they are listed here.
!!! warning
Plugins extend NetBox by allowing external code to run with the same access and privileges as NetBox itself. Only install plugins from trusted sources. The NetBox maintainers make absolutely no guarantees about the integrity or security of your installation with plugins enabled.
---
## PLUGINS_CONFIG
Default: Empty
This parameter holds configuration settings for individual NetBox plugins. It is defined as a dictionary, with each key using the name of an installed plugin. The specific parameters supported are unique to each plugin: Reference the plugin's documentation to determine the supported parameters. An example configuration is shown below:
```python
PLUGINS_CONFIG = {
'plugin1': {
'foo': 123,
'bar': True
},
'plugin2': {
'foo': 456,
},
}
```
Note that a plugin must be listed in `PLUGINS` for its configuration to take effect.
---
## RELEASE_CHECK_URL
Default: None (disabled)
This parameter defines the URL of the repository that will be checked for new NetBox releases. When a new release is detected, a message will be displayed to administrative users on the home page. This can be set to the official repository (`'https://api.github.com/repos/netbox-community/netbox/releases'`) or a custom fork. Set this to `None` to disable automatic update checks.
!!! note
The URL provided **must** be compatible with the [GitHub REST API](https://docs.github.com/en/rest).
---
## REPORTS_ROOT
Default: `$INSTALL_ROOT/netbox/reports/`
The file path to the location where [custom reports](../customization/reports.md) will be kept. By default, this is the `netbox/reports/` directory within the base NetBox installation path.
---
## RQ_DEFAULT_TIMEOUT
Default: `300`
The maximum execution time of a background task (such as running a custom script), in seconds.
---
## SCRIPTS_ROOT
Default: `$INSTALL_ROOT/netbox/scripts/`
The file path to the location where [custom scripts](../customization/custom-scripts.md) will be kept. By default, this is the `netbox/scripts/` directory within the base NetBox installation path.
---
## SESSION_COOKIE_NAME
Default: `sessionid`
The name used for the session cookie. See the [Django documentation](https://docs.djangoproject.com/en/stable/ref/settings/#session-cookie-name) for more detail.
---
## SESSION_FILE_PATH
Default: None
HTTP session data is used to track authenticated users when they access NetBox. By default, NetBox stores session data in its PostgreSQL database. However, this inhibits authentication to a standby instance of NetBox without write access to the database. Alternatively, a local file path may be specified here and NetBox will store session data as files instead of using the database. Note that the NetBox system user must have read and write permissions to this path.
---
## STORAGE_BACKEND
Default: None (local storage)
The backend storage engine for handling uploaded files (e.g. image attachments). NetBox supports integration with the [`django-storages`](https://django-storages.readthedocs.io/en/stable/) package, which provides backends for several popular file storage services. If not configured, local filesystem storage will be used.
The configuration parameters for the specified storage backend are defined under the `STORAGE_CONFIG` setting.
---
## STORAGE_CONFIG
Default: Empty
A dictionary of configuration parameters for the storage backend configured as `STORAGE_BACKEND`. The specific parameters to be used here are specific to each backend; see the [`django-storages` documentation](https://django-storages.readthedocs.io/en/stable/) for more detail.
If `STORAGE_BACKEND` is not defined, this setting will be ignored.
---
## TIME_ZONE
Default: UTC
The time zone NetBox will use when dealing with dates and times. It is recommended to use UTC time unless you have a specific need to use a local time zone. Please see the [list of available time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
---
## Date and Time Formatting
You may define custom formatting for date and times. For detailed instructions on writing format strings, please see [the Django documentation](https://docs.djangoproject.com/en/stable/ref/templates/builtins/#date). Default formats are listed below.
```python
DATE_FORMAT = 'N j, Y' # June 26, 2016
SHORT_DATE_FORMAT = 'Y-m-d' # 2016-06-26
TIME_FORMAT = 'g:i a' # 1:23 p.m.
SHORT_TIME_FORMAT = 'H:i:s' # 13:23:00
DATETIME_FORMAT = 'N j, Y g:i a' # June 26, 2016 1:23 p.m.
A list of installed [NetBox plugins](../plugins/index.md) to enable. Plugins will not take effect unless they are listed here.
!!! warning
Plugins extend NetBox by allowing external code to run with the same access and privileges as NetBox itself. Only install plugins from trusted sources. The NetBox maintainers make absolutely no guarantees about the integrity or security of your installation with plugins enabled.
---
## PLUGINS_CONFIG
Default: Empty
This parameter holds configuration settings for individual NetBox plugins. It is defined as a dictionary, with each key using the name of an installed plugin. The specific parameters supported are unique to each plugin: Reference the plugin's documentation to determine the supported parameters. An example configuration is shown below:
```python
PLUGINS_CONFIG={
'plugin1':{
'foo':123,
'bar':True
},
'plugin2':{
'foo':456,
},
}
```
Note that a plugin must be listed in `PLUGINS` for its configuration to take effect.
@@ -4,6 +4,14 @@ The configuration parameters listed here control remote authentication for NetBo
---
## REMOTE_AUTH_AUTO_CREATE_GROUPS
Default: `False`
If true, NetBox will automatically create groups specified in the `REMOTE_AUTH_GROUP_HEADER` header if they don't already exist. (Requires `REMOTE_AUTH_ENABLED`.)
---
## REMOTE_AUTH_AUTO_CREATE_USER
Default: `False`
@@ -16,7 +24,7 @@ If true, NetBox will automatically create local accounts for users authenticated
This is the Python path to the custom [Django authentication backend](https://docs.djangoproject.com/en/stable/topics/auth/customizing/) to use for external user authentication. NetBox provides two built-in backends (listed below), though custom authentication backends may also be provided by other packages or plugins.
This is the Python path to the custom [Django authentication backend](https://docs.djangoproject.com/en/stable/topics/auth/customizing/) to use for external user authentication. NetBox provides two built-in backends (listed below), though custom authentication backends may also be provided by other packages or plugins. Provide a string for a single backend, or an iterable for multiple backends, which will be attempted in the order given.
*`netbox.authentication.RemoteUserBackend`
*`netbox.authentication.LDAPBackend`
@@ -47,6 +55,22 @@ NetBox can be configured to support remote user authentication by inferring user
---
## REMOTE_AUTH_GROUP_HEADER
Default: `'HTTP_REMOTE_USER_GROUP'`
When remote user authentication is in use, this is the name of the HTTP header which informs NetBox of the currently authenticated user. For example, to use the request header `X-Remote-User-Groups` it needs to be set to `HTTP_X_REMOTE_USER_GROUPS`. (Requires `REMOTE_AUTH_ENABLED` and `REMOTE_AUTH_GROUP_SYNC_ENABLED` )
---
## REMOTE_AUTH_GROUP_SEPARATOR
Default: `|` (Pipe)
The Separator upon which `REMOTE_AUTH_GROUP_HEADER` gets split into individual Groups. This needs to be coordinated with your authentication Proxy. (Requires `REMOTE_AUTH_ENABLED` and `REMOTE_AUTH_GROUP_SYNC_ENABLED` )
---
## REMOTE_AUTH_GROUP_SYNC_ENABLED
Default: `False`
@@ -61,13 +85,32 @@ Default: `'HTTP_REMOTE_USER'`
When remote user authentication is in use, this is the name of the HTTP header which informs NetBox of the currently authenticated user. For example, to use the request header `X-Remote-User` it needs to be set to `HTTP_X_REMOTE_USER`. (Requires `REMOTE_AUTH_ENABLED`.)
!!! warning Verify Header Compatibility
Some WSGI servers may drop headers which contain unsupported characters. For instance, gunicorn v22.0 and later silently drops HTTP headers containing underscores. This behavior can be disabled by changing gunicorn's [`header_map`](https://docs.gunicorn.org/en/stable/settings.html#header-map) setting to `dangerous`.
---
## REMOTE_AUTH_GROUP_HEADER
## REMOTE_AUTH_USER_EMAIL
Default: `'HTTP_REMOTE_USER_GROUP'`
Default: `'HTTP_REMOTE_USER_EMAIL'`
When remote user authentication is in use, this is the name of the HTTP header which informs NetBox of the currently authenticated user. For example, to use the request header `X-Remote-User-Groups` it needs to be set to `HTTP_X_REMOTE_USER_GROUPS`. (Requires `REMOTE_AUTH_ENABLED` and `REMOTE_AUTH_GROUP_SYNC_ENABLED`)
When remote user authentication is in use, this is the name of the HTTP header which informs NetBox of the email address of the currently authenticated user. For example, to use the request header `X-Remote-User-Email` it needs to be set to `HTTP_X_REMOTE_USER_EMAIL`. (Requires `REMOTE_AUTH_ENABLED`.)
---
## REMOTE_AUTH_USER_FIRST_NAME
Default: `'HTTP_REMOTE_USER_FIRST_NAME'`
When remote user authentication is in use, this is the name of the HTTP header which informs NetBox of the first name of the currently authenticated user. For example, to use the request header `X-Remote-User-First-Name` it needs to be set to `HTTP_X_REMOTE_USER_FIRST_NAME`. (Requires `REMOTE_AUTH_ENABLED`.)
---
## REMOTE_AUTH_USER_LAST_NAME
Default: `'HTTP_REMOTE_USER_LAST_NAME'`
When remote user authentication is in use, this is the name of the HTTP header which informs NetBox of the last name of the currently authenticated user. For example, to use the request header `X-Remote-User-Last-Name` it needs to be set to `HTTP_X_REMOTE_USER_LAST_NAME`. (Requires `REMOTE_AUTH_ENABLED`.)
---
@@ -100,11 +143,3 @@ The list of groups that promote an remote User to Staff on Login. If group isn't
Default: `[]` (Empty list)
The list of users that get promoted to Staff on Login. If user isn't present in list on next Login, the Role gets revoked. (Requires `REMOTE_AUTH_ENABLED` and `REMOTE_AUTH_GROUP_SYNC_ENABLED` )
---
## REMOTE_AUTH_GROUP_SEPARATOR
Default: `|` (Pipe)
The Seperator upon which `REMOTE_AUTH_GROUP_HEADER` gets split into individual Groups. This needs to be coordinated with your authentication Proxy. (Requires `REMOTE_AUTH_ENABLED` and `REMOTE_AUTH_GROUP_SYNC_ENABLED` )
NetBox requires access to a PostgreSQL 10 or later database service to store data. This service can run locally on the NetBox server or on a remote system. The following parameters must be defined within the `DATABASE` dictionary:
NetBox requires access to a PostgreSQL 12 or later database service to store data. This service can run locally on the NetBox server or on a remote system. The following parameters must be defined within the `DATABASE` dictionary:
* `NAME` - Database name
* `USER` - PostgreSQL username
@@ -33,11 +33,13 @@ NetBox requires access to a PostgreSQL 10 or later database service to store dat
* `HOST` - Name or IP address of the database server (use `localhost` if running locally)
* `PORT` - TCP port of the PostgreSQL service; leave blank for default port (TCP/5432)
* `CONN_MAX_AGE` - Lifetime of a [persistent database connection](https://docs.djangoproject.com/en/stable/ref/databases/#persistent-connections), in seconds (300 is the default)
* `ENGINE` - The database backend to use; must be a PostgreSQL-compatible backend (e.g. `django.db.backends.postgresql`)
NetBox supports all PostgreSQL database options supported by the underlying Django framework. For a complete list of available parameters, please see [the Django documentation](https://docs.djangoproject.com/en/stable/ref/settings/#databases).
!!! warning
Make sure to use a PostgreSQL-compatible backend for the ENGINE setting. If you don't specify an ENGINE, the default will be django.db.backends.postgresql.
---
## REDIS
[Redis](https://redis.io/) is an in-memory data store similar to memcached. While Redis has been an optional component of
NetBox since the introduction of webhooks in version 2.4, it is required starting in 2.6 to support NetBox's caching
functionality (as well as other planned features). In 2.7, the connection settings were broken down into two sections for
task queuing and caching, allowing the user to connect to different Redis instances/databases per feature.
[Redis](https://redis.io/) is a lightweight in-memory data store similar to memcached. NetBox employs Redis for background task queuing and other features.
Redis is configured using a configuration setting similar to `DATABASE` and these settings are the same for both of the `tasks` and `caching` subsections:
* `HOST` - Name or IP address of the Redis server (use `localhost` if running locally)
* `PORT` - TCP port of the Redis service; leave blank for default port (6379)
* `USERNAME` - Redis username (if set)
* `PASSWORD` - Redis password (if set)
* `DATABASE` - Numeric database ID
* `SSL` - Use SSL connection to Redis
@@ -75,6 +78,7 @@ REDIS = {
'tasks': {
'HOST': 'redis.example.com',
'PORT': 1234,
'USERNAME': 'netbox',
'PASSWORD': 'foobar',
'DATABASE': 0,
'SSL': False,
@@ -82,6 +86,7 @@ REDIS = {
'caching': {
'HOST': 'localhost',
'PORT': 6379,
'USERNAME': '',
'PASSWORD': '',
'DATABASE': 1,
'SSL': False,
@@ -89,15 +94,25 @@ REDIS = {
}
```
!!! note
If you are upgrading from a NetBox release older than v2.7.0, please note that the Redis connection configuration
settings have changed. Manual modification to bring the `REDIS` section inline with the above specification is
necessary
!!! warning
It is highly recommended to keep the task and cache databases separate. Using the same database number on the
same Redis instance for both may result in queued background tasks being lost during cache flushing events.
### UNIX Socket Support
Redis may alternatively be configured by specifying a complete URL instead of individual components. This approach supports the use of a UNIX socket connection. For example:
```python
REDIS = {
'tasks': {
'URL': 'unix:///run/redis-netbox/redis.sock?db=0'
},
'caching': {
'URL': 'unix:///run/redis-netbox/redis.sock?db=1'
},
}
```
### Using Redis Sentinel
If you are using [Redis Sentinel](https://redis.io/topics/sentinel) for high-availability purposes, there is minimal
@@ -141,8 +156,6 @@ REDIS = {
## SECRET_KEY
This is a secret, random string used to assist in the creation new cryptographic hashes for passwords and HTTP cookies. The key defined here should not be shared outside of the configuration file. `SECRET_KEY` can be changed at any time, however be aware that doing so will invalidate all existing sessions.
This is a secret, pseudorandom string used to assist in the creation new cryptographic hashes for passwords and HTTP cookies. The key defined here should not be shared outside the configuration file. `SECRET_KEY` can be changed at any time without impacting stored data, however be aware that doing so will invalidate all existing user sessions. NetBox deployments comprising multiple nodes must have the same secret key configured on all nodes.
Please note that this key is **not** used directly for hashing user passwords or for the encrypted storage of secret data in NetBox.
`SECRET_KEY` should be at least 50 characters in length and contain a random mix of letters, digits, and symbols. The script located at `$INSTALL_ROOT/netbox/generate_secret_key.py` may be used to generate a suitable key.
`SECRET_KEY`**must** be at least 50 characters in length, and should contain a mix of letters, digits, and symbols. The script located at `$INSTALL_ROOT/netbox/generate_secret_key.py` may be used to generate a suitable key. Please note that this key is **not** used directly for hashing user passwords or for the encrypted storage of secret data in NetBox.
If disabled, the values of API tokens will not be displayed after each token's initial creation. A user **must** record the value of a token prior to its creation, or it will be lost. Note that this affects _all_ users, regardless of assigned permissions.
A list of permitted URL schemes referenced when rendering links within NetBox. Note that only the schemes specified in this list will be accepted: If adding your own, be sure to replicate all the default values as well (excluding those schemes which are not desirable).
---
## AUTH_PASSWORD_VALIDATORS
This parameter acts as a pass-through for configuring Django's built-in password validators for local user accounts. If configured, these will be applied whenever a user's password is updated to ensure that it meets minimum criteria such as length or complexity. An example is provided below. For more detail on the available options, please see [the Django documentation](https://docs.djangoproject.com/en/stable/topics/auth/passwords/#password-validation).
If True, cross-origin resource sharing (CORS) requests will be accepted from all origins. If False, a whitelist will be used (see below).
---
## CORS_ORIGIN_WHITELIST
## CORS_ORIGIN_REGEX_WHITELIST
These settings specify a list of origins that are authorized to make cross-site API requests. Use
`CORS_ORIGIN_WHITELIST` to define a list of exact hostnames, or `CORS_ORIGIN_REGEX_WHITELIST` to define a set of regular
expressions. (These settings have no effect if `CORS_ORIGIN_ALLOW_ALL` is True.) For example:
```python
CORS_ORIGIN_WHITELIST=[
'https://example.com',
]
```
---
## CSRF_COOKIE_NAME
Default: `csrftoken`
The name of the cookie to use for the cross-site request forgery (CSRF) authentication token. See the [Django documentation](https://docs.djangoproject.com/en/stable/ref/settings/#csrf-cookie-name) for more detail.
---
## CSRF_COOKIE_SECURE
Default: False
If true, the cookie employed for cross-site request forgery (CSRF) protection will be marked as secure, meaning that it can only be sent across an HTTPS connection.
---
## CSRF_TRUSTED_ORIGINS
Default: `[]`
Defines a list of trusted origins for unsafe (e.g. `POST`) requests. This is a pass-through to Django's [`CSRF_TRUSTED_ORIGINS`](https://docs.djangoproject.com/en/4.0/ref/settings/#std:setting-CSRF_TRUSTED_ORIGINS) setting. Note that each host listed must specify a scheme (e.g. `http://` or `https://).
```python
CSRF_TRUSTED_ORIGINS = (
'http://netbox.local',
'https://netbox.local',
)
```
---
## DEFAULT_PERMISSIONS
Default:
```python
{
'users.view_token': ({'user': '$user'},),
'users.add_token': ({'user': '$user'},),
'users.change_token': ({'user': '$user'},),
'users.delete_token': ({'user': '$user'},),
}
```
This parameter defines object permissions that are applied automatically to _any_ authenticated user, regardless of what permissions have been defined in the database. By default, this parameter is defined to allow all users to manage their own API tokens, however it can be overriden for any purpose.
For example, to allow all users to create a device role beginning with the word "temp," you could configure the following:
```python
DEFAULT_PERMISSIONS = {
'dcim.add_devicerole': (
{'name__startswith': 'temp'},
)
}
```
!!! warning
Setting a custom value for this parameter will overwrite the default permission mapping shown above. If you want to retain the default mapping, be sure to reproduce it in your custom configuration.
---
## EXEMPT_VIEW_PERMISSIONS
Default: Empty list
A list of NetBox models to exempt from the enforcement of view permissions. Models listed here will be viewable by all users, both authenticated and anonymous.
List models in the form `<app>.<model>`. For example:
```python
EXEMPT_VIEW_PERMISSIONS = [
'dcim.site',
'dcim.region',
'ipam.prefix',
]
```
To exempt _all_ models from view permission enforcement, set the following. (Note that `EXEMPT_VIEW_PERMISSIONS` must be an iterable.)
```python
EXEMPT_VIEW_PERMISSIONS = ['*']
```
!!! note
Using a wildcard will not affect certain potentially sensitive models, such as user permissions. If there is a need to exempt these models, they must be specified individually.
---
## LOGIN_PERSISTENCE
Default: False
If true, the lifetime of a user's authentication session will be automatically reset upon each valid request. For example, if [`LOGIN_TIMEOUT`](#login_timeout) is configured to 14 days (the default), and a user whose session is due to expire in five days makes a NetBox request (with a valid session cookie), the session's lifetime will be reset to 14 days.
Note that enabling this setting causes NetBox to update a user's session in the database (or file, as configured per [`SESSION_FILE_PATH`](#session_file_path)) with each request, which may introduce significant overhead in very active environments. It also permits an active user to remain authenticated to NetBox indefinitely.
---
## LOGIN_REQUIRED
Default: True
When enabled, only authenticated users are permitted to access any part of NetBox. Disabling this will allow unauthenticated users to access most areas of NetBox (but not make any changes).
!!! info "Changed in NetBox v4.0.2"
Prior to NetBox v4.0.2, this setting was disabled by default.
---
## LOGIN_TIMEOUT
Default: 1209600 seconds (14 days)
The lifetime (in seconds) of the authentication cookie issued to a NetBox user upon login.
---
## LOGOUT_REDIRECT_URL
Default: `'home'`
The view name or URL to which a user is redirected after logging out.
---
## SECURE_HSTS_INCLUDE_SUBDOMAINS
Default: False
If true, the `includeSubDomains` directive will be included in the HTTP Strict Transport Security (HSTS) header. This directive instructs the browser to apply the HSTS policy to all subdomains of the current domain.
---
## SECURE_HSTS_PRELOAD
Default: False
If true, the `preload` directive will be included in the HTTP Strict Transport Security (HSTS) header. This directive instructs the browser to preload the site in HTTPS. Browsers that use the HSTS preload list will force the site to be accessed via HTTPS even if the user types HTTP in the address bar.
---
## SECURE_HSTS_SECONDS
Default: 0
If set to a non-zero integer value, the SecurityMiddleware sets the HTTP Strict Transport Security (HSTS) header on all responses that do not already have it. This will instruct the browser that the website must be accessed via HTTPS, blocking any HTTP request.
---
## SECURE_SSL_REDIRECT
Default: False
If true, all non-HTTPS requests will be automatically redirected to use HTTPS.
!!! warning
Ensure that your frontend HTTP daemon has been configured to forward the HTTP scheme correctly before enabling this option. An incorrectly configured frontend may result in a looping redirect.
---
## SESSION_COOKIE_NAME
Default: `sessionid`
The name used for the session cookie. See the [Django documentation](https://docs.djangoproject.com/en/stable/ref/settings/#session-cookie-name) for more detail.
---
## SESSION_COOKIE_SECURE
Default: False
If true, the cookie employed for session authentication will be marked as secure, meaning that it can only be sent across an HTTPS connection.
---
## SESSION_FILE_PATH
Default: None
HTTP session data is used to track authenticated users when they access NetBox. By default, NetBox stores session data in its PostgreSQL database. However, this inhibits authentication to a standby instance of NetBox without write access to the database. Alternatively, a local file path may be specified here and NetBox will store session data as files instead of using the database. Note that the NetBox system user must have read and write permissions to this path.
The base URL path to use when accessing NetBox. Do not include the scheme or domain name. For example, if installed at https://example.com/netbox/, set:
```python
BASE_PATH='netbox/'
```
---
## DEFAULT_LANGUAGE
Default: `en-us` (US English)
Defines the default preferred language/locale for requests that do not specify one. (This parameter maps to Django's [`LANGUAGE_CODE`](https://docs.djangoproject.com/en/stable/ref/settings/#language-code) internal setting.)
---
## DOCS_ROOT
Default: `$INSTALL_ROOT/docs/`
The filesystem path to NetBox's documentation. This is used when presenting context-sensitive documentation in the web UI. By default, this will be the `docs/` directory within the root NetBox installation path. (Set this to `None` to disable the embedded documentation.)
---
## EMAIL
In order to send email, NetBox needs an email server configured. The following items can be defined within the `EMAIL` configuration parameter:
*`SERVER` - Hostname or IP address of the email server (use `localhost` if running locally)
*`PORT` - TCP port to use for the connection (default: `25`)
*`USERNAME` - Username with which to authenticate
*`PASSWORD` - Password with which to authenticate
*`USE_SSL` - Use SSL when connecting to the server (default: `False`)
*`USE_TLS` - Use TLS when connecting to the server (default: `False`)
*`SSL_CERTFILE` - Path to the PEM-formatted SSL certificate file (optional)
*`SSL_KEYFILE` - Path to the PEM-formatted SSL private key file (optional)
*`TIMEOUT` - Amount of time to wait for a connection, in seconds (default: `10`)
*`FROM_EMAIL` - Sender address for emails sent by NetBox
!!! note
The `USE_SSL` and `USE_TLS` parameters are mutually exclusive.
Email is sent from NetBox only for critical events or if configured for [logging](#logging). If you would like to test the email server configuration, Django provides a convenient [send_mail()](https://docs.djangoproject.com/en/stable/topics/email/#send-mail) function accessible within the NetBox shell:
```no-highlight
# python ./manage.py nbshell
>>> from django.core.mail import send_mail
>>> send_mail(
'Test Email Subject',
'Test Email Body',
'noreply-netbox@example.com',
['users@example.com'],
fail_silently=False
)
```
---
## HTTP_PROXIES
Default: None
A dictionary of HTTP proxies to use for outbound requests originating from NetBox (e.g. when sending webhook requests). Proxies should be specified by schema (HTTP and HTTPS) as per the [Python requests library documentation](https://requests.readthedocs.io/en/latest/user/advanced/#proxies). For example:
```python
HTTP_PROXIES = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
}
```
---
## INTERNAL_IPS
Default: `('127.0.0.1', '::1')`
A list of IP addresses recognized as internal to the system, used to control the display of debugging output. For
example, the debugging toolbar will be viewable only when a client is accessing NetBox from one of the listed IP
addresses (and [`DEBUG`](#debug) is true).
---
## JINJA2_FILTERS
Default: `{}`
A dictionary of custom jinja2 filters with the key being the filter name and the value being a callable. For more information see the [Jinja2 documentation](https://jinja.palletsprojects.com/en/3.1.x/api/#custom-filters). For example:
```python
def uppercase(x):
return str(x).upper()
JINJA2_FILTERS = {
'uppercase': uppercase,
}
```
---
## LOGGING
By default, all messages of INFO severity or higher will be logged to the console. Additionally, if [`DEBUG`](#debug) is False and email access has been configured, ERROR and CRITICAL messages will be emailed to the users defined in [`ADMINS`](#admins).
The Django framework on which NetBox runs allows for the customization of logging format and destination. Please consult the [Django logging documentation](https://docs.djangoproject.com/en/stable/topics/logging/) for more information on configuring this setting. Below is an example which will write all INFO and higher messages to a local file:
```python
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': '/var/log/netbox.log',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'INFO',
},
},
}
```
### Available Loggers
* `netbox.<app>.<model>` - Generic form for model-specific log messages
* `netbox.auth.*` - Authentication events
* `netbox.api.views.*` - Views which handle business logic for the REST API
* `netbox.views.*` - Views which handle business logic for the web UI
---
## MEDIA_ROOT
Default: $INSTALL_ROOT/netbox/media/
The file path to the location where media files (such as image attachments) are stored. By default, this is the `netbox/media/` directory within the base NetBox installation path.
---
## REPORTS_ROOT
Default: `$INSTALL_ROOT/netbox/reports/`
The file path to the location where [custom reports](../customization/reports.md) will be kept. By default, this is the `netbox/reports/` directory within the base NetBox installation path.
---
## SCRIPTS_ROOT
Default: `$INSTALL_ROOT/netbox/scripts/`
The file path to the location where [custom scripts](../customization/custom-scripts.md) will be kept. By default, this is the `netbox/scripts/` directory within the base NetBox installation path.
The dotted path to the desired search backend class. `CachedValueSearchBackend` is currently the only search backend provided in NetBox, however this setting can be used to enable a custom backend.
---
## STORAGE_BACKEND
Default: None (local storage)
The backend storage engine for handling uploaded files (e.g. image attachments). NetBox supports integration with the [`django-storages`](https://django-storages.readthedocs.io/en/stable/) and [`django-storage-swift`](https://github.com/dennisv/django-storage-swift) packages, which provide backends for several popular file storage services. If not configured, local filesystem storage will be used.
The configuration parameters for the specified storage backend are defined under the `STORAGE_CONFIG` setting.
---
## STORAGE_CONFIG
Default: Empty
A dictionary of configuration parameters for the storage backend configured as `STORAGE_BACKEND`. The specific parameters to be used here are specific to each backend; see the documentation for your selected backend ([`django-storages`](https://django-storages.readthedocs.io/en/stable/) or [`django-storage-swift`](https://github.com/dennisv/django-storage-swift)) for more detail.
If `STORAGE_BACKEND` is not defined, this setting will be ignored.
---
## TIME_ZONE
Default: UTC
The time zone NetBox will use when dealing with dates and times. It is recommended to use UTC time unless you have a specific need to use a local time zone. Please see the [list of available time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
---
## TRANSLATION_ENABLED
Default: True
Enables language translation for the user interface. (This parameter maps to Django's [USE_I18N](https://docs.djangoproject.com/en/stable/ref/settings/#std-setting-USE_I18N) setting.)
Each device type is assigned a number of component templates which define the physical components within a device. These are:
* Console ports
* Console server ports
* Power ports
* Power outlets
* Network interfaces
* Front ports
* Rear ports
* Device bays (which house child devices)
Whenever a new device is created, its components are automatically created per the templates assigned to its device type. For example, a Juniper EX4300-48T device type might have the following component templates defined:
* One template for a console port ("Console")
* Two templates for power ports ("PSU0" and "PSU1")
* 48 templates for 1GE interfaces ("ge-0/0/0" through "ge-0/0/47")
* Four templates for 10GE interfaces ("xe-0/2/0" through "xe-0/2/3")
Once component templates have been created, every new device that you create as an instance of this type will automatically be assigned each of the components listed above.
!!! note
Assignment of components from templates occurs only at the time of device creation. If you modify the templates of a device type, it will not affect devices which have already been created. However, you always have the option of adding, modifying, or deleting components on existing devices.
Each model in NetBox is represented in the database as a discrete table, and each attribute of a model exists as a column within its table. For example, sites are stored in the `dcim_site` table, which has columns named `name`, `facility`, `physical_address`, and so on. As new attributes are added to objects throughout the development of NetBox, tables are expanded to include new rows.
However, some users might want to store additional object attributes that are somewhat esoteric in nature, and that would not make sense to include in the core NetBox database schema. For instance, suppose your organization needs to associate each device with a ticket number correlating it with an internal support system record. This is certainly a legitimate use for NetBox, but it's not a common enough need to warrant including a field for _every_ NetBox installation. Instead, you can create a custom field to hold this data.
Within the database, custom fields are stored as JSON data directly alongside each object. This alleviates the need for complex queries when retrieving objects.
## Creating Custom Fields
Custom fields may be created by navigating to Customization > Custom Fields. NetBox supports many types of custom field:
* Text: Free-form text (intended for single-line use)
* Long text: Free-form of any length; supports Markdown rendering
* Integer: A whole number (positive or negative)
* Decimal: A fixed-precision decimal number (4 decimal places)
* Boolean: True or false
* Date: A date in ISO 8601 format (YYYY-MM-DD)
* Date & time: A date and time in ISO 8601 format (YYYY-MM-DD HH:MM:SS)
* URL: This will be presented as a link in the web UI
* JSON: Arbitrary data stored in JSON format
* Selection: A selection of one of several pre-defined custom choices
* Multiple selection: A selection field which supports the assignment of multiple values
* Object: A single NetBox object of the type defined by `object_type`
* Multiple object: One or more NetBox objects of the type defined by `object_type`
Each custom field must have a name. This should be a simple database-friendly string (e.g. `tps_report`) and may contain only alphanumeric characters and underscores. You may also assign a corresponding human-friendly label (e.g. "TPS report"); the label will be displayed on web forms. A weight is also required: Higher-weight fields will be ordered lower within a form. (The default weight is 100.) If a description is provided, it will appear beneath the field in a form.
Marking a field as required will force the user to provide a value for the field when creating a new object or when saving an existing object. A default value for the field may also be provided. Use "true" or "false" for boolean fields, or the exact value of a choice for selection fields.
A custom field must be assigned to one or more object types, or models, in NetBox. Once created, custom fields will automatically appear as part of these models in the web UI and REST API. Note that not all models support custom fields.
### Filtering
The filter logic controls how values are matched when filtering objects by the custom field. Loose filtering (the default) matches on a partial value, whereas exact matching requires a complete match of the given string to a field's value. For example, exact filtering with the string "red" will only match the exact value "red", whereas loose filtering will match on the values "red", "red-orange", or "bored". Setting the filter logic to "disabled" disables filtering by the field entirely.
### Grouping
Related custom fields can be grouped together within the UI by assigning each the same group name. When at least one custom field for an object type has a group defined, it will appear under the group heading within the custom fields panel under the object view. All custom fields with the same group name will appear under that heading. (Note that the group names must match exactly, or each will appear as a separate heading.)
This parameter has no effect on the API representation of custom field data.
### Visibility & Editing
When creating a custom field, users can control the conditions under which it may be displayed and edited within the NetBox user interface. The following choices are available for controlling the display of a custom field on an object:
* **Always** (default): The custom field is included when viewing an object.
* **If Set**: The custom field is included only if a value has been defined for the object.
* **Hidden**: The custom field will never be displayed within the UI. This option is recommended for fields which are not intended for use by human users.
Additionally, the following options are available for controlling whether custom field values can be altered within the NetBox UI:
* **Yes** (default): The custom field's value may be modified when editing an object.
* **No**: The custom field is displayed for reference when editing an object, but its value may not be modified.
* **Hidden**: The custom field is not displayed when editing an object.
Note that this setting has no impact on the REST or GraphQL APIs: Custom field data will always be available via either API.
### Validation
NetBox supports limited custom validation for custom field values. Following are the types of validation enforced for each field type:
* Text: Regular expression (optional)
* Integer: Minimum and/or maximum value (optional)
* Selection: Must exactly match one of the prescribed choices
### Custom Selection Fields
Each custom selection field must designate a [choice set](../models/extras/customfieldchoiceset.md) containing at least two choices. These are specified as a comma-separated list.
If a default value is specified for a selection field, it must exactly match one of the provided choices. The value of a multiple selection field will always return a list, even if only one value is selected.
### Custom Object Fields
An object or multi-object custom field can be used to refer to a particular NetBox object or objects as the "value" for a custom field. These custom fields must define an `object_type`, which determines the type of object to which custom field instances point.
Custom links allow users to display arbitrary hyperlinks to external content within NetBox object views. These are helpful for cross-referencing related records in systems outside NetBox. For example, you might create a custom link on the device view which links to the current device in a Network Monitoring System (NMS).
Custom links are created by navigating to Customization > Custom Links. Each link is associated with a particular NetBox object type (site, device, prefix, etc.) and will be displayed on relevant views. Each link has display text and a URL, and data from the NetBox item being viewed can be included in the link using [Jinja2 template code](https://jinja2docs.readthedocs.io/en/stable/) through the variable `object`, and custom fields through `object.cf`.
Custom links appear as buttons in the top right corner of the page. Numeric weighting can be used to influence the ordering of links, and each link can be enabled or disabled individually.
!!! warning
Custom links rely on user-created code to generate arbitrary HTML output, which may be dangerous. Only grant permission to create or modify custom links to trusted users.
## Context Data
The following context data is available within the template when rendering a custom link's text or URL.
| `debug` | A boolean indicating whether debugging is enabled |
| `request` | The current WSGI request |
| `user` | The current user (if authenticated) |
| `perms` | The [permissions](https://docs.djangoproject.com/en/stable/topics/auth/default/#permissions) assigned to the user |
While most of the context variables listed above will have consistent attributes, the object will be an instance of the specific object being viewed when the link is rendered. Different models have different fields and properties, so you may need to some research to determine the attributes available for use within your template for a specific object type.
Checking the REST API representation of an object is generally a convenient way to determine what attributes are available. You can also reference the NetBox source code directly for a comprehensive list.
## Conditional Rendering
Only links which render with non-empty text are included on the page. You can employ conditional Jinja2 logic to control the conditions under which a link gets rendered.
For example, if you only want to display a link for active devices, you could set the link text to
```jinja2
{% if object.status == 'active' %}View NMS{% endif %}
```
The link will not appear when viewing a device with any status other than "active."
As another example, if you wanted to show only devices belonging to a certain manufacturer, you could do something like this:
```jinja2
{% if object.device_type.manufacturer.name == 'Cisco' %}View NMS{% endif %}
```
The link will only appear when viewing a device with a manufacturer name of "Cisco."
## Link Groups
Group names can be specified to organize links into groups. Links with the same group name will render as a dropdown menu beneath a single button bearing the name of the group.
## Table Columns
Custom links can also be included in object tables by selecting the desired links from the table configuration form. When displayed, each link will render as a hyperlink for its corresponding object. When exported (e.g. as CSV data), each link render only its URL.
@@ -5,8 +5,17 @@ Custom scripting was introduced to provide a way for users to execute custom log
* Automatically populate new devices and cables in preparation for a new site deployment
* Create a range of new reserved prefixes or IP addresses
* Fetch data from an external source and import it to NetBox
* Update objects with invalid or incomplete data
Custom scripts are Python code and exist outside of the official NetBox code base, so they can be updated and changed without interfering with the core NetBox installation. And because they're completely custom, there is no inherent limitation on what a script can accomplish.
They can also be used as a mechanism for validating the integrity of data within NetBox. Script authors can define test to check object against specific rules and conditions. For example, you can write script to check that:
* All top-of-rack switches have a console connection
* Every router has a loopback interface with an IP address assigned
* Each interface description conforms to a standard format
* Every site has a minimum set of VLANs defined
* All IP addresses have a parent prefix
Custom scripts are Python code which exists outside the NetBox code base, so they can be updated and changed without interfering with the core NetBox installation. And because they're completely custom, there is no inherent limitation on what a script can accomplish.
## Writing Custom Scripts
@@ -35,12 +44,9 @@ class MyScript(Script):
The `run()` method should accept two arguments:
*`data` - A dictionary containing all of the variable data passed via the web form.
*`data` - A dictionary containing all the variable data passed via the web form.
*`commit` - A boolean indicating whether database changes will be committed.
!!! note
The `commit` argument was introduced in NetBox v2.7.8. Backward compatibility is maintained for scripts which accept only the `data` argument, however beginning with v2.10 NetBox will require the `run()` method of every script to accept both arguments. (Either argument may still be ignored within the method.)
Defining script variables is optional: You may create a script with only a `run()` method if no user input is needed.
Any output generated by the script during its execution will be displayed under the "output" tab in the UI.
@@ -59,12 +65,6 @@ class AnotherCustomScript(Script):
script_order=(MyCustomScript,AnotherCustomScript)
```
## Module Attributes
### `name`
You can define `name` within a script module (the Python file which contains one or more scripts) to set the module name. If `name` is not defined, the module's file name will be used.
## Script Attributes
Script attributes are defined under a class named `Meta` within the script. These are optional, but encouraged.
@@ -79,7 +79,22 @@ A human-friendly description of what your script does.
### `field_order`
By default, script variables will be ordered in the form as they are defined in the script. `field_order` may be defined as an iterable of field names to determine the order in which variables are rendered. Any fields not included in this iterable be listed last.
By default, script variables will be ordered in the form as they are defined in the script. `field_order` may be defined as an iterable of field names to determine the order in which variables are rendered within a default "Script Data" group. Any fields not included in this iterable be listed last. If `fieldsets` is defined, `field_order` will be ignored. A fieldset group for "Script Execution Parameters" will be added to the end of the form by default for the user.
### `fieldsets`
`fieldsets` may be defined as an iterable of field groups and their field names to determine the order in which variables are group and rendered. Any fields not included in this iterable will not be displayed in the form. If `fieldsets` is defined, `field_order` will be ignored. A fieldset group for "Script Execution Parameters" will be added to the end of the fieldsets by default for the user.
An example fieldset definition is provided below:
```python
classMyScript(Script):
classMeta:
fieldsets=(
('First group',('field1','field2','field3')),
('Second group',('field4','field5')),
)
```
### `commit_default`
@@ -89,12 +104,14 @@ The checkbox to commit database changes when executing a script is checked by de
commit_default=False
```
### `scheduling_enabled`
By default, a script can be scheduled for execution at a later time. Setting `scheduling_enabled` to False disables this ability: Only immediate execution will be possible. (This also disables the ability to set a recurring execution interval.)
### `job_timeout`
Set the maximum allowed runtime for the script. If not set, `RQ_DEFAULT_TIMEOUT` will be used.
!!! info "This feature was introduced in v3.2.1"
## Accessing Request Data
Details of the current HTTP request (the one being made to execute the script) are available as the instance attribute `self.request`. This can be used to infer, for example, the user executing the script and the client IP address:
@@ -121,13 +138,101 @@ These two methods will load data in YAML or JSON format, respectively, from file
The Script object provides a set of convenient functions for recording messages at different severity levels:
*`log_debug`
*`log_success`
*`log_info`
*`log_warning`
*`log_failure`
*`log_debug(message=None, obj=None)`
*`log_success(message=None, obj=None)`
*`log_info(message=None, obj=None)`
*`log_warning(message=None, obj=None)`
*`log_failure(message=None, obj=None)`
Log messages are returned to the user upon execution of the script. Markdown rendering is supported for log messages.
Log messages are returned to the user upon execution of the script. Markdown rendering is supported for log messages. A message may optionally be associated with a particular object by passing it as the second argument to the logging method.
## Test Methods
A script can define one or more test methods to report on certain conditions. All test methods must have a name beginning with `test_` and accept no arguments beyond `self`.
These methods are detected and run automatically when the script is executed, unless its `run()` method has been overridden. (When overriding `run()`, `run_tests()` can be called to run all test methods present in the script.)
Calling any of these logging methods without a message will increment the relevant counter, but will not generate an output line in the script's log.
!!! info
This functionality was ported from [legacy reports](./reports.md) in NetBox v4.0.
### Example
```
from dcim.choices import DeviceStatusChoices
from dcim.models import ConsolePort, Device, PowerPort
from extras.scripts import Script
class DeviceConnectionsReport(Script):
description = "Validate the minimum physical connections for each device"
def test_console_connection(self):
# Check that every console port for every active device has a connection defined.
active = DeviceStatusChoices.STATUS_ACTIVE
for console_port in ConsolePort.objects.prefetch_related('device').filter(device__status=active):
if not console_port.connected_endpoints:
self.log_failure(
f"No console connection defined for {console_port.name}",
console_port.device,
)
elif not console_port.connection_status:
self.log_warning(
f"Console connection for {console_port.name} marked as planned",
console_port.device,
)
else:
self.log_success("Passed", console_port.device)
def test_power_connections(self):
# Check that every active device has at least two connected power supplies.
for device in Device.objects.filter(status=DeviceStatusChoices.STATUS_ACTIVE):
connected_ports = 0
for power_port in PowerPort.objects.filter(device=device):
if power_port.connected_endpoints:
connected_ports += 1
if not power_port.path.is_active:
self.log_warning(
f"Power connection for {power_port.name} marked as planned",
device,
)
if connected_ports < 2:
self.log_failure(
f"{connected_ports} connected power supplies found (2 needed)",
device,
)
else:
self.log_success("Passed", device)
```
## Change Logging
To generate the correct change log data when editing an existing object, a snapshot of the object must be taken before making any changes to the object.
```python
ifobj.pkandhasattr(obj,'snapshot'):
obj.snapshot()
obj.property="New Value"
obj.full_clean()
obj.save()
```
## Error handling
Sometimes things go wrong and a script will run into an `Exception`. If that happens and an uncaught exception is raised by the custom script, the execution is aborted and a full stack trace is reported.
Although this is helpful for debugging, in some situations it might be required to cleanly abort the execution of a custom script (e.g. because of invalid input data) and thereby make sure no changes are performed on the database. In this case the script can throw an `AbortScript` exception, which will prevent the stack trace from being reported, but still terminating the script's execution and reporting a given error message.
```python
fromutilities.exceptionsimportAbortScript
ifsome_error:
raiseAbortScript("Some meaningful error message")
```
## Variable Reference
@@ -195,6 +300,7 @@ A particular object within NetBox. Each ObjectVar must specify a particular mode
*`model` - The model class
*`query_params` - A dictionary of query parameters to use when retrieving available options (optional)
*`context` - A custom dictionary mapping template context variables to fields, used when rendering `<option>` elements within the dropdown menu (optional; see below)
*`null_option` - A label representing a "null" or empty choice (optional)
To limit the selections available within the list, additional query parameters can be passed as the `query_params` dictionary. For example, to show only devices with an "active" status:
@@ -222,6 +328,22 @@ site = ObjectVar(
)
```
#### Context Variables
Custom context variables can be passed to override the default attribute names or to display additional information, such as a parent object.
| `value` | `"id"` | The attribute which contains the option's value |
| `label` | `"display"` | The attribute used as the option's human-friendly label |
| `description` | `"description"` | The attribute to use as a description |
| `depth`[^1] | `"_depth"` | The attribute which indicates an object's depth within a recursive hierarchy |
| `disabled` | -- | The attribute which, if true, signifies that the option should be disabled |
| `parent` | -- | The attribute which represents the object's parent object |
| `count`[^1] | -- | The attribute which contains a numeric count of related objects |
[^1]: The value of this attribute must be a positive integer
### MultiObjectVar
Similar to `ObjectVar`, but allows for the selection of multiple objects.
@@ -245,16 +367,24 @@ An IPv4 or IPv6 network with a mask. Returns a `netaddr.IPNetwork` object. Two a
*`min_prefix_length` - Minimum length of the mask
*`max_prefix_length` - Maximum length of the mask
### DateVar
A calendar date. Returns a `datetime.date` object.
### DateTimeVar
A complete date & time. Returns a `datetime.datetime` object.
## Running Custom Scripts
!!! note
To run a custom script, a user must be assigned the `extras.run_script` permission. This is achieved by assigning the user (or group) a permission on the Script object and specifying the `run` action in the admin UI as shown below.
To run a custom script, a user must be assigned permissions for `Extras > Script`, `Extras > Script Module`, and `Core > Managed File` objects. They must also be assigned the `extras.run_script` permission. This is achieved by assigning the user (or group) a permission on the Script object and specifying the `run` action in "Permissions" as shown below.


### Via the Web UI
Custom scripts can be run via the web UI by navigating to the script, completing any required form data, and clicking the "run script" button.
Custom scripts can be run via the web UI by navigating to the script, completing any required form data, and clicking the "run script" button. It is possible to schedule a script to be executed at specified time in the future. A scheduled script can be canceled by deleting the associated job result object.
The required ``<module>.<script>`` argument is the script to run where ``<module>`` is the name of the python file in the ``scripts`` directory without the ``.py`` extension and ``<script>`` is the name of the script class in the ``<module>`` to run.
@@ -336,6 +468,7 @@ class NewBranchScript(Script):
slug=slugify(data['site_name']),
status=SiteStatusChoices.STATUS_PLANNED
)
site.full_clean()
site.save()
self.log_success(f"Created new site: {site}")
@@ -347,8 +480,9 @@ class NewBranchScript(Script):
@@ -4,7 +4,7 @@ NetBox validates every object prior to it being written to the database to ensur
## Custom Validation Rules
Custom validation rules are expressed as a mapping of model attributes to a set of rules to which that attribute must conform. For example:
Custom validation rules are expressed as a mapping of object attributes to a set of rules to which that attribute must conform. For example:
```json
{
@@ -17,6 +17,8 @@ Custom validation rules are expressed as a mapping of model attributes to a set
This defines a custom validator which checks that the length of the `name` attribute for an object is at least five characters long, and no longer than 30 characters. This validation is executed _after_ NetBox has performed its own internal validation.
### Validation Types
The `CustomValidator` class supports several validation types:
*`min`: Minimum value
@@ -26,6 +28,8 @@ The `CustomValidator` class supports several validation types:
*`regex`: Application of a [regular expression](https://en.wikipedia.org/wiki/Regular_expression)
*`required`: A value must be specified
*`prohibited`: A value must _not_ be specified
*`eq`: A value must be equal to the specified value
*`neq`: A value must _not_ be equal to the specified value
The `min` and `max` types should be defined for numeric values, whereas `min_length`, `max_length`, and `regex` are suitable for character strings (text values). The `required` and `prohibited` validators may be used for any field, and should be passed a value of `True`.
@@ -34,14 +38,14 @@ The `min` and `max` types should be defined for numeric values, whereas `min_len
### Custom Validation Logic
There may be instances where the provided validation types are insufficient. NetBox provides a `CustomValidator` class which can be extended to enforce arbitrary validation logic by overriding its `validate()` method, and calling `fail()` when an unsatisfactory condition is detected.
There may be instances where the provided validation types are insufficient. NetBox provides a `CustomValidator` class which can be extended to enforce arbitrary validation logic by overriding its `validate()` method, and calling `fail()` when an unsatisfactory condition is detected. The `validate()` method should accept an instance (the object being saved) as well as the current request effecting the change.
self.fail("Active sites must have a description set!",field='status')
```
@@ -50,7 +54,7 @@ The `fail()` method may optionally specify a field with which to associate the s
## Assigning Custom Validators
Custom validators are associated with specific NetBox models under the [CUSTOM_VALIDATORS](../configuration/dynamic-settings.md#custom_validators) configuration parameter. There are three manners by which custom validation rules can be defined:
Custom validators are associated with specific NetBox models under the [CUSTOM_VALIDATORS](../configuration/data-validation.md#custom_validators) configuration parameter. There are three manners by which custom validation rules can be defined:
1. Plain JSON mapping (no custom logic)
2. Dotted path to a custom validator class
@@ -80,7 +84,42 @@ CUSTOM_VALIDATORS = {
}
```
### Dotted Path
#### Referencing Related Object Attributes
!!! info "This feature was introduced in NetBox v4.0."
The attributes of a related object can be referenced by specifying a dotted path. For example, to reference the name of a region to which a site is assigned, use `region.name`:
```python
CUSTOM_VALIDATORS={
"dcim.site":[
{
"region.name":{
"neq":"New York"
}
}
]
}
```
#### Validating Request Parameters
!!! info "This feature was introduced in NetBox v4.0."
In addition to validating object attributes, custom validators can also match against parameters of the current request (where available). For example, the following rule will permit only the user named "admin" to modify an object:
```json
{
"request.user.username":{
"eq":"admin"
}
}
```
!!! tip
Custom validation should generally not be used to enforce permissions. NetBox provides a robust [object-based permissions](../administration/permissions.md) mechanism which should be used for this purpose.
### Dotted Path to Class
In instances where a custom validator class is needed, it can be referenced by its Python path (relative to NetBox's working directory):
NetBox allows users to define custom templates that can be used when exporting objects. To create an export template, navigate to Customization > Export Templates.
Each export template is associated with a certain type of object. For instance, if you create an export template for VLANs, your custom template will appear under the "Export" button on the VLANs list. Each export template must have a name, and may optionally designate a specific export [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) and/or file extension.
Export templates must be written in [Jinja2](https://jinja.palletsprojects.com/).
!!! note
The name `table` is reserved for internal use.
!!! warning
Export templates are rendered using user-submitted code, which may pose security risks under certain conditions. Only grant permission to create or modify export templates to trusted users.
The list of objects returned from the database when rendering an export template is stored in the `queryset` variable, which you'll typically want to iterate through using a `for` loop. Object properties can be access by name. For example:
```jinja2
{% for rack in queryset %}
Rack: {{ rack.name }}
Site: {{ rack.site.name }}
Height: {{ rack.u_height }}U
{% endfor %}
```
To access custom fields of an object within a template, use the `cf` attribute. For example, `{{ obj.cf.color }}` will return the value (if any) for a custom field named `color` on `obj`.
If you need to use the config context data in an export template, you'll should use the function `get_config_context` to get all the config context data. For example:
```
{% for server in queryset %}
{% set data = server.get_config_context() %}
{{ data.syslog }}
{% endfor %}
```
The `as_attachment` attribute of an export template controls its behavior when rendered. If true, the rendered content will be returned to the user as a downloadable file. If false, it will be displayed within the browser. (This may be handy e.g. for generating HTML content.)
A MIME type and file extension can optionally be defined for each export template. The default MIME type is `text/plain`.
## REST API Integration
When it is necessary to provide authentication credentials (such as when [`LOGIN_REQUIRED`](../configuration/optional-settings.md#login_required) has been enabled), it is recommended to render export templates via the REST API. This allows the client to specify an authentication token. To render an export template via the REST API, make a `GET` request to the model's list endpoint and append the `export` parameter specifying the export template name. For example:
When it is necessary to provide authentication credentials (such as when [`LOGIN_REQUIRED`](../configuration/security.md#login_required) has been enabled), it is recommended to render export templates via the REST API. This allows the client to specify an authentication token. To render an export template via the REST API, make a `GET` request to the model's list endpoint and append the `export` parameter specifying the export template name. For example:
A NetBox report is a mechanism for validating the integrity of data within NetBox. Running a report allows the user to verify that the objects defined within NetBox meet certain arbitrary conditions. For example, you can write reports to check that:
* All top-of-rack switches have a console connection
* Every router has a loopback interface with an IP address assigned
* Each interface description conforms to a standard format
* Every site has a minimum set of VLANs defined
* All IP addresses have a parent prefix
...and so on. Reports are completely customizable, so there's practically no limit to what you can test for.
## Writing Reports
Reports must be saved as files in the [`REPORTS_ROOT`](../configuration/optional-settings.md#reports_root) path (which defaults to `netbox/reports/`). Each file created within this path is considered a separate module. Each module holds one or more reports (Python classes), each of which performs a certain function. The logic of each report is broken into discrete test methods, each of which applies a small portion of the logic comprising the overall test.
!!! warning
The reports path includes a file named `__init__.py`, which registers the path as a Python module. Do not delete this file.
Reports are deprecated beginning with NetBox v4.0, and their functionality has been merged with [custom scripts](./custom-scripts.md). While backward compatibility has been maintained, users are advised to convert legacy reports into custom scripts soon, as support for legacy reports will be removed in a future release.
For example, we can create a module named `devices.py` to hold all of our reports which pertain to devices in NetBox. Within that module, we might define several reports. Each report is defined as a Python class inheriting from `extras.reports.Report`.
## Converting Reports to Scripts
```
### Step 1: Update Class Definition
Change the parent class from `Report` to `Script`:
```python title="Old code"
from extras.reports import Report
class DeviceConnectionsReport(Report):
description = "Validate the minimum physical connections for each device"
class DeviceIPsReport(Report):
description = "Check that every device has a primary IP address assigned"
class MyReport(Report):
```
Within each report class, we'll create a number of test methods to execute our report's logic. In DeviceConnectionsReport, for instance, we want to ensure that every live device has a console connection, an out-of-band management connection, and two power connections.
```python title="New code"
from extras.scripts import Script
```
from dcim.choices import DeviceStatusChoices
from dcim.models import ConsolePort, Device, PowerPort
from extras.reports import Report
class DeviceConnectionsReport(Report):
description = "Validate the minimum physical connections for each device"
def test_console_connection(self):
# Check that every console port for every active device has a connection defined.
active = DeviceStatusChoices.STATUS_ACTIVE
for console_port in ConsolePort.objects.prefetch_related('device').filter(device__status=active):
if console_port.connected_endpoint is None:
self.log_failure(
console_port.device,
"No console connection defined for {}".format(console_port.name)
)
elif not console_port.connection_status:
self.log_warning(
console_port.device,
"Console connection for {} marked as planned".format(console_port.name)
)
else:
self.log_success(console_port.device)
def test_power_connections(self):
# Check that every active device has at least two connected power supplies.
for device in Device.objects.filter(status=DeviceStatusChoices.STATUS_ACTIVE):
connected_ports = 0
for power_port in PowerPort.objects.filter(device=device):
if power_port.connected_endpoint is not None:
connected_ports += 1
if not power_port.path.is_active:
self.log_warning(
device,
"Power connection for {} marked as planned".format(power_port.name)
)
if connected_ports < 2:
self.log_failure(
device,
"{} connected power supplies found (2 needed)".format(connected_ports)
)
else:
self.log_success(device)
class MyReport(Script):
```
As you can see, reports are completely customizable. Validation logic can be as simple or as complex as needed. Also note that the `description` attribute support markdown syntax. It will be rendered in the report list page.
### Step 2: Update Logging Calls
!!! warning
Reports should never alter data: If you find yourself using the `create()`, `save()`, `update()`, or `delete()` methods on objects within reports, stop and re-evaluate what you're trying to accomplish. Note that there are no safeguards against the accidental alteration or destruction of data.
Reports and scripts both provide logging methods, however their signatures differ. All script logging methods accept a message as the first parameter, and accept an object as an optional second parameter.
## Report Attributes
Additionally, the Report class' generic `log()` method is **not** available on Script. Users are advised to replace calls of this method with `log_info()`.
### `description`
Use the table below as a reference when updating these methods.
A human-friendly description of what your report does.
[^1]: `log_debug()` was added to the Report class in v4.0 to avoid confusion with the same method on Script
Set the maximum allowed runtime for the report. If not set, `RQ_DEFAULT_TIMEOUT` will be used.
!!! info "This feature was introduced in v3.2.1"
## Logging
The following methods are available to log results within a report:
* log(message)
* log_success(object, message=None)
* log_info(object, message)
* log_warning(object, message)
* log_failure(object, message)
The recording of one or more failure messages will automatically flag a report as failed. It is advised to log a success for each object that is evaluated so that the results will reflect how many objects are being reported on. (The inclusion of a log message is optional for successes.) Messages recorded with `log()` will appear in a report's results but are not associated with a particular object or status. Log messages also support using markdown syntax and will be rendered on the report result page.
To perform additional tasks, such as sending an email or calling a webhook, before or after a report is run, extend the `pre_run()` and/or `post_run()` methods, respectively. The status of a completed report is available as `self.failed` and the results object is `self.result`.
By default, reports within a module are ordered alphabetically in the reports list page. To return reports in a specific order, you can define the `report_order` variable at the end of your module. The `report_order` variable is a tuple which contains each Report class in the desired order. Any reports that are omitted from this list will be listed last.
f"No console connection defined for {console_port.name}"
)
```
Once you have created a report, it will appear in the reports list. Initially, reports will have no results associated with them. To generate results, run the report.
## Running Reports
!!! note
To run a report, a user must be assigned the `extras.run_report` permission. This is achieved by assigning the user (or group) a permission on the Report object and specifying the `run` action in the admin UI as shown below.

### Via the Web UI
Reports can be run via the web UI by navigating to the report and clicking the "run report" button at top right. Once a report has been run, its associated results will be included in the report view.
### Via the API
To run a report via the API, simply issue a POST request to its `run` endpoint. Reports are identified by their module and class name.
```
POST /api/extras/reports/<module>.<name>/run/
```python title="New code"
self.log_failure(
f"No console connection defined for {console_port.name}",
obj=console_port.device,
)
```
Our example report above would be called as:
### Other Notes
```
POST /api/extras/reports/devices.DeviceConnectionsReport/run/
```
Existing reports will be converted to scripts automatically upon upgrading to NetBox v4.0, and previous job history will be retained. However, users are advised to convert legacy reports into custom scripts at the earliest opportunity, as support for legacy reports will be removed in a future release.
### Via the CLI
The `pre_run()` and `post_run()` Report methods have been carried over to Script. These are called automatically by Script's `run()` method. (Note that if you opt to override this method, you are responsible for calling `pre_run()` and `post_run()` where applicable.)
Reports can be run on the CLI by invoking the management command:
```
python3 manage.py runreport <module>
```
where ``<module>`` is the name of the python file in the ``reports`` directory without the ``.py`` extension. One or more report modules may be specified.
The `is_valid()` method on Report is no longer needed and has been removed.
@@ -54,15 +54,19 @@ Each model should have a corresponding FilterSet class defined. This is used to
Create a table class for the model in `tables.py` by subclassing `utilities.tables.BaseTable`. Under the table's `Meta` class, be sure to list both the fields and default columns.
## 9. Create the object template
## 9. Create a SearchIndex subclass
If this model will be included in global search results, create a subclass of `netbox.search.SearchIndex` for it and specify the fields to be indexed.
## 10. Create the object template
Create the HTML template for the object view. (The other views each typically employ a generic template.) This template should extend `generic/object.html`.
## 10. Add the model to the navigation menu
## 11. Add the model to the navigation menu
Add the relevant navigation menu items in `netbox/netbox/navigation_menu.py`.
Add the relevant navigation menu items in `netbox/netbox/navigation/menu.py`.
## 11. REST API components
## 12. REST API components
Create the following for each model:
@@ -71,13 +75,13 @@ Create the following for each model:
* API view in `api/views.py`
* Endpoint route in `api/urls.py`
## 12. GraphQL API components
## 13. GraphQL API components
Create a Graphene object type for the model in `graphql/types.py` by subclassing the appropriate class from `netbox.graphql.types`.
Create a GraphQL object type for the model in `graphql/types.py` by subclassing the appropriate class from `netbox.graphql.types`.
Also extend the schema class defined in `graphql/schema.py` with the individual object and object list fields per the established convention.
## 13. Add tests
## 14. Add tests
Add tests for the following:
@@ -85,7 +89,7 @@ Add tests for the following:
* API views
* Filter sets
## 14. Documentation
## 15. Documentation
Create a new documentation page for the model in `docs/models/<app_label>/<model_name>.md`. Include this file under the "features" documentation where appropriate.
@@ -8,6 +8,18 @@ The registry can be inspected by importing `registry` from `extras.registry`.
## Stores
### `counter_fields`
A dictionary mapping of models to foreign keys with which cached counter fields are associated.
### `data_backends`
A dictionary mapping data backend types to their respective classes. These are used to interact with [remote data sources](../models/core/datasource.md).
### `denormalized_fields`
Stores registration made using `netbox.denormalized.register()`. For each model, a list of related models and their field mappings is maintained to facilitate automatic updates.
### `model_features`
A dictionary of particular features (e.g. custom fields) mapped to the NetBox models which support them, arranged by app. For example:
@@ -19,39 +31,32 @@ A dictionary of particular features (e.g. custom fields) mapped to the NetBox mo
'dcim':['site','rack','devicetype',...],
...
},
'webhooks':{
...
'event_rules':{
'extras':['configcontext','tag',...],
'dcim':['site','rack','devicetype',...],
},
...
}
```
### `plugin_menu_items`
Supported model features are listed in the [features matrix](./models.md#features-matrix).
Navigation menu items provided by NetBox plugins. Each plugin is registered as a key with the list of menu items it provides. An example:
### `models`
```python
{
'Plugin A':(
<MenuItem>,<MenuItem>,<MenuItem>,
),
'Plugin B':(
<MenuItem>,<MenuItem>,<MenuItem>,
),
}
```
This key lists all models which have been registered in NetBox which are not designated for private use. (Setting `_netbox_private` to True on a model excludes it from this list.) As with individual features under `model_features`, models are organized by app label.
### `plugin_template_extensions`
### `plugins`
Plugin content that gets embedded into core NetBox templates. The store comprises NetBox models registered as dictionary keys, each pointing to a list of applicable template extension classes that exist. An example:
This store maintains all registered items for plugins, such as navigation menus, template extensions, etc.
A dictionary mapping each model (identified by its app and label) to its search index class, if one has been registered for it.
### `tables`
A dictionary mapping table classes to lists of extra columns that have been registered by plugins using the `register_table_column()` utility function. Each column is defined as a tuple of name and column instance.
### `views`
A hierarchical mapping of registered views for each model. Mappings are added using the `register_model_view()` decorator, and URLs paths can be generated from these using `get_model_urls()`.
[Django migrations](https://docs.djangoproject.com/en/stable/topics/migrations/) are used to express changes to the database schema. In most cases, Django can generate these automatically, however very complex changes may require manual intervention. Always remember to specify a short but descriptive name when generating a new migration.
@@ -16,7 +29,7 @@ Where possible, try to merge related changes into a single migration. For exampl
!!! warning "Do not alter existing migrations"
Migrations can only be merged within a release. Once a new release has been published, its migrations cannot be altered (other than for the purpose of correcting a bug).
## 2. Add validation logic to `clean()`
## 3. Add validation logic to `clean()`
If the new field introduces additional validation requirements (beyond what's included with the field itself), implement them in the model's `clean()` method. Remember to call the model's original method using `super()` before or after your custom validation as appropriate:
@@ -31,15 +44,15 @@ class Foo(models.Model):
raise ValidationError()
```
## 3. Update relevant querysets
## 4. Update relevant querysets
If you're adding a relational field (e.g. `ForeignKey`) and intend to include the data when retrieving a list of objects, be sure to include the field using `prefetch_related()` as appropriate. This will optimize the view and avoid extraneous database queries.
## 4. Update API serializer
## 5. Update API serializer
Extend the model's API serializer in `<app>.api.serializers` to include the new field. In most cases, it will not be necessary to also extend the nested serializer, which produces a minimal representation of the model.
## 5. Add fields to forms
## 6. Add fields to forms
Extend any forms to include the new field(s) as appropriate. These are found under the `forms/` directory within each app. Common forms include:
@@ -48,19 +61,23 @@ Extend any forms to include the new field(s) as appropriate. These are found und
* **CSV import** - The form used when bulk importing objects in CSV format
* **Filter** - Displays the options available for filtering a list of objects (both UI and API)
## 6. Extend object filter set
## 7. Extend object filter set
If the new field should be filterable, add it to the `FilterSet` for the model. If the field should be searchable, remember to query it in the FilterSet's `search()` method.
## 7. Add column to object table
## 8. Add column to object table
If the new field will be included in the object list view, add a column to the model's table. For simple fields, adding the field name to `Meta.fields` will be sufficient. More complex fields may require declaring a custom column. Also add the field name to `default_columns` if the column should be present in the table by default.
## 8. Update the UI templates
## 9. Update the SearchIndex
Where applicable, add the new field to the model's SearchIndex for inclusion in global search.
## 10. Update the UI templates
Edit the object's view template to display the new field. There may also be a custom add/edit form template that needs to be updated.
## 9. Create/extend test cases
## 11. Create/extend test cases
Create or extend the relevant test cases to verify that the new field and any accompanying validation logic perform as expected. This is especially important for relational fields. NetBox incorporates various test suites, including:
@@ -70,8 +87,8 @@ Create or extend the relevant test cases to verify that the new field and any ac
* Model tests
* View tests
Be diligent to ensure all of the relevant test suites are adapted or extended as necessary to test any new functionality.
Be diligent to ensure all the relevant test suites are adapted or extended as necessary to test any new functionality.
## 10. Update the model's documentation
## 12. Update the model's documentation
Each model has a dedicated page in the documentation, at `models/<app>/<model>.md`. Update this file to include any relevant information about the new field.
Getting started with NetBox development is pretty straightforward, and should feel very familiar to anyone with Django development experience. There are a few things you'll need:
* A Linux system or environment
* A Linux system or compatible environment
* A PostgreSQL server, which can be installed locally [per the documentation](../installation/1-postgresql.md)
* A Redis server, which can also be [installed locally](../installation/2-redis.md)
*A supported version of Python
*Python 3.10 or later
### Fork the Repo
### 1. Fork the Repo
Assuming you'll be working on your own fork, your first step will be to fork the [official git repository](https://github.com/netbox-community/netbox). (If you're a maintainer who's going to be working directly with the official repo, skip this step.) Click the "fork" button at top right (be sure that you've logged into GitHub first).
@@ -21,7 +21,7 @@ Copy the URL provided in the dialog box.
You can then clone your GitHub fork locally for development:
The NetBox project utilizes three persistent git branches to track work:
* `master` - Serves as a snapshot of the current stable release
* `develop` - All development on the upcoming stable release occurs here
* `feature` - Tracks work on an upcoming major release
* `develop` - All development on the upcoming stable (patch) release occurs here
* `feature` - Tracks work on an upcoming minor release
Typically, you'll base pull requests off of the `develop` branch, or off of `feature` if you're working on a new major release. **Never** merge pull requests into the `master` branch: This branch only ever merges pull requests from the `develop` branch, to effect a new release.
Typically, you'll base pull requests off of the `develop` branch, or off of `feature` if you're working on a new major release. For example, assume that the current NetBox release is v3.3.5. Work applied to the `develop` branch will appear in v3.3.6, and work done under the `feature` branch will be included in the next minor release (v3.4.0).
For example, assume that the current NetBox release is v3.1.1. Work applied to the `develop` branch will appear in v3.1.2, and work done under the `feature` branch will be included in the next minor release (v3.2.0).
!!! warning
**Never** merge pull requests into the `master` branch: This branch only ever merges pull requests from the `develop` branch, to effect a new release.
### Enable Pre-Commit Hooks
To create a new branch, first ensure that you've checked out the desired base branch, then run:
```no-highlight
git checkout -B $branchname
```
When naming a new git branch, contributors are strongly encouraged to use the relevant issue number followed by a very brief description of the work:
```no-highlight
$issue-$description
```
The description should be just two or three words to imply the focus of the work being performed. For example, bug #1234 to fix a TypeError exception when creating a device might be named `1234-device-typerror`. This ensures that branches are always follow some logical ordering (e.g. when running `git branch -a`) and helps other developers quickly identify the purpose of each.
### 3. Enable Pre-Commit Hooks
NetBox ships with a [git pre-commit hook](https://githooks.com/) script that automatically checks for style compliance and missing database migrations prior to committing changes. This helps avoid erroneous commits that result in CI test failures. You are encouraged to enable it by creating a link to `scripts/git-hooks/pre-commit`:
```no-highlight
$ cd .git/hooks/
$ ln -s ../../scripts/git-hooks/pre-commit
cd .git/hooks/
ln -s ../../scripts/git-hooks/pre-commit
```
For the pre-commit hooks to work, you will also need to install the pycodestyle package:
### Create a Python Virtual Environment
```no-highlight
python -m pip install pycodestyle
```
...and set up the yarn packages as shown in the [Web UI Development Guide](web-ui.md)
### 4. Create a Python Virtual Environment
A [virtual environment](https://docs.python.org/3/tutorial/venv.html) (or "venv" for short) is like a container for a set of Python packages. These allow you to build environments suited to specific projects without interfering with system packages or other projects. When installed per the documentation, NetBox uses a virtual environment in production.
Create a virtual environment using the `venv` Python module:
```no-highlight
$ mkdir ~/.venv
$ python3 -m venv ~/.venv/netbox
mkdir ~/.venv
python3 -m venv ~/.venv/netbox
```
This will create a directory named `.venv/netbox/` in your home directory, which houses a virtual copy of the Python executable and its related libraries and tooling. When running NetBox for development, it will be run using the Python binary at `~/.venv/netbox/bin/python`.
!!! info "Where to Create Your Virtual Environments"
Keeping virtual environments in `~/.venv/` is a common convention but entirely optional: Virtual environments can be created almost wherever you please. Also consider using [`virtualenvwrapper`](https://virtualenvwrapper.readthedocs.io/en/stable/) to simplify the management of multiple venvs.
!!! tip "Virtual Environments"
Keeping virtual environments in `~/.venv/` is a common convention but entirely optional: Virtual environments can be created almost wherever you please. Also consider using [`virtualenvwrapper`](https://virtualenvwrapper.readthedocs.io/en/stable/) to simplify the management of multiple environments.
Once created, activate the virtual environment:
```no-highlight
$ source ~/.venv/netbox/bin/activate
(netbox) $
source ~/.venv/netbox/bin/activate
```
Notice that the console prompt changes to indicate the active environment. This updates the necessary system environment variables to ensure that any Python scripts are run within the virtual environment.
### Install Dependencies
### 5. Install Required Packages
With the virtual environment activated, install the project's required Python packages using the `pip` module:
With the virtual environment activated, install the project's required Python packages using the `pip` module. Required packages are defined in `requirements.txt`. Each line in this file specifies the name and specific version of a required package.
* `REDIS`: Redis configuration, if different from the defaults
* `REDIS`: Redis configuration (if different from the defaults)
* `SECRET_KEY`: Set to a random string (use `generate_secret_key.py` in the parent directory to generate a suitable key)
* `DEBUG`: Set to `True`
* `DEVELOPER`: Set to `True` (this enables the creation of new database migrations)
### Start the Development Server
### 7. Start the Development Server
Django provides a lightweight, auto-updating HTTP/WSGI server for development use. It is started with the `runserver` management command:
Django provides a lightweight, auto-updating [HTTP/WSGI server](https://docs.djangoproject.com/en/stable/ref/django-admin/#runserver) for development use. It is started with the `runserver` management command:
```no-highlight
```no-highlight hl_lines="1"
$ ./manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
February 18, 2022 - 20:29:57
Django version 4.0.2, using settings 'netbox.settings'
August 18, 2022 - 15:17:52
Django version 4.0.7, using settings 'netbox.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
```
This ensures that your development environment is now complete and operational. Any changes you make to the code base will be automatically adapted by the development server.
This ensures that your development environment is now complete and operational. The development server will monitor the development environment and automatically reload in response to any changes made.
!!! info "IDE Integration"
Some IDEs, such as PyCharm, will integrate with Django's development server and allow you to run it directly within the IDE. This is strongly encouraged as it makes for a much more convenient development environment.
!!! tip "IDE Integration"
Some IDEs, such as the highly-recommended [PyCharm](https://www.jetbrains.com/pycharm/), will integrate with Django's development server and allow you to run it directly within the IDE. This is strongly encouraged as it makes for a much more convenient development environment.
## UI Development
For UI development you will need to review the [Web UI Development Guide](web-ui.md)
## Populating Demo Data
@@ -131,48 +152,51 @@ The demo data is provided in JSON format and loaded into an empty database using
## Running Tests
Prior to committing any substantial changes to the code base, be sure to run NetBox's test suite to catch any potential errors. Tests are run using the `test` management command, which employs Python's [`unittest`](https://docs.python.org/3/library/unittest.html#module-unittest) library. Remember to ensure the Python virtual environment is active before running this command. Also keep in mind that these commands are executed in the `netbox/` directory, not the root directory of the repository.
Prior to committing any substantial changes to the code base, be sure to run NetBox's test suite to catch potential errors. Tests are run using the `test` management command, which employs Python's [`unittest`](https://docs.python.org/3/library/unittest.html#module-unittest) library. Remember to ensure that the Python virtual environment is active before running this command. Also keep in mind that these commands are executed in the `netbox/` directory, not the root directory of the repository.
To avoid potential issues with your local configuration file, set the `NETBOX_CONFIGURATION` to point to the packaged test configuration at `netbox/configuration_testing.py`. This will handle things like ensuring that the dummy plugin is enabled for comprehensive testing.
In cases where you haven't made any changes to the database schema (which is typical), you can append the `--keepdb` argument to this command to reuse the test database between runs. This cuts down on the time it takes to run the test suite since the database doesn't have to be rebuilt each time. (Note that this argument will cause errors if you've modified any model fields since the previous test run.)
```no-highlight
$ python manage.py test --keepdb
python manage.py test --keepdb
```
You can also reduce testing time by enabling parallel test execution with the `--parallel` flag. (By default, this will run as many parallel tests as you have processors. To avoid sluggishness, it's a good idea to specify a lower number of parallel tests.) This flag can be combined with `--keepdb`, although if you encounter any strange errors, try running the test suite again with parallelization disabled.
```no-highlight
$ python manage.py test --parallel <n>
python manage.py test --parallel <n>
```
Finally, it's possible to limit the run to a specific set of tests, specified by their Python path. For example, to run only IPAM and DCIM view tests:
```no-highlight
$ python manage.py test dcim.tests.test_views ipam.tests.test_views
python manage.py test dcim.tests.test_views ipam.tests.test_views
```
This is handy for instances where just a few tests are failing and you want to re-run them individually.
!!! info
NetBox uses [django-rich](https://github.com/adamchainz/django-rich) to enhance Django's default `test` management command.
## Submitting Pull Requests
Once you're happy with your work and have verified that all tests pass, commit your changes and push it upstream to your fork. Always provide descriptive (but not excessively verbose) commit messages. When working on a specific issue, be sure to prefix your commit message with the word "Fixes" or "Closes" and the issue number (with a hash mark). This tells GitHub to automatically close the referenced issue once the commit has been merged.
Once you're happy with your work and have verified that all tests pass, commit your changes and push it upstream to your fork. Always provide descriptive (but not excessively verbose) commit messages. Be sure to prefix your commit message with the word "Fixes" or "Closes" and the relevant issue number (with a hash mark). This tells GitHub to automatically close the referenced issue once the commit has been merged.
```no-highlight
$ git commit -m "Closes #1234: Add IPv5 support"
$ git push origin
git commit -m "Closes #1234: Add IPv5 support"
git push origin
```
Once your fork has the new commit, submit a [pull request](https://github.com/netbox-community/netbox/compare) to the NetBox repo to propose the changes. Be sure to provide a detailed accounting of the changes being made and the reasons for doing so.
Once submitted, a maintainer will review your pull request and either merge it or request changes. If changes are needed, you can make them via new commits to your fork: The pull request will update automatically.
!!! note "Remember to Open an Issue First"
!!! warning
Remember, pull requests are permitted only for **accepted** issues. If an issue you want to work on hasn't been approved by a maintainer yet, it's best to avoid risking your time and effort on a change that might not be accepted. (The one exception to this is trivial changes to the documentation or other non-critical resources.)
This cheat sheet serves as a convenient reference for NetBox contributors who already somewhat familiar with using git. For a general introduction to the tooling and workflows involved, please see GitHub's guide [Getting started with git](https://docs.github.com/en/get-started/getting-started-with-git/setting-your-username-in-git).
## Common Operations
### Clone a Repo
This copies a remote git repository (e.g. from GitHub) to your local workstation. It will create a new directory bearing the repo's name in the current path.
`git branch` lists all local branches. Appending `-a` to this command will list both local (green) and remote (red) branches.
``` title="Command"
git branch -a
```
``` title="Example"
$ git branch -a
* develop
remotes/origin/10170-changelog
remotes/origin/HEAD -> origin/develop
remotes/origin/develop
remotes/origin/feature
remotes/origin/master
```
### Switch Branches
To switch to a different branch, use the `checkout` command.
``` title="Command"
git checkout $branchname
```
``` title="Example"
$ git checkout feature
Branch 'feature' set up to track remote branch 'feature' from 'origin'.
Switched to a new branch 'feature'
```
### Create a New Branch
Use the `-b` argument with `checkout` to create a new _local_ branch from the current branch.
``` title="Command"
git checkout -b $newbranch
```
``` title="Example"
$ git checkout -b 123-fix-foo
Switched to a new branch '123-fix-foo'
```
### Rename a Branch
To rename the current branch, use the `git branch` command with the `-m` argument (for "modify").
``` title="Command"
git branch -m $newname
```
``` title="Example"
$ git branch -m jstretch-testing
$ git branch
develop
feature
* jstretch-testing
```
### Merge a Branch
To merge one branch into another, use the `git merge` command. Start by checking out the _destination_ branch, and merge the _source_ branch into it.
``` title="Command"
git merge $sourcebranch
```
``` title="Example"
$ git checkout testing
Switched to branch 'testing'
Your branch is up to date with 'origin/testing'.
$ git merge branch2
Updating 9a12b5b5f..8ee42390b
Fast-forward
newfile.py | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 newfile.py
```
!!! warning "Avoid Merging Remote Branches"
You generally want to avoid merging branches that exist on the remote (upstream) repository, such as `develop` and `feature`: Merges into these branches should be done via a pull request on GitHub. Only merge branches when it is necessary to consolidate work you've done locally.
### Show Pending Changes
After making changes to files in the repo, `git status` will display a summary of created, modified, and deleted files.
``` title="Command"
git status
```
``` title="Example"
$ git status
On branch 123-fix-foo
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
foo.py
no changes added to commit (use "git add" and/or "git commit -a")
```
### Stage Changed Files
Before creating a new commit, modified files must be staged. This is typically done with the `git add` command. You can specify a particular path, or just append `-A` to automatically staged _all_ changed files within the current directory. Run `git status` again to verify what files have been staged.
``` title="Command"
git add -A
```
``` title="Example"
$ git add -A
$ git status
On branch 123-fix-foo
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.md
new file: foo.py
```
### Review Staged Files
It's a good idea to thoroughly review all staged changes immediately prior to creating a new commit. This can be done using the `git diff` command. Appending the `--staged` argument will show staged changes; omitting it will show changes that have not yet been staged.
The `git commit` command records your changes to the current branch. Specify a commit message with the `-m` argument. (If omitted, a file editor will be opened to provide a message.
``` title="Command"
git commit -m "Fixes #123: Fixed the thing that was broken"
```
``` title="Example"
$ git commit -m "Fixes #123: Fixed the thing that was broken"
[123-fix-foo 9a12b5b5f] Fixes #123: Fixed the thing that was broken
2 files changed, 5 insertions(+)
create mode 100644 foo.py
```
!!! tip "Automatically Closing Issues"
GitHub will [automatically close](https://github.blog/2013-01-22-closing-issues-via-commit-messages/) any issues referenced in a commit message by `Fixes:` or `Closes:` when the commit is merged into the repository's default branch. Contributors are strongly encouraged to follow this convention when forming commit messages. (Use "Closes" for feature requests and "Fixes" for bugs.)
### Push a Commit Upstream
Once you've made a commit locally, it needs to be pushed upstream to the _remote_ repository (typically called "origin"). This is done with the `git push` command. If this is a new branch that doesn't yet exist on the remote repository, you'll need to set the upstream for it when pushing.
Branch 'testing' set up to track remote branch 'testing' from 'origin'.
```
!!! tip
You can apply the following git configuration to automatically set the upstream for all new branches. This obviates the need to specify `-u origin`.
```
git config --global push.default current
```
## The GitHub CLI Client
GitHub provides a [free CLI client](https://cli.github.com/) to simplify many aspects of interacting with GitHub repositories. Note that this utility is separate from `git`, and must be [installed separately](https://github.com/cli/cli#installation).
This guide provides some examples of common operations, but be sure to check out the [GitHub CLI manual](https://cli.github.com/manual/) for a complete accounting of available commands.
### List Open Pull Requests
``` title="Command"
gh pr list
```
``` title="Example"
$ gh pr list
Showing 3 of 3 open pull requests in netbox-community/netbox
#10223 #7503 API Bulk-Create of Devices does not check Rack-Space 7503-bulkdevice about 17 hours ago
#9716 Closes #9599: Add cursor pagination mode lyuyangh:cursor-pagination about 1 month ago
#9498 Adds replication and adoption for module import sleepinggenius2:issue_9361 about 2 months ago
```
### Check Out a PR
This command will automatically check out the remote branch associated with an open pull request.
``` title="Command"
gh pr checkout $number
```
``` title="Example"
$ gh pr checkout 10223
Branch '7503-bulkdevice' set up to track remote branch '7503-bulkdevice' from 'origin'.
Switched to a new branch '7503-bulkdevice'
```
## Fixing Mistakes
### Modify the Previous Commit
Sometimes you'll find that you've overlooked a necessary change and need to commit again. If you haven't pushed your most recent commit and just need to make a small tweak or two, you can _amend_ your most recent commit instead of creating a new one.
First, stage the desired files with `git add` and verify the changes, the issue the `git commit` command with the `--amend` argument. You can also append the `--no-edit` argument if you would like to keep the previous commit message.
``` title="Command"
git commit --amend --no-edit
```
``` title="Example"
$ git add -A
$ git diff --staged
$ git commit --amend --no-edit
[testing 239b16921] Added a new file
Date: Fri Aug 26 16:30:05 2022 -0400
2 files changed, 1 insertion(+)
create mode 100644 newfile.py
```
!!! danger "Don't Amend After Pushing"
Never amend a commit you've already pushed upstream unless you're **certain** no one else is working on the same branch. Force-pushing will overwrite the change history, which will break any commits from other contributors. When in doubt, create a new commit instead.
### Undo the Last Commit
The `git reset` command can be used to undo the most recent commit. (`HEAD~` is equivalent to `HEAD~1` and references the commit prior to the current HEAD.) After making and staging your changes, commit using `-c ORIG_HEAD` to replace the erroneous commit.
``` title="Command"
git reset HEAD~
```
``` title="Example"
$ git add -A
$ git commit -m "Erroneous commit"
[testing 09ce06736] Erroneous commit
Date: Mon Aug 29 15:20:04 2022 -0400
1 file changed, 1 insertion(+)
create mode 100644 BADCHANGE
$ git reset HEAD~
$ rm BADFILE
$ git add -A
$ git commit -m "Fixed commit"
[testing c585709f3] Fixed commit
Date: Mon Aug 29 15:22:38 2022 -0400
1 file changed, 65 insertions(+), 20 deletions(-)
```
!!! danger "Don't Reset After Pushing"
Resetting only works until you've pushed your local changes upstream. If you've already pushed upstream, use `git revert` instead. This will create a _new_ commit that reverts the erroneous one, but ensures that the git history remains intact.
### Rebase from Upstream
If a change has been pushed to the upstream branch since you most recently pulled it, attempting to push a new local commit will fail:
```
$ git push
To https://github.com/netbox-community/netbox.git
! [rejected] develop -> develop (fetch first)
error: failed to push some refs to 'https://github.com/netbox-community/netbox.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```
To resolve this, first fetch the upstream branch to update your local copy, and then [rebase](https://git-scm.com/book/en/v2/Git-Branching-Rebasing) your local branch to include the new changes. Once the rebase has completed, you can push your local commits upstream.
NetBox is maintained as a [GitHub project](https://github.com/netbox-community/netbox) under the Apache 2 license. Users are encouraged to submit GitHub issues for feature requests and bug reports, however we are very selective about pull requests. Each pull request must be preceded by an **approved** issue. Please see the `CONTRIBUTING` guide for more direction on contributing to NetBox.
Thanks for your interest in contributing to NetBox! This introduction covers a few important things to know before you get started.
## Communication
## The Code
There are several official forums for communication among the developers and community members:
NetBox and many of its related projects are maintained on [GitHub](https://github.com/netbox-community/netbox). GitHub also serves as one of our primary discussion forums. While all the code and discussion is publicly accessible, you'll need register for a [free GitHub account](https://github.com/signup) to engage in participation. Most people begin by [forking](https://docs.github.com/en/get-started/quickstart/fork-a-repo) the NetBox repository under their own GitHub account to begin working on the code.
*[GitHub issues](https://github.com/netbox-community/netbox/issues) - All feature requests, bug reports, and other substantial changes to the code base **must** be documented in a GitHub issue.
* [GitHub discussions](https://github.com/netbox-community/netbox/discussions) - The preferred forum for general discussion and support issues. Ideal for shaping a feature request prior to submitting an issue.
* [#netbox on NetDev Community Slack](https://netdev.chat/) - Good for quick chats. Avoid any discussion that might need to be referenced later on, as the chat history is not retained long.

## Governance
There are three permanent branches in the repository:
NetBox follows the [benevolent dictator](http://oss-watch.ac.uk/resources/benevolentdictatorgovernancemodel) model of governance, with [Jeremy Stretch](https://github.com/jeremystretch) ultimately responsible for all changes to the code base. While community contributions are welcomed and encouraged, the lead maintainer's primary role is to ensure the project's long-term maintainability and continued focus on its primary functions.
## Project Structure
All development of the current NetBox release occurs in the `develop` branch; releases are packaged from the `master` branch. The `master` branch should _always_ represent the current stable release in its entirety, such that installing NetBox by either downloading a packaged release or cloning the `master` branch provides the same code base. Only pull requests representing new releases should be merged into `master`.
*`master` - The current stable release. Individual changes should never be pushed directly to this branch, but rather merged from `develop`.
*`develop` - Active development for the upcoming patch release. Pull requests will typically be based on this branch unless they introduce breaking changes that must be deferred until the next minor release.
*`feature` - New feature work to be introduced in the next minor release (e.g. from v3.3 to v3.4).
NetBox components are arranged into Django apps. Each app holds the models, views, and other resources relevant to a particular function:
@@ -31,3 +27,34 @@ NetBox components are arranged into Django apps. Each app holds the models, view
*`wireless`: Wireless links and LANs
All core functionality is stored within the `netbox/` subdirectory. HTML templates are stored in a common `templates/` directory, with model- and view-specific templates arranged by app. Documentation is kept in the `docs/` root directory.
## Proposing Changes
All substantial changes made to the code base are tracked using [GitHub issues](https://docs.github.com/en/issues). Feature requests, bug reports, and similar proposals must all be filed as issues and approved by a maintainer before work begins. This ensures that all changes to the code base are properly documented for future reference.
To submit a new feature request or bug report for NetBox, select and complete the appropriate [issue template](https://github.com/netbox-community/netbox/issues/new/choose). Once your issue has been approved, you're welcome to submit a [pull request](https://docs.github.com/en/pull-requests) containing your proposed changes.

Check out our [issue intake policy](https://github.com/netbox-community/netbox/wiki/Issue-Intake-Policy) for an overview of the issue triage and approval processes.
!!! tip
Avoid starting work on a proposal before it has been accepted. Not all proposed changes will be accepted, and we'd hate for you to waste time working on code that might not make it into the project.
## Getting Help
There are two primary forums for getting assistance with NetBox development:
* [GitHub discussions](https://github.com/netbox-community/netbox/discussions) - The preferred forum for general discussion and support issues. Ideal for shaping a feature requests prior to submitting an issue.
* [#netbox on NetDev Community Slack](https://netdev.chat/) - Good for quick chats. Avoid any discussion that might need to be referenced later on, as the chat history is not retained indefinitely.
!!! note
Don't use GitHub issues to ask for help: These are reserved for proposed code changes only.
## Governance
NetBox follows the [benevolent dictator](http://oss-watch.ac.uk/resources/benevolentdictatorgovernancemodel) model of governance, with [Jeremy Stretch](https://github.com/jeremystretch) ultimately responsible for all changes to the code base. While community contributions are welcomed and encouraged, the lead maintainer's primary role is to ensure the project's long-term maintainability and continued focus on its primary functions.
## Licensing
The entire NetBox project is licensed as open source under the [Apache 2.0 license](https://github.com/netbox-community/netbox/blob/master/LICENSE.txt). This is a very permissive license which allows unlimited redistribution of all code within the project. Note that all submissions to the project are subject to the same license.
Beginning with NetBox v4.0, NetBox will leverage [Django's automatic translation](https://docs.djangoproject.com/en/stable/topics/i18n/translation/) to support languages other than English. This page details the areas of the project which require special attention to ensure functioning translation support. Briefly, these include:
* The `verbose_name` and `verbose_name_plural` Meta attributes for each model
* The `verbose_name` and (if defined) `help_text` for each model field
* The `label` for each form field
* Headers for `fieldsets` on each form class
* The `verbose_name` for each table column
* All human-readable strings within templates must be wrapped with `{% trans %}` or `{% blocktrans %}`
The rest of this document elaborates on each of the items above.
## General Guidance
* Wrap human-readable strings with Django's `gettext()` or `gettext_lazy()` utility functions to enable automatic translation. Generally, `gettext_lazy()` is preferred (and sometimes required) to defer translation until the string is displayed.
* By convention, the preferred translation function is typically imported as an underscore (`_`) to minimize boilerplate code. Thus, you will often see translation as e.g. `_("Some text")`. It is still an option to import and use alternative translation functions (e.g. `pgettext()` and `ngettext()`) normally as needed.
* Avoid passing markup and other non-natural language where possible. Everything wrapped by a translation function gets exported to a messages file for translation by a human.
* Where the intended meaning of the translated string may not be obvious, use `pgettext()` or `pgettext_lazy()` to include assisting context for the translator. For example:
```python
# Context, string
pgettext("month name", "May")
```
* **Format strings do not support translation.** Avoid "f" strings for messages that must support translation. Instead, use `format()` to accomplish variable replacement:
```python
# Translation will not work
f"There are {count} objects"
# Do this instead
"There are {count} objects".format(count=count)
```
## Models
1. Import `gettext_lazy` as `_`.
2. Ensure both `verbose_name` and `verbose_name_plural` are defined under the model's `Meta` class and wrapped with the `gettext_lazy()` shortcut.
3. Ensure each model field specifies a `verbose_name` wrapped with `gettext_lazy()`.
4. Ensure any `help_text` attributes on model fields are also wrapped with `gettext_lazy()`.
```python
from django.utils.translation import gettext_lazy as _
class Circuit(PrimaryModel):
commit_rate = models.PositiveIntegerField(
...
verbose_name=_('commit rate (Kbps)'),
help_text=_("Committed rate")
)
class Meta:
verbose_name = _('circuit')
verbose_name_plural = _('circuits')
```
## Forms
1. Import `gettext_lazy` as `_`.
2. All form fields must specify a `label` wrapped with `gettext_lazy()`.
3. The name of each FieldSet on a form must be wrapped with `gettext_lazy()`.
```python
from django.utils.translation import gettext_lazy as _
from utilities.forms.rendering import FieldSet
class CircuitBulkEditForm(NetBoxModelBulkEditForm):
2. All table columns must specify a `verbose_name` wrapped with `gettext_lazy()`.
```python
from django.utils.translation import gettext_lazy as _
class CircuitTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
provider = tables.Column(
verbose_name=_('Provider'),
...
)
```
## Templates
1. Ensure translation support is enabled by including `{% load i18n %}` at the top of the template.
2. Use the [`{% trans %}`](https://docs.djangoproject.com/en/stable/topics/i18n/translation/#translate-template-tag) tag (short for "translate") to wrap short strings.
3. Longer strings may be enclosed between [`{% blocktrans %}`](https://docs.djangoproject.com/en/stable/topics/i18n/translation/#blocktranslate-template-tag) and `{% endblocktrans %}` tags to improve readability and to enable variable replacement. (Remember to include the `trimmed` argument to trim whitespace between the tags.)
4. Avoid passing HTML within translated strings where possible, as this can complicate the work needed of human translators to develop message maps.
```
{% load i18n %}
{# A short string #}
<h5 class="card-header">{% trans "Circuit List" %}</h5>
{# A longer string with a context variable #}
{% blocktrans trimmed with count=object.circuits.count %}
There are {count} circuits. Would you like to continue?
{% endblocktrans %}
```
!!! warning
The `{% blocktrans %}` tag supports only **limited variable replacement**, comparable to the `format()` method on Python strings. It does not permit access to object attributes or the use of other template tags or filters inside it. Ensure that any necessary context is passed as simple variables.
!!! info
The `{% trans %}` and `{% blocktrans %}` support the inclusion of contextual hints for translators using the `context` argument:
A NetBox model represents a discrete object type such as a device or IP address. Each model is defined as a Python class and has its own SQL table. All NetBox data models can be categorized by type.
A NetBox model represents a discrete object type such as a device or IP address. Per [Django convention](https://docs.djangoproject.com/en/stable/topics/db/models/), each model is defined as a Python class and has its own table in the PostgreSQL database. All NetBox data models can be categorized by type.
The Django [content types](https://docs.djangoproject.com/en/stable/ref/contrib/contenttypes/) framework can be used to reference models within the database. A ContentType instance references a model by its `app_label` and `name`: For example, the Site model is referred to as `dcim.site`. The content type combined with an object's primary key form a globally unique identifier for the object (e.g. `dcim.site:123`).
The Django [content types](https://docs.djangoproject.com/en/stable/ref/contrib/contenttypes/) framework is used to map Django models to database tables. A ContentType instance references a model by its `app_label` and `name`: For example, the Site model within the DCIM app is referred to as `dcim.site`. The content type combined with an object's primary key form a globally unique identifier for the object (e.g. `dcim.site:123`).
### Features Matrix
* [Change logging](../additional-features/change-logging.md) - Changes to these objects are automatically recorded in the change log
* [Webhooks](../additional-features/webhooks.md) - NetBox is capable of generating outgoing webhooks for these objects
* [Custom fields](../customization/custom-fields.md) - These models support the addition of user-defined fields
* [Export templates](../customization/export-templates.md) - Users can create custom export templates for these models
* [Tagging](../models/extras/tag.md) - The models can be tagged with user-defined tags
* [Journaling](../additional-features/journaling.md) - These models support persistent historical commentary
* Nesting - These models can be nested recursively to create a hierarchy
Depending on its classification, each NetBox model may support various features which enhance its operation. Each feature is enabled by inheriting from its designated mixin class, and some features also make use of the [application registry](./application-registry.md#model_features).
| [Change logging](../features/change-logging.md) | `ChangeLoggingMixin` | - | Changes to these objects are automatically recorded in the change log |
| Cloning | `CloningMixin` | - | Provides the `clone()` method to prepare a copy |
| [Custom fields](../customization/custom-fields.md) | `CustomFieldsMixin` | `custom_fields` | These models support the addition of user-defined fields |
| [Custom links](../customization/custom-links.md) | `CustomLinksMixin` | `custom_links` | These models support the assignment of custom links |
| [Custom validation](../customization/custom-validation.md) | `CustomValidationMixin` | - | Supports the enforcement of custom validation rules |
| [Export templates](../customization/export-templates.md) | `ExportTemplatesMixin` | `export_templates` | Users can create custom export templates for these models |
| [Job results](../features/background-jobs.md) | `JobsMixin` | `jobs` | Users can create custom export templates for these models |
| [Journaling](../features/journaling.md) | `JournalingMixin` | `journaling` | These models support persistent historical commentary |
| [Synchronized data](../integrations/synchronized-data.md) | `SyncedDataMixin` | `synced_data` | Certain model data can be automatically synchronized from a remote data source |
| [Tagging](../models/extras/tag.md) | `TagsMixin` | `tags` | The models can be tagged with user-defined tags |
| [Event rules](../features/event-rules.md) | `EventRulesMixin` | `event_rules` | Event rules can send webhooks or run custom scripts automatically in response to events |
## Models Index
### Primary Models
These are considered the "core" application models which are used to model network infrastructure.
@@ -73,6 +91,8 @@ The Django [content types](https://docs.djangoproject.com/en/stable/ref/contrib/
### Nested Group Models
Nested group models behave like organizational model, but self-nest within a recursive hierarchy. For example, the Region model can be used to represent a hierarchy of countries, states, and cities.
These function as templates to effect the replication of device and virtual machine components. Component template models support a limited feature set, including change logging, custom validation, and event rules.
This documentation describes the process of packaging and publishing a new NetBox release. There are three types of release:
### Address Pinned Dependencies
* Major release (e.g. v2.11 to v3.0)
* Minor release (e.g. v3.2 to v3.3)
* Patch release (e.g. v3.3.0 to v3.3.1)
Check `base_requirements.txt` for any dependencies pinned to a specific version, and upgrade them to their most stable release (where possible).
While major releases generally introduce some very substantial change to the application, they are typically treated the same as minor version increments for the purpose of release packaging.
### Link to the Release Notes Page
## Minor Version Releases
Add the release notes (`/docs/release-notes/X.Y.md`) to the table of contents within `mkdocs.yml`, and add a summary of the major changes to `index.md`.
### Address Constrained Dependencies
### Manually Perform a New Install
Install `mkdocs` in your local environment, then start the documentation server:
```no-highlight
$ pip install -r docs/requirements.txt
$ mkdocs serve
```
Follow these instructions to perform a new installation of NetBox. This process must _not_ be automated: The goal of this step is to catch any errors or omissions in the documentation, and ensure that it is kept up-to-date for each release. Make any necessary changes to the documentation before proceeding with the release.
### Close the Release Milestone
Close the release milestone on GitHub after ensuring there are no remaining open issues associated with it.
### Merge the Release Branch
Submit a pull request to merge the `feature` branch into the `develop` branch in preparation for its release.
---
## All Releases
### Update Requirements
Required Python packages are maintained in two files. `base_requirements.txt` contains a list of all the packages required by NetBox. Some of them may be pinned to a specific version of the package due to a known issue. For example:
Sometimes it becomes necessary to constrain dependencies to a particular version, e.g. to work around a bug in a newer release or to avoid a breaking change that we have yet to accommodate. (Another common example is to limit the upstream Django release.) For example:
The other file is `requirements.txt`, which lists each of the required packages pinned to its current stable version. When NetBox is installed, the Python environment is configured to match this file. This helps ensure that a new release of a dependency doesn't break NetBox.
These version constraints are added to `base_requirements.txt` to ensure that newer packages are not installed when updating the pinned dependencies in`requirements.txt` (see the [Update Requirements](#update-requirements) section below). Before each new minor version of NetBox is released, all such constraints on dependent packages should be addressed if feasible. This guards against the collection of stale constraints over time.
Every release should refresh `requirements.txt` so that it lists the most recent stable release of each package. To do this:
### Close the Release Milestone
1. Create a new virtual environment.
2. Install the latest version of all required packages `pip install -U -r base_requirements.txt`).
3. Run all tests and check that the UI and API function as expected.
4. Review each requirement's release notes for any breaking or otherwise noteworthy changes.
5. Update the package versions in `requirements.txt` as appropriate.
Close the [release milestone](https://github.com/netbox-community/netbox/milestones) on GitHub after ensuring there are no remaining open issues associated with it.
In cases where upgrading a dependency to its most recent release is breaking, it should be pinned to its current minor version in `base_requirements.txt` (with an explanatory comment) and revisited for the next major NetBox release.
### Update the Release Notes
### Verify CI Build Status
Check that a link to the release notes for the new version is present in the navigation menu (defined in `mkdocs.yml`), and that a summary of all major new features has been added to `docs/index.md`.
Ensure that continuous integration testing on the `develop` branch is completing successfully.
### Manually Perform a New Install
Start the documentation server and navigate to the current version of the installation docs:
```no-highlight
mkdocs serve
```
Follow these instructions to perform a new installation of NetBox in a temporary environment. This process must not be automated: The goal of this step is to catch any errors or omissions in the documentation, and ensure that it is kept up-to-date for each release. Make any necessary changes to the documentation before proceeding with the release.
### Merge the Release Branch
Submit a pull request to merge the `feature` branch into the `develop` branch in preparation for its release. Once it has been merged, continue with the section for patch releases below.
### Rebuild Demo Data (After Release)
After the release of a new minor version, generate a new demo data snapshot compatible with the new release. See the [`netbox-demo-data`](https://github.com/netbox-community/netbox-demo-data) repository for instructions.
---
## Patch Releases
### Notify netbox-docker Project of Any Relevant Changes
Notify the [`netbox-docker`](https://github.com/netbox-community/netbox-docker) maintainers (in **#netbox-docker**) of any changes that may be relevant to their build process, including:
* Significant changes to `upgrade.sh`
* Increases in minimum versions for service dependencies (PostgreSQL, Redis, etc.)
* Any changes to the reference installation
### Update Python Dependencies
Before each release, update each of NetBox's Python dependencies to its most recent stable version. These are defined in `requirements.txt`, which is updated from `base_requirements.txt` using `pip`. To do this:
1. Upgrade the installed version of all required packages in your environment (`pip install -U -r base_requirements.txt`).
2. Run all tests and check that the UI and API function as expected.
3. Review each requirement's release notes for any breaking or otherwise noteworthy changes.
4. Update the package versions in `requirements.txt` as appropriate.
In cases where upgrading a dependency to its most recent release is breaking, it should be constrained to its current minor version in `base_requirements.txt` with an explanatory comment and revisited for the next major NetBox release (see the [Address Constrained Dependencies](#address-constrained-dependencies) section above).
### Update UI Dependencies
Check whether any UI dependencies (JavaScript packages, fonts, etc.) need to be updated by running `yarn outdated` from within the `project-static/` directory. [Upgrade these dependencies](./web-ui.md#updating-dependencies) as necessary, then run `yarn bundle` to generate the necessary files for distribution.
### Rebuild the Device Type Definition Schema
Run the following command to update the device type definition validation schema:
```nohighlight
./manage.py buildschema --write
```
This will automatically update the schema file at `contrib/generated_schema.json`.
### Update & Compile Translations
Updated language translations should be pulled from [Transifex](https://app.transifex.com/netbox-community/netbox/dashboard/) and re-compiled for each new release. Follow the documented process for [updating translated strings](./translations.md#updating-translated-strings) to do this.
### Update Version and Changelog
@@ -64,28 +94,47 @@ Ensure that continuous integration testing on the `develop` branch is completing
* Update the example version numbers in the feature request and bug report templates under `.github/ISSUE_TEMPLATES/`.
* Replace the "FUTURE" placeholder in the release notes with the current date.
Commit these changes to the `develop` branch.
Commit these changes to the `develop` branch and push upstream.
### Verify CI Build Status
Ensure that continuous integration testing on the `develop` branch is completing successfully. If it fails, take action to correct the failure before proceeding with the release.
### Submit a Pull Request
Submit a pull request title **"Release vX.Y.Z"** to merge the `develop` branch into `master`. Copy the documented release notes into the pull request's body.
Submit a pull request titled **"Release vX.Y.Z"** to merge the `develop` branch into `master`. Copy the documented release notes into the pull request's body.
Once CI has completed on the PR, merge it.
Once CI has completed on the PR, merge it. This effects a new release in the `master` branch.
### Create a New Release
Draft a [new release](https://github.com/netbox-community/netbox/releases/new) with the following parameters.
Create a [new release](https://github.com/netbox-community/netbox/releases/new) on GitHub with the following parameters.
* **Tag:** Current version (e.g. `v2.9.9`)
* **Tag:** Current version (e.g. `v3.3.1`)
* **Target:** `master`
* **Title:** Version and date (e.g. `v2.9.9 - 2020-11-09`)
* **Title:** Version and date (e.g. `v3.3.1 - 2022-08-25`)
* **Description:** Copy from the pull request body
Copy the description from the pull request to the release.
Once created, the release will become available for users to install.
### Update the Development Version
On the `develop` branch, update `VERSION` in `settings.py` to point to the next release. For example, if you just released v2.9.9, set:
On the `develop` branch, update `VERSION` in `settings.py` to point to the next release. For example, if you just released v3.3.1, set:
```
VERSION = 'v2.9.10-dev'
VERSION = 'v3.3.2-dev'
```
Commit this change with the comment "PRVB" (for _post-release version bump_) and push the commit upstream.
### Update the Public Documentation
After a release has been published, the public NetBox documentation needs to be updated. This is accomplished by running two actions on the [netboxlabs-docs](https://github.com/netboxlabs/netboxlabs-docs) repository.
First, run the `build-site` action, by navigating to Actions > build-site > Run workflow. This process compiles the documentation along with an overlay for integration with the documentation portal at <https://netboxlabs.com/docs>. The job should take about two minutes.
Once the documentation files have been compiled, they must be published by running the `deploy-kinsta` action. Select the desired deployment environment (staging or production) and specify `latest` as the deploy tag.
Clear the CDN cache from the [Kinsta](https://my.kinsta.com/) portal. Navigate to _Sites_ / _NetBox Labs_ / _Live_, select _CDN_ in the left-nav, click the _Clear CDN cache_ button, and confirm the clear operation.
Finally, verify that the documentation at <https://netboxlabs.com/docs/netbox/en/stable/> has been updated.
NetBox v3.4 introduced a new global search mechanism, which employs the `extras.CachedValue` model to store discrete field values from many models in a single table.
## SearchIndex
To enable search support for a model, declare and register a subclass of `netbox.search.SearchIndex` for it. Typically, this will be done within an app's `search.py` module.
A SearchIndex subclass defines both its model and a list of two-tuples specifying which model fields to be indexed and the weight (precedence) associated with each. Guidance on weight assignment for fields is provided below.
NetBox generally follows the [Django style guide](https://docs.djangoproject.com/en/stable/internals/contributing/writing-code/coding-style/), which is itself based on [PEP 8](https://www.python.org/dev/peps/pep-0008/). [Pycodestyle](https://github.com/pycqa/pycodestyle) is used to validate code formatting, ignoring certain violations. See `scripts/cibuild.sh` for details.
NetBox generally follows the [Django style guide](https://docs.djangoproject.com/en/stable/internals/contributing/writing-code/coding-style/), which is itself based on [PEP 8](https://www.python.org/dev/peps/pep-0008/). [Pycodestyle](https://github.com/pycqa/pycodestyle) is used to validate code formatting, ignoring certain violations.
## PEP 8 Exceptions
## Code
* Wildcard imports (for example, `from .constants import *`) are acceptable under any of the following conditions:
* The library being import contains only constant declarations (e.g. `constants.py`)
* The library being imported explicitly defines `__all__`
### General Guidance
*Maximum line length is 120 characters (E501)
* This does not apply to HTML templates or to automatically generated code (e.g. database migrations).
*When in doubt, remain consistent: It is better to be consistently incorrect than inconsistently correct. If you notice in the course of unrelated work a pattern that should be corrected, continue to follow the pattern for now and submit a separate bug report so that the entire code base can be evaluated at a later point.
*Line breaks are permitted following binary operators (W504)
*Prioritize readability over concision. Python is a very flexible language that typically offers several multiple options for expressing a given piece of logic, but some may be more friendly to the reader than others. (List comprehensions are particularly vulnerable to over-optimization.) Always remain considerate of the future reader who may need to interpret your code without the benefit of the context within which you are writing it.
## Enforcing Code Style
* Include a newline at the end of every file.
The `pycodestyle` utility (previously `pep8`) is used by the CI process to enforce code style. It is strongly recommended to include as part of your commit process. A git commit hook is provided in the source at `scripts/git-hooks/pre-commit`. Linking to this script from `.git/hooks/` will invoke `pycodestyle` prior to every commit attempt and abort if the validation fails.
* No easter eggs. While they can be fun, NetBox must be considered as a business-critical tool. The potential, however minor, for introducing a bug caused by unnecessary code is best avoided entirely.
```
$ cd .git/hooks/
$ ln -s ../../scripts/git-hooks/pre-commit
```
* Constants (variables which do not change) should be declared in `constants.py` within each app. Wildcard imports from the file are acceptable.
To invoke `pycodestyle` manually, run:
* Every model must have a [docstring](https://peps.python.org/pep-0257/). Every custom method should include an explanation of its function.
* Nested API serializers generate minimal representations of an object. These are stored separately from the primary serializers to avoid circular dependencies. Always import nested serializers from other apps directly. For example, from within the DCIM app you would write `from ipam.api.nested_serializers import NestedIPAddressSerializer`.
### PEP 8 Exceptions
NetBox ignores certain PEP8 assertions. These are listed below.
#### Wildcard Imports
Wildcard imports (for example, `from .constants import *`) are acceptable under any of the following conditions:
* The library being import contains only constant declarations (e.g. `constants.py`)
* The library being imported explicitly defines `__all__`
#### Maximum Line Length (E501)
NetBox does not restrict lines to a maximum length of 79 characters. We use a maximum line length of 120 characters, however this is not enforced by CI. The maximum length does not apply to HTML templates or to automatically generated code (e.g. database migrations).
#### Line Breaks Following Binary Operators (W504)
Line breaks are permitted following binary operators.
### Enforcing Code Style
The [`pycodestyle`](https://pypi.org/project/pycodestyle/) utility (formerly `pep8`) is used by the CI process to enforce code style. A [pre-commit hook](./getting-started.md#2-enable-pre-commit-hooks) which runs this automatically is included with NetBox. To invoke `pycodestyle` manually, run:
```
pycodestyle --ignore=W504,E501 netbox/
```
## Introducing New Dependencies
### Introducing New Dependencies
The introduction of a new dependency is best avoided unless it is absolutely necessary. For small features, it's generally preferable to replicate functionality within the NetBox code base rather than to introduce reliance on an external project. This reduces both the burden of tracking new releases and our exposure to outside bugs and supply chain attacks.
@@ -39,24 +58,22 @@ If there's a strong case for introducing a new dependency, it must meet the foll
* It must be actively maintained, with no longer than one year between releases.
* It must be available via the [Python Package Index](https://pypi.org/) (PyPI).
When adding a new dependency, a short description of the package and the URL of its code repository must be added to `base_requirements.txt`. Additionally, a line specifying the package name pinned to the current stable release must be added to `requirements.txt`. This ensures that NetBox will install only the known-good release and simplify support efforts.
When adding a new dependency, a short description of the package and the URL of its code repository must be added to `base_requirements.txt`. Additionally, a line specifying the package name pinned to the current stable release must be added to `requirements.txt`. This ensures that NetBox will install only the known-good release.
## General Guidance
## Written Works
* When in doubt, remain consistent: It is better to be consistently incorrect than inconsistently correct. If you notice in the course of unrelated work a pattern that should be corrected, continue to follow the pattern for now and submit a separate bug report so that the entire code base can be evaluated at a later point.
### General Guidance
*Prioritize readability over concision. Python is a very flexible language that typically offers several options for expressing a given piece of logic, but some may be more friendly to the reader than others. (List comprehensions are particularly vulnerable to over-optimization.) Always remain considerate of the future reader who may need to interpret your code without the benefit of the context within which you are writing it.
*Written material must always meet a reasonable professional standard, with proper grammar, spelling, and punctuation.
*No easter eggs. While they can be fun, NetBox must be considered as a business-critical tool. The potential, however minor, for introducing a bug caused by unnecessary logic is best avoided entirely.
*Use two line breaks between paragraphs.
*Constants (variables which generally do not change) should be declared in `constants.py` within each app. Wildcard imports from the file are acceptable.
*Use only a single space between sentences.
*Every model should have a docstring. Every custom method should include an explanation of its function.
*All documentation is to be written in [Markdown](../reference/markdown.md), with modest amounts of HTML permitted where needed to overcome technical limitations.
* Nested API serializers generate minimal representations of an object. These are stored separately from the primary serializers to avoid circular dependencies. Always import nested serializers from other apps directly. For example, from within the DCIM app you would write `from ipam.api.nested_serializers import NestedIPAddressSerializer`.
### Branding
## Branding
* When referring to NetBox in writing, use the proper form "NetBox," with the letters N and B capitalized. The lowercase form "netbox" should be used in code, filenames, etc. But never "Netbox" or any other deviation.
* When referring to NetBox in writing, use the proper form "NetBox," with the letters N and B capitalized. The lowercase form "netbox" should be used in code, filenames, etc. but never "Netbox" or any other deviation.
* There is an SVG form of the NetBox logo at [docs/netbox_logo.svg](../netbox_logo.svg). It is preferred to use this logo for all purposes as it scales to arbitrary sizes without loss of resolution. If a raster image is required, the SVG logo should be converted to a PNG image of the prescribed size.
NetBox coordinates all translation work using the [Transifex](https://explore.transifex.com/netbox-community/netbox/) platform. Signing up for a Transifex account is free.
All language translations in NetBox are generated from the source file found at `netbox/translations/en/LC_MESSAGES/django.po`. This file contains the original English strings with empty mappings, and is generated as part of NetBox's release process. Transifex updates source strings from this file on a recurring basis, so new translation strings will appear in the platform automatically as it is updated in the code base.
Reviewers log into Transifex and navigate to their designated language(s) to translate strings. The initial translation for most strings will be machine-generated via the AWS Translate service. Human reviewers are responsible for reviewing these translations and making corrections where necessary.
## Updating Translation Sources
To update the English `.po` file from which all translations are derived, use the `makemessages` management command (ignoring the `project-static/` directory):
```nohighlight
./manage.py makemessages -l en -i "project-static/*"
```
Then, commit the change and push to the `develop` branch on GitHub. Any new strings will appear for translation on Transifex automatically.
## Updating Translated Strings
Typically, translated strings need to be updated only as part of the NetBox [release process](./release-checklist.md).
To update translated strings, start by initiating a sync from Transifex. From the Transifex dashboard, navigate to Settings > Integrations > GitHub > Manage, and click the **Manual Sync** button at top right.
Enter a threshold percentage of 1 (to ensure all translations are captured) and select the `develop` branch, then click **Sync**. This will initiate a pull request to GitHub to update any newly modified translation (`.po`) files.
!!! tip
The new PR should appear within a few minutes. If it does not, check that there are in fact new translations to be added.
Once the PR has been merged, the updated strings need to be compiled into new `.mo` files so they can be used by the application. Update the `develop` branch locally to pull in the changes from the Transifex PR, then run Django's [`compilemessages`](https://docs.djangoproject.com/en/stable/ref/django-admin/#django-admin-compilemessages) management command:
```nohighlight
./manage.py compilemessages
```
Once any new `.mo` files have been generated, they need to be committed and pushed back up to GitHub. (Again, this is typically done as part of publishing a new NetBox release.)
## Proposing New Languages
If you'd like to add support for a new language to NetBox, the first step is to [submit a GitHub issue](https://github.com/netbox-community/netbox/issues/new?assignees=&labels=type%3A+translation&projects=&template=translation.yaml) to capture the proposal. While we'd like to add as many languages as possible, we do need to limit the rate at which new languages are added. New languages will be selected according to community interest and the number of volunteers who sign up as translators.
Once a proposed language has been approved, a NetBox maintainer will:
* Add it to the Transifex platform
* Designate one or more reviewers
* Create the initial machine-generated translations for review
| `dist/` | Destination path for installed dependencies |
| `docs/` | Local build path for documentation |
| `img/` | Image files |
| `js/` | Miscellaneous JavaScript resources served directly |
| `src/` | TypeScript resources (to be compiled into JS) |
| `styles/` | Sass resources (to be compiled into CSS) |
## Front End Technologies
The NetBox UI is built on languages and frameworks:
Front end scripting is written in [TypeScript](https://www.typescriptlang.org/), which is a strongly-typed extension to JavaScript. TypeScript is "transpiled" into JavaScript resources which are served to and executed by the client web browser.
### Styling & HTML Elements
All UI styling is written in [Sass](https://sass-lang.com/), which is an extension to browser-native [Cascading Stylesheets (CSS)](https://developer.mozilla.org/en-US/docs/Web/CSS). Similar to how TypeScript content is transpiled to JavaScript, Sass resources (`.scss` files) are compiled to CSS.
#### [Bootstrap](https://getbootstrap.com/) 5
## Dependencies
The majority of the NetBox UI is made up of stock Bootstrap components, with some styling modifications and custom components added on an as-needed basis. Bootstrap uses [Sass](https://sass-lang.com/), and NetBox extends Bootstrap's core Sass files for theming and customization.
The following software is employed by the NetBox user interface.
All client-side scripting is transpiled from TypeScript to JavaScript and served by Django. In development, TypeScript is an _extremely_ effective tool for accurately describing and checking the code, which leads to significantly fewer bugs, a better development experience, and more predictable/readable code.
As part of the [bundling](#bundling) process, Bootstrap's JavaScript plugins are imported and bundled alongside NetBox's front-end code.
!!! danger "NetBox is jQuery-free"
Following the Bootstrap team's deprecation of jQuery in Bootstrap 5, NetBox also no longer uses jQuery in front-end code.
* [Bootstrap 5](https://getbootstrap.com/) - A popular CSS & JS framework
* [clipboard.js](https://clipboardjs.com/) - A lightweight package for enabling copy-to-clipboard functionality
* [flatpickr](https://flatpickr.js.org/) - A lightweight date & time selection widget
* [gridstack.js](https://gridstackjs.com/) - Enables interactive grid layouts (for the dashboard)
* [HTMX](https://htmx.org/) - Enables dynamic web interfaces through the use of HTML element attributes
* [Material Design Icons](https://pictogrammers.com/library/mdi/) - An extensive open source collection of graphical icons, delivered as a web font
* [query-string](https://www.npmjs.com/package/query-string) - Assists with parsing URL query strings
* [Tabler](https://tabler.io/) - A web application UI toolkit & theme based on Bootstrap 5
* [Tom Select](https://tom-select.js.org/) - Provides dynamic selection form fields
## Guidance
@@ -54,6 +66,41 @@ $ yarn
!!! warning "Check Your Working Directory"
You need to be in the `netbox/project-static` directory to run the below `yarn` commands.
### Updating Dependencies
Run `yarn outdated` to identify outdated dependencies.
```
$ yarn outdated
yarn outdated v1.22.19
info Color legend :
"<red>" : Major Update backward-incompatible updates
"<yellow>" : Minor Update backward-compatible features
Run `yarn upgrade --latest` to automatically upgrade these packages to their most recent versions.
```
$ yarn upgrade bootstrap --latest
yarn upgrade v1.22.19
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Rebuilding all packages...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ bootstrap@5.3.3
info All dependencies
└─ bootstrap@5.3.3
Done in 0.95s.
```
`package.json` will be updated to reflect the new package versions automatically.
### Bundling
In order for the TypeScript and Sass (SCSS) source files to be usable by a browser, they must first be transpiled (TypeScript → JavaScript, Sass → CSS), bundled, and minified. After making changes to TypeScript or Sass source files, run `yarn bundle`.
NetBox includes a slew of features which enable integration with other tools and resources powering your network.
## REST API
NetBox's REST API, powered by the [Django REST Framework](https://www.django-rest-framework.org/), provides a robust yet accessible interface for creating, modifying, and deleting objects. Employing HTTP for transfer and JSON for data encapsulation, the REST API is easily consumed by clients on any platform and extremely well suited for automation tasks.
The REST API employs token-based authentication, which maps API clients to user accounts and their assigned permissions. The API endpoints are fully documented using OpenAPI, and NetBox even includes a convenient browser-based version of the API for exploration. The open source [pynetbox](https://github.com/netbox-community/pynetbox) and [go-netbox](https://github.com/netbox-community/go-netbox) API client libraries are also available for Python and Go, respectively.
To learn more about this feature, check out the [REST API documentation](../integrations/rest-api.md).
## GraphQL API
NetBox also provides a [GraphQL](https://graphql.org/) API to complement its REST API. GraphQL enables complex queries for arbitrary objects and fields, enabling the client to retrieve only the specific data it needs from NetBox. This is a special-purpose read-only API intended for efficient queries. Like the REST API, the GraphQL API employs token-based authentication.
To learn more about this feature, check out the [GraphQL API documentation](../integrations/graphql-api.md).
## Webhooks
A webhook is a mechanism for conveying to some external system a change that has taken place in NetBox. For example, you may want to notify a monitoring system whenever the status of a device is updated in NetBox. To do this, first create a [webhook](../models/extras/webhook.md) identifying the remote receiver (URL), HTTP method, and any other necessary parameters. Then, define an [event rule](../models/extras/eventrule.md) which is triggered by device changes to transmit the webhook.
When NetBox detects a change to a device, an HTTP request containing the details of the change and who made it be sent to the specified receiver. Webhooks are an excellent mechanism for building event-based automation processes. To learn more about this feature, check out the [webhooks documentation](../integrations/webhooks.md).
## Prometheus Metrics
NetBox includes a special `/metrics` view which exposes metrics for a [Prometheus](https://prometheus.io/) scraper, powered by the open source [django-prometheus](https://github.com/korfuri/django-prometheus) library. To learn more about this feature, check out the [Prometheus metrics documentation](../integrations/prometheus-metrics.md).
NetBox boasts a very robust permissions system which extends well beyond the model-based permissions of the underlying Django framework. Assigning permissions in NetBox involves several dimensions:
* The type(s) of object to which the permission applies
* The users and/or groups being granted the permissions
* The action(s) permitted by the permission (e.g. view, add, change, etc.)
* Any constraints limiting application of the permission to a particular subset of objects
The implementation of constrains is what enables NetBox administrators to assign per-object permissions: Users can be limited to viewing or interacting with arbitrary subsets of objects based on the objects' attributes. For example, you might restrict a particular user to viewing only those prefixes or IP addresses within a particular VRF. Or you might restrict a group to modifying devices within a particular region.
Permission constraints are declared in JSON format when creating a permission, and operate very similarly to Django ORM queries. For instance, here's a constraint that matches reserved VLANs with a VLAN ID between 100 and 199:
```json
[
{
"vid__gte":100,
"vid__lt":200
},
{
"status":"reserved"
}
]
```
Check out the [permissions documentation](../administration/permissions.md) for more information about permission constraints.
## LDAP Authentication
NetBox includes a built-in authentication backend for authenticating users against a remote LDAP server. The [installation documentation](../installation/6-ldap.md) provides more detail on this capability.
## Single Sign-On (SSO)
NetBox integrates with the open source [python-social-auth](https://github.com/python-social-auth) library to provide [myriad options](https://python-social-auth.readthedocs.io/en/latest/backends/index.html#supported-backends) for single sign-on (SSO) authentication. These include:
* Cognito
* GitHub & GitHub Enterprise
* GitLab
* Google
* Hashicorp Vault
* Keycloak
* Microsoft Azure AD
* Microsoft Graph
* Okta
* OIDC
...and many others. It's also possible to build your own custom backends as needed using python-social-auth's base OAuth, OpenID, and SAML classes. You can find some examples of configuring SSO in NetBox' [authentication documentation](../administration/authentication/overview.md).
* Synchronization of [remote data sources](../integrations/synchronized-data.md)
Additionally, NetBox plugins can enqueue their own background tasks. This is accomplished using the [Job model](../models/core/job.md). Background tasks are executed by the `rqworker` process(es).
## Scheduled Jobs
Background jobs can be configured to run immediately, or at a set time in the future. Scheduled jobs can also be configured to repeat at a set interval.
Every time an object in NetBox is created, updated, or deleted, a serialized copy of that object taken both before and after the change is saved to the database, along with metadata including the current time and the user associated with the change. These records form a persistent record of changes both for each individual object as well as NetBox as a whole. The global change log can be viewed by navigating to Other > Change Log.
Every time an object in NetBox is created, updated, or deleted, a serialized copy of that object taken both before and after the change is saved to the database, along with metadata including the current time and the user associated with the change. These records form a persistent record of changes both for each individual object as well as NetBox as a whole. The global change log can be viewed by navigating to Other > Change Log.
A serialized representation of the instance being modified is included in JSON format. This is similar to how objects are conveyed within the REST API, but does not include any nested representations. For instance, the `tenant` field of a site will record only the tenant's ID, not a representation of the tenant.
When a request is made, a UUID is generated and attached to any change records resulting from that request. For example, editing three objects in bulk will create a separate change record for each (three in total), and each of those objects will be associated with the same UUID. This makes it easy to identify all the change records resulting from a particular request.
Change records are exposed in the API via the read-only endpoint `/api/extras/object-changes/`. They may also be exported via the web UI in CSV format.
## Correlating Changes by Request
Every request made to NetBox is assigned a random unique ID that can be used to correlate change records. For example, if you change the status of three sites using the UI's bulk edit feature, you will see three new change records (one for each site) all referencing the same request ID. This shows that all three changes were made as part of the same request.
NetBox is ideal for managing your network's transit and peering providers and circuits. It provides all the flexibility needed to model physical circuits in both data center and enterprise environments, and allows for "connecting" circuits directly to device interfaces via cables.
A provider is any organization which provides Internet or private connectivity. Typically, these are large carriers, however they might also include regional providers or even internal services. Each provider can be assigned account and contact details, and may have one or more AS numbers assigned to it.
Sometimes you'll need to model provider networks into which you don't have full visibility; these are typically represented on topology diagrams with cloud icons. NetBox facilitates this through its provider network model: A provider network represents a "black box" network to which your circuits can connect. A common example is a provider MPLS network connecting multiple sites.
## Circuits
A circuit is a physical connection between two points, which is installed and maintained by an external provider. For example, an Internet connection delivered as a fiber optic cable would be modeled as a circuit in NetBox.
Each circuit is associated with a provider and assigned a circuit ID, which must be unique to that provider. A circuit is also assigned a user-defined type, operational status, and various other operating characteristics. Provider accounts can also be employed to further categorize circuits belonging to a common provider: These may represent different business units or technologies.
Each circuit may have up to two terminations (A and Z) defined. Each termination can be associated with a particular site or provider network. In the case of the former, a cable can be connected between the circuit termination and a device component to map its physical connectivity.
!!! warning "Physical vs. Virtual Circuits"
The circuit model in NetBox represents **physical** connections. Don't confuse these with _virtual_ circuits which may be offered by providers overlaid on physical infrastructure. (For example, a VLAN-tagged subinterface would be a virtual circuit.) A good rule of thumb: If you can't point to it, it's not a physical circuit.
One of the critical aspects of operating a network is ensuring that every network node is configured correctly. By leveraging configuration templates and [context data](./context-data.md), NetBox can render complete configuration files for each device on your network.
Configuration templates are written in the [Jinja2 templating language](https://jinja.palletsprojects.com/), and may be automatically populated from remote data sources. Context data is applied to a template during rendering to output a complete configuration file. Below is an example Jinja2 template which renders a simple network switch configuration file.
```jinja2
{% extends 'base.j2' %}
{% block content %}
system {
host-name {{ device.name }};
domain-name example.com;
time-zone UTC;
authentication-order [ password radius ];
ntp {
{% for server in ntp_servers %}
server {{ server }};
{% endfor %}
}
}
{% for interface in device.interfaces.all() %}
{% include 'common/interface.j2' %}
{% endfor %}
{% endblock %}
```
When rendered for a specific NetBox device, the template's `device` variable will be populated with the device instance, and `ntp_servers` will be pulled from the device's available context data. The resulting output will be a valid configuration segment that can be applied directly to a compatible network device.
### Context Data
The object for which the configuration is being rendered is made available as template context as `device` or `virtualmachine` for devices and virtual machines, respectively. Additionally, NetBox model classes can be accessed by the app or plugin in which they reside. For example:
```
There are {{ dcim.Site.objects.count() }} sites.
```
## Rendering Templates
### Device Configurations
NetBox provides a REST API endpoint specifically for rendering the default configuration template for a specific device. This is accomplished by sending a POST request to the device's unique URL, optionally including additional context data.
This request will trigger resolution of the device's preferred config template in the following order:
* The config template assigned to the individual device
* The config template assigned to the device's role
* The config template assigned to the device's platform
If no config template has been assigned to any of these three objects, the request will fail.
The configuration can be rendered as JSON or as plaintext by setting the `Accept:` HTTP header. For example:
* `Accept: application/json`
* `Accept: text/plain`
### General Purpose Use
NetBox config templates can also be rendered without being tied to any specific device, using a separate general purpose REST API endpoint. Any data included with a POST request to this endpoint will be passed as context data for the template.
Much like [tenancy](./tenancy.md), contact assignment enables you to track ownership of resources modeled in NetBox. A contact represents an individual responsible for a resource within the context of its assigned role.
Contacts can be grouped arbitrarily into a recursive hierarchy, and a contact can be assigned to a group at any level within the hierarchy.
## Contact Roles
A contact role defines the relationship of a contact to an assigned object. For example, you might define roles for administrative, operational, and emergency contacts.
## Contacts
A contact should represent an individual or permanent point of contact. Each contact must define a name, and may optionally include a title, phone number, email address, and related details.
Contacts are reused for assignments, so each unique contact must be created only once and can be assigned to any number of NetBox objects, and there is no limit to the number of assigned contacts an object may have. Most core objects in NetBox can have contacts assigned to them.
The following models support the assignment of contacts:
Configuration context data (or "config contexts" for short) is a powerful feature that enables users to define arbitrary data that applies to device and virtual machines based on certain characteristics. For example, suppose you want to define syslog servers for devices assigned to sites within a particular region. In NetBox, you can create a config context instance containing this data and apply it to the desired region. All devices within this region will now include this data when fetched via an API.
```json
{
"syslog-servers":[
"192.168.43.107",
"192.168.48.112"
]
}
```
Context data can be consumed by remote API clients, or it can be employed natively to render [configuration templates](./configuration-rendering.md).
Config contexts can be computed for objects based on the following criteria:
| Tenant group | :material-check: | :material-check: |
| Tenant | :material-check: | :material-check: |
| Tag | :material-check: | :material-check: |
There are no restrictions around what data can be stored in a configuration context, so long as it can be expressed in JSON.
## Hierarchical Rendering
While this is handy on its own, the real power of context data stems from its ability to be merged and overridden using multiple instances. For example, perhaps you need to define _different_ syslog servers within the region for a particular device role. You can create a second config context with the appropriate data and a higher weight, and apply it to the desired role. This will override the lower-weight data that applies to the entire region. As you can imagine, this flexibility can cater to many complex use cases.
For example, suppose we want to specify a set of syslog and NTP servers for all devices within a region. We could create a config context instance with a weight of 1000 assigned to the region, with the following JSON data:
```json
{
"ntp-servers":[
"172.16.10.22",
"172.16.10.33"
],
"syslog-servers":[
"172.16.9.100",
"172.16.9.101"
]
}
```
But suppose there's a problem at one particular site within this region preventing traffic from reaching the regional syslog server. Devices there need to use a local syslog server instead of the two defined above. We'll create a second config context assigned only to that site with a weight of 2000 and the following data:
```json
{
"syslog-servers":[
"192.168.43.107"
]
}
```
When the context data for a device at this site is rendered, the second, higher-weight data overwrite the first, resulting in the following:
```json
{
"ntp-servers":[
"172.16.10.22",
"172.16.10.33"
],
"syslog-servers":[
"192.168.43.107"
]
}
```
Data from the higher-weight context overwrites conflicting data from the lower-weight context, while the non-conflicting portion of the lower-weight context (the list of NTP servers) is preserved.
## Local Context Data
Devices and virtual machines may also have a local context data defined. This local context will _always_ take precedence over any separate config context objects which apply to the device/VM. This is useful in situations where we need to call out a specific deviation in the data for a particular object.
!!! warning
If you find that you're routinely defining local context data for many individual devices or virtual machines, [custom fields](./customization.md#custom-fields) may offer a more effective solution.
While NetBox strives to meet the needs of every network, the needs of users to cater to their own unique environments cannot be ignored. NetBox was built with this in mind, and can be customized in many ways to better suit your particular needs.
## Tags
Most objects in NetBox can be assigned user-created tags to aid with organization and filtering. Tag values are completely arbitrary: They may be used to store data in key-value pairs, or they may be employed simply as labels against which objects can be filtered. Each tag can also be assigned a color for quicker differentiation in the user interface.
Objects can be filtered by the tags they have applied. For example, the following API request will retrieve all devices tagged as "monitored":
```no-highlight
GET /api/dcim/devices/?tag=monitored
```
The `tag` filter can be specified multiple times to match only objects which have _all_ the specified tags assigned:
```no-highlight
GET /api/dcim/devices/?tag=monitored&tag=deprecated
```
## Bookmarks
Users can bookmark their most commonly visited objects for convenient access. Bookmarks are listed under a user's profile, and can be displayed with custom filtering and ordering on the user's personal dashboard.
## Custom Fields
While NetBox provides a rather extensive data model out of the box, the need may arise to store certain additional data associated with NetBox objects. For example, you might need to record the invoice ID alongside an installed device, or record an approving authority when creating a new IP prefix. NetBox administrators can create custom fields on built-in objects to meet these needs.
NetBox supports many types of custom field, from basic data types like strings and integers, to complex structures like selection lists or raw JSON. It's even possible to add a custom field which references other NetBox objects. Custom field data is stored directly alongside the object to which it is applied in the database, which ensures minimal performance impact. And custom field data can be written and read via the REST API, just like built-in fields.
To learn more about this feature, check out the [custom field documentation](../customization/custom-fields.md).
## Custom Links
Custom links allow you to conveniently reference external resources related to NetBox objects from within the NetBox UI. For example, you might wish to link each virtual machine modeled in NetBox to its corresponding view in some orchestration application. You can do this by creating a templatized custom link for the virtual machine model, specifying something like the following for the link URL:
```no-highlight
http://server.local/vms/?name={{ object.name }}
```
Now, when viewing a virtual machine in NetBox, a user will see a handy button with the chosen title and link (complete with the name of the VM being viewed). Both the text and URL of custom links can be templatized in this manner, and custom links can be grouped together into dropdowns for more efficient display.
To learn more about this feature, check out the [custom link documentation](../customization/custom-links.md).
## Custom Validation
While NetBox employs robust built-in object validation to ensure the integrity of its database, you might wish to enforce additional rules governing the creation and modification of certain objects. For example, perhaps you require that every device defined in NetBox adheres to a particular naming scheme and includes an asset tag. You can configure a custom validation rule in NetBox to enforce these requirements for the device model:
```python
CUSTOM_VALIDATORS = {
"dcim.device": [
{
"name": {
"regex": "[a-z]+\d{3}"
},
"asset_tag": {
"required": True
}
}
]
}
```
To learn more about this feature, check out the [custom validation documentation](../customization/custom-validation.md).
## Export Templates
Most NetBox objects can be exported in bulk in two built-in CSV formats: The current view (what the user currently sees in the objects list), or all available data. NetBox also provides the capability to define your own custom data export formats via export templates. An export template is essentially [Jinja2](https://jinja.palletsprojects.com/) template code associated with a particular object type. From the objects list in the NetBox UI, a user can select any of the created export templates to export the objects according to the template logic.
An export template doesn't have to render CSV data: Its output can be in any character-based format. For example, you might want to render data using tabs as delimiters, or even create DNS address records directly from the IP addresses list. Export templates are a great way to get the data you need in the format you need quickly.
To learn more about this feature, check out the [export template documentation](../customization/export-templates.md).
## Reports
NetBox administrators can install custom Python scripts, known as _reports_, which run within NetBox and can be executed and analyzed within the NetBox UI. Reports are a great way to evaluate NetBox objects against a set of arbitrary rules. For example, you could write a report to check that every router has a loopback interface with an IP address assigned, or that every site has a minimum set of VLANs defined.
When a report runs, its logs messages pertaining to the operations being performed, and will ultimately result in either a pass or fail. Reports can be executed via the UI, REST API, or CLI (as a management command). They can be run immediately or scheduled to run at a future time.
To learn more about this feature, check out the [documentation for reports](../customization/reports.md).
## Custom Scripts
Custom scripts are similar to reports, but more powerful. A custom script can prompt the user for input via a form (or API data), and is built to do much more than just reporting. Custom scripts are generally used to automate tasks, such as the population of new objects in NetBox, or exchanging data with external systems. As with reports, they can be run via the UI, REST API, or CLI, and be scheduled to execute at a future time.
The complete Python environment is available to a custom script, including all of NetBox's internal mechanisms: There are no artificial restrictions on what a script can do. As such, custom scripting is considered an advanced feature and requires sufficient familiarity with Python and NetBox's data model.
To learn more about this feature, check out the [documentation for custom scripts](../customization/custom-scripts.md).
At its heart, NetBox is a tool for modeling your network infrastructure, and the device object is pivotal to that function. A device can be any piece of physical hardware installed within your network, such as server, router, or switch, and may optionally be mounted within a rack. Within each device, resources such as network interfaces and console ports are modeled as discrete components, which may optionally be grouped into modules.
NetBox uses device types to represent unique real-world device models. This allows a user to define a device type and all its components once, and easily replicate an unlimited number of device instances from it.
A manufacturer generally represents an organization which produces hardware devices. These can be defined by users, however they should represent an actual entity rather than some abstract idea.
## Device Types
A device type represents a unique combination of manufacturer and hardware model which maps to discrete make and model of device which exists in the real world. Each device type typically has a number of components created on it, representing network interfaces, device bays, and so on. New devices of this type can then be created in NetBox, and any associated components will be automatically replicated from the device type. This avoids needing to tediously recreate components for each device as it is added in NetBox.
!!! tip "The Device Type Library"
While users are always free to create their own device types in NetBox, many find it convenient to draw from our [community library](https://github.com/netbox-community/devicetype-library) of pre-defined device types. This is possible because a particular make and model of device is applicable universally and never changes.
All the following can be modeled as components:
* Interfaces
* Console ports
* Console server ports
* Power ports
* Power outlets
* Pass-through ports (front and rear)
* Module bays (which house modules)
* Device bays (which house child devices)
For example, a Juniper EX4300-48T device type might have the following component templates defined:
* One template for a console port ("Console")
* Two templates for power ports ("PSU0" and "PSU1")
* 48 templates for 1GE interfaces ("ge-0/0/0" through "ge-0/0/47")
* Four templates for 10GE interfaces ("xe-0/2/0" through "xe-0/2/3")
Once component templates have been created, every new device that you create as an instance of this type will automatically be assigned each of the components listed above.
!!! note "Component Instantiation is not Retroactive"
The instantiation of components from a device type definition occurs only at the time of device creation. If you modify the components assigned to a device type, it will not affect devices which have already been created. This guards against any inadvertent changes to existing devices. However, you always have the option of adding, modifying, or deleting components on existing devices. (These changes can easily be applied to multiple devices at once using the bulk operations available in the UI.)
## Devices
Whereas a device type defines the make and model of a device, a device itself represents an actual piece of installed hardware somewhere in the real world. A device can be installed at a particular position within an equipment rack, or simply associated with a site (and optionally with a location within that site).
Each device can have an operational status, functional role, and software platform assigned. Device components are instantiated automatically from the assigned device type upon creation.
### Virtual Chassis
Sometimes it is necessary to model a set of physical devices as sharing a single management plane. Perhaps the most common example of such a scenario is stackable switches. These can be modeled as virtual chassis in NetBox, with one device acting as the chassis master and the rest as members. All components of member devices will appear on the master.
### Virtual Device Contexts
A virtual device context (VDC) is a logical partition within a device. Each VDC operates autonomously but shares a common pool of resources. Each interface can be assigned to one or more VDCs on its device.
## Module Types & Modules
Much like device types and devices, module types can instantiate discrete modules, which are hardware components installed within devices. Modules often have their own child components, which become available to the parent device. For example, when modeling a chassis-based switch with multiple line cards in NetBox, the chassis would be created (from a device type) as a device, and each of its line cards would be instantiated from a module type as a module installed in one of the device's module bays.
!!! tip "Device Bays vs. Module Bays"
What's the difference between device bays and module bays? Device bays are appropriate when the installed hardware has its own management plane, isolated from the parent device. A common example is a blade server chassis in which the blades share power but operate independently. In contrast, a module bay holds a module which does _not_ operate independently of its parent device, as with the chassis switch line card example mentioned above.
One especially nice feature of modules is that templated components can be automatically renamed according to the module bay into which the parent module is installed. For example, if we create a module type with interfaces named `Gi{module}/0/1-48` and install a module of this type into module bay 7 of a device, NetBox will create interfaces named `Gi7/0/1-48`.
## Cables
NetBox models cables as connections among certain types of device components and other objects. Each cable can be assigned a type, color, length, and label. NetBox will enforce basic sanity checks to prevent invalid connections. (For example, a network interface cannot be connected to a power outlet.)
Either end of a cable may terminate to multiple objects of the same type. For example, a network interface can be connected via a fiber optic cable to two discrete ports on a patch panel (each port attaching to an individual fiber strand in the patch cable).
For example, suppose you want to automatically configure a monitoring system to start monitoring a device when its operational status is changed to active, and remove it from monitoring for any other status. You can create a webhook in NetBox for the device model and craft its content and destination URL to effect the desired change on the receiving system. You can then associate an event rule with this webhook and the webhook will be sent automatically by NetBox whenever the configured constraints are met.
Each event must be associated with at least one NetBox object type and at least one event (e.g. create, update, or delete).
## Conditional Event Rules
An event rule may include a set of conditional logic expressed in JSON used to control whether an event triggers for a specific object. For example, you may wish to trigger an event for devices only when the `status` field of an object is "active":
```json
{
"and":[
{
"attr":"status.value",
"value":"active"
}
]
}
```
For more detail, see the reference documentation for NetBox's [conditional logic](../reference/conditions.md).
## Event Rule Processing
When a change is detected, any resulting events are placed into a Redis queue for processing. This allows the user's request to complete without needing to wait for the outgoing event(s) to be processed. The events are then extracted from the queue by the `rqworker` process. The current event queue and any failed events can be inspected under System > Background Tasks.
From global regions down to individual equipment racks, NetBox allows you to model your network's entire presence. This is accomplished through the use of several purpose-built models. The graph below illustrates these models and their relationships.
```mermaid
flowchart TD
Region --> Region
SiteGroup --> SiteGroup
Region & SiteGroup --> Site
Site --> Location & Device
Location --> Location
Location --> Rack & Device
Rack --> Device
Site --> Rack
RackRole --> Rack
click Device "../../models/dcim/device/"
click Location "../../models/dcim/location/"
click Rack "../../models/dcim/rack/"
click RackRole "../../models/dcim/rackrole/"
click Region "../../models/dcim/region/"
click Site "../../models/dcim/site/"
click SiteGroup "../../models/dcim/sitegroup/"
```
## Regions
Regions represent geographic domains in which your network or its customers have a presence. These are typically used to model countries, states, and cities, although NetBox does not prescribe any precise uses and your needs may differ.
Regions are self-nesting, so you can define child regions within a parent, and grandchildren within each child. For example, you might create a hierarchy like this:
* Europe
* France
* Germany
* Spain
* North America
* Canada
* United States
* California
* New York
* Texas
Regions will always be listed alphabetically by name within each parent, and there is no maximum depth for the hierarchy.
## Site Groups
Like regions, site groups can be arranged in a recursive hierarchy for grouping sites. However, whereas regions are intended for geographic organization, site groups may be used for functional grouping. For example, you might classify sites as corporate, branch, or customer sites in addition to where they are physically located.
The use of both regions and site groups affords to independent but complementary dimensions across which sites can be organized.
## Sites
A site typically represents a building within a region and/or site group. Each site is assigned an operational status (e.g. active or planned), and can have a discrete mailing address and GPS coordinates assigned to it.
## Locations
A location can be any logical subdivision within a building, such as a floor or room. Like regions and site groups, locations can be nested into a self-recursive hierarchy for maximum flexibility. And like sites, each location has an operational status assigned to it.
## Racks
Finally, NetBox models each equipment rack as a discrete object within a site and location. These are physical objects into which devices are installed. Each rack can be assigned an operational status, type, facility ID, and other attributes related to inventory tracking. Each rack also must define a height (in rack units) and width, and may optionally specify its physical dimensions.
Each rack must be associated to a site, but the assignment to a location within that site is optional. Users can also create custom roles to which racks can be assigned. NetBox supports tracking rack space in half-unit increments, so it's possible to mount devices at e.g. position 2.5 within a rack.
!!! tip "Devices"
You'll notice in the diagram above that a device can be installed within a site, location, or rack. This approach affords plenty of flexibility as not all sites need to define child locations, and not all devices reside in racks.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.