From 319799b5ce4ab4908f4858e5b0c53c3626d16351 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 25 Jun 2020 17:08:51 -0400 Subject: [PATCH] Closes #4795: Add bulk disconnect capability for console and power ports --- docs/release-notes/version-2.9.md | 1 + netbox/dcim/forms.py | 35 ------------------------------- netbox/dcim/urls.py | 4 ++-- netbox/dcim/views.py | 28 ++++++++++++++++++------- netbox/templates/dcim/device.html | 6 ++++++ 5 files changed, 30 insertions(+), 44 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 799acbcfe..3fefd8569 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -16,6 +16,7 @@ NetBox v2.9 replaces Django's built-in permissions framework with one that suppo * [#4742](https://github.com/netbox-community/netbox/issues/4742) - Add tagging for cables, power panels, and rack reservations * [#4788](https://github.com/netbox-community/netbox/issues/4788) - Add dedicated views for all device components * [#4792](https://github.com/netbox-community/netbox/issues/4792) - Add bulk rename capability for console and power ports +* [#4795](https://github.com/netbox-community/netbox/issues/4795) - Add bulk disconnect capability for console and power ports ### Configuration Changes diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index e4beaa56d..deb61729f 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -2375,13 +2375,6 @@ class ConsoleServerPortBulkEditForm( ] -class ConsoleServerPortBulkDisconnectForm(ConfirmationForm): - pk = forms.ModelMultipleChoiceField( - queryset=ConsoleServerPort.objects.all(), - widget=forms.MultipleHiddenInput() - ) - - class ConsoleServerPortCSVForm(CSVModelForm): device = CSVModelChoiceField( queryset=Device.objects.all(), @@ -2603,13 +2596,6 @@ class PowerOutletBulkEditForm( self.fields['power_port'].widget.attrs['disabled'] = True -class PowerOutletBulkDisconnectForm(ConfirmationForm): - pk = forms.ModelMultipleChoiceField( - queryset=PowerOutlet.objects.all(), - widget=forms.MultipleHiddenInput - ) - - class PowerOutletCSVForm(CSVModelForm): device = CSVModelChoiceField( queryset=Device.objects.all(), @@ -2908,13 +2894,6 @@ class InterfaceBulkEditForm( self.cleaned_data['tagged_vlans'] = [] -class InterfaceBulkDisconnectForm(ConfirmationForm): - pk = forms.ModelMultipleChoiceField( - queryset=Interface.objects.all(), - widget=forms.MultipleHiddenInput() - ) - - class InterfaceCSVForm(CSVModelForm): device = CSVModelChoiceField( queryset=Device.objects.all(), @@ -3094,13 +3073,6 @@ class FrontPortBulkEditForm( ] -class FrontPortBulkDisconnectForm(ConfirmationForm): - pk = forms.ModelMultipleChoiceField( - queryset=FrontPort.objects.all(), - widget=forms.MultipleHiddenInput - ) - - class FrontPortCSVForm(CSVModelForm): device = CSVModelChoiceField( queryset=Device.objects.all(), @@ -3217,13 +3189,6 @@ class RearPortBulkEditForm( ] -class RearPortBulkDisconnectForm(ConfirmationForm): - pk = forms.ModelMultipleChoiceField( - queryset=RearPort.objects.all(), - widget=forms.MultipleHiddenInput - ) - - class RearPortCSVForm(CSVModelForm): device = CSVModelChoiceField( queryset=Device.objects.all(), diff --git a/netbox/dcim/urls.py b/netbox/dcim/urls.py index 43fa259bd..45b10cd0c 100644 --- a/netbox/dcim/urls.py +++ b/netbox/dcim/urls.py @@ -188,7 +188,7 @@ urlpatterns = [ path('console-ports/import/', views.ConsolePortBulkImportView.as_view(), name='consoleport_import'), path('console-ports/edit/', views.ConsolePortBulkEditView.as_view(), name='consoleport_bulk_edit'), path('console-ports/rename/', views.ConsolePortBulkRenameView.as_view(), name='consoleport_bulk_rename'), - # TODO: Bulk disconnect view for ConsolePorts + path('console-ports/disconnect/', views.ConsolePortBulkDisconnectView.as_view(), name='consoleport_bulk_disconnect'), path('console-ports/delete/', views.ConsolePortBulkDeleteView.as_view(), name='consoleport_bulk_delete'), path('console-ports//', views.ConsolePortView.as_view(), name='consoleport'), path('console-ports//edit/', views.ConsolePortEditView.as_view(), name='consoleport_edit'), @@ -220,7 +220,7 @@ urlpatterns = [ path('power-ports/import/', views.PowerPortBulkImportView.as_view(), name='powerport_import'), path('power-ports/edit/', views.PowerPortBulkEditView.as_view(), name='powerport_bulk_edit'), path('power-ports/rename/', views.PowerPortBulkRenameView.as_view(), name='powerport_bulk_rename'), - # TODO: Bulk disconnect view for PowerPorts + path('power-ports/disconnect/', views.PowerPortBulkDisconnectView.as_view(), name='powerport_bulk_disconnect'), path('power-ports/delete/', views.PowerPortBulkDeleteView.as_view(), name='powerport_bulk_delete'), path('power-ports//', views.PowerPortView.as_view(), name='powerport'), path('power-ports//edit/', views.PowerPortEditView.as_view(), name='powerport_edit'), diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 7ca150e3d..3ec77d356 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -6,7 +6,7 @@ from django.contrib.contenttypes.models import ContentType from django.core.paginator import EmptyPage, PageNotAnInteger from django.db import transaction from django.db.models import Count, F -from django.forms import modelformset_factory +from django.forms import ModelMultipleChoiceField, MultipleHiddenInput, modelformset_factory from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse from django.utils.html import escape @@ -46,9 +46,20 @@ class BulkDisconnectView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View) An extendable view for disconnection console/power/interface components in bulk. """ queryset = None - form = None template_name = 'dcim/bulk_disconnect.html' + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Create a new Form class from ConfirmationForm + class _Form(ConfirmationForm): + pk = ModelMultipleChoiceField( + queryset=self.queryset, + widget=MultipleHiddenInput() + ) + + self.form = _Form + def get_required_permission(self): return get_permission_for_model(self.queryset.model, 'change') @@ -1203,6 +1214,10 @@ class ConsolePortBulkRenameView(BulkRenameView): queryset = ConsolePort.objects.all() +class ConsolePortBulkDisconnectView(BulkDisconnectView): + queryset = ConsolePort.objects.all() + + class ConsolePortBulkDeleteView(BulkDeleteView): queryset = ConsolePort.objects.all() filterset = filters.ConsolePortFilterSet @@ -1262,7 +1277,6 @@ class ConsoleServerPortBulkRenameView(BulkRenameView): class ConsoleServerPortBulkDisconnectView(BulkDisconnectView): queryset = ConsoleServerPort.objects.all() - form = forms.ConsoleServerPortBulkDisconnectForm class ConsoleServerPortBulkDeleteView(BulkDeleteView): @@ -1322,6 +1336,10 @@ class PowerPortBulkRenameView(BulkRenameView): queryset = PowerPort.objects.all() +class PowerPortBulkDisconnectView(BulkDisconnectView): + queryset = PowerPort.objects.all() + + class PowerPortBulkDeleteView(BulkDeleteView): queryset = PowerPort.objects.all() filterset = filters.PowerPortFilterSet @@ -1381,7 +1399,6 @@ class PowerOutletBulkRenameView(BulkRenameView): class PowerOutletBulkDisconnectView(BulkDisconnectView): queryset = PowerOutlet.objects.all() - form = forms.PowerOutletBulkDisconnectForm class PowerOutletBulkDeleteView(BulkDeleteView): @@ -1476,7 +1493,6 @@ class InterfaceBulkRenameView(BulkRenameView): class InterfaceBulkDisconnectView(BulkDisconnectView): queryset = Interface.objects.all() - form = forms.InterfaceBulkDisconnectForm class InterfaceBulkDeleteView(BulkDeleteView): @@ -1538,7 +1554,6 @@ class FrontPortBulkRenameView(BulkRenameView): class FrontPortBulkDisconnectView(BulkDisconnectView): queryset = FrontPort.objects.all() - form = forms.FrontPortBulkDisconnectForm class FrontPortBulkDeleteView(BulkDeleteView): @@ -1600,7 +1615,6 @@ class RearPortBulkRenameView(BulkRenameView): class RearPortBulkDisconnectView(BulkDisconnectView): queryset = RearPort.objects.all() - form = forms.RearPortBulkDisconnectForm class RearPortBulkDeleteView(BulkDeleteView): diff --git a/netbox/templates/dcim/device.html b/netbox/templates/dcim/device.html index c7f58aa4d..03ca0f8b4 100644 --- a/netbox/templates/dcim/device.html +++ b/netbox/templates/dcim/device.html @@ -346,6 +346,9 @@ + {% endif %} {% if console_ports and perms.dcim.delete_consoleport %} + {% endif %} {% if power_ports and perms.dcim.delete_powerport %}