diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c3b65a06..452b093cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ NetBox now supports modeling physical cables for console, power, and interface c * [#2616](https://github.com/digitalocean/netbox/issues/2616) - Convert Rack `outer_unit` and Cable `length_unit` to integer-based choice fields * [#2632](https://github.com/digitalocean/netbox/issues/2632) - Change representation of null values from `0` to `null` * [#2639](https://github.com/digitalocean/netbox/issues/2639) - Fix preservation of length/dimensions unit for racks and cables +* [#2626](https://github.com/digitalocean/netbox/issues/2626) - Remove extraneous permissions generated from proxy models ## API Changes diff --git a/netbox/dcim/migrations/0066_cables.py b/netbox/dcim/migrations/0066_cables.py index c0f99d858..9b4cc7152 100644 --- a/netbox/dcim/migrations/0066_cables.py +++ b/netbox/dcim/migrations/0066_cables.py @@ -313,36 +313,4 @@ class Migration(migrations.Migration): migrations.DeleteModel( name='InterfaceConnection', ), - - # Proxy models - migrations.CreateModel( - name='ConsoleConnection', - fields=[ - ], - options={ - 'proxy': True, - 'indexes': [], - }, - bases=('dcim.consoleport',), - ), - migrations.CreateModel( - name='InterfaceConnection', - fields=[ - ], - options={ - 'proxy': True, - 'indexes': [], - }, - bases=('dcim.interface',), - ), - migrations.CreateModel( - name='PowerConnection', - fields=[ - ], - options={ - 'proxy': True, - 'indexes': [], - }, - bases=('dcim.powerport',), - ), ] diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 379460f84..5dcf8a492 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -2631,64 +2631,3 @@ class Cable(ChangeLoggedModel): # (A path end, B path end, connected/planned) return a_path[-1][2], b_path[-1][2], path_status - - -# -# Connection proxy models -# - -class ConsoleConnection(ConsolePort): - - csv_headers = [ - 'console_server', 'port', 'device', 'console_port', 'connection_status', - ] - - class Meta: - proxy = True - - def to_csv(self): - return ( - self.connected_endpoint.device.identifier if self.connected_endpoint else None, - self.connected_endpoint.name if self.connected_endpoint else None, - self.device.identifier, - self.name, - self.get_connection_status_display(), - ) - - -class PowerConnection(PowerPort): - - csv_headers = [ - 'pdu', 'outlet', 'device', 'power_port', 'connection_status', - ] - - class Meta: - proxy = True - - def to_csv(self): - return ( - self.connected_endpoint.device.identifier if self.connected_endpoint else None, - self.connected_endpoint.name if self.connected_endpoint else None, - self.device.identifier, - self.name, - self.get_connection_status_display(), - ) - - -class InterfaceConnection(Interface): - - csv_headers = [ - 'device_a', 'interface_a', 'device_b', 'interface_b', 'connection_status', - ] - - class Meta: - proxy = True - - def to_csv(self): - return ( - self.connected_endpoint.device.identifier if self.connected_endpoint else None, - self.connected_endpoint.name if self.connected_endpoint else None, - self.device.identifier, - self.name, - self.get_connection_status_display(), - ) diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index aa5f77cc0..b38a60827 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -4,11 +4,10 @@ from django_tables2.utils import Accessor from tenancy.tables import COL_TENANT from utilities.tables import BaseTable, BooleanColumn, ColorColumn, ToggleColumn from .models import ( - Cable, ConsoleConnection, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, - DeviceBay, DeviceBayTemplate, DeviceRole, DeviceType, FrontPort, FrontPortTemplate, Interface, InterfaceConnection, - InterfaceTemplate, InventoryItem, Manufacturer, Platform, PowerConnection, PowerOutlet, PowerOutletTemplate, - PowerPort, PowerPortTemplate, Rack, RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site, - VirtualChassis, + Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay, + DeviceBayTemplate, DeviceRole, DeviceType, FrontPort, FrontPortTemplate, Interface, InterfaceTemplate, + InventoryItem, Manufacturer, Platform, PowerOutlet, PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack, + RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site, VirtualChassis, ) REGION_LINK = """ @@ -683,7 +682,7 @@ class ConsoleConnectionTable(BaseTable): ) class Meta(BaseTable.Meta): - model = ConsoleConnection + model = ConsolePort fields = ('console_server', 'connected_endpoint', 'device', 'name', 'connection_status') @@ -706,7 +705,7 @@ class PowerConnectionTable(BaseTable): ) class Meta(BaseTable.Meta): - model = PowerConnection + model = PowerPort fields = ('pdu', 'connected_endpoint', 'device', 'name', 'connection_status') @@ -745,7 +744,7 @@ class InterfaceConnectionTable(BaseTable): ) class Meta(BaseTable.Meta): - model = InterfaceConnection + model = Interface fields = ( 'device_a', 'interface_a', 'description_a', 'device_b', 'interface_b', 'description_b', 'connection_status', ) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 136e2c249..632b58d23 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -17,6 +17,7 @@ from ipam.models import Prefix, VLAN from ipam.tables import InterfaceIPAddressTable, InterfaceVLANTable from utilities.forms import ConfirmationForm from utilities.paginator import EnhancedPaginator +from utilities.utils import csv_format from utilities.views import ( BulkComponentCreateView, BulkDeleteView, BulkEditView, BulkImportView, ComponentCreateView, GetReturnURLMixin, ObjectDeleteView, ObjectEditView, ObjectListView, @@ -24,11 +25,10 @@ from utilities.views import ( from virtualization.models import VirtualMachine from . import filters, forms, tables from .models import ( - Cable, ConsoleConnection, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, - DeviceBay, DeviceBayTemplate, DeviceRole, DeviceType, FrontPort, FrontPortTemplate, Interface, InterfaceConnection, - InterfaceTemplate, InventoryItem, Manufacturer, Platform, PowerConnection, PowerOutlet, PowerOutletTemplate, - PowerPort, PowerPortTemplate, Rack, RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site, - VirtualChassis, + Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay, + DeviceBayTemplate, DeviceRole, DeviceType, FrontPort, FrontPortTemplate, Interface, InterfaceTemplate, + InventoryItem, Manufacturer, Platform, PowerOutlet, PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack, + RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site, VirtualChassis, ) @@ -1688,7 +1688,7 @@ class CableBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): # class ConsoleConnectionsListView(ObjectListView): - queryset = ConsoleConnection.objects.select_related( + queryset = ConsolePort.objects.select_related( 'device', 'connected_endpoint__device' ).filter( connected_endpoint__isnull=False @@ -1700,9 +1700,25 @@ class ConsoleConnectionsListView(ObjectListView): table = tables.ConsoleConnectionTable template_name = 'dcim/console_connections_list.html' + def queryset_to_csv(self): + csv_data = [ + # Headers + ','.join(['console_server', 'port', 'device', 'console_port', 'connection_status']) + ] + for obj in self.queryset: + csv = csv_format([ + obj.connected_endpoint.device.identifier if obj.connected_endpoint else None, + obj.connected_endpoint.name if obj.connected_endpoint else None, + obj.device.identifier, + obj.name, + obj.get_connection_status_display(), + ]) + csv_data.append(csv) + return csv_data + class PowerConnectionsListView(ObjectListView): - queryset = PowerConnection.objects.select_related( + queryset = PowerPort.objects.select_related( 'device', 'connected_endpoint__device' ).filter( connected_endpoint__isnull=False @@ -1714,9 +1730,25 @@ class PowerConnectionsListView(ObjectListView): table = tables.PowerConnectionTable template_name = 'dcim/power_connections_list.html' + def queryset_to_csv(self): + csv_data = [ + # Headers + ','.join(['pdu', 'outlet', 'device', 'power_port', 'connection_status']) + ] + for obj in self.queryset: + csv = csv_format([ + obj.connected_endpoint.device.identifier if obj.connected_endpoint else None, + obj.connected_endpoint.name if obj.connected_endpoint else None, + obj.device.identifier, + obj.name, + obj.get_connection_status_display(), + ]) + csv_data.append(csv) + return csv_data + class InterfaceConnectionsListView(ObjectListView): - queryset = InterfaceConnection.objects.select_related( + queryset = Interface.objects.select_related( 'device', 'cable', '_connected_interface__device' ).filter( # Avoid duplicate connections by only selecting the lower PK in a connected pair @@ -1730,6 +1762,22 @@ class InterfaceConnectionsListView(ObjectListView): table = tables.InterfaceConnectionTable template_name = 'dcim/interface_connections_list.html' + def queryset_to_csv(self): + csv_data = [ + # Headers + ','.join(['device_a', 'interface_a', 'device_b', 'interface_b', 'connection_status']) + ] + for obj in self.queryset: + csv = csv_format([ + obj.connected_endpoint.device.identifier if obj.connected_endpoint else None, + obj.connected_endpoint.name if obj.connected_endpoint else None, + obj.device.identifier, + obj.name, + obj.get_connection_status_display(), + ]) + csv_data.append(csv) + return csv_data + # # Inventory items