Преглед на файлове

fix(circuits): Add provider network name filters

Circuits, circuit terminations, virtual circuits and virtual circuit
terminations offered only provider_network_id, so a provider_network
query parameter was ignored. Each now matches provider networks by
name, including names shared across providers.

Fixes #23473
Martin Hauser преди 1 седмица
родител
ревизия
65ee472b40
променени са 2 файла, в които са добавени 43 реда и са изтрити 0 реда
  1. 27 0
      netbox/circuits/filtersets.py
  2. 16 0
      netbox/circuits/tests/test_filtersets.py

+ 27 - 0
netbox/circuits/filtersets.py

@@ -199,6 +199,12 @@ class CircuitFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilt
         queryset=ProviderNetwork.objects.all(),
         queryset=ProviderNetwork.objects.all(),
         label=_('Provider network (ID)'),
         label=_('Provider network (ID)'),
     )
     )
+    provider_network = django_filters.ModelMultipleChoiceFilter(
+        field_name='terminations___provider_network__name',
+        queryset=ProviderNetwork.objects.all(),
+        to_field_name='name',
+        label=_('Provider network (name)'),
+    )
     type_id = django_filters.ModelMultipleChoiceFilter(
     type_id = django_filters.ModelMultipleChoiceFilter(
         queryset=CircuitType.objects.all(),
         queryset=CircuitType.objects.all(),
         distinct=False,
         distinct=False,
@@ -358,6 +364,13 @@ class CircuitTerminationFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet):
         field_name='_provider_network',
         field_name='_provider_network',
         label=_('ProviderNetwork (ID)'),
         label=_('ProviderNetwork (ID)'),
     )
     )
+    provider_network = django_filters.ModelMultipleChoiceFilter(
+        field_name='_provider_network__name',
+        queryset=ProviderNetwork.objects.all(),
+        distinct=False,
+        to_field_name='name',
+        label=_('Provider network (name)'),
+    )
     provider_id = django_filters.ModelMultipleChoiceFilter(
     provider_id = django_filters.ModelMultipleChoiceFilter(
         field_name='circuit__provider_id',
         field_name='circuit__provider_id',
         queryset=Provider.objects.all(),
         queryset=Provider.objects.all(),
@@ -547,6 +560,13 @@ class VirtualCircuitFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
         distinct=False,
         distinct=False,
         label=_('Provider network (ID)'),
         label=_('Provider network (ID)'),
     )
     )
+    provider_network = django_filters.ModelMultipleChoiceFilter(
+        field_name='provider_network__name',
+        queryset=ProviderNetwork.objects.all(),
+        distinct=False,
+        to_field_name='name',
+        label=_('Provider network (name)'),
+    )
     type_id = django_filters.ModelMultipleChoiceFilter(
     type_id = django_filters.ModelMultipleChoiceFilter(
         queryset=VirtualCircuitType.objects.all(),
         queryset=VirtualCircuitType.objects.all(),
         distinct=False,
         distinct=False,
@@ -627,6 +647,13 @@ class VirtualCircuitTerminationFilterSet(NetBoxModelFilterSet):
         field_name='virtual_circuit__provider_network',
         field_name='virtual_circuit__provider_network',
         label=_('Provider network (ID)'),
         label=_('Provider network (ID)'),
     )
     )
+    provider_network = django_filters.ModelMultipleChoiceFilter(
+        field_name='virtual_circuit__provider_network__name',
+        queryset=ProviderNetwork.objects.all(),
+        distinct=False,
+        to_field_name='name',
+        label=_('Provider network (name)'),
+    )
     interface_id = django_filters.ModelMultipleChoiceFilter(
     interface_id = django_filters.ModelMultipleChoiceFilter(
         queryset=Interface.objects.all(),
         queryset=Interface.objects.all(),
         distinct=False,
         distinct=False,

+ 16 - 0
netbox/circuits/tests/test_filtersets.py

@@ -377,6 +377,8 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTestMixin):
         provider_networks = ProviderNetwork.objects.all()[:2]
         provider_networks = ProviderNetwork.objects.all()[:2]
         params = {'provider_network_id': [provider_networks[0].pk, provider_networks[1].pk]}
         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(), 2)
+        params = {'provider_network': [provider_networks[0].name, provider_networks[1].name]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
 
 
     def test_type(self):
     def test_type(self):
         circuit_type = CircuitType.objects.first()
         circuit_type = CircuitType.objects.first()
@@ -597,6 +599,16 @@ class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTestMixin):
         provider_networks = ProviderNetwork.objects.all()[:2]
         provider_networks = ProviderNetwork.objects.all()[:2]
         params = {'provider_network_id': [provider_networks[0].pk, provider_networks[1].pk]}
         params = {'provider_network_id': [provider_networks[0].pk, provider_networks[1].pk]}
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
+        params = {'provider_network': [provider_networks[0].name]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+        params = {'provider_network': [provider_networks[0].name, provider_networks[1].name]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
+
+    def test_provider_network_shared_name(self):
+        """A name shared by networks of two providers matches both networks."""
+        ProviderNetwork.objects.filter(name='Provider Network 2').update(name='Provider Network 1')
+        params = {'provider_network': ['Provider Network 1']}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
 
 
     def test_cabled(self):
     def test_cabled(self):
         params = {'cabled': True}
         params = {'cabled': True}
@@ -1064,6 +1076,8 @@ class VirtualCircuitTestCase(TestCase, ChangeLoggedFilterSetTestMixin):
         provider_networks = ProviderNetwork.objects.all()[:2]
         provider_networks = ProviderNetwork.objects.all()[:2]
         params = {'provider_network_id': [provider_networks[0].pk, provider_networks[1].pk]}
         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(), 2)
+        params = {'provider_network': [provider_networks[0].name, provider_networks[1].name]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
 
 
     def test_type(self):
     def test_type(self):
         virtual_circuit_types = VirtualCircuitType.objects.all()[:2]
         virtual_circuit_types = VirtualCircuitType.objects.all()[:2]
@@ -1259,6 +1273,8 @@ class VirtualCircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTestMixin
         provider_networks = ProviderNetwork.objects.all()[:2]
         provider_networks = ProviderNetwork.objects.all()[:2]
         params = {'provider_network_id': [provider_networks[0].pk, provider_networks[1].pk]}
         params = {'provider_network_id': [provider_networks[0].pk, provider_networks[1].pk]}
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
+        params = {'provider_network': [provider_networks[0].name, provider_networks[1].name]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
 
 
     def test_provider_account(self):
     def test_provider_account(self):
         provider_accounts = ProviderAccount.objects.all()[:2]
         provider_accounts = ProviderAccount.objects.all()[:2]