Commit Graph

15314 Commits

Author SHA1 Message Date
Martin Hauser a93aae12fa
Closes #21862: Stabilize ScriptModule tests and reduce CI noise (#21867) 2026-04-09 09:33:55 -05:00
Martin Hauser cb7e97c7f7 docs(configuration): Expand S3 storage configuration examples
Update STORAGES configuration examples to include all three storage
backends (default, staticfiles, scripts) with complete option sets.
Add region_name to environment variable example and clarify usage for
S3-compatible services.

Fixes #21864
2026-04-09 09:52:07 -04:00
Martin Hauser e864dc3ae0
fix(extras): Ensure unique Image Attachment names on S3
Make image attachment filename generation use Django's base collision
handling so overwrite-style storage backends behave like local file
storage.

This preserves the original filename for the first upload, adds a
suffix only on collision, and avoids duplicate image paths in object
change records.

Add regression tests for path generation and collision handling.

Fixes #21801
2026-04-08 22:16:36 +02:00
github-actions dbb871b75a Update source translation strings 2026-04-08 05:32:13 +00:00
Jeremy Stretch d75583828b
Fixes #21835: Remove misleading help text from ColorField (#21852) 2026-04-07 22:50:41 +02:00
Martin Hauser 7ff7c6d17e feat(ui): Add colored rendering for related object attributes
Introduce `colored` parameter to `RelatedObjectAttr`,
`NestedObjectAttr`, and `ObjectListAttr` to render objects as colored
badges when they expose a `color` attribute.
Update badge template tag to support hex colors and optional URLs.
Apply colored rendering to circuit types, device roles, rack roles,
inventory item roles, and VM roles.

Fixes #21430
2026-04-07 16:40:18 -04:00
bctiemann cc03d509d1
Merge pull request #21842 from netbox-community/21455-sql-indexes-audit
Closes #21455: Add SQL indexes for default ordering
2026-04-07 13:00:17 -04:00
Jeremy Stretch 296e708e09
Fixes #21814: Correct display of custom script "last run" time (#21853) 2026-04-07 18:11:12 +02:00
Jeremy Stretch 87bc20cdd5 Add default ordering index for ipam.VLANGroup 2026-04-07 12:04:42 -04:00
Jeremy Stretch 1bbecef77d
Fixes #21841: Fix display of the "edit" button for script modules (#21851) 2026-04-07 08:48:40 -07:00
Jeremy Stretch 1ebeb71ad8
Fixes #21845: Remove whitespace from connection values in interface CSV exports (#21850) 2026-04-07 10:38:22 -05:00
Jeremy Stretch 48e790c9f0
#21409: Disable CHANGELOG_RETAIN_CREATE_LAST_UPDATE by default (#21849) 2026-04-07 16:26:26 +02:00
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