diff --git a/netbox/ipam/filters.py b/netbox/ipam/filters.py index 0876a0d1a..d6561ceb7 100644 --- a/netbox/ipam/filters.py +++ b/netbox/ipam/filters.py @@ -11,7 +11,7 @@ from utilities.filters import ( BaseFilterSet, MultiValueCharFilter, MultiValueNumberFilter, NameSlugSearchFilterSet, TagFilter, TreeNodeMultipleChoiceFilter, ) -from virtualization.models import VirtualMachine +from virtualization.models import VirtualMachine, VMInterface from .choices import * from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF @@ -319,17 +319,28 @@ class IPAddressFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, field_name='pk', label='Virtual machine (ID)', ) - # TODO: Restore filtering by assigned interface - # interface = django_filters.ModelMultipleChoiceFilter( - # field_name='interface__name', - # queryset=Interface.objects.unrestricted(), - # to_field_name='name', - # label='Interface (ID)', - # ) - # interface_id = django_filters.ModelMultipleChoiceFilter( - # queryset=Interface.objects.unrestricted(), - # label='Interface (ID)', - # ) + interface = django_filters.ModelMultipleChoiceFilter( + field_name='interface__name', + queryset=Interface.objects.unrestricted(), + to_field_name='name', + label='Interface (name)', + ) + interface_id = django_filters.ModelMultipleChoiceFilter( + field_name='interface', + queryset=Interface.objects.unrestricted(), + label='Interface (ID)', + ) + vminterface = django_filters.ModelMultipleChoiceFilter( + field_name='vminterface__name', + queryset=VMInterface.objects.unrestricted(), + to_field_name='name', + label='VM interface (name)', + ) + vminterface_id = django_filters.ModelMultipleChoiceFilter( + field_name='vminterface', + queryset=VMInterface.objects.unrestricted(), + label='VM interface (ID)', + ) assigned_to_interface = django_filters.BooleanFilter( method='_assigned_to_interface', label='Is assigned to an interface', @@ -397,7 +408,7 @@ class IPAddressFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, for vm in virtual_machines: interface_ids.extend(vm.interfaces.values_list('id', flat=True)) return queryset.filter( - vm_interface__in=interface_ids + vminterface__in=interface_ids ) def _assigned_to_interface(self, queryset, name, value): diff --git a/netbox/ipam/tests/test_filters.py b/netbox/ipam/tests/test_filters.py index db9241480..560313f0a 100644 --- a/netbox/ipam/tests/test_filters.py +++ b/netbox/ipam/tests/test_filters.py @@ -392,12 +392,12 @@ class IPAddressTestCase(TestCase): ) VirtualMachine.objects.bulk_create(virtual_machines) - vm_interfaces = ( + vminterfaces = ( VMInterface(virtual_machine=virtual_machines[0], name='Interface 1'), VMInterface(virtual_machine=virtual_machines[1], name='Interface 2'), VMInterface(virtual_machine=virtual_machines[2], name='Interface 3'), ) - VMInterface.objects.bulk_create(vm_interfaces) + VMInterface.objects.bulk_create(vminterfaces) tenant_groups = ( TenantGroup(name='Tenant group 1', slug='tenant-group-1'), @@ -421,9 +421,9 @@ class IPAddressTestCase(TestCase): IPAddress(address='10.0.0.4/24', tenant=tenants[2], vrf=vrfs[2], assigned_object=interfaces[2], status=IPAddressStatusChoices.STATUS_DEPRECATED, role=IPAddressRoleChoices.ROLE_SECONDARY, dns_name='ipaddress-d'), IPAddress(address='10.0.0.1/25', tenant=None, vrf=None, assigned_object=None, status=IPAddressStatusChoices.STATUS_ACTIVE), IPAddress(address='2001:db8::1/64', tenant=None, vrf=None, assigned_object=None, status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-a'), - IPAddress(address='2001:db8::2/64', tenant=tenants[0], vrf=vrfs[0], assigned_object=vm_interfaces[0], status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-b'), - IPAddress(address='2001:db8::3/64', tenant=tenants[1], vrf=vrfs[1], assigned_object=vm_interfaces[1], status=IPAddressStatusChoices.STATUS_RESERVED, role=IPAddressRoleChoices.ROLE_VIP, dns_name='ipaddress-c'), - IPAddress(address='2001:db8::4/64', tenant=tenants[2], vrf=vrfs[2], assigned_object=vm_interfaces[2], status=IPAddressStatusChoices.STATUS_DEPRECATED, role=IPAddressRoleChoices.ROLE_SECONDARY, dns_name='ipaddress-d'), + IPAddress(address='2001:db8::2/64', tenant=tenants[0], vrf=vrfs[0], assigned_object=vminterfaces[0], status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-b'), + IPAddress(address='2001:db8::3/64', tenant=tenants[1], vrf=vrfs[1], assigned_object=vminterfaces[1], status=IPAddressStatusChoices.STATUS_RESERVED, role=IPAddressRoleChoices.ROLE_VIP, dns_name='ipaddress-c'), + IPAddress(address='2001:db8::4/64', tenant=tenants[2], vrf=vrfs[2], assigned_object=vminterfaces[2], status=IPAddressStatusChoices.STATUS_DEPRECATED, role=IPAddressRoleChoices.ROLE_SECONDARY, dns_name='ipaddress-d'), IPAddress(address='2001:db8::1/65', tenant=None, vrf=None, assigned_object=None, status=IPAddressStatusChoices.STATUS_ACTIVE), ) IPAddress.objects.bulk_create(ipaddresses) @@ -486,13 +486,19 @@ class IPAddressTestCase(TestCase): params = {'virtual_machine': [vms[0].name, vms[1].name]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - # TODO: Restore filtering by interface - # def test_interface(self): - # interfaces = Interface.objects.all()[:2] - # params = {'interface_id': [interfaces[0].pk, interfaces[1].pk]} - # self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - # params = {'interface': ['Interface 1', 'Interface 2']} - # self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) + def test_interface(self): + interfaces = Interface.objects.all()[:2] + params = {'interface_id': [interfaces[0].pk, interfaces[1].pk]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'interface': ['Interface 1', 'Interface 2']} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + + def test_vminterface(self): + vminterfaces = VMInterface.objects.all()[:2] + params = {'vminterface_id': [vminterfaces[0].pk, vminterfaces[1].pk]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'vminterface': ['Interface 1', 'Interface 2']} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_assigned_to_interface(self): params = {'assigned_to_interface': 'true'}