From 0803feb032d2ce50235d4dda5be40e944710641b Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 31 Jul 2023 08:16:59 -0400 Subject: [PATCH] Misc cleanup; add filterset tests --- netbox/dcim/api/serializers.py | 1 + netbox/dcim/tables/power.py | 6 +-- netbox/dcim/tests/test_filtersets.py | 70 ++++++++++++++++++++++++++-- 3 files changed, 71 insertions(+), 6 deletions(-) diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index cce69ea31..550e9123b 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -1238,6 +1238,7 @@ class PowerFeedSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect ) tenant = NestedTenantSerializer( required=False, + allow_null=True ) class Meta: diff --git a/netbox/dcim/tables/power.py b/netbox/dcim/tables/power.py index b7b659079..e4313da65 100644 --- a/netbox/dcim/tables/power.py +++ b/netbox/dcim/tables/power.py @@ -1,6 +1,6 @@ import django_tables2 as tables from dcim.models import PowerFeed, PowerPanel -from tenancy.tables import ContactsColumnMixin +from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin from netbox.tables import NetBoxTable, columns @@ -51,7 +51,7 @@ class PowerPanelTable(ContactsColumnMixin, NetBoxTable): # We're not using PathEndpointTable for PowerFeed because power connections # cannot traverse pass-through ports. -class PowerFeedTable(CableTerminationTable): +class PowerFeedTable(TenancyColumnsMixin, CableTerminationTable): name = tables.Column( linkify=True ) @@ -82,7 +82,7 @@ class PowerFeedTable(CableTerminationTable): fields = ( 'pk', 'id', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase', 'max_utilization', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'available_power', 'tenant', - 'description', 'comments', 'tags', 'created', 'last_updated', + 'tenant_group', 'description', 'comments', 'tags', 'created', 'last_updated', ) default_columns = ( 'pk', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase', 'cable', diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index a1e684cb9..c75df5cf6 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -4419,6 +4419,21 @@ class PowerFeedTestCase(TestCase, ChangeLoggedFilterSetTests): ) Rack.objects.bulk_create(racks) + tenant_groups = ( + TenantGroup(name='Tenant group 1', slug='tenant-group-1'), + TenantGroup(name='Tenant group 2', slug='tenant-group-2'), + TenantGroup(name='Tenant group 3', slug='tenant-group-3'), + ) + for tenantgroup in tenant_groups: + tenantgroup.save() + + tenants = ( + Tenant(name='Tenant 1', slug='tenant-1', group=tenant_groups[0]), + Tenant(name='Tenant 2', slug='tenant-2', group=tenant_groups[1]), + Tenant(name='Tenant 3', slug='tenant-3', group=tenant_groups[2]), + ) + Tenant.objects.bulk_create(tenants) + power_panels = ( PowerPanel(name='Power Panel 1', site=sites[0]), PowerPanel(name='Power Panel 2', site=sites[1]), @@ -4427,9 +4442,44 @@ class PowerFeedTestCase(TestCase, ChangeLoggedFilterSetTests): PowerPanel.objects.bulk_create(power_panels) power_feeds = ( - PowerFeed(power_panel=power_panels[0], rack=racks[0], name='Power Feed 1', status=PowerFeedStatusChoices.STATUS_ACTIVE, type=PowerFeedTypeChoices.TYPE_PRIMARY, supply=PowerFeedSupplyChoices.SUPPLY_AC, phase=PowerFeedPhaseChoices.PHASE_3PHASE, voltage=100, amperage=100, max_utilization=10), - PowerFeed(power_panel=power_panels[1], rack=racks[1], name='Power Feed 2', status=PowerFeedStatusChoices.STATUS_FAILED, type=PowerFeedTypeChoices.TYPE_PRIMARY, supply=PowerFeedSupplyChoices.SUPPLY_AC, phase=PowerFeedPhaseChoices.PHASE_3PHASE, voltage=200, amperage=200, max_utilization=20), - PowerFeed(power_panel=power_panels[2], rack=racks[2], name='Power Feed 3', status=PowerFeedStatusChoices.STATUS_OFFLINE, type=PowerFeedTypeChoices.TYPE_REDUNDANT, supply=PowerFeedSupplyChoices.SUPPLY_DC, phase=PowerFeedPhaseChoices.PHASE_SINGLE, voltage=300, amperage=300, max_utilization=30), + PowerFeed( + power_panel=power_panels[0], + rack=racks[0], + name='Power Feed 1', + tenant=tenants[0], + status=PowerFeedStatusChoices.STATUS_ACTIVE, + type=PowerFeedTypeChoices.TYPE_PRIMARY, + supply=PowerFeedSupplyChoices.SUPPLY_AC, + phase=PowerFeedPhaseChoices.PHASE_3PHASE, + voltage=100, + amperage=100, + max_utilization=10 + ), + PowerFeed( + power_panel=power_panels[1], + rack=racks[1], + name='Power Feed 2', + tenant=tenants[1], + status=PowerFeedStatusChoices.STATUS_FAILED, + type=PowerFeedTypeChoices.TYPE_PRIMARY, + supply=PowerFeedSupplyChoices.SUPPLY_AC, + phase=PowerFeedPhaseChoices.PHASE_3PHASE, + voltage=200, + amperage=200, + max_utilization=20), + PowerFeed( + power_panel=power_panels[2], + rack=racks[2], + name='Power Feed 3', + tenant=tenants[2], + status=PowerFeedStatusChoices.STATUS_OFFLINE, + type=PowerFeedTypeChoices.TYPE_REDUNDANT, + supply=PowerFeedSupplyChoices.SUPPLY_DC, + phase=PowerFeedPhaseChoices.PHASE_SINGLE, + voltage=300, + amperage=300, + max_utilization=30 + ), ) PowerFeed.objects.bulk_create(power_feeds) @@ -4520,6 +4570,20 @@ class PowerFeedTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'connected': False} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + def test_tenant(self): + tenants = Tenant.objects.all()[:2] + params = {'tenant_id': [tenants[0].pk, tenants[1].pk]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'tenant': [tenants[0].slug, tenants[1].slug]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + + def test_tenant_group(self): + tenant_groups = TenantGroup.objects.all()[:2] + params = {'tenant_group_id': [tenant_groups[0].pk, tenant_groups[1].pk]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'tenant_group': [tenant_groups[0].slug, tenant_groups[1].slug]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + class VirtualDeviceContextTestCase(TestCase, ChangeLoggedFilterSetTests): queryset = VirtualDeviceContext.objects.all()