diff --git a/netbox/ipam/filtersets.py b/netbox/ipam/filtersets.py index 9b57cb273..bc9181286 100644 --- a/netbox/ipam/filtersets.py +++ b/netbox/ipam/filtersets.py @@ -467,6 +467,10 @@ class IPRangeFilterSet(TenancyFilterSet, NetBoxModelFilterSet): choices=IPRangeStatusChoices, null_value=None ) + parent = MultiValueCharFilter( + method='search_by_parent', + label=_('Parent prefix'), + ) class Meta: model = IPRange @@ -501,6 +505,18 @@ class IPRangeFilterSet(TenancyFilterSet, NetBoxModelFilterSet): except ValidationError: return queryset.none() + def search_by_parent(self, queryset, name, value): + if not value: + return queryset + q = Q() + for prefix in value: + try: + query = str(netaddr.IPNetwork(prefix.strip()).cidr) + q |= Q(start_address__net_host_contained=query, end_address__net_host_contained=query) + except (AddrFormatError, ValueError): + return queryset.none() + return queryset.filter(q) + class IPAddressFilterSet(NetBoxModelFilterSet, TenancyFilterSet): family = django_filters.NumberFilter( diff --git a/netbox/ipam/tests/test_filtersets.py b/netbox/ipam/tests/test_filtersets.py index 0ae7544ab..0aa78e622 100644 --- a/netbox/ipam/tests/test_filtersets.py +++ b/netbox/ipam/tests/test_filtersets.py @@ -10,7 +10,6 @@ from ipam.models import * from utilities.testing import ChangeLoggedFilterSetTests, create_test_device, create_test_virtualmachine from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface from tenancy.models import Tenant, TenantGroup -from rest_framework import serializers class ASNRangeTestCase(TestCase, ChangeLoggedFilterSetTests): @@ -807,6 +806,12 @@ class IPRangeTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'description': ['foobar1', 'foobar2']} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + def test_parent(self): + params = {'parent': ['10.0.1.0/24', '10.0.2.0/24']} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'parent': ['10.0.1.0/25']} # Range 10.0.1.100-199 is not fully contained by 10.0.1.0/25 + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 0) + class IPAddressTestCase(TestCase, ChangeLoggedFilterSetTests): queryset = IPAddress.objects.all()