diff --git a/docs/release-notes/version-3.1.md b/docs/release-notes/version-3.1.md index 912a68357..2c09082af 100644 --- a/docs/release-notes/version-3.1.md +++ b/docs/release-notes/version-3.1.md @@ -3,6 +3,7 @@ ### Enhancements * [#7619](https://github.com/netbox-community/netbox/issues/7619) - Permit custom validation rules to be defined as plain data or dotted path to class +* [#7769](https://github.com/netbox-community/netbox/issues/7769) - Enable assignment of IP addresses to an existing FHRP group * [#7775](https://github.com/netbox-community/netbox/issues/7775) - Enable dynamic config for `CHANGELOG_RETENTION`, `CUSTOM_VALIDATORS`, and `GRAPHQL_ENABLED` ### Bug Fixes diff --git a/netbox/ipam/forms/models.py b/netbox/ipam/forms/models.py index 2875c5182..eea3bb216 100644 --- a/netbox/ipam/forms/models.py +++ b/netbox/ipam/forms/models.py @@ -321,6 +321,11 @@ class IPAddressForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): 'virtual_machine_id': '$virtual_machine' } ) + fhrpgroup = DynamicModelChoiceField( + queryset=FHRPGroup.objects.all(), + required=False, + label='FHRP Group' + ) vrf = DynamicModelChoiceField( queryset=VRF.objects.all(), required=False, @@ -428,6 +433,8 @@ class IPAddressForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): initial['interface'] = instance.assigned_object elif type(instance.assigned_object) is VMInterface: initial['vminterface'] = instance.assigned_object + elif type(instance.assigned_object) is FHRPGroup: + initial['fhrpgroup'] = instance.assigned_object if instance.nat_inside: nat_inside_parent = instance.nat_inside.assigned_object if type(nat_inside_parent) is Interface: @@ -454,10 +461,13 @@ class IPAddressForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): def clean(self): super().clean() - # Cannot select both a device interface and a VM interface - if self.cleaned_data.get('interface') and self.cleaned_data.get('vminterface'): - raise forms.ValidationError("Cannot select both a device interface and a virtual machine interface") - self.instance.assigned_object = self.cleaned_data.get('interface') or self.cleaned_data.get('vminterface') + # Handle object assignment + if self.cleaned_data['interface']: + self.instance.assigned_object = self.cleaned_data['interface'] + elif self.cleaned_data['vminterface']: + self.instance.assigned_object = self.cleaned_data['vminterface'] + elif self.cleaned_data['fhrpgroup']: + self.instance.assigned_object = self.cleaned_data['fhrpgroup'] # Primary IP assignment is only available if an interface has been assigned. interface = self.cleaned_data.get('interface') or self.cleaned_data.get('vminterface') @@ -471,7 +481,7 @@ class IPAddressForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): # Assign/clear this IPAddress as the primary for the associated Device/VirtualMachine. interface = self.instance.assigned_object - if interface: + if type(interface) in (Interface, VMInterface): parent = interface.parent_object if self.cleaned_data['primary_for_parent']: if ipaddress.address.version == 4: diff --git a/netbox/ipam/models/fhrp.py b/netbox/ipam/models/fhrp.py index e6624b27b..42ba8d84d 100644 --- a/netbox/ipam/models/fhrp.py +++ b/netbox/ipam/models/fhrp.py @@ -47,7 +47,7 @@ class FHRPGroup(PrimaryModel): to='ipam.IPAddress', content_type_field='assigned_object_type', object_id_field='assigned_object_id', - related_query_name='fhrp_group' + related_query_name='fhrpgroup' ) objects = RestrictedQuerySet.as_manager() diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index 2267a27d3..21f0857b3 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -739,6 +739,12 @@ class IPAddressEditView(generic.ObjectEditView): except (ValueError, VMInterface.DoesNotExist): pass + elif 'fhrpgroup' in request.GET: + try: + obj.assigned_object = FHRPGroup.objects.get(pk=request.GET['fhrpgroup']) + except (ValueError, FHRPGroup.DoesNotExist): + pass + return obj diff --git a/netbox/templates/ipam/fhrpgroup.html b/netbox/templates/ipam/fhrpgroup.html index a7fa1a248..0ee94ab90 100644 --- a/netbox/templates/ipam/fhrpgroup.html +++ b/netbox/templates/ipam/fhrpgroup.html @@ -68,6 +68,13 @@