From 23d2cf1718f30f144440ebdf700d1d7a979ced0c Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 12 Apr 2022 09:56:33 -0400 Subject: [PATCH] Closes #9081: Add fhrpgroup_id filter for IP addresses --- docs/release-notes/version-3.2.md | 1 + netbox/ipam/filtersets.py | 5 +++++ netbox/ipam/tests/test_filtersets.py | 23 +++++++++++++++++++---- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index faa87c6d2..171783e36 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -6,6 +6,7 @@ * [#5479](https://github.com/netbox-community/netbox/issues/5479) - Allow custom job timeouts for scripts & reports * [#8973](https://github.com/netbox-community/netbox/issues/8973) - Display VLAN group count under site view +* [#9081](https://github.com/netbox-community/netbox/issues/9081) - Add `fhrpgroup_id` filter for IP addresses * [#9099](https://github.com/netbox-community/netbox/issues/9099) - Enable display of installed module serial & asset tag in module bays list ### Bug Fixes diff --git a/netbox/ipam/filtersets.py b/netbox/ipam/filtersets.py index 88b586bf2..977e70020 100644 --- a/netbox/ipam/filtersets.py +++ b/netbox/ipam/filtersets.py @@ -535,6 +535,11 @@ class IPAddressFilterSet(NetBoxModelFilterSet, TenancyFilterSet): queryset=VMInterface.objects.all(), label='VM interface (ID)', ) + fhrpgroup_id = django_filters.ModelMultipleChoiceFilter( + field_name='fhrpgroup', + queryset=FHRPGroup.objects.all(), + label='FHRP group (ID)', + ) assigned_to_interface = django_filters.BooleanFilter( method='_assigned_to_interface', label='Is assigned to an interface', diff --git a/netbox/ipam/tests/test_filtersets.py b/netbox/ipam/tests/test_filtersets.py index eaf84ee16..9bae84e3a 100644 --- a/netbox/ipam/tests/test_filtersets.py +++ b/netbox/ipam/tests/test_filtersets.py @@ -771,6 +771,12 @@ class IPAddressTestCase(TestCase, ChangeLoggedFilterSetTests): ) VMInterface.objects.bulk_create(vminterfaces) + fhrp_groups = ( + FHRPGroup(protocol=FHRPGroupProtocolChoices.PROTOCOL_VRRP2, group_id=101), + FHRPGroup(protocol=FHRPGroupProtocolChoices.PROTOCOL_VRRP2, group_id=102), + ) + FHRPGroup.objects.bulk_create(fhrp_groups) + tenant_groups = ( TenantGroup(name='Tenant group 1', slug='tenant-group-1'), TenantGroup(name='Tenant group 2', slug='tenant-group-2'), @@ -791,18 +797,22 @@ class IPAddressTestCase(TestCase, ChangeLoggedFilterSetTests): IPAddress(address='10.0.0.2/24', tenant=tenants[0], vrf=vrfs[0], assigned_object=interfaces[0], status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-b'), IPAddress(address='10.0.0.3/24', tenant=tenants[1], vrf=vrfs[1], assigned_object=interfaces[1], status=IPAddressStatusChoices.STATUS_RESERVED, role=IPAddressRoleChoices.ROLE_VIP, dns_name='ipaddress-c'), 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.5/24', tenant=None, vrf=None, assigned_object=fhrp_groups[0], status=IPAddressStatusChoices.STATUS_ACTIVE), 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', description='foobar2'), 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::5/64', tenant=None, vrf=None, assigned_object=fhrp_groups[1], status=IPAddressStatusChoices.STATUS_ACTIVE), IPAddress(address='2001:db8::1/65', tenant=None, vrf=None, assigned_object=None, status=IPAddressStatusChoices.STATUS_ACTIVE), ) IPAddress.objects.bulk_create(ipaddresses) def test_family(self): + params = {'family': '4'} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6) params = {'family': '6'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6) def test_dns_name(self): params = {'dns_name': ['ipaddress-a', 'ipaddress-b']} @@ -814,9 +824,9 @@ class IPAddressTestCase(TestCase, ChangeLoggedFilterSetTests): def test_parent(self): params = {'parent': '10.0.0.0/24'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6) params = {'parent': '2001:db8::/64'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6) def test_filter_address(self): # Check IPv4 and IPv6, with and without a mask @@ -835,7 +845,7 @@ class IPAddressTestCase(TestCase, ChangeLoggedFilterSetTests): def test_mask_length(self): params = {'mask_length': '24'} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5) def test_vrf(self): vrfs = VRF.objects.all()[:2] @@ -872,6 +882,11 @@ class IPAddressTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'vminterface': ['Interface 1', 'Interface 2']} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + def test_fhrpgroup(self): + fhrp_groups = FHRPGroup.objects.all()[:2] + params = {'fhrpgroup_id': [fhrp_groups[0].pk, fhrp_groups[1].pk]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + def test_assigned_to_interface(self): params = {'assigned_to_interface': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6)