diff --git a/CHANGELOG.md b/CHANGELOG.md index d46f2f3c0..b65c10f7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ NetBox now supports modeling physical cables for console, power, and interface c * [#2566](https://github.com/digitalocean/netbox/issues/2566) - Prevent both ends of a cable from connecting to the same termination point * [#2567](https://github.com/digitalocean/netbox/issues/2567) - Introduced proxy models to represent console/power/interface connections * [#2569](https://github.com/digitalocean/netbox/issues/2569) - Added LSH fiber type; removed SC duplex/simplex designations +* [#2570](https://github.com/digitalocean/netbox/issues/2570) - Add bulk disconnect view for front/rear pass-through ports * [#2571](https://github.com/digitalocean/netbox/issues/2571) - Enforce deletion of attached cable when deleting a termination point * [#2572](https://github.com/digitalocean/netbox/issues/2572) - Add button to disconnect cable from circuit termination * [#2573](https://github.com/digitalocean/netbox/issues/2573) - Fix bulk console/power/interface disconnections diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index e36554613..7b8c13ffa 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1723,6 +1723,13 @@ class FrontPortBulkRenameForm(BulkRenameForm): ) +class FrontPortBulkDisconnectForm(ConfirmationForm): + pk = forms.ModelMultipleChoiceField( + queryset=FrontPort.objects.all(), + widget=forms.MultipleHiddenInput + ) + + # # Rear pass-through ports # @@ -1760,6 +1767,13 @@ class RearPortBulkRenameForm(BulkRenameForm): ) +class RearPortBulkDisconnectForm(ConfirmationForm): + pk = forms.ModelMultipleChoiceField( + queryset=RearPort.objects.all(), + widget=forms.MultipleHiddenInput + ) + + # # Cables # diff --git a/netbox/dcim/urls.py b/netbox/dcim/urls.py index da9be6f72..dc1fbbf39 100644 --- a/netbox/dcim/urls.py +++ b/netbox/dcim/urls.py @@ -221,6 +221,7 @@ urlpatterns = [ url(r'^front-ports/(?P\d+)/delete/$', views.FrontPortDeleteView.as_view(), name='frontport_delete'), url(r'^front-ports/(?P\d+)/trace/$', views.CableTraceView.as_view(), name='frontport_trace', kwargs={'model': FrontPort}), url(r'^front-ports/rename/$', views.FrontPortBulkRenameView.as_view(), name='frontport_bulk_rename'), + url(r'^front-ports/disconnect/$', views.FrontPortBulkDisconnectView.as_view(), name='frontport_bulk_disconnect'), # Rear ports # url(r'^devices/rear-ports/add/$', views.DeviceBulkAddRearPortView.as_view(), name='device_bulk_add_rearport'), @@ -231,6 +232,7 @@ urlpatterns = [ url(r'^rear-ports/(?P\d+)/delete/$', views.RearPortDeleteView.as_view(), name='rearport_delete'), url(r'^rear-ports/(?P\d+)/trace/$', views.CableTraceView.as_view(), name='rearport_trace', kwargs={'model': RearPort}), url(r'^rear-ports/rename/$', views.RearPortBulkRenameView.as_view(), name='rearport_bulk_rename'), + url(r'^rear-ports/disconnect/$', views.RearPortBulkDisconnectView.as_view(), name='rearport_bulk_disconnect'), # Device bays url(r'^devices/device-bays/add/$', views.DeviceBulkAddDeviceBayView.as_view(), name='device_bulk_add_devicebay'), diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index c24740471..ceea73db3 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1297,12 +1297,6 @@ class InterfaceDeleteView(PermissionRequiredMixin, ObjectDeleteView): model = Interface -class InterfaceBulkDisconnectView(PermissionRequiredMixin, BulkDisconnectView): - permission_required = 'dcim.change_interface' - model = Interface - form = forms.InterfaceBulkDisconnectForm - - class InterfaceBulkEditView(PermissionRequiredMixin, BulkEditView): permission_required = 'dcim.change_interface' queryset = Interface.objects.all() @@ -1317,6 +1311,12 @@ class InterfaceBulkRenameView(PermissionRequiredMixin, BulkRenameView): form = forms.InterfaceBulkRenameForm +class InterfaceBulkDisconnectView(PermissionRequiredMixin, BulkDisconnectView): + permission_required = 'dcim.change_interface' + model = Interface + form = forms.InterfaceBulkDisconnectForm + + class InterfaceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): permission_required = 'dcim.delete_interface' queryset = Interface.objects.all() @@ -1355,6 +1355,12 @@ class FrontPortBulkRenameView(PermissionRequiredMixin, BulkRenameView): form = forms.FrontPortBulkRenameForm +class FrontPortBulkDisconnectView(PermissionRequiredMixin, BulkDisconnectView): + permission_required = 'dcim.change_frontport' + model = FrontPort + form = forms.FrontPortBulkDisconnectForm + + class FrontPortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): permission_required = 'dcim.delete_frontport' queryset = FrontPort.objects.all() @@ -1393,6 +1399,12 @@ class RearPortBulkRenameView(PermissionRequiredMixin, BulkRenameView): form = forms.RearPortBulkRenameForm +class RearPortBulkDisconnectView(PermissionRequiredMixin, BulkDisconnectView): + permission_required = 'dcim.change_rearport' + model = RearPort + form = forms.RearPortBulkDisconnectForm + + class RearPortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): permission_required = 'dcim.delete_rearport' queryset = RearPort.objects.all() diff --git a/netbox/templates/dcim/device.html b/netbox/templates/dcim/device.html index 5a6bcecb4..79030b69b 100644 --- a/netbox/templates/dcim/device.html +++ b/netbox/templates/dcim/device.html @@ -695,6 +695,9 @@ + {% endif %} {% if front_ports and perms.dcim.delete_frontport %} + {% endif %} {% if rear_ports and perms.dcim.delete_rearport %}