Просмотр исходного кода

Fixes #5211: Add missing has_primary_ip filter for virtual machines

Jeremy Stretch 5 лет назад
Родитель
Сommit
b5a65bc66c

+ 1 - 0
docs/release-notes/version-2.9.md

@@ -12,6 +12,7 @@
 * [#5199](https://github.com/netbox-community/netbox/issues/5199) - Change default LDAP logging to INFO
 * [#5201](https://github.com/netbox-community/netbox/issues/5201) - Fix missing querystring when bulk editing/deleting VLAN Group VLANs when selecting "select all x items matching query"
 * [#5206](https://github.com/netbox-community/netbox/issues/5206) - Apply user pagination preferences to all paginated object lists
+* [#5211](https://github.com/netbox-community/netbox/issues/5211) - Add missing `has_primary_ip` filter for virtual machines
 * [#5217](https://github.com/netbox-community/netbox/issues/5217) - Prevent erroneous removal of prefetched GenericForeignKey data from tables
 * [#5218](https://github.com/netbox-community/netbox/issues/5218) - Raise validation error if a power port's `allocated_draw` exceeds its `maximum_draw`
 * [#5220](https://github.com/netbox-community/netbox/issues/5220) - Fix API patch request against IP Address endpoint with null assigned_object_type 

+ 3 - 9
netbox/dcim/filters.py

@@ -662,16 +662,10 @@ class DeviceFilterSet(
         ).distinct()
 
     def _has_primary_ip(self, queryset, name, value):
+        params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False)
         if value:
-            return queryset.filter(
-                Q(primary_ip4__isnull=False) |
-                Q(primary_ip6__isnull=False)
-            )
-        else:
-            return queryset.exclude(
-                Q(primary_ip4__isnull=False) |
-                Q(primary_ip6__isnull=False)
-            )
+            return queryset.filter(params)
+        return queryset.exclude(params)
 
     def _virtual_chassis_member(self, queryset, name, value):
         return queryset.exclude(virtual_chassis__isnull=value)

+ 10 - 0
netbox/virtualization/filters.py

@@ -186,6 +186,10 @@ class VirtualMachineFilterSet(
         field_name='interfaces__mac_address',
         label='MAC address',
     )
+    has_primary_ip = django_filters.BooleanFilter(
+        method='_has_primary_ip',
+        label='Has a primary IP',
+    )
     tag = TagFilter()
 
     class Meta:
@@ -200,6 +204,12 @@ class VirtualMachineFilterSet(
             Q(comments__icontains=value)
         )
 
+    def _has_primary_ip(self, queryset, name, value):
+        params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False)
+        if value:
+            return queryset.filter(params)
+        return queryset.exclude(params)
+
 
 class VMInterfaceFilterSet(BaseFilterSet):
     q = django_filters.CharFilter(

+ 7 - 0
netbox/virtualization/forms.py

@@ -516,6 +516,13 @@ class VirtualMachineFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFil
         required=False,
         label='MAC address'
     )
+    has_primary_ip = forms.NullBooleanField(
+        required=False,
+        label='Has a primary IP',
+        widget=StaticSelect2(
+            choices=BOOLEAN_WITH_BLANK_CHOICES
+        )
+    )
     tag = TagFilterField(model)
 
 

+ 16 - 0
netbox/virtualization/tests/test_filters.py

@@ -1,6 +1,7 @@
 from django.test import TestCase
 
 from dcim.models import DeviceRole, Platform, Region, Site
+from ipam.models import IPAddress
 from tenancy.models import Tenant, TenantGroup
 from virtualization.choices import *
 from virtualization.filters import *
@@ -266,6 +267,15 @@ class VirtualMachineTestCase(TestCase):
         )
         VMInterface.objects.bulk_create(interfaces)
 
+        # Assign primary IPs for filtering
+        ipaddresses = (
+            IPAddress(address='192.0.2.1/24', assigned_object=interfaces[0]),
+            IPAddress(address='192.0.2.2/24', assigned_object=interfaces[1]),
+        )
+        IPAddress.objects.bulk_create(ipaddresses)
+        VirtualMachine.objects.filter(pk=vms[0].pk).update(primary_ip4=ipaddresses[0])
+        VirtualMachine.objects.filter(pk=vms[1].pk).update(primary_ip4=ipaddresses[1])
+
     def test_id(self):
         params = {'id': self.queryset.values_list('pk', flat=True)[:2]}
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
@@ -344,6 +354,12 @@ class VirtualMachineTestCase(TestCase):
         params = {'mac_address': ['00-00-00-00-00-01', '00-00-00-00-00-02']}
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
 
+    def test_has_primary_ip(self):
+        params = {'has_primary_ip': 'true'}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+        params = {'has_primary_ip': 'false'}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
+
     def test_local_context_data(self):
         params = {'local_context_data': 'true'}
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)