From 4afebd3565145fffd6bee41b3679e99be88441d8 Mon Sep 17 00:00:00 2001 From: Anders Harrisson Date: Tue, 6 Feb 2024 12:32:03 +0100 Subject: [PATCH 01/80] Fix custom script documentation example script The example script still uses the old "role" field when creating a Device object. Fixes #15052 --- docs/customization/custom-scripts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/customization/custom-scripts.md b/docs/customization/custom-scripts.md index e2bc53cfc..c68bc21f1 100644 --- a/docs/customization/custom-scripts.md +++ b/docs/customization/custom-scripts.md @@ -390,7 +390,7 @@ class NewBranchScript(Script): name=f'{site.slug}-switch{i}', site=site, status=DeviceStatusChoices.STATUS_PLANNED, - role=switch_role + device_role=switch_role ) switch.full_clean() switch.save() From 64b2ebdc794f80af8f021eb2a0d425f1a1f32bfd Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 8 Feb 2024 08:47:16 -0500 Subject: [PATCH 02/80] Fixes #15084: Fix "add export template" link --- docs/release-notes/version-3.7.md | 4 ++++ netbox/utilities/templates/buttons/export.html | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.7.md b/docs/release-notes/version-3.7.md index 103b0664c..531678f2d 100644 --- a/docs/release-notes/version-3.7.md +++ b/docs/release-notes/version-3.7.md @@ -2,6 +2,10 @@ ## v3.7.3 (FUTURE) +### Bug Fixes + +* [#15084](https://github.com/netbox-community/netbox/issues/15084) - Fix "add export template" link under "export" button on object list views + --- ## v3.7.2 (2024-02-05) diff --git a/netbox/utilities/templates/buttons/export.html b/netbox/utilities/templates/buttons/export.html index 879fc02c5..baa1253eb 100644 --- a/netbox/utilities/templates/buttons/export.html +++ b/netbox/utilities/templates/buttons/export.html @@ -25,7 +25,7 @@
  • - {% trans "Add export template" %}... + {% trans "Add export template" %}...
  • {% endif %} From 040dbcc8751f51aaf650ba07ec7861c20b7aeb35 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 8 Feb 2024 09:10:24 -0500 Subject: [PATCH 03/80] Fixes #15070: Fix inclusion of config_template field on REST API serializer for virtual machines --- docs/release-notes/version-3.7.md | 1 + netbox/virtualization/api/serializers.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/version-3.7.md b/docs/release-notes/version-3.7.md index 531678f2d..e3c2f8e48 100644 --- a/docs/release-notes/version-3.7.md +++ b/docs/release-notes/version-3.7.md @@ -4,6 +4,7 @@ ### Bug Fixes +* [#15070](https://github.com/netbox-community/netbox/issues/15070) - Fix inclusion of `config_template` field on REST API serializer for virtual machines * [#15084](https://github.com/netbox-community/netbox/issues/15084) - Fix "add export template" link under "export" button on object list views --- diff --git a/netbox/virtualization/api/serializers.py b/netbox/virtualization/api/serializers.py index 7ed36388b..1dcb413ec 100644 --- a/netbox/virtualization/api/serializers.py +++ b/netbox/virtualization/api/serializers.py @@ -103,8 +103,8 @@ class VirtualMachineWithConfigContextSerializer(VirtualMachineSerializer): fields = [ 'id', 'url', 'display', 'name', 'status', 'site', 'cluster', 'device', 'role', 'tenant', 'platform', 'primary_ip', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory', 'disk', 'description', 'comments', - 'local_context_data', 'tags', 'custom_fields', 'config_context', 'created', 'last_updated', - 'interface_count', 'virtual_disk_count', + 'config_template', 'local_context_data', 'tags', 'custom_fields', 'config_context', 'created', + 'last_updated', 'interface_count', 'virtual_disk_count', ] @extend_schema_field(serializers.JSONField(allow_null=True)) From ae7d6ffd925ecdd9f921a594f2e1858b4da3c8e5 Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Mon, 12 Feb 2024 17:31:59 +0900 Subject: [PATCH 04/80] Update remote-authentication.md Seperator -> Separator --- docs/configuration/remote-authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration/remote-authentication.md b/docs/configuration/remote-authentication.md index fb789bd98..e7fe56a09 100644 --- a/docs/configuration/remote-authentication.md +++ b/docs/configuration/remote-authentication.md @@ -67,7 +67,7 @@ When remote user authentication is in use, this is the name of the HTTP header w 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` ) +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` ) --- From c7ae2db8e31960ee1b38d11c15108b3e07ffbbf9 Mon Sep 17 00:00:00 2001 From: teapot Date: Sun, 11 Feb 2024 14:50:24 +0900 Subject: [PATCH 05/80] Fixes #15111: Correct typo in error message --- netbox/dcim/models/devices.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/models/devices.py b/netbox/dcim/models/devices.py index 4b9689a22..f9e8ba213 100644 --- a/netbox/dcim/models/devices.py +++ b/netbox/dcim/models/devices.py @@ -875,7 +875,7 @@ class Device( if self.position and self.device_type.u_height == 0: raise ValidationError({ 'position': _( - "A U0 device type ({device_type}) cannot be assigned to a rack position." + "A 0U device type ({device_type}) cannot be assigned to a rack position." ).format(device_type=self.device_type) }) From 1f800a975fe2549903a41a3c5da64f437e1bc8f8 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 13 Feb 2024 09:34:59 -0500 Subject: [PATCH 06/80] Fixes #15115: Fix unhandled exception with invalid permission constraints --- netbox/users/forms/model_forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/users/forms/model_forms.py b/netbox/users/forms/model_forms.py index 99320fa25..aa5811cd1 100644 --- a/netbox/users/forms/model_forms.py +++ b/netbox/users/forms/model_forms.py @@ -385,7 +385,7 @@ class ObjectPermissionForm(BootstrapMixin, forms.ModelForm): CONSTRAINT_TOKEN_USER: 0, # Replace token with a null user ID } model.objects.filter(qs_filter_from_constraints(constraints, tokens)).exists() - except FieldError as e: + except (FieldError, ValueError) as e: raise forms.ValidationError({ 'constraints': _('Invalid filter for {model}: {error}').format(model=model, error=e) }) From df910928f2f3cc429ffe50f9f8a40cc1664cbdc7 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 13 Feb 2024 09:26:45 -0500 Subject: [PATCH 07/80] Fixes #15126: group field should be optional when creating VPN tunnel via REST API --- netbox/vpn/api/serializers.py | 5 ++++- netbox/vpn/tests/test_api.py | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/netbox/vpn/api/serializers.py b/netbox/vpn/api/serializers.py index dedcbfbf5..5f6fcd5f7 100644 --- a/netbox/vpn/api/serializers.py +++ b/netbox/vpn/api/serializers.py @@ -46,7 +46,10 @@ class TunnelSerializer(NetBoxModelSerializer): status = ChoiceField( choices=TunnelStatusChoices ) - group = NestedTunnelGroupSerializer() + group = NestedTunnelGroupSerializer( + required=False, + allow_null=True + ) encapsulation = ChoiceField( choices=TunnelEncapsulationChoices ) diff --git a/netbox/vpn/tests/test_api.py b/netbox/vpn/tests/test_api.py index eb0520c8b..64c175fe5 100644 --- a/netbox/vpn/tests/test_api.py +++ b/netbox/vpn/tests/test_api.py @@ -105,7 +105,6 @@ class TunnelTest(APIViewTestCases.APIViewTestCase): { 'name': 'Tunnel 6', 'status': TunnelStatusChoices.STATUS_DISABLED, - 'group': tunnel_groups[1].pk, 'encapsulation': TunnelEncapsulationChoices.ENCAP_GRE, }, ] From c37dfdc15028170863cb37379ea164ecf9129303 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 13 Feb 2024 09:42:10 -0500 Subject: [PATCH 08/80] Fixes #15091: Fix initial active tab when editing an L2VPN termination --- netbox/templates/vpn/l2vpntermination_edit.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/templates/vpn/l2vpntermination_edit.html b/netbox/templates/vpn/l2vpntermination_edit.html index 0df2c883e..cbce78dbc 100644 --- a/netbox/templates/vpn/l2vpntermination_edit.html +++ b/netbox/templates/vpn/l2vpntermination_edit.html @@ -13,7 +13,7 @@
    -
    +
    {% render_field form.vlan %}
    From 12d830bcf2a552adcf423fc13f857a5f2f473aee Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 13 Feb 2024 11:29:53 -0500 Subject: [PATCH 09/80] 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 --- netbox/ipam/api/nested_serializers.py | 3 ++- netbox/ipam/tests/test_api.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/netbox/ipam/api/nested_serializers.py b/netbox/ipam/api/nested_serializers.py index 17d8d74a7..c012eca6d 100644 --- a/netbox/ipam/api/nested_serializers.py +++ b/netbox/ipam/api/nested_serializers.py @@ -116,10 +116,11 @@ class NestedFHRPGroupSerializer(WritableNestedSerializer): class NestedFHRPGroupAssignmentSerializer(WritableNestedSerializer): url = serializers.HyperlinkedIdentityField(view_name='ipam-api:fhrpgroupassignment-detail') + group = NestedFHRPGroupSerializer() class Meta: model = models.FHRPGroupAssignment - fields = ['id', 'url', 'display', 'interface_type', 'interface_id', 'group_id', 'priority'] + fields = ['id', 'url', 'display', 'group', 'interface_type', 'interface_id', 'priority'] # diff --git a/netbox/ipam/tests/test_api.py b/netbox/ipam/tests/test_api.py index cb633e162..447415a69 100644 --- a/netbox/ipam/tests/test_api.py +++ b/netbox/ipam/tests/test_api.py @@ -760,7 +760,7 @@ class FHRPGroupTest(APIViewTestCases.APIViewTestCase): class FHRPGroupAssignmentTest(APIViewTestCases.APIViewTestCase): model = FHRPGroupAssignment - brief_fields = ['display', 'group_id', 'id', 'interface_id', 'interface_type', 'priority', 'url'] + brief_fields = ['display', 'group', 'id', 'interface_id', 'interface_type', 'priority', 'url'] bulk_update_data = { 'priority': 100, } From 01fa2710eba125dbc49e5378198fc10f178e58bd Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 13 Feb 2024 10:20:26 -0500 Subject: [PATCH 10/80] Fixes #15067: Fix uncaught exception when attempting invalid device bay import --- netbox/dcim/forms/bulk_import.py | 2 +- netbox/dcim/models/device_components.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/netbox/dcim/forms/bulk_import.py b/netbox/dcim/forms/bulk_import.py index f30ff91fa..732bb87ae 100644 --- a/netbox/dcim/forms/bulk_import.py +++ b/netbox/dcim/forms/bulk_import.py @@ -996,7 +996,7 @@ class DeviceBayImportForm(NetBoxModelImportForm): device_type__subdevice_role=SubdeviceRoleChoices.ROLE_CHILD ).exclude(pk=device.pk) else: - self.fields['installed_device'].queryset = Interface.objects.none() + self.fields['installed_device'].queryset = Device.objects.none() class InventoryItemImportForm(NetBoxModelImportForm): diff --git a/netbox/dcim/models/device_components.py b/netbox/dcim/models/device_components.py index 88dddb312..5b2564b32 100644 --- a/netbox/dcim/models/device_components.py +++ b/netbox/dcim/models/device_components.py @@ -1133,13 +1133,13 @@ class DeviceBay(ComponentModel, TrackingModelMixin): super().clean() # Validate that the parent Device can have DeviceBays - if not self.device.device_type.is_parent_device: + if hasattr(self, 'device') and not self.device.device_type.is_parent_device: raise ValidationError(_("This type of device ({device_type}) does not support device bays.").format( device_type=self.device.device_type )) # Cannot install a device into itself, obviously - if self.device == self.installed_device: + if self.installed_device and getattr(self, 'device', None) == self.installed_device: raise ValidationError(_("Cannot install a device into itself.")) # Check that the installed device is not already installed elsewhere From 2d70b502868d1fd5f4e01b12621c19966b92168a Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 13 Feb 2024 10:36:23 -0500 Subject: [PATCH 11/80] Fixes #15059: Correct IP address count link in VM interfaces table --- netbox/dcim/tables/template_code.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/tables/template_code.py b/netbox/dcim/tables/template_code.py index 3f8b63688..de27d67ad 100644 --- a/netbox/dcim/tables/template_code.py +++ b/netbox/dcim/tables/template_code.py @@ -37,7 +37,7 @@ DEVICEBAY_STATUS = """ INTERFACE_IPADDRESSES = """
    {% if value.count >= 3 %} - {{ value.count }} + {{ value.count }} {% else %} {% for ip in value.all %} {% if ip.status != 'active' %} From 20824ceb25bf47ab7e399d2c5c83bbc260e13649 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 13 Feb 2024 16:31:17 -0500 Subject: [PATCH 12/80] Closes #13283: Add context to dropdown options (#15104) * 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 --- docs/customization/custom-scripts.md | 17 +++++++ netbox/dcim/forms/bulk_edit.py | 6 +++ netbox/dcim/forms/connections.py | 12 +++-- netbox/dcim/forms/model_forms.py | 26 ++++++++-- netbox/extras/scripts.py | 5 +- netbox/ipam/forms/model_forms.py | 8 ++- netbox/project-static/dist/netbox.js | Bin 374348 -> 375736 bytes netbox/project-static/dist/netbox.js.map | Bin 339643 -> 340629 bytes .../src/select/classes/dynamicTomSelect.ts | 46 ++++++++++++++++-- netbox/project-static/src/select/dynamic.ts | 35 ++++++++++--- netbox/project-static/src/select/static.ts | 11 +++-- netbox/utilities/forms/fields/dynamic.py | 26 ++++++++-- netbox/wireless/forms/model_forms.py | 8 ++- 13 files changed, 171 insertions(+), 29 deletions(-) diff --git a/docs/customization/custom-scripts.md b/docs/customization/custom-scripts.md index 96423a94b..bdc3f9104 100644 --- a/docs/customization/custom-scripts.md +++ b/docs/customization/custom-scripts.md @@ -304,6 +304,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 `