Commit Graph

15152 Commits

Author SHA1 Message Date
bctiemann 25fb457331
Merge pull request #21846 from netbox-community/21780-add-changelog-message-support-to-bulk-creation-of-ip
Closes #21780: Add changelog message support for bulk creation of IP Addresses and Prefixes
2026-04-07 10:21:16 -04:00
Jeremy Stretch 06c90cb86a
Closes #21847: Correct webhook documentation for deprecated keys (#21848) 2026-04-07 15:58:45 +02:00
Jeremy Stretch bcc410d99f
Closes #20924: Ready UI components for use by plugins (#21827)
* Misc cleanup

* Include permissions in TemplatedAttr context

* Introduce CircuitTerminationPanel to replace generic panel

* Replace all instantiations of Panel with TemplatePanel

* Misc cleanup for layouts

* Enable specifying column grid width

* Panel.render() should pass the request to render_to_string()

* CopyContent does not need to override render()

* Avoid setting mutable panel actions

* Catch exceptions raised when rendering embedded plugin content

* Handle panel title when object is not available

* Introduce should_render() method on Panel class

* Misc cleanup

* Pass the value returned by get_context() to should_render()

* Yet more cleanup

* Fix typos

* Clean up object attrs

* Replace candidate template panels with ObjectAttributesPanel subclasses

* Add tests for object attrs

* Remove beta warning

* PluginContentPanel should not call should_render()

* Clean up AddObject

* speed.html should reference value for port_speed

* Address PR feedback
2026-04-06 15:35:18 -04:00
Martin Hauser d630afaf14
feat(ipam): Add changelog message support to bulk Prefix/IP creation
Extend bulk add forms for Prefix and IPAddress to support changelog
messages. Switch IPAddressBulkAddForm to PrimaryModelForm base, update
field ordering, consolidate template rendering, and add test coverage.

Fixes #21780
2026-04-06 20:15:02 +02:00
Martin Hauser d6a1cc5558 test(tables): Add reusable StandardTableTestCase
Introduce `TableTestCases.StandardTableTestCase`, a shared base class
for model-backed table smoke tests. It currently discovers sortable
columns from list-view querysets and verifies that each renders without
exceptions in both ascending and descending order.

Add per-table smoke tests across circuits, core, dcim, extras, ipam,
tenancy, users, virtualization, vpn, and wireless apps.

Fixes #21766
2026-04-06 13:53:13 -04:00
github-actions 09f7df0726 Update source translation strings 2026-04-04 05:26:28 +00:00
Martin Hauser f242f17ce5
Fixes #21542: Increase supported interface speed values above 2.1 Tbps (#21834) 2026-04-03 16:55:11 -05:00
Jeremy Stretch 2b1f4ab51a Add migration files for indexes 2026-04-03 16:32:08 -04:00
Jeremy Stretch 84502e80d0 Add SQL indexes for default ordering on applicable models 2026-04-03 16:22:18 -04:00
bctiemann 7d71503ea2
Merge pull request #21837 from netbox-community/21795-update-humanize_speed-to-support-decimal-gbpstbps-output
Closes #21795: Improve humanize_speed formatting for decimal Gbps/Tbps values
2026-04-03 13:06:55 -04:00
bctiemann 02f9ca8f01
Merge pull request #21816 from netbox-community/21770-embedded-table-columns
Closes #21770: Enable including/excluding columns on ObjectsTablePanel
2026-04-03 13:04:27 -04:00
Jeremy Stretch d0651f6474
Release v4.5.7 (#21838) 2026-04-03 12:24:24 -04:00
Jeremy Stretch fecd4e2f97 Closes #21839: Document the RQ configuration parameter 2026-04-03 12:01:15 -04:00
Martin Hauser e07a5966ae
feat(dcim): Support decimal Gbps/Tbps output in humanize_speed
Update the humanize_speed template filter to always use the largest
appropriate unit, even when the result is not a whole number.
Previously, values like 2500000 Kbps rendered as "2500 Mbps" instead of
"2.5 Gbps", and 1600000000 Kbps rendered as "1600 Gbps" instead of
"1.6 Tbps".

Fixes #21795
2026-04-03 15:36:42 +02:00
github-actions f058ee3d60 Update source translation strings 2026-04-03 05:31:13 +00:00
bctiemann 49ba0dd495
Fix filtering of object-type custom fields when "is empty" is selected (#21829) 2026-04-02 16:17:49 -07:00
Martin Hauser b4ee2cf447
fix(dcim): Refresh stale CablePath references during serialization (#21815)
Cable edits can delete and recreate CablePath rows while endpoint
instances remain in memory. Deferred event serialization can then
encounter a stale `_path` reference and raise `CablePath.DoesNotExist`.

Refresh stale `_path` references through `PathEndpoint.path` and route
internal callers through that accessor. Update `EventContext` to track
the latest serialization source for coalesced duplicate enqueues, while
eagerly freezing delete-event payloads before row removal.

Also avoid mutating `event_rule.action_data` when merging the event
payload.

Fixes #21498
2026-04-02 15:49:42 -07:00
Jason Novinger 34098bb20a
Fixes #21760: Add 1C2P:2C1P breakout cable profile (#21824)
* Add Breakout1C2Px2C1PCableProfile class
* Add BREAKOUT_1C2P_2C1P choice
* Add new CableProfileChoices (BREAKOUT_1C2P_2C1P)

---------

Co-authored-by: Paulo Santos <paulo.banon@gmail.com>
2026-04-02 23:33:35 +02:00
Jonathan Senecal a19daa5466
Fixes #21095: Add IEC unit labels support and rename humanize helpers to be unit-agnostic (#21789) 2026-04-02 14:30:49 -07:00
bctiemann 40eec679d9
Fixes: #21696 - Upgrade to django-rq==4.0.1 (#21805) 2026-04-02 14:09:53 -07:00
Martin Hauser 57556e3fdb fix(tables): Correct sortable column definitions across tables
Fix broken sorting metadata caused by incorrect accessors, field
references, and naming mismatches in several table definitions.

Update accessor paths for provider_account and device order_by; add
order_by mapping for the is_active property column; correct field name
typos such as termination_count to terminations_count; rename the
ssl_validation column to ssl_verification to match the model field; and
mark computed columns as orderable=False where sorting is not supported.

Fixes #21825
2026-04-02 16:20:53 -04:00
Martin Hauser 5ad4e95207
Closes #21720: Improve validation of URLs containing HTTP basic authentication (#21822)
Fixes #21720
2026-04-02 11:42:06 -05:00
Arthur Hanson f2d8ae29c2
21701 Allow scripts to be uploaded via post to API (#21756)
* #21701 allow upload script via API

* #21701 allow upload script via API

* add extra test

* change to use Script api endpoint

* ruff fix

* review feedback:

* review feedback:

* review feedback:

* Fix permission check, perform_create delegation, and test mock setup

- destroy() now checks extras.delete_script (queryset is Script.objects.all())
- create() delegates to self.perform_create() instead of calling serializer.save() directly
- Add comment explaining why update/partial_update intentionally return 405
- Fix test_upload_script_module: set mock_storage.save.return_value so file_path
  receives a real string after the _save_upload return-value fix; add DB existence check

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Return 400 instead of 500 on duplicate script module upload

Catch IntegrityError from the unique (file_root, file_path) constraint
and re-raise as a ValidationError so the API returns a 400 with a clear
message rather than a 500.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Validate upload_file + data_source conflict for multipart requests

DRF 3.16 Serializer.get_value() uses parse_html_dict() or empty for all
HTML/multipart input. A flat key like data_source=2 produces an empty
dict ({}), which is falsy, so it falls back to empty and the nested
field is silently skipped. data.get('data_source') is therefore always
None in multipart requests, bypassing the conflict check.

Fix: also check self.initial_data for data_source and data_file in all
three guards in validate(), so the raw submitted value is detected even
when DRF's HTML parser drops the deserialized object.

Add test_upload_with_data_source_fails to cover the multipart conflict
path explicitly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Require data_file when data_source is specified

data_source alone is not a valid creation payload — a data_file must
also be provided to identify which file within the source to sync.
Add the corresponding validation error and a test to cover the case.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Align ManagedFileForm validation with API serializer rules

Add the missing checks to ManagedFileForm.clean():
- upload_file + data_source is rejected (matches API)
- data_source without data_file is rejected with a specific message
- Update the 'nothing provided' error to mention data source + data file

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Revert "Align ManagedFileForm validation with API serializer rules"

This reverts commit f0ac7c3bd2.

* Align API validation messages with UI; restore complete checks

- Match UI error messages for upload+data_file conflict and no-source case
- Keep API-only guards for upload+data_source and data_source-without-data_file
- Restore test_upload_with_data_source_fails

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Run source/file conflict checks before super().validate() / full_clean()

super().validate() calls full_clean() on the model instance, which raises
a unique-constraint error for (file_root, file_path) when file_path is
empty (e.g. data_source-only requests). Move the conflict guards above the
super() call so they produce clear, actionable error messages before
full_clean() has a chance to surface confusing database-level errors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* destroy() deletes ScriptModule, not Script

DELETE /api/extras/scripts/<pk>/ now deletes the entire ScriptModule
(matching the UI's delete view), including modules with no Script
children (e.g. sync hasn't run yet). Permission check updated to
delete_scriptmodule. The queryset restriction for destroy is removed
since the module is deleted via script.module, not super().destroy().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* review feedback:

* cleanup

* cleanup

* cleanup

* cleanup

* change to ScriptModule

* change to ScriptModule

* change to ScriptModule

* update docs

* cleanup

* restore file

* cleanup

* cleanup

* cleanup

* cleanup

* cleanup

* keep only upload functionality

* cleanup

* cleanup

* cleanup

* change to scripts/upload api

* cleanup

* cleanup

* cleanup

* cleanup

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 08:42:14 -04:00
github-actions f6eb5dda0f Update source translation strings 2026-04-02 05:30:39 +00:00
Mark Robert Coleman a06a300913
Implement {module} position inheritance for nested module bays (#21753)
* Implement {module} position inheritance for nested module bays (#19796)

Enables a single ModuleType to produce correctly named components at any
nesting depth by resolving {module} in module bay position fields during
tree traversal. The user controls the separator through the position
field template itself (e.g. {module}/1 vs {module}-1 vs {module}.1).

Model layer:
- Add _get_inherited_positions() to resolve {module} in positions as
  the module tree is walked from root to leaf
- Update _resolve_module_placeholder() with single-token logic: one
  {module} resolves to the leaf bay's inherited position; multi-token
  continues level-by-level replacement for backwards compatibility

Form layer:
- Update _get_module_bay_tree() to resolve {module} in positions during
  traversal, propagating parent positions through the tree
- Extract validation into _validate_module_tokens() private method

Tests:
- Position inheritance at depth 2 and 3
- Custom separator (dot notation)
- Multi-token backwards compatibility
- Documentation for position inheritance

Fixes: #19796

* Consolidate {module} placeholder logic into shared utilities and add API validation

Extract get_module_bay_positions() and resolve_module_placeholder() into
dcim/utils.py as shared routines used by the model, form, and API serializer.
This eliminates duplicated traversal and resolution logic across three layers.

Key changes:
- Add position inheritance: {module} tokens in bay position fields resolve
  using the parent bay's position during hierarchy traversal
- Single {module} token now resolves to the leaf bay's inherited position
- Mismatched token count vs tree depth now raises ValueError instead of
  silently producing partial strings
- API serializer validation uses shared utilities for parity with the form
- Fix error message wording ("levels deep" instead of "in tree")
2026-04-01 17:58:16 -07:00
Mark Robert Coleman c7bbfb24c5
Fix single {module} token rejection at nested module bay depth (#21740)
* Fix single {module} token rejection at nested depth (#20474)

A module type with a single {module} placeholder in component template
names could not be installed in a nested module bay (depth > 1) because
the form validation required an exact match between the token count and
the tree depth. This resolves the issue by treating a single {module}
token as a reference to the immediate parent bay's position, regardless
of nesting depth. Multi-token behavior is unchanged.

Refactors resolve_name() and resolve_label() into a shared
_resolve_module_placeholder() helper to eliminate duplication.

Fixes: #20474

* Address review feedback for PR #21740 (fixes #20474)

- Rebase on latest main to resolve merge conflicts
- Extract shared module bay traversal and {module} token resolution
  into dcim/utils.py (get_module_bay_positions, resolve_module_placeholder)
- Update ModuleCommonForm, ModularComponentTemplateModel, and
  ModuleBayTemplate to use shared utility functions
- Add {module} token validation to ModuleSerializer.validate() so the
  API enforces the same rules as the UI form
- Remove duplicated _get_module_bay_tree (form) and _get_module_tree
  (model) methods in favor of the shared routine
2026-04-01 16:19:43 -07:00
Jeremy Stretch 6c08941542 Tweak behavior of include_columns 2026-04-01 14:58:41 -04:00
Jeremy Stretch be1a29d7ee Misc cleanup 2026-04-01 14:46:53 -04:00
Jeremy Stretch f06f8f3f1d Exclude assigned object columns from IP addresses table on interface views 2026-04-01 14:25:31 -04:00
Jeremy Stretch a45ec6620a Protect exempt columns from exclusion 2026-04-01 14:17:57 -04:00
Jeremy Stretch bd35afe320 Apply column hiding before prefetching 2026-04-01 14:14:13 -04:00
Jeremy Stretch 364868a207 Implement exclude_columns on embedded tables 2026-04-01 13:46:59 -04:00
Jeremy Stretch d4569df305 Closes #21770: Enable including/excluding columns on ObjectsTablePanel 2026-04-01 13:32:42 -04:00
Jeremy Stretch b62c5e1ac4 Merge branch 'main' into feature 2026-04-01 13:22:52 -04:00
bctiemann 1277bb6138
Merge pull request #21806 from netbox-community/21771-rest-api-add-remove-tags
Closes #21771: Add `add_tags` & `remove_tags` fields for taggable objects
2026-04-01 13:02:19 -04:00
Fabi e98e5e11a7
Fixes #21784: Fix AttributeError when an AnonymousUser tries to sort a table (#21817) 2026-04-01 18:36:21 +02:00
Johannes Rueschel 3ce2bf75b4
Fixes #21533: Fix missing `family`/`mask_length` in API when creating IP-related objects (#21546) 2026-04-01 11:25:00 -05:00
Martin Hauser b1af9a7218
fix(dcim): Use hasattr check for virtual_circuit_termination (#21811)
Replace direct attribute access with hasattr() to prevent AttributeError
when the virtual_circuit_termination relation doesn't exist on the
object.

Fixes #21808
2026-04-01 18:06:18 +02:00
Artem Kotik b73f7f7d00
Fixes #21655: Fix duplicate SQL queries on serializing custom fields (#21750)
Co-authored-by: Jason Novinger <jnovinger@gmail.com>
Co-authored-by: Artem Kotik <artem.i.kotik@ringcentral.com>
2026-04-01 09:52:38 -05:00
Martin Hauser 9492b55f4b fix(dcim): Fix Virtual Chassis Member add action context
Fix context variable references in VirtualChassMembersPanel add action
to use 'virtual_chassis' instead of 'object'. Add safe checks for
master_id existence to prevent errors when master is not set.

Fixes #21810
2026-04-01 08:59:39 -04:00
github-actions 2563122352 Update source translation strings 2026-04-01 05:39:05 +00:00
Martin Hauser 0455e14c29 docs(plugins): Use @register_search in plugin search docs
Align the plugin search example with the recommended registration
pattern used in the general search documentation and NetBox core.

Replace the legacy `indexes = [...]` example with decorator-based
registration to make the preferred approach clearer for plugin authors.
2026-03-31 16:55:27 -04:00
Jeremy Stretch 76c02d5aa9 Raise a validation error if the same tag is present in both add_tags and remove_tags 2026-03-31 16:44:37 -04:00
Jeremy Stretch 8bc691099c Raise a validation error if remove_tags is specified when creating an object 2026-03-31 16:38:15 -04:00
Jeremy Stretch 95011821bb Closes #21771: Add add_tags & remove_tags fields for taggable objects 2026-03-31 16:02:32 -04:00
bctiemann b8b12f3f90
#20923 - Convert extras to new declarative UI layout (#21765) 2026-03-31 20:28:16 +02:00
Jeremy Stretch e5b9e5a279
Closes #19025: Add schema validation for JSON custom fields (#21746) 2026-03-31 12:41:49 -05:00
Jeremy Stretch 05059f4a86 Release v4.5.6 2026-03-31 12:43:26 -04:00
Martin Hauser 2389feea6b feat(virtualization): Add Virtual Machine Type model
Introduce `VirtualMachineType` to classify virtual machines and apply
default platform, vCPU, and memory values when creating a VM.

This adds the new model and its relationship to `VirtualMachine`, and
wires it through forms, filtersets, tables, views, the REST API,
GraphQL, navigation, search, documentation, and tests.

Explicit values set on a virtual machine continue to take precedence,
and changes to a type do not retroactively update existing VMs.
2026-03-31 09:10:02 -04:00
Martin Hauser e4e4c1c56d
feat(dcim): Add 50G, 800G, and 1.6T interface speed options (#21796)
Adds support for 50 Gbps, 800 Gbps, and 1.6 Tbps interface speeds to
the InterfaceSpeedChoices to cover newer high-speed networking hardware.
2026-03-31 14:33:23 +02:00