Quellcode durchsuchen

Closes #17669: Enable filtering VLANs by assigned interface (#17674)

* Closes #17669: Enable filtering VLANs by assigned interface

* Add tests
Jeremy Stretch vor 1 Jahr
Ursprung
Commit
fec0badd5a
2 geänderte Dateien mit 66 neuen und 0 gelöschten Zeilen
  1. 26 0
      netbox/ipam/filtersets.py
  2. 40 0
      netbox/ipam/tests/test_filtersets.py

+ 26 - 0
netbox/ipam/filtersets.py

@@ -1035,6 +1035,16 @@ class VLANFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
         to_field_name='identifier',
         label=_('L2VPN'),
     )
+    interface_id = django_filters.ModelChoiceFilter(
+        queryset=Interface.objects.all(),
+        method='filter_interface_id',
+        label=_('Assigned interface')
+    )
+    vminterface_id = django_filters.ModelChoiceFilter(
+        queryset=VMInterface.objects.all(),
+        method='filter_vminterface_id',
+        label=_('Assigned VM interface')
+    )
 
     class Meta:
         model = VLAN
@@ -1062,6 +1072,22 @@ class VLANFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
     def get_for_virtualmachine(self, queryset, name, value):
         return queryset.get_for_virtualmachine(value)
 
+    def filter_interface_id(self, queryset, name, value):
+        if value is None:
+            return queryset.none()
+        return queryset.filter(
+            Q(interfaces_as_tagged=value) |
+            Q(interfaces_as_untagged=value)
+        )
+
+    def filter_vminterface_id(self, queryset, name, value):
+        if value is None:
+            return queryset.none()
+        return queryset.filter(
+            Q(vminterfaces_as_tagged=value) |
+            Q(vminterfaces_as_untagged=value)
+        )
+
 
 class ServiceTemplateFilterSet(NetBoxModelFilterSet):
     port = NumericArrayFilter(

+ 40 - 0
netbox/ipam/tests/test_filtersets.py

@@ -1658,6 +1658,13 @@ class VLANTestCase(TestCase, ChangeLoggedFilterSetTests):
         )
         Device.objects.bulk_create(devices)
 
+        interfaces = (
+            Interface(device=devices[0], name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
+            Interface(device=devices[1], name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
+            Interface(device=devices[2], name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED),
+        )
+        Interface.objects.bulk_create(interfaces)
+
         cluster_groups = (
             ClusterGroup(name='Cluster Group 1', slug='cluster-group-1'),
             ClusterGroup(name='Cluster Group 2', slug='cluster-group-2'),
@@ -1680,6 +1687,13 @@ class VLANTestCase(TestCase, ChangeLoggedFilterSetTests):
         )
         VirtualMachine.objects.bulk_create(virtual_machines)
 
+        vm_interfaces = (
+            VMInterface(virtual_machine=virtual_machines[0], name='VM Interface 1'),
+            VMInterface(virtual_machine=virtual_machines[1], name='VM Interface 2'),
+            VMInterface(virtual_machine=virtual_machines[2], name='VM Interface 3'),
+        )
+        VMInterface.objects.bulk_create(vm_interfaces)
+
         groups = (
             # Scoped VLAN groups
             VLANGroup(name='Region 1', slug='region-1', scope=regions[0]),
@@ -1773,6 +1787,22 @@ class VLANTestCase(TestCase, ChangeLoggedFilterSetTests):
         )
         VLAN.objects.bulk_create(vlans)
 
+        # Assign VLANs to device interfaces
+        interfaces[0].untagged_vlan = vlans[0]
+        interfaces[0].tagged_vlans.add(vlans[1])
+        interfaces[1].untagged_vlan = vlans[2]
+        interfaces[1].tagged_vlans.add(vlans[3])
+        interfaces[2].untagged_vlan = vlans[4]
+        interfaces[2].tagged_vlans.add(vlans[5])
+
+        # Assign VLANs to VM interfaces
+        vm_interfaces[0].untagged_vlan = vlans[0]
+        vm_interfaces[0].tagged_vlans.add(vlans[1])
+        vm_interfaces[1].untagged_vlan = vlans[2]
+        vm_interfaces[1].tagged_vlans.add(vlans[3])
+        vm_interfaces[2].untagged_vlan = vlans[4]
+        vm_interfaces[2].tagged_vlans.add(vlans[5])
+
     def test_q(self):
         params = {'q': 'foobar1'}
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
@@ -1857,6 +1887,16 @@ class VLANTestCase(TestCase, ChangeLoggedFilterSetTests):
         params = {'available_at_site': site_id}
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5)  # 4 scoped + 1 global group + 1 global
 
+    def test_interface(self):
+        interface_id = Interface.objects.first().pk
+        params = {'interface_id': interface_id}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
+
+    def test_vminterface(self):
+        vminterface_id = VMInterface.objects.first().pk
+        params = {'vminterface_id': vminterface_id}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
+
 
 class ServiceTemplateTestCase(TestCase, ChangeLoggedFilterSetTests):
     queryset = ServiceTemplate.objects.all()