diff --git a/docs/release-notes/version-3.1.md b/docs/release-notes/version-3.1.md index 1fbd9de04..f26d15d6c 100644 --- a/docs/release-notes/version-3.1.md +++ b/docs/release-notes/version-3.1.md @@ -9,6 +9,7 @@ * [#8001](https://github.com/netbox-community/netbox/issues/8001) - Correct verbose name for wireless LAN group model * [#8003](https://github.com/netbox-community/netbox/issues/8003) - Fix cable tracing across bridged interfaces with no cable * [#8005](https://github.com/netbox-community/netbox/issues/8005) - Fix contact email display +* [#8009](https://github.com/netbox-community/netbox/issues/8009) - Validate IP addresses for uniqueness when creating an FHRP group * [#8010](https://github.com/netbox-community/netbox/issues/8010) - Allow filtering devices by multiple serial numbers * [#8019](https://github.com/netbox-community/netbox/issues/8019) - Exclude metrics endpoint when `LOGIN_REQUIRED` is true diff --git a/netbox/ipam/forms/models.py b/netbox/ipam/forms/models.py index aa2fa3214..6185b9198 100644 --- a/netbox/ipam/forms/models.py +++ b/netbox/ipam/forms/models.py @@ -575,9 +575,9 @@ class FHRPGroupForm(CustomFieldModelForm): vrf=self.cleaned_data['ip_vrf'], address=self.cleaned_data['ip_address'], status=self.cleaned_data['ip_status'], + role=FHRP_PROTOCOL_ROLE_MAPPINGS[self.cleaned_data['protocol']], assigned_object=instance ) - ipaddress.role = FHRP_PROTOCOL_ROLE_MAPPINGS[self.cleaned_data['protocol']] ipaddress.save() # Check that the new IPAddress conforms with any assigned object-level permissions @@ -587,13 +587,20 @@ class FHRPGroupForm(CustomFieldModelForm): return instance def clean(self): + ip_vrf = self.cleaned_data.get('ip_vrf') ip_address = self.cleaned_data.get('ip_address') ip_status = self.cleaned_data.get('ip_status') - if ip_address and not ip_status: - raise forms.ValidationError({ - 'ip_status': "Status must be set when creating a new IP address." + if ip_address: + ip_form = IPAddressForm({ + 'address': ip_address, + 'vrf': ip_vrf, + 'status': ip_status, }) + if not ip_form.is_valid(): + self.errors.update({ + f'ip_{field}': error for field, error in ip_form.errors.items() + }) class FHRPGroupAssignmentForm(BootstrapMixin, forms.ModelForm):