From b4877e7fac49282a766ebcdd2f886f71e8d61fa5 Mon Sep 17 00:00:00 2001 From: Arthur Date: Wed, 7 Sep 2022 15:45:01 -0700 Subject: [PATCH 1/6] #8580 add interface filters for connected --- netbox/dcim/filtersets.py | 9 +++++++++ netbox/dcim/forms/filtersets.py | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index 5d92af878..1a9887c31 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -1304,6 +1304,9 @@ class InterfaceFilterSet( to_field_name='rd', label='VRF (RD)', ) + is_occupied = django_filters.BooleanFilter( + method='filter_is_occupied' + ) class Meta: model = Interface @@ -1359,6 +1362,12 @@ class InterfaceFilterSet( 'wireless': queryset.filter(type__in=WIRELESS_IFACE_TYPES), }.get(value, queryset.none()) + def filter_is_occupied(self, queryset, name, value): + if value: + return queryset.filter(Q(cable__isnull=False) | Q(mark_connected=True)) + else: + return queryset.filter(cable__isnull=True, mark_connected=False) + class FrontPortFilterSet( ModularDeviceComponentFilterSet, diff --git a/netbox/dcim/forms/filtersets.py b/netbox/dcim/forms/filtersets.py index 173ea5d1e..85fe909c5 100644 --- a/netbox/dcim/forms/filtersets.py +++ b/netbox/dcim/forms/filtersets.py @@ -1009,6 +1009,7 @@ class InterfaceFilterForm(DeviceComponentFilterForm): ('PoE', ('poe_mode', 'poe_type')), ('Wireless', ('rf_role', 'rf_channel', 'rf_channel_width', 'tx_power')), ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')), + ('Connection', ('cabled', 'connected', 'is_occupied')) ) kind = MultipleChoiceField( choices=InterfaceKindChoices, @@ -1087,6 +1088,24 @@ class InterfaceFilterForm(DeviceComponentFilterForm): label='VRF' ) tag = TagFilterField(model) + cabled = forms.NullBooleanField( + required=False, + widget=StaticSelect( + choices=BOOLEAN_WITH_BLANK_CHOICES + ) + ) + connected = forms.NullBooleanField( + required=False, + widget=StaticSelect( + choices=BOOLEAN_WITH_BLANK_CHOICES + ) + ) + is_occupied = forms.NullBooleanField( + required=False, + widget=StaticSelect( + choices=BOOLEAN_WITH_BLANK_CHOICES + ) + ) class FrontPortFilterForm(DeviceComponentFilterForm): From d51e833bf378912c67f60d6eab6f6ba9565a6f09 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 8 Sep 2022 13:11:17 -0700 Subject: [PATCH 2/6] #8580 changes from code review --- netbox/dcim/filtersets.py | 6 ++--- netbox/dcim/forms/filtersets.py | 41 ++++++++++++++++++--------------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index 1a9887c31..4ccf0dda5 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -1144,6 +1144,9 @@ class CabledObjectFilterSet(django_filters.FilterSet): lookup_expr='isnull', exclude=True ) + is_occupied = django_filters.BooleanFilter( + method='filter_is_occupied' + ) class PathEndpointFilterSet(django_filters.FilterSet): @@ -1304,9 +1307,6 @@ class InterfaceFilterSet( to_field_name='rd', label='VRF (RD)', ) - is_occupied = django_filters.BooleanFilter( - method='filter_is_occupied' - ) class Meta: model = Interface diff --git a/netbox/dcim/forms/filtersets.py b/netbox/dcim/forms/filtersets.py index 85fe909c5..fe92350f9 100644 --- a/netbox/dcim/forms/filtersets.py +++ b/netbox/dcim/forms/filtersets.py @@ -1000,7 +1000,28 @@ class PowerOutletFilterForm(DeviceComponentFilterForm): tag = TagFilterField(model) -class InterfaceFilterForm(DeviceComponentFilterForm): +class CabledFilterForm(forms.Form): + cabled = forms.NullBooleanField( + required=False, + widget=StaticSelect( + choices=BOOLEAN_WITH_BLANK_CHOICES + ) + ) + connected = forms.NullBooleanField( + required=False, + widget=StaticSelect( + choices=BOOLEAN_WITH_BLANK_CHOICES + ) + ) + is_occupied = forms.NullBooleanField( + required=False, + widget=StaticSelect( + choices=BOOLEAN_WITH_BLANK_CHOICES + ) + ) + + +class InterfaceFilterForm(CabledFilterForm, DeviceComponentFilterForm): model = Interface fieldsets = ( (None, ('q', 'tag')), @@ -1088,24 +1109,6 @@ class InterfaceFilterForm(DeviceComponentFilterForm): label='VRF' ) tag = TagFilterField(model) - cabled = forms.NullBooleanField( - required=False, - widget=StaticSelect( - choices=BOOLEAN_WITH_BLANK_CHOICES - ) - ) - connected = forms.NullBooleanField( - required=False, - widget=StaticSelect( - choices=BOOLEAN_WITH_BLANK_CHOICES - ) - ) - is_occupied = forms.NullBooleanField( - required=False, - widget=StaticSelect( - choices=BOOLEAN_WITH_BLANK_CHOICES - ) - ) class FrontPortFilterForm(DeviceComponentFilterForm): From 1daa2ff98d07020c864c90b5f0e306956da35479 Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 12 Sep 2022 10:22:05 -0700 Subject: [PATCH 3/6] #8580 add tests --- netbox/dcim/tests/test_filtersets.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index 1aaf861ef..15e109030 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -2741,12 +2741,6 @@ class InterfaceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'label': ['A', 'B']} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - def test_connected(self): - params = {'connected': True} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) - params = {'connected': False} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) - def test_enabled(self): params = {'enabled': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6) @@ -2885,6 +2879,18 @@ class InterfaceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'cabled': 'false'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) + def test_connected(self): + params = {'connected': True} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) + params = {'connected': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) + + def is_occupied(self): + params = {'is_occupied': 'true'} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) + params = {'is_occupied': 'false'} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) + def test_kind(self): params = {'kind': 'physical'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6) From d24f10ce6e2878a8963412ec271f0dd449862bf7 Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 12 Sep 2022 10:52:40 -0700 Subject: [PATCH 4/6] #8580 add tests --- netbox/circuits/tests/test_filtersets.py | 18 ++++++++++++++++-- netbox/dcim/filtersets.py | 12 ++++++------ netbox/dcim/tests/test_filtersets.py | 6 +++--- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/netbox/circuits/tests/test_filtersets.py b/netbox/circuits/tests/test_filtersets.py index abcfa8a00..ada3d9bf1 100644 --- a/netbox/circuits/tests/test_filtersets.py +++ b/netbox/circuits/tests/test_filtersets.py @@ -344,6 +344,7 @@ class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests): Circuit(provider=providers[0], type=circuit_types[0], cid='Circuit 4'), Circuit(provider=providers[0], type=circuit_types[0], cid='Circuit 5'), Circuit(provider=providers[0], type=circuit_types[0], cid='Circuit 6'), + Circuit(provider=providers[0], type=circuit_types[0], cid='Circuit 7'), ) Circuit.objects.bulk_create(circuits) @@ -357,6 +358,7 @@ class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests): CircuitTermination(circuit=circuits[3], provider_network=provider_networks[0], term_side='A'), CircuitTermination(circuit=circuits[4], provider_network=provider_networks[1], term_side='A'), CircuitTermination(circuit=circuits[5], provider_network=provider_networks[2], term_side='A'), + CircuitTermination(circuit=circuits[6], provider_network=provider_networks[0], term_side='A', mark_connected=True), )) CircuitTermination.objects.bulk_create(circuit_terminations) @@ -364,7 +366,7 @@ class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests): def test_term_side(self): params = {'term_side': 'A'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 7) def test_port_speed(self): params = {'port_speed': ['1000', '2000']} @@ -397,12 +399,24 @@ class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests): def test_provider_network(self): provider_networks = ProviderNetwork.objects.all()[:2] params = {'provider_network_id': [provider_networks[0].pk, provider_networks[1].pk]} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3) def test_cabled(self): params = {'cabled': True} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + def test_connected(self): + params = {'connected': True} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 10) + params = {'connected': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 10) + + def test_is_occupied(self): + params = {'is_occupied': True} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3) + params = {'is_occupied': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 7) + class ProviderNetworkTestCase(TestCase, ChangeLoggedFilterSetTests): queryset = ProviderNetwork.objects.all() diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index 4ccf0dda5..3af5883ba 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -1148,6 +1148,12 @@ class CabledObjectFilterSet(django_filters.FilterSet): method='filter_is_occupied' ) + def filter_is_occupied(self, queryset, name, value): + if value: + return queryset.filter(Q(cable__isnull=False) | Q(mark_connected=True)) + else: + return queryset.filter(cable__isnull=True, mark_connected=False) + class PathEndpointFilterSet(django_filters.FilterSet): connected = django_filters.BooleanFilter( @@ -1362,12 +1368,6 @@ class InterfaceFilterSet( 'wireless': queryset.filter(type__in=WIRELESS_IFACE_TYPES), }.get(value, queryset.none()) - def filter_is_occupied(self, queryset, name, value): - if value: - return queryset.filter(Q(cable__isnull=False) | Q(mark_connected=True)) - else: - return queryset.filter(cable__isnull=True, mark_connected=False) - class FrontPortFilterSet( ModularDeviceComponentFilterSet, diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index 15e109030..6cbd91122 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -2885,10 +2885,10 @@ class InterfaceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'connected': False} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) - def is_occupied(self): - params = {'is_occupied': 'true'} + def test_is_occupied(self): + params = {'is_occupied': True} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) - params = {'is_occupied': 'false'} + params = {'is_occupied': False} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) def test_kind(self): From 57365ef7b9d012b4c5d27361bfe7c0ca3012db15 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 12 Sep 2022 16:42:04 -0400 Subject: [PATCH 5/6] Rename is_occupied to occupied --- netbox/circuits/tests/test_filtersets.py | 6 +++--- netbox/dcim/filtersets.py | 6 +++--- netbox/dcim/forms/filtersets.py | 4 ++-- netbox/dcim/tests/test_filtersets.py | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/netbox/circuits/tests/test_filtersets.py b/netbox/circuits/tests/test_filtersets.py index ada3d9bf1..0bc0711c1 100644 --- a/netbox/circuits/tests/test_filtersets.py +++ b/netbox/circuits/tests/test_filtersets.py @@ -411,10 +411,10 @@ class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'connected': False} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 10) - def test_is_occupied(self): - params = {'is_occupied': True} + def test_occupied(self): + params = {'occupied': True} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3) - params = {'is_occupied': False} + params = {'occupied': False} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 7) diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index 3af5883ba..afecf551c 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -1144,11 +1144,11 @@ class CabledObjectFilterSet(django_filters.FilterSet): lookup_expr='isnull', exclude=True ) - is_occupied = django_filters.BooleanFilter( - method='filter_is_occupied' + occupied = django_filters.BooleanFilter( + method='filter_occupied' ) - def filter_is_occupied(self, queryset, name, value): + def filter_occupied(self, queryset, name, value): if value: return queryset.filter(Q(cable__isnull=False) | Q(mark_connected=True)) else: diff --git a/netbox/dcim/forms/filtersets.py b/netbox/dcim/forms/filtersets.py index fe92350f9..93e221b19 100644 --- a/netbox/dcim/forms/filtersets.py +++ b/netbox/dcim/forms/filtersets.py @@ -1013,7 +1013,7 @@ class CabledFilterForm(forms.Form): choices=BOOLEAN_WITH_BLANK_CHOICES ) ) - is_occupied = forms.NullBooleanField( + occupied = forms.NullBooleanField( required=False, widget=StaticSelect( choices=BOOLEAN_WITH_BLANK_CHOICES @@ -1030,7 +1030,7 @@ class InterfaceFilterForm(CabledFilterForm, DeviceComponentFilterForm): ('PoE', ('poe_mode', 'poe_type')), ('Wireless', ('rf_role', 'rf_channel', 'rf_channel_width', 'tx_power')), ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')), - ('Connection', ('cabled', 'connected', 'is_occupied')) + ('Connection', ('cabled', 'connected', 'occupied')) ) kind = MultipleChoiceField( choices=InterfaceKindChoices, diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index 6cbd91122..49e68b9a2 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -2885,10 +2885,10 @@ class InterfaceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'connected': False} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) - def test_is_occupied(self): - params = {'is_occupied': True} + def test_occupied(self): + params = {'occupied': True} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) - params = {'is_occupied': False} + params = {'occupied': False} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) def test_kind(self): From f10460d774db773c759faa4b9b96c59470c12a5a Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 12 Sep 2022 17:03:33 -0400 Subject: [PATCH 6/6] Add relevant tests for all device components --- netbox/circuits/tests/test_filtersets.py | 8 +- netbox/dcim/forms/filtersets.py | 157 ++++++++++++----------- netbox/dcim/tests/test_filtersets.py | 128 +++++++++++------- 3 files changed, 167 insertions(+), 126 deletions(-) diff --git a/netbox/circuits/tests/test_filtersets.py b/netbox/circuits/tests/test_filtersets.py index 0bc0711c1..2646de3c2 100644 --- a/netbox/circuits/tests/test_filtersets.py +++ b/netbox/circuits/tests/test_filtersets.py @@ -404,12 +404,8 @@ class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests): def test_cabled(self): params = {'cabled': True} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - - def test_connected(self): - params = {'connected': True} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 10) - params = {'connected': False} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 10) + params = {'cabled': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 8) def test_occupied(self): params = {'occupied': True} diff --git a/netbox/dcim/forms/filtersets.py b/netbox/dcim/forms/filtersets.py index 93e221b19..98be0983e 100644 --- a/netbox/dcim/forms/filtersets.py +++ b/netbox/dcim/forms/filtersets.py @@ -936,70 +936,6 @@ class PowerFeedFilterForm(NetBoxModelFilterSetForm): # Device components # -class ConsolePortFilterForm(DeviceComponentFilterForm): - model = ConsolePort - fieldsets = ( - (None, ('q', 'tag')), - ('Attributes', ('name', 'label', 'type', 'speed')), - ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')), - ) - type = MultipleChoiceField( - choices=ConsolePortTypeChoices, - required=False - ) - speed = MultipleChoiceField( - choices=ConsolePortSpeedChoices, - required=False - ) - tag = TagFilterField(model) - - -class ConsoleServerPortFilterForm(DeviceComponentFilterForm): - model = ConsoleServerPort - fieldsets = ( - (None, ('q', 'tag')), - ('Attributes', ('name', 'label', 'type', 'speed')), - ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')), - ) - type = MultipleChoiceField( - choices=ConsolePortTypeChoices, - required=False - ) - speed = MultipleChoiceField( - choices=ConsolePortSpeedChoices, - required=False - ) - tag = TagFilterField(model) - - -class PowerPortFilterForm(DeviceComponentFilterForm): - model = PowerPort - fieldsets = ( - (None, ('q', 'tag')), - ('Attributes', ('name', 'label', 'type')), - ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')), - ) - type = MultipleChoiceField( - choices=PowerPortTypeChoices, - required=False - ) - tag = TagFilterField(model) - - -class PowerOutletFilterForm(DeviceComponentFilterForm): - model = PowerOutlet - fieldsets = ( - (None, ('q', 'tag')), - ('Attributes', ('name', 'label', 'type')), - ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')), - ) - type = MultipleChoiceField( - choices=PowerOutletTypeChoices, - required=False - ) - tag = TagFilterField(model) - - class CabledFilterForm(forms.Form): cabled = forms.NullBooleanField( required=False, @@ -1007,12 +943,6 @@ class CabledFilterForm(forms.Form): choices=BOOLEAN_WITH_BLANK_CHOICES ) ) - connected = forms.NullBooleanField( - required=False, - widget=StaticSelect( - choices=BOOLEAN_WITH_BLANK_CHOICES - ) - ) occupied = forms.NullBooleanField( required=False, widget=StaticSelect( @@ -1021,7 +951,84 @@ class CabledFilterForm(forms.Form): ) -class InterfaceFilterForm(CabledFilterForm, DeviceComponentFilterForm): +class PathEndpointFilterForm(CabledFilterForm): + connected = forms.NullBooleanField( + required=False, + widget=StaticSelect( + choices=BOOLEAN_WITH_BLANK_CHOICES + ) + ) + + +class ConsolePortFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm): + model = ConsolePort + fieldsets = ( + (None, ('q', 'tag')), + ('Attributes', ('name', 'label', 'type', 'speed')), + ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')), + ('Connection', ('cabled', 'connected', 'occupied')), + ) + type = MultipleChoiceField( + choices=ConsolePortTypeChoices, + required=False + ) + speed = MultipleChoiceField( + choices=ConsolePortSpeedChoices, + required=False + ) + tag = TagFilterField(model) + + +class ConsoleServerPortFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm): + model = ConsoleServerPort + fieldsets = ( + (None, ('q', 'tag')), + ('Attributes', ('name', 'label', 'type', 'speed')), + ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')), + ('Connection', ('cabled', 'connected', 'occupied')), + ) + type = MultipleChoiceField( + choices=ConsolePortTypeChoices, + required=False + ) + speed = MultipleChoiceField( + choices=ConsolePortSpeedChoices, + required=False + ) + tag = TagFilterField(model) + + +class PowerPortFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm): + model = PowerPort + fieldsets = ( + (None, ('q', 'tag')), + ('Attributes', ('name', 'label', 'type')), + ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')), + ('Connection', ('cabled', 'connected', 'occupied')), + ) + type = MultipleChoiceField( + choices=PowerPortTypeChoices, + required=False + ) + tag = TagFilterField(model) + + +class PowerOutletFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm): + model = PowerOutlet + fieldsets = ( + (None, ('q', 'tag')), + ('Attributes', ('name', 'label', 'type')), + ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')), + ('Connection', ('cabled', 'connected', 'occupied')), + ) + type = MultipleChoiceField( + choices=PowerOutletTypeChoices, + required=False + ) + tag = TagFilterField(model) + + +class InterfaceFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm): model = Interface fieldsets = ( (None, ('q', 'tag')), @@ -1030,7 +1037,7 @@ class InterfaceFilterForm(CabledFilterForm, DeviceComponentFilterForm): ('PoE', ('poe_mode', 'poe_type')), ('Wireless', ('rf_role', 'rf_channel', 'rf_channel_width', 'tx_power')), ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')), - ('Connection', ('cabled', 'connected', 'occupied')) + ('Connection', ('cabled', 'connected', 'occupied')), ) kind = MultipleChoiceField( choices=InterfaceKindChoices, @@ -1111,11 +1118,12 @@ class InterfaceFilterForm(CabledFilterForm, DeviceComponentFilterForm): tag = TagFilterField(model) -class FrontPortFilterForm(DeviceComponentFilterForm): +class FrontPortFilterForm(CabledFilterForm, DeviceComponentFilterForm): fieldsets = ( (None, ('q', 'tag')), ('Attributes', ('name', 'label', 'type', 'color')), ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')), + ('Cable', ('cabled', 'occupied')), ) model = FrontPort type = MultipleChoiceField( @@ -1128,12 +1136,13 @@ class FrontPortFilterForm(DeviceComponentFilterForm): tag = TagFilterField(model) -class RearPortFilterForm(DeviceComponentFilterForm): +class RearPortFilterForm(CabledFilterForm, DeviceComponentFilterForm): model = RearPort fieldsets = ( (None, ('q', 'tag')), ('Attributes', ('name', 'label', 'type', 'color')), ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')), + ('Cable', ('cabled', 'occupied')), ) type = MultipleChoiceField( choices=PortTypeChoices, diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index 49e68b9a2..eb4627ac0 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -1983,12 +1983,6 @@ class ConsolePortTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'description': ['First', 'Second']} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - def test_connected(self): - params = {'connected': True} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - params = {'connected': False} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) - def test_region(self): regions = Region.objects.all()[:2] params = {'region_id': [regions[0].pk, regions[1].pk]} @@ -2037,9 +2031,21 @@ class ConsolePortTestCase(TestCase, ChangeLoggedFilterSetTests): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_cabled(self): - params = {'cabled': 'true'} + params = {'cabled': True} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - params = {'cabled': 'false'} + params = {'cabled': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + + def test_occupied(self): + params = {'occupied': True} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'occupied': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + + def test_connected(self): + params = {'connected': True} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'connected': False} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) @@ -2144,12 +2150,6 @@ class ConsoleServerPortTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'description': ['First', 'Second']} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - def test_connected(self): - params = {'connected': True} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - params = {'connected': False} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) - def test_region(self): regions = Region.objects.all()[:2] params = {'region_id': [regions[0].pk, regions[1].pk]} @@ -2198,9 +2198,21 @@ class ConsoleServerPortTestCase(TestCase, ChangeLoggedFilterSetTests): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_cabled(self): - params = {'cabled': 'true'} + params = {'cabled': True} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - params = {'cabled': 'false'} + params = {'cabled': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + + def test_occupied(self): + params = {'occupied': True} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'occupied': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + + def test_connected(self): + params = {'connected': True} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'connected': False} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) @@ -2313,12 +2325,6 @@ class PowerPortTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'allocated_draw': [50, 100]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - def test_connected(self): - params = {'connected': True} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - params = {'connected': False} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) - def test_region(self): regions = Region.objects.all()[:2] params = {'region_id': [regions[0].pk, regions[1].pk]} @@ -2367,9 +2373,21 @@ class PowerPortTestCase(TestCase, ChangeLoggedFilterSetTests): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_cabled(self): - params = {'cabled': 'true'} + params = {'cabled': True} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - params = {'cabled': 'false'} + params = {'cabled': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + + def test_occupied(self): + params = {'occupied': True} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'occupied': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + + def test_connected(self): + params = {'connected': True} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'connected': False} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) @@ -2478,12 +2496,6 @@ class PowerOutletTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'feed_leg': [PowerOutletFeedLegChoices.FEED_LEG_A, PowerOutletFeedLegChoices.FEED_LEG_B]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - def test_connected(self): - params = {'connected': True} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - params = {'connected': False} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) - def test_region(self): regions = Region.objects.all()[:2] params = {'region_id': [regions[0].pk, regions[1].pk]} @@ -2532,9 +2544,21 @@ class PowerOutletTestCase(TestCase, ChangeLoggedFilterSetTests): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_cabled(self): - params = {'cabled': 'true'} + params = {'cabled': True} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - params = {'cabled': 'false'} + params = {'cabled': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + + def test_occupied(self): + params = {'occupied': True} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'occupied': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + + def test_connected(self): + params = {'connected': True} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'connected': False} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) @@ -2874,15 +2898,9 @@ class InterfaceTestCase(TestCase, ChangeLoggedFilterSetTests): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_cabled(self): - params = {'cabled': 'true'} + params = {'cabled': True} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) - params = {'cabled': 'false'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) - - def test_connected(self): - params = {'connected': True} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) - params = {'connected': False} + params = {'cabled': False} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) def test_occupied(self): @@ -2891,6 +2909,12 @@ class InterfaceTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'occupied': False} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) + def test_connected(self): + params = {'connected': True} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) + params = {'connected': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) + def test_kind(self): params = {'kind': 'physical'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6) @@ -3097,9 +3121,15 @@ class FrontPortTestCase(TestCase, ChangeLoggedFilterSetTests): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_cabled(self): - params = {'cabled': 'true'} + params = {'cabled': True} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) - params = {'cabled': 'false'} + params = {'cabled': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + + def test_occupied(self): + params = {'occupied': True} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) + params = {'occupied': False} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) @@ -3261,9 +3291,15 @@ class RearPortTestCase(TestCase, ChangeLoggedFilterSetTests): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_cabled(self): - params = {'cabled': 'true'} + params = {'cabled': True} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) - params = {'cabled': 'false'} + params = {'cabled': False} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + + def test_occupied(self): + params = {'occupied': True} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) + params = {'occupied': False} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) @@ -4165,9 +4201,9 @@ class PowerFeedTestCase(TestCase, ChangeLoggedFilterSetTests): self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_cabled(self): - params = {'cabled': 'true'} + params = {'cabled': True} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - params = {'cabled': 'false'} + params = {'cabled': False} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) def test_connected(self):