Closes #4795: Add bulk disconnect capability for console and power ports

This commit is contained in:
Jeremy Stretch 2020-06-25 17:08:51 -04:00
parent 128327b8a3
commit 319799b5ce
5 changed files with 30 additions and 44 deletions

View File

@ -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

View File

@ -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(),

View File

@ -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/<int:pk>/', views.ConsolePortView.as_view(), name='consoleport'),
path('console-ports/<int:pk>/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/<int:pk>/', views.PowerPortView.as_view(), name='powerport'),
path('power-ports/<int:pk>/edit/', views.PowerPortEditView.as_view(), name='powerport_edit'),

View File

@ -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):

View File

@ -346,6 +346,9 @@
<button type="submit" name="_edit" formaction="{% url 'dcim:consoleport_bulk_edit' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit
</button>
<button type="submit" name="_disconnect" formaction="{% url 'dcim:consoleport_bulk_disconnect' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
<span class="glyphicon glyphicon-resize-full" aria-hidden="true"></span> Disconnect
</button>
{% endif %}
{% if console_ports and perms.dcim.delete_consoleport %}
<button type="submit" name="_delete" formaction="{% url 'dcim:consoleport_bulk_delete' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
@ -383,6 +386,9 @@
<button type="submit" name="_edit" formaction="{% url 'dcim:powerport_bulk_edit' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit
</button>
<button type="submit" name="_disconnect" formaction="{% url 'dcim:powerport_bulk_disconnect' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
<span class="glyphicon glyphicon-resize-full" aria-hidden="true"></span> Disconnect
</button>
{% endif %}
{% if power_ports and perms.dcim.delete_powerport %}
<button type="submit" name="_delete" formaction="{% url 'dcim:powerport_bulk_delete' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">