Skip to content

Commit 6b89da2

Browse files
miaow2Artem I. Kotikjeremystretch
authored
Closes #13936: Add primary_ip4 and primary_ip6 filters to VirtualMachine and VirtualDeviceContext filtersets (#14203)
* Add primary_ip4 and primary_ip6 filters for VirtualMachine and VirtualDeviceContext filtersets (#13936) * Add PrimaryIPFilterSet to __all__ --------- Co-authored-by: Artem I. Kotik <[email protected]> Co-authored-by: Jeremy Stretch <[email protected]>
1 parent 092f2b0 commit 6b89da2

File tree

6 files changed

+70
-16
lines changed

6 files changed

+70
-16
lines changed

netbox/dcim/filtersets.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from extras.filtersets import LocalConfigContextFilterSet
66
from extras.models import ConfigTemplate
7+
from ipam.filtersets import PrimaryIPFilterSet
78
from ipam.models import ASN, L2VPN, IPAddress, VRF
89
from netbox.filtersets import (
910
BaseFilterSet, ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, NetBoxModelFilterSet,
@@ -817,7 +818,13 @@ class Meta:
817818
fields = ['id', 'name', 'slug', 'description']
818819

819820

820-
class DeviceFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet, LocalConfigContextFilterSet):
821+
class DeviceFilterSet(
822+
NetBoxModelFilterSet,
823+
TenancyFilterSet,
824+
ContactModelFilterSet,
825+
LocalConfigContextFilterSet,
826+
PrimaryIPFilterSet,
827+
):
821828
manufacturer_id = django_filters.ModelMultipleChoiceFilter(
822829
field_name='device_type__manufacturer',
823830
queryset=Manufacturer.objects.all(),
@@ -993,16 +1000,6 @@ class DeviceFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilter
9931000
method='_device_bays',
9941001
label=_('Has device bays'),
9951002
)
996-
primary_ip4_id = django_filters.ModelMultipleChoiceFilter(
997-
field_name='primary_ip4',
998-
queryset=IPAddress.objects.all(),
999-
label=_('Primary IPv4 (ID)'),
1000-
)
1001-
primary_ip6_id = django_filters.ModelMultipleChoiceFilter(
1002-
field_name='primary_ip6',
1003-
queryset=IPAddress.objects.all(),
1004-
label=_('Primary IPv6 (ID)'),
1005-
)
10061003
oob_ip_id = django_filters.ModelMultipleChoiceFilter(
10071004
field_name='oob_ip',
10081005
queryset=IPAddress.objects.all(),
@@ -1069,7 +1066,7 @@ def _device_bays(self, queryset, name, value):
10691066
return queryset.exclude(devicebays__isnull=value)
10701067

10711068

1072-
class VirtualDeviceContextFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
1069+
class VirtualDeviceContextFilterSet(NetBoxModelFilterSet, TenancyFilterSet, PrimaryIPFilterSet):
10731070
device_id = django_filters.ModelMultipleChoiceFilter(
10741071
field_name='device',
10751072
queryset=Device.objects.all(),

netbox/dcim/tests/test_filtersets.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4712,12 +4712,18 @@ def setUpTestData(cls):
47124712
addresses = (
47134713
IPAddress(assigned_object=interfaces[0], address='10.1.1.1/24'),
47144714
IPAddress(assigned_object=interfaces[1], address='10.1.1.2/24'),
4715+
IPAddress(assigned_object=None, address='10.1.1.3/24'),
4716+
IPAddress(assigned_object=interfaces[0], address='2001:db8::1/64'),
4717+
IPAddress(assigned_object=interfaces[1], address='2001:db8::2/64'),
4718+
IPAddress(assigned_object=None, address='2001:db8::3/64'),
47154719
)
47164720
IPAddress.objects.bulk_create(addresses)
47174721

47184722
vdcs[0].primary_ip4 = addresses[0]
4723+
vdcs[0].primary_ip6 = addresses[3]
47194724
vdcs[0].save()
47204725
vdcs[1].primary_ip4 = addresses[1]
4726+
vdcs[1].primary_ip6 = addresses[4]
47214727
vdcs[1].save()
47224728

47234729
def test_device(self):
@@ -4738,3 +4744,17 @@ def test_has_primary_ip(self):
47384744
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
47394745
params = {'has_primary_ip': False}
47404746
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
4747+
4748+
def test_primary_ip4(self):
4749+
addresses = IPAddress.objects.filter(address__family=4)
4750+
params = {'primary_ip4_id': [addresses[0].pk, addresses[1].pk]}
4751+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
4752+
params = {'primary_ip4_id': [addresses[2].pk]}
4753+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 0)
4754+
4755+
def test_primary_ip6(self):
4756+
addresses = IPAddress.objects.filter(address__family=6)
4757+
params = {'primary_ip6_id': [addresses[0].pk, addresses[1].pk]}
4758+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
4759+
params = {'primary_ip6_id': [addresses[2].pk]}
4760+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 0)

netbox/extras/tests/test_views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ def setUpTestData(cls):
457457
'platforms': [],
458458
'tenant_groups': [],
459459
'tenants': [],
460-
'device_types': [devicetype.id,],
460+
'device_types': [devicetype.id],
461461
'tags': [],
462462
'data': '{"foo": 123}',
463463
}

netbox/ipam/filtersets.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
'L2VPNFilterSet',
3030
'L2VPNTerminationFilterSet',
3131
'PrefixFilterSet',
32+
'PrimaryIPFilterSet',
3233
'RIRFilterSet',
3334
'RoleFilterSet',
3435
'RouteTargetFilterSet',
@@ -1232,3 +1233,19 @@ def filter_region(self, queryset, name, value):
12321233
)
12331234
)
12341235
return qs
1236+
1237+
1238+
class PrimaryIPFilterSet(django_filters.FilterSet):
1239+
"""
1240+
An inheritable FilterSet for models which support primary IP assignment.
1241+
"""
1242+
primary_ip4_id = django_filters.ModelMultipleChoiceFilter(
1243+
field_name='primary_ip4',
1244+
queryset=IPAddress.objects.all(),
1245+
label=_('Primary IPv4 (ID)'),
1246+
)
1247+
primary_ip6_id = django_filters.ModelMultipleChoiceFilter(
1248+
field_name='primary_ip6',
1249+
queryset=IPAddress.objects.all(),
1250+
label=_('Primary IPv6 (ID)'),
1251+
)

netbox/virtualization/filtersets.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from dcim.models import Device, DeviceRole, Platform, Region, Site, SiteGroup
77
from extras.filtersets import LocalConfigContextFilterSet
88
from extras.models import ConfigTemplate
9+
from ipam.filtersets import PrimaryIPFilterSet
910
from netbox.filtersets import OrganizationalModelFilterSet, NetBoxModelFilterSet
1011
from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet
1112
from utilities.filters import MultiValueCharFilter, MultiValueMACAddressFilter, TreeNodeMultipleChoiceFilter
@@ -114,7 +115,8 @@ class VirtualMachineFilterSet(
114115
NetBoxModelFilterSet,
115116
TenancyFilterSet,
116117
ContactModelFilterSet,
117-
LocalConfigContextFilterSet
118+
LocalConfigContextFilterSet,
119+
PrimaryIPFilterSet,
118120
):
119121
status = django_filters.MultipleChoiceFilter(
120122
choices=VirtualMachineStatusChoices,

netbox/virtualization/tests/test_filtersets.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,14 @@ def setUpTestData(cls):
291291
ipaddresses = (
292292
IPAddress(address='192.0.2.1/24', assigned_object=interfaces[0]),
293293
IPAddress(address='192.0.2.2/24', assigned_object=interfaces[1]),
294+
IPAddress(address='192.0.2.3/24', assigned_object=None),
295+
IPAddress(address='2001:db8::1/64', assigned_object=interfaces[0]),
296+
IPAddress(address='2001:db8::2/64', assigned_object=interfaces[1]),
297+
IPAddress(address='2001:db8::3/64', assigned_object=None),
294298
)
295299
IPAddress.objects.bulk_create(ipaddresses)
296-
VirtualMachine.objects.filter(pk=vms[0].pk).update(primary_ip4=ipaddresses[0])
297-
VirtualMachine.objects.filter(pk=vms[1].pk).update(primary_ip4=ipaddresses[1])
300+
VirtualMachine.objects.filter(pk=vms[0].pk).update(primary_ip4=ipaddresses[0], primary_ip6=ipaddresses[3])
301+
VirtualMachine.objects.filter(pk=vms[1].pk).update(primary_ip4=ipaddresses[1], primary_ip6=ipaddresses[4])
298302

299303
def test_name(self):
300304
params = {'name': ['Virtual Machine 1', 'Virtual Machine 2']}
@@ -412,6 +416,20 @@ def test_tenant_group(self):
412416
params = {'tenant_group': [tenant_groups[0].slug, tenant_groups[1].slug]}
413417
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
414418

419+
def test_primary_ip4(self):
420+
addresses = IPAddress.objects.filter(address__family=4)
421+
params = {'primary_ip4_id': [addresses[0].pk, addresses[1].pk]}
422+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
423+
params = {'primary_ip4_id': [addresses[2].pk]}
424+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 0)
425+
426+
def test_primary_ip6(self):
427+
addresses = IPAddress.objects.filter(address__family=6)
428+
params = {'primary_ip6_id': [addresses[0].pk, addresses[1].pk]}
429+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
430+
params = {'primary_ip6_id': [addresses[2].pk]}
431+
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 0)
432+
415433

416434
class VMInterfaceTestCase(TestCase, ChangeLoggedFilterSetTests):
417435
queryset = VMInterface.objects.all()

0 commit comments

Comments
 (0)