From 75b0bea22b15adabe95d53f2af74653e46e4e752 Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Mon, 19 Aug 2024 21:16:08 -0500 Subject: [PATCH 1/3] Fixes: #14044 - Allow regex renaming of unnamed devices * Allow regex renaming of unnamed devices (already allowed actually) * Catch errors relating to unnamed devices or integrity errors as a result of the rename process --- netbox/dcim/views.py | 11 +++++++++++ netbox/netbox/views/generic/bulk_views.py | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index b18ecdd5b6..a89bafc1a1 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -2122,6 +2122,17 @@ class DeviceBulkRenameView(generic.BulkRenameView): filterset = filtersets.DeviceFilterSet table = tables.DeviceTable + def _rename_objects(self, form, selected_objects): + # Check devices for any unnamed devices and enforce requirements on the renaming of devices + for obj in selected_objects: + if not form.cleaned_data['use_regex'] and not obj.name: + from django.core.exceptions import ValidationError + raise ValidationError({ + 'use_regex': 'You must use regex to rename a unnamed device and must pass device uniqueness checks' + }) + + super()._rename_objects(form, selected_objects) + @register_model_view(Device, 'contacts') class DeviceContactsView(ObjectContactsView): diff --git a/netbox/netbox/views/generic/bulk_views.py b/netbox/netbox/views/generic/bulk_views.py index bdc9a7152a..8270507b5f 100644 --- a/netbox/netbox/views/generic/bulk_views.py +++ b/netbox/netbox/views/generic/bulk_views.py @@ -776,6 +776,14 @@ def post(self, request): ) return redirect(self.get_return_url(request)) + except IntegrityError as e: + messages.error(self.request, ", ".join(e.args)) + clear_events.send(sender=self) + + except ValidationError as e: + messages.error(self.request, ", ".join(e.messages)) + clear_events.send(sender=self) + except (AbortRequest, PermissionsViolation) as e: logger.debug(e.message) form.add_error(None, e.message) From ec3a7f3bcbd00969e76df588b999f41a29eef705 Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Sun, 25 Aug 2024 15:55:18 -0500 Subject: [PATCH 2/3] Move validation to ensure all renames are eligible --- netbox/dcim/views.py | 11 ----------- netbox/netbox/views/generic/bulk_views.py | 5 +++++ 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index a89bafc1a1..b18ecdd5b6 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -2122,17 +2122,6 @@ class DeviceBulkRenameView(generic.BulkRenameView): filterset = filtersets.DeviceFilterSet table = tables.DeviceTable - def _rename_objects(self, form, selected_objects): - # Check devices for any unnamed devices and enforce requirements on the renaming of devices - for obj in selected_objects: - if not form.cleaned_data['use_regex'] and not obj.name: - from django.core.exceptions import ValidationError - raise ValidationError({ - 'use_regex': 'You must use regex to rename a unnamed device and must pass device uniqueness checks' - }) - - super()._rename_objects(form, selected_objects) - @register_model_view(Device, 'contacts') class DeviceContactsView(ObjectContactsView): diff --git a/netbox/netbox/views/generic/bulk_views.py b/netbox/netbox/views/generic/bulk_views.py index 8270507b5f..d05de36d37 100644 --- a/netbox/netbox/views/generic/bulk_views.py +++ b/netbox/netbox/views/generic/bulk_views.py @@ -727,6 +727,11 @@ def _rename_objects(self, form, selected_objects): renamed_pks = [] for obj in selected_objects: + # Validate that the rename will be successful and not trigger an error + if not form.cleaned_data['use_regex'] and not obj.name: + raise ValidationError({ + 'use_regex': 'You must use regex to rename and must pass uniqueness checks' + }) # Take a snapshot of change-logged models if hasattr(obj, 'snapshot'): From f5e1b5aec65b6c3d82f7eb229a68cb118bde8dfb Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Thu, 12 Sep 2024 10:41:47 -0500 Subject: [PATCH 3/3] Update to treat null name an empty string --- netbox/netbox/views/generic/bulk_views.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/netbox/netbox/views/generic/bulk_views.py b/netbox/netbox/views/generic/bulk_views.py index d05de36d37..bce40bb795 100644 --- a/netbox/netbox/views/generic/bulk_views.py +++ b/netbox/netbox/views/generic/bulk_views.py @@ -727,12 +727,6 @@ def _rename_objects(self, form, selected_objects): renamed_pks = [] for obj in selected_objects: - # Validate that the rename will be successful and not trigger an error - if not form.cleaned_data['use_regex'] and not obj.name: - raise ValidationError({ - 'use_regex': 'You must use regex to rename and must pass uniqueness checks' - }) - # Take a snapshot of change-logged models if hasattr(obj, 'snapshot'): obj.snapshot() @@ -746,7 +740,7 @@ def _rename_objects(self, form, selected_objects): except re.error: obj.new_name = obj.name else: - obj.new_name = obj.name.replace(find, replace) + obj.new_name = (obj.name or '').replace(find, replace) renamed_pks.append(obj.pk) return renamed_pks @@ -785,10 +779,6 @@ def post(self, request): messages.error(self.request, ", ".join(e.args)) clear_events.send(sender=self) - except ValidationError as e: - messages.error(self.request, ", ".join(e.messages)) - clear_events.send(sender=self) - except (AbortRequest, PermissionsViolation) as e: logger.debug(e.message) form.add_error(None, e.message)