Commit Graph

15342 Commits

Author SHA1 Message Date
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
Martin Hauser c99d8481b2 refactor(ui): Improve object change diff styling and layout
Update change data diff styling with CSS custom properties, better color
contrast, and consistent borders. Replace btn-group with card-actions
for navigation buttons and improve spacing.
2026-03-31 08:26:01 -04:00
Martin Hauser 0923a3dec8 fix(tables): Disable ordering on non-orderable accessor columns
Mark provider, member, and action_object columns as non-orderable since
they use complex accessors that cannot be sorted. Add regression tests
to verify all orderable columns render without exceptions.

Fixes table rendering errors when attempting to sort columns with
multi-level field accessors that don't support database ordering.
2026-03-31 08:18:36 -04:00
Martin Hauser 80b9c25674
feat(dcim): Add 2.5GE SFP interface type (#21794)
Add the `SFP (2.5GE)` interface type for devices with dedicated 2.5G SFP
slots that do not fit the existing SFP or SFP+ options.
2026-03-31 14:09:44 +02:00
github-actions 6d13bc8b96 Update source translation strings 2026-03-31 05:31:31 +00:00
Jeremy Stretch ee17e83da6
Update `CLAUDE.md` (#21777) 2026-03-30 16:33:10 -05:00
Jeremy Stretch 5ab9608e38
Revert "Fixes #21747: Skip search caching when encountering an invalid schema during migrations (#21748)" (#21787)
This reverts commit 296b89ae02.
2026-03-30 23:31:41 +02:00
Martin Hauser c7504628bd
feat(dcim): Add changelog message support to bulk component creation (#21769)
Add ChangelogMessageMixin to DeviceBulkAddComponentForm and capture
changelog_message during bulk component creation. Ensure message is
applied to each created component instance. Add test coverage for
changelog message propagation.
2026-03-30 08:42:05 -07:00
bctiemann e54ed87863
Merge pull request #21778 from netbox-community/21763-m2m-form-fields
Fixes #21763: Replace M2M selection field with separate add/remove fields
2026-03-30 11:23:36 -04:00
Jeremy Stretch 55daf4c52f Add/fix tests 2026-03-30 10:02:38 -04:00
Jeremy Stretch a45e8571da Revert changes to ASNForm 2026-03-30 09:29:08 -04:00