Prechádzať zdrojové kódy

Adds parent filter on iprange (#13568)

* adds parent filter on iprange #13313

* lint fix

* adds filterset test

* Filter should match both start & end of IP range

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
Abhimanyu Saharan 2 rokov pred
rodič
commit
8d8f57e8b8

+ 16 - 0
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(

+ 6 - 1
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()