diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 80f54a2a3..b2b77b78c 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -558,8 +558,8 @@ class PowerOutletSerializer(TaggitSerializer, ValidatedModelSerializer): class Meta: model = PowerOutlet - fields = ['id', 'device', 'name', 'connected_port', 'tags'] - read_only_fields = ['connected_port'] + fields = ['id', 'device', 'name', 'connected_endpoint', 'tags'] + read_only_fields = ['connected_endpoint'] class NestedPowerOutletSerializer(WritableNestedSerializer): @@ -572,7 +572,7 @@ class NestedPowerOutletSerializer(WritableNestedSerializer): fields = ['id', 'url', 'device', 'name', 'is_connected'] def get_is_connected(self, obj): - return hasattr(obj, 'connected_port') and obj.connected_port is not None + return hasattr(obj, 'connected_endpoint') and obj.connected_endpoint is not None # @@ -581,12 +581,12 @@ class NestedPowerOutletSerializer(WritableNestedSerializer): class PowerPortSerializer(TaggitSerializer, ValidatedModelSerializer): device = NestedDeviceSerializer() - power_outlet = NestedPowerOutletSerializer(required=False, allow_null=True) + connected_endpoint = NestedPowerOutletSerializer(required=False, allow_null=True) tags = TagListSerializerField(required=False) class Meta: model = PowerPort - fields = ['id', 'device', 'name', 'power_outlet', 'connection_status', 'tags'] + fields = ['id', 'device', 'name', 'connected_endpoint', 'connection_status', 'tags'] class NestedPowerPortSerializer(TaggitSerializer, ValidatedModelSerializer): @@ -599,7 +599,7 @@ class NestedPowerPortSerializer(TaggitSerializer, ValidatedModelSerializer): fields = ['id', 'url', 'device', 'name', 'is_connected'] def get_is_connected(self, obj): - return obj.power_outlet is not None + return obj.connected_endpoint is not None # diff --git a/netbox/dcim/api/views.py b/netbox/dcim/api/views.py index ef4bec9cd..db7149d18 100644 --- a/netbox/dcim/api/views.py +++ b/netbox/dcim/api/views.py @@ -343,13 +343,13 @@ class ConsoleServerPortViewSet(ModelViewSet): class PowerPortViewSet(ModelViewSet): - queryset = PowerPort.objects.select_related('device', 'power_outlet__device').prefetch_related('tags') + queryset = PowerPort.objects.select_related('device', 'connected_endpoint__device').prefetch_related('tags') serializer_class = serializers.PowerPortSerializer filter_class = filters.PowerPortFilter class PowerOutletViewSet(ModelViewSet): - queryset = PowerOutlet.objects.select_related('device', 'connected_port__device').prefetch_related('tags') + queryset = PowerOutlet.objects.select_related('device', 'connected_endpoint__device').prefetch_related('tags') serializer_class = serializers.PowerOutletSerializer filter_class = filters.PowerOutletFilter @@ -399,13 +399,21 @@ class InventoryItemViewSet(ModelViewSet): # class ConsoleConnectionViewSet(ListModelMixin, GenericViewSet): - queryset = ConsolePort.objects.select_related('device', 'connected_endpoint__device').filter(connected_endpoint__isnull=False) + queryset = ConsolePort.objects.select_related( + 'device', 'connected_endpoint__device' + ).filter( + connected_endpoint__isnull=False + ) serializer_class = serializers.ConsolePortSerializer filter_class = filters.ConsoleConnectionFilter class PowerConnectionViewSet(ListModelMixin, GenericViewSet): - queryset = PowerPort.objects.select_related('device', 'power_outlet__device').filter(power_outlet__isnull=False) + queryset = PowerPort.objects.select_related( + 'device', 'connected_endpoint__device' + ).filter( + connected_endpoint__isnull=False + ) serializer_class = serializers.PowerPortSerializer filter_class = filters.PowerConnectionFilter diff --git a/netbox/dcim/filters.py b/netbox/dcim/filters.py index 3b854dd61..da2055506 100644 --- a/netbox/dcim/filters.py +++ b/netbox/dcim/filters.py @@ -831,14 +831,14 @@ class PowerConnectionFilter(django_filters.FilterSet): def filter_site(self, queryset, name, value): if not value.strip(): return queryset - return queryset.filter(power_outlet__device__site__slug=value) + return queryset.filter(connected_endpoint__device__site__slug=value) def filter_device(self, queryset, name, value): if not value.strip(): return queryset return queryset.filter( Q(device__name__icontains=value) | - Q(power_outlet__device__name__icontains=value) + Q(connected_endpoint__device__name__icontains=value) ) diff --git a/netbox/dcim/fixtures/dcim.json b/netbox/dcim/fixtures/dcim.json index 148ce8ca6..6c3e4b7df 100644 --- a/netbox/dcim/fixtures/dcim.json +++ b/netbox/dcim/fixtures/dcim.json @@ -2685,7 +2685,7 @@ "fields": { "device": 1, "name": "PEM0", - "power_outlet": 25, + "connected_endpoint": 25, "connection_status": true } }, @@ -2695,7 +2695,7 @@ "fields": { "device": 1, "name": "PEM1", - "power_outlet": 49, + "connected_endpoint": 49, "connection_status": true } }, @@ -2705,7 +2705,7 @@ "fields": { "device": 1, "name": "PEM2", - "power_outlet": null, + "connected_endpoint": null, "connection_status": true } }, @@ -2715,7 +2715,7 @@ "fields": { "device": 1, "name": "PEM3", - "power_outlet": null, + "connected_endpoint": null, "connection_status": true } }, @@ -2725,7 +2725,7 @@ "fields": { "device": 2, "name": "PEM0", - "power_outlet": 26, + "connected_endpoint": 26, "connection_status": true } }, @@ -2735,7 +2735,7 @@ "fields": { "device": 2, "name": "PEM1", - "power_outlet": 50, + "connected_endpoint": 50, "connection_status": true } }, @@ -2745,7 +2745,7 @@ "fields": { "device": 2, "name": "PEM2", - "power_outlet": null, + "connected_endpoint": null, "connection_status": true } }, @@ -2755,7 +2755,7 @@ "fields": { "device": 2, "name": "PEM3", - "power_outlet": null, + "connected_endpoint": null, "connection_status": true } }, @@ -2765,7 +2765,7 @@ "fields": { "device": 4, "name": "PSU0", - "power_outlet": 28, + "connected_endpoint": 28, "connection_status": true } }, @@ -2775,7 +2775,7 @@ "fields": { "device": 4, "name": "PSU1", - "power_outlet": 52, + "connected_endpoint": 52, "connection_status": true } }, @@ -2785,7 +2785,7 @@ "fields": { "device": 5, "name": "PSU0", - "power_outlet": 56, + "connected_endpoint": 56, "connection_status": true } }, @@ -2795,7 +2795,7 @@ "fields": { "device": 5, "name": "PSU1", - "power_outlet": 32, + "connected_endpoint": 32, "connection_status": true } }, @@ -2805,7 +2805,7 @@ "fields": { "device": 3, "name": "PSU0", - "power_outlet": 27, + "connected_endpoint": 27, "connection_status": true } }, @@ -2815,7 +2815,7 @@ "fields": { "device": 3, "name": "PSU1", - "power_outlet": 51, + "connected_endpoint": 51, "connection_status": true } }, @@ -2825,7 +2825,7 @@ "fields": { "device": 7, "name": "PEM0", - "power_outlet": 53, + "connected_endpoint": 53, "connection_status": true } }, @@ -2835,7 +2835,7 @@ "fields": { "device": 7, "name": "PEM1", - "power_outlet": 29, + "connected_endpoint": 29, "connection_status": true } }, @@ -2845,7 +2845,7 @@ "fields": { "device": 7, "name": "PEM2", - "power_outlet": null, + "connected_endpoint": null, "connection_status": true } }, @@ -2855,7 +2855,7 @@ "fields": { "device": 7, "name": "PEM3", - "power_outlet": null, + "connected_endpoint": null, "connection_status": true } }, @@ -2865,7 +2865,7 @@ "fields": { "device": 8, "name": "PEM0", - "power_outlet": 54, + "connected_endpoint": 54, "connection_status": true } }, @@ -2875,7 +2875,7 @@ "fields": { "device": 8, "name": "PEM1", - "power_outlet": 30, + "connected_endpoint": 30, "connection_status": true } }, @@ -2885,7 +2885,7 @@ "fields": { "device": 8, "name": "PEM2", - "power_outlet": null, + "connected_endpoint": null, "connection_status": true } }, @@ -2895,7 +2895,7 @@ "fields": { "device": 8, "name": "PEM3", - "power_outlet": null, + "connected_endpoint": null, "connection_status": true } }, @@ -2905,7 +2905,7 @@ "fields": { "device": 6, "name": "PSU0", - "power_outlet": 55, + "connected_endpoint": 55, "connection_status": true } }, @@ -2915,7 +2915,7 @@ "fields": { "device": 6, "name": "PSU1", - "power_outlet": 31, + "connected_endpoint": 31, "connection_status": true } }, @@ -2925,7 +2925,7 @@ "fields": { "device": 9, "name": "PSU", - "power_outlet": null, + "connected_endpoint": null, "connection_status": true } }, diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index a59553b49..762fe7c4c 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1570,7 +1570,7 @@ class PowerConnectionCSVForm(forms.ModelForm): 'invalid_choice': 'PDU not found.', } ) - power_outlet = forms.CharField( + connected_endpoint = forms.CharField( help_text='Power outlet name' ) device = FlexibleModelChoiceField( @@ -1591,7 +1591,7 @@ class PowerConnectionCSVForm(forms.ModelForm): class Meta: model = PowerPort - fields = ['pdu', 'power_outlet', 'device', 'power_port', 'connection_status'] + fields = ['pdu', 'connected_endpoint', 'device', 'power_port', 'connection_status'] def clean_power_port(self): @@ -1605,7 +1605,7 @@ class PowerConnectionCSVForm(forms.ModelForm): device=self.cleaned_data['device'], name=power_port_name ) # Check if the power port is already connected - if powerport.power_outlet is not None: + if powerport.connected_endpoint is not None: raise forms.ValidationError("{} {} is already connected".format( self.cleaned_data['device'], power_port_name )) @@ -1617,28 +1617,28 @@ class PowerConnectionCSVForm(forms.ModelForm): self.instance = powerport return powerport - def clean_power_outlet(self): + def clean_connected_endpoint(self): - power_outlet_name = self.cleaned_data.get('power_outlet') - if not self.cleaned_data.get('pdu') or not power_outlet_name: + poweroutlet_name = self.cleaned_data.get('connected_endpoint') + if not self.cleaned_data.get('pdu') or not poweroutlet_name: return None try: # Retrieve power outlet by name - power_outlet = PowerOutlet.objects.get( - device=self.cleaned_data['pdu'], name=power_outlet_name + poweroutlet = PowerOutlet.objects.get( + device=self.cleaned_data['pdu'], name=poweroutlet_name ) # Check if the power outlet is already connected - if PowerPort.objects.filter(power_outlet=power_outlet).count(): + if PowerPort.objects.filter(connected_endpoint=poweroutlet).count(): raise forms.ValidationError("{} {} is already connected".format( - self.cleaned_data['pdu'], power_outlet_name + self.cleaned_data['pdu'], poweroutlet_name )) except PowerOutlet.DoesNotExist: raise forms.ValidationError("Invalid power outlet ({} {})".format( - self.cleaned_data['pdu'], power_outlet_name + self.cleaned_data['pdu'], poweroutlet_name )) - return power_outlet + return poweroutlet class PowerPortConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelForm): @@ -1672,7 +1672,7 @@ class PowerPortConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelFor widget=APISelect( api_url='/api/dcim/devices/?site_id={{site}}&rack_id={{rack}}&is_pdu=True', display_field='display_name', - attrs={'filter-for': 'power_outlet'} + attrs={'filter-for': 'connected_endpoint'} ) ) livesearch = forms.CharField( @@ -1684,7 +1684,7 @@ class PowerPortConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelFor field_to_update='pdu' ) ) - power_outlet = ChainedModelChoiceField( + connected_endpoint = ChainedModelChoiceField( queryset=PowerOutlet.objects.all(), chains=( ('device', 'pdu'), @@ -1698,9 +1698,9 @@ class PowerPortConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelFor class Meta: model = PowerPort - fields = ['site', 'rack', 'pdu', 'livesearch', 'power_outlet', 'connection_status'] + fields = ['site', 'rack', 'pdu', 'livesearch', 'connected_endpoint', 'connection_status'] labels = { - 'power_outlet': 'Outlet', + 'connected_endpoint': 'Outlet', 'connection_status': 'Status', } diff --git a/netbox/dcim/migrations/0066_cables.py b/netbox/dcim/migrations/0066_cables.py index d160e57d7..2413fa3a5 100644 --- a/netbox/dcim/migrations/0066_cables.py +++ b/netbox/dcim/migrations/0066_cables.py @@ -42,13 +42,13 @@ def power_connections_to_cables(apps, schema_editor): poweroutlet_type = ContentType.objects.get_for_model(PowerOutlet) # Create a new Cable instance from each power connection - for powerport in PowerPort.objects.filter(power_outlet__isnull=False): + for powerport in PowerPort.objects.filter(connected_endpoint__isnull=False): c = Cable() # We have to assign GFK fields manually because we're inside a migration. c.endpoint_a_type = powerport_type c.endpoint_a_id = powerport.id c.endpoint_b_type = poweroutlet_type - c.endpoint_b_id = powerport.power_outlet_id + c.endpoint_b_id = powerport.connected_endpoint_id c.connection_status = powerport.connection_status c.save() @@ -108,7 +108,7 @@ class Migration(migrations.Migration): unique_together={('endpoint_b_type', 'endpoint_b_id'), ('endpoint_a_type', 'endpoint_a_id')}, ), - # Rename model fields + # Alter console port models migrations.RenameField( model_name='consoleport', old_name='cs_port', @@ -125,6 +125,23 @@ class Migration(migrations.Migration): field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='consoleserverports', to='dcim.Device'), ), + # Alter power port models + migrations.RenameField( + model_name='powerport', + old_name='power_outlet', + new_name='connected_endpoint' + ), + migrations.AlterField( + model_name='powerport', + name='connected_endpoint', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='connected_endpoint', to='dcim.PowerOutlet'), + ), + migrations.AlterField( + model_name='poweroutlet', + name='device', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='poweroutlets', to='dcim.Device'), + ), + # Copy console/power/interface connections as Cables migrations.RunPython(console_connections_to_cables), migrations.RunPython(power_connections_to_cables), diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 412079682..53459143c 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -1732,10 +1732,10 @@ class PowerPort(ComponentModel): name = models.CharField( max_length=50 ) - power_outlet = models.OneToOneField( + connected_endpoint = models.OneToOneField( to='dcim.PowerOutlet', on_delete=models.SET_NULL, - related_name='connected_port', + related_name='connected_endpoint', blank=True, null=True ) @@ -1746,7 +1746,7 @@ class PowerPort(ComponentModel): tags = TaggableManager() - csv_headers = ['pdu', 'power_outlet', 'device', 'power_port', 'connection_status'] + csv_headers = ['pdu', 'connected_endpoint', 'device', 'power_port', 'connection_status'] class Meta: ordering = ['device', 'name'] @@ -1760,8 +1760,8 @@ class PowerPort(ComponentModel): def to_csv(self): return ( - self.power_outlet.device.identifier if self.power_outlet else None, - self.power_outlet.name if self.power_outlet else None, + 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(), @@ -1789,7 +1789,7 @@ class PowerOutlet(ComponentModel): device = models.ForeignKey( to='dcim.Device', on_delete=models.CASCADE, - related_name='power_outlets' + related_name='poweroutlets' ) name = models.CharField( max_length=50 diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index b5f62e792..6174593af 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -638,15 +638,19 @@ class ConsoleConnectionTable(BaseTable): class PowerConnectionTable(BaseTable): - pdu = tables.LinkColumn('dcim:device', accessor=Accessor('power_outlet.device'), - args=[Accessor('power_outlet.device.pk')], verbose_name='PDU') - power_outlet = tables.Column(verbose_name='Outlet') + pdu = tables.LinkColumn( + 'dcim:device', + accessor=Accessor('connected_endpoint.device'), + args=[Accessor('connected_endpoint.device.pk')], + verbose_name='PDU' + ) + connected_endpoint = tables.Column(verbose_name='Outlet') device = tables.LinkColumn('dcim:device', args=[Accessor('device.pk')], verbose_name='Device') name = tables.Column(verbose_name='Power Port') class Meta(BaseTable.Meta): model = PowerPort - fields = ('pdu', 'power_outlet', 'device', 'name') + fields = ('pdu', 'connected_endpoint', 'device', 'name') class InterfaceConnectionTable(BaseTable): diff --git a/netbox/dcim/tests/test_api.py b/netbox/dcim/tests/test_api.py index 040c6dab5..e6cc02537 100644 --- a/netbox/dcim/tests/test_api.py +++ b/netbox/dcim/tests/test_api.py @@ -2231,7 +2231,7 @@ class PowerPortTest(APITestCase): data = { 'device': self.device.pk, 'name': 'Test Power Port X', - 'power_outlet': poweroutlet.pk, + 'connected_endpoint': poweroutlet.pk, } url = reverse('dcim-api:powerport-detail', kwargs={'pk': self.powerport1.pk}) @@ -2241,7 +2241,7 @@ class PowerPortTest(APITestCase): self.assertEqual(PowerPort.objects.count(), 3) powerport1 = PowerPort.objects.get(pk=response.data['id']) self.assertEqual(powerport1.name, data['name']) - self.assertEqual(powerport1.power_outlet_id, data['power_outlet']) + self.assertEqual(powerport1.connected_endpoint_id, data['connected_endpoint']) def test_delete_powerport(self): @@ -2861,17 +2861,17 @@ class PowerConnectionTest(APITestCase): device2 = Device.objects.create( device_type=devicetype, device_role=devicerole, name='Test Device 2', site=site ) - power_outlet1 = PowerOutlet.objects.create(device=device1, name='Test Power Outlet 1') - power_outlet2 = PowerOutlet.objects.create(device=device1, name='Test Power Outlet 2') - power_outlet3 = PowerOutlet.objects.create(device=device1, name='Test Power Outlet 3') + poweroutlet1 = PowerOutlet.objects.create(device=device1, name='Test Power Outlet 1') + poweroutlet2 = PowerOutlet.objects.create(device=device1, name='Test Power Outlet 2') + poweroutlet3 = PowerOutlet.objects.create(device=device1, name='Test Power Outlet 3') PowerPort.objects.create( - device=device2, power_outlet=power_outlet1, name='Test Power Port 1', connection_status=True + device=device2, connected_endpoint=poweroutlet1, name='Test Power Port 1', connection_status=True ) PowerPort.objects.create( - device=device2, power_outlet=power_outlet2, name='Test Power Port 2', connection_status=True + device=device2, connected_endpoint=poweroutlet2, name='Test Power Port 2', connection_status=True ) PowerPort.objects.create( - device=device2, power_outlet=power_outlet3, name='Test Power Port 3', connection_status=True + device=device2, connected_endpoint=poweroutlet3, name='Test Power Port 3', connection_status=True ) def test_list_powerconnections(self): diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index bcf39f626..5dcb70c0e 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -862,8 +862,9 @@ class PlatformBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): # class DeviceListView(ObjectListView): - queryset = Device.objects.select_related('device_type__manufacturer', 'device_role', 'tenant', 'site', 'rack', - 'primary_ip4', 'primary_ip6') + queryset = Device.objects.select_related( + 'device_type__manufacturer', 'device_role', 'tenant', 'site', 'rack', 'primary_ip4', 'primary_ip6' + ) filter = filters.DeviceFilter filter_form = forms.DeviceFilterForm table = tables.DeviceDetailTable @@ -894,11 +895,11 @@ class DeviceView(View): # Power ports power_ports = natsorted( - PowerPort.objects.filter(device=device).select_related('power_outlet__device'), key=attrgetter('name') + PowerPort.objects.filter(device=device).select_related('connected_endpoint__device'), key=attrgetter('name') ) # Power outlets - power_outlets = PowerOutlet.objects.filter(device=device).select_related('connected_port') + poweroutlets = PowerOutlet.objects.filter(device=device).select_related('connected_endpoint') # Interfaces interfaces = device.vc_interfaces.order_naturally( @@ -943,7 +944,7 @@ class DeviceView(View): 'console_ports': console_ports, 'consoleserverports': consoleserverports, 'power_ports': power_ports, - 'power_outlets': power_outlets, + 'poweroutlets': poweroutlets, 'interfaces': interfaces, 'device_bays': device_bays, 'front_panel_ports': front_panel_ports, @@ -1419,9 +1420,9 @@ class PowerPortConnectView(PermissionRequiredMixin, View): powerport.device.get_absolute_url(), escape(powerport.device), escape(powerport.name), - powerport.power_outlet.device.get_absolute_url(), - escape(powerport.power_outlet.device), - escape(powerport.power_outlet.name), + powerport.connected_endpoint.device.get_absolute_url(), + escape(powerport.connected_endpoint.device), + escape(powerport.connected_endpoint.name), ) messages.success(request, mark_safe(msg)) @@ -1442,7 +1443,7 @@ class PowerPortDisconnectView(PermissionRequiredMixin, View): powerport = get_object_or_404(PowerPort, pk=pk) form = ConfirmationForm() - if not powerport.power_outlet: + if not powerport.connected_endpoint: messages.warning( request, "Cannot disconnect power port {}: It is not connected to an outlet.".format(powerport) ) @@ -1461,17 +1462,17 @@ class PowerPortDisconnectView(PermissionRequiredMixin, View): if form.is_valid(): - power_outlet = powerport.power_outlet - powerport.power_outlet = None + poweroutlet = powerport.connected_endpoint + powerport.connected_endpoint = None powerport.connection_status = None powerport.save() msg = 'Disconnected {} {} from {} {}'.format( powerport.device.get_absolute_url(), escape(powerport.device), escape(powerport.name), - power_outlet.device.get_absolute_url(), - escape(power_outlet.device), - escape(power_outlet.name), + poweroutlet.device.get_absolute_url(), + escape(poweroutlet.device), + escape(poweroutlet.name), ) messages.success(request, mark_safe(msg)) @@ -1549,7 +1550,7 @@ class PowerOutletConnectView(PermissionRequiredMixin, View): if form.is_valid(): powerport = form.cleaned_data['port'] - powerport.power_outlet = poweroutlet + powerport.connected_endpoint = poweroutlet powerport.connection_status = form.cleaned_data['connection_status'] powerport.save() msg = 'Connected {} {} to {} {}'.format( @@ -1579,7 +1580,7 @@ class PowerOutletDisconnectView(PermissionRequiredMixin, View): poweroutlet = get_object_or_404(PowerOutlet, pk=pk) form = ConfirmationForm() - if not hasattr(poweroutlet, 'connected_port'): + if not hasattr(poweroutlet, 'connected_endpoint'): messages.warning( request, "Cannot disconnect power outlet {}: Nothing is connected to it.".format(poweroutlet) ) @@ -1598,8 +1599,8 @@ class PowerOutletDisconnectView(PermissionRequiredMixin, View): if form.is_valid(): - powerport = poweroutlet.connected_port - powerport.power_outlet = None + powerport = poweroutlet.connected_endpoint + powerport.connected_endpoint = None powerport.connection_status = None powerport.save() msg = 'Disconnected {} {} from {} {}'.format( @@ -1643,9 +1644,9 @@ class PowerOutletBulkDisconnectView(PermissionRequiredMixin, BulkDisconnectView) model = PowerOutlet form = forms.PowerOutletBulkDisconnectForm - def disconnect_objects(self, power_outlets): - return PowerPort.objects.filter(power_outlet__in=power_outlets).update( - power_outlet=None, connection_status=None + def disconnect_objects(self, poweroutlets): + return PowerPort.objects.filter(connected_endpoint__in=poweroutlets).update( + connected_endpoint=None, connection_status=None ) @@ -2143,8 +2144,13 @@ class ConsoleConnectionsListView(ObjectListView): class PowerConnectionsListView(ObjectListView): - queryset = PowerPort.objects.select_related('device', 'power_outlet__device').filter(power_outlet__isnull=False) \ - .order_by('power_outlet__device__name', 'power_outlet__name') + queryset = PowerPort.objects.select_related( + 'device', 'connected_endpoint__device' + ).filter( + connected_endpoint__isnull=False + ).order_by( + 'connected_endpoint__device__name', 'connected_endpoint__name' + ) filter = filters.PowerConnectionFilter filter_form = forms.PowerConnectionFilterForm table = tables.PowerConnectionTable diff --git a/netbox/extras/models.py b/netbox/extras/models.py index 5e7dbac24..8bc0a8726 100644 --- a/netbox/extras/models.py +++ b/netbox/extras/models.py @@ -526,8 +526,7 @@ class TopologyMap(models.Model): from dcim.models import ConsolePort # Add all console connections to the graph - console_ports = ConsolePort.objects.filter(device__in=devices, connected_endpoint__device__in=devices) - for cp in console_ports: + for cp in ConsolePort.objects.filter(device__in=devices, connected_endpoint__device__in=devices): style = 'solid' if cp.connection_status == CONNECTION_STATUS_CONNECTED else 'dashed' self.graph.edge(cp.connected_endpoint.device.name, cp.device.name, style=style) @@ -536,10 +535,9 @@ class TopologyMap(models.Model): from dcim.models import PowerPort # Add all power connections to the graph - power_ports = PowerPort.objects.filter(device__in=devices, power_outlet__device__in=devices) - for pp in power_ports: + for pp in PowerPort.objects.filter(device__in=devices, connected_endpoint__device__in=devices): style = 'solid' if pp.connection_status == CONNECTION_STATUS_CONNECTED else 'dashed' - self.graph.edge(pp.power_outlet.device.name, pp.device.name, style=style) + self.graph.edge(pp.connected_endpoint.device.name, pp.device.name, style=style) # diff --git a/netbox/netbox/views.py b/netbox/netbox/views.py index d7bb29f2e..e13a3df5a 100644 --- a/netbox/netbox/views.py +++ b/netbox/netbox/views.py @@ -168,7 +168,7 @@ class HomeView(View): 'device_count': Device.objects.count(), 'interface_connections_count': InterfaceConnection.objects.count(), 'console_connections_count': ConsolePort.objects.filter(connected_endpoint__isnull=False).count(), - 'power_connections_count': PowerPort.objects.filter(power_outlet__isnull=False).count(), + 'power_connections_count': PowerPort.objects.filter(connected_endpoint__isnull=False).count(), # IPAM 'vrf_count': VRF.objects.count(), diff --git a/netbox/templates/dcim/device.html b/netbox/templates/dcim/device.html index 194b6ab64..2d838704c 100644 --- a/netbox/templates/dcim/device.html +++ b/netbox/templates/dcim/device.html @@ -631,7 +631,7 @@ {% endif %} {% endif %} - {% if power_outlets or device.device_type.is_pdu %} + {% if poweroutlets or device.device_type.is_pdu %} {% if perms.dcim.delete_poweroutlet %}
{% csrf_token %} @@ -652,7 +652,7 @@ - {% for po in power_outlets %} + {% for po in poweroutlets %} {% include 'dcim/inc/poweroutlet.html' %} {% empty %} @@ -662,7 +662,7 @@ - {% render_field form.power_outlet %} + {% render_field form.connected_endpoint %} {% render_field form.connection_status %} diff --git a/netbox/templates/dcim/powerport_disconnect.html b/netbox/templates/dcim/powerport_disconnect.html index f98694d9f..6953b1e2f 100644 --- a/netbox/templates/dcim/powerport_disconnect.html +++ b/netbox/templates/dcim/powerport_disconnect.html @@ -4,5 +4,5 @@ {% block title %}Disconnect power port {{ powerport }}?{% endblock %} {% block message %} -

Are you sure you want to disconnect this power port from {{ powerport.power_outlet.device }} {{ powerport.power_outlet }}?

+

Are you sure you want to disconnect this power port from {{ powerport.connected_endpoint.device }} {{ powerport.connected_endpoint }}?

{% endblock %}