-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes #14482 - Fix validation error when primary IP is moved #14514
Fixes #14482 - Fix validation error when primary IP is moved #14514
Conversation
netbox/ipam/forms/model_forms.py
Outdated
@@ -341,6 +341,19 @@ def __init__(self, *args, **kwargs): | |||
self.fields['vminterface'].disabled = True | |||
self.fields['fhrpgroup'].disabled = True | |||
|
|||
# Correctly assigned assigned_object if the error exists when validating this form. | |||
def add_error(self, field, errors): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't a tenable approach to fixing the validation. We need to adjust the logic under the model form's clean()
method to ensure it's catching the error and raising a ValidationError against the appropriate field before the model's full_clean()
method is called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to adjust the logic under the model form's
clean()
method to ensure it's catching the error and raising a ValidationError against the appropriate field before the model'sfull_clean()
method is called.
This isn't an option.
The "clean" flow is:
form.save() -> form.full_clean() -> form._clean_fields()
form._clean_form() -> form.clean()
form._post_clean() -> model.full_clean()
the form.clean_form() catches the validation error and adds it to the stack, however the post_clean calls the model clean regardless of whether there is already an error on the stack.
The error stack looks like this:
{
"assigned_object": "Cannot reassign IP address while it is designated as the primary IP for the parent object",
"vminterface": "Cannot reassign IP address while it is designated as the primary IP for the parent object"
}
The only way to remove this problem seems to be to also remove the ErrorDict from the model clean() and just throw a straight string validation error (pushing this change now).
I think realistically we need to re-investigate GFK's and see if there isn't a way to:
- Create a fieldgroup called "assigned_object" (or whatever the GFK name is)
- Create a select field called "assigned_object_type" (or whatever the GFK type field name is) that is populated with the types available for selection
- Create a select field called "assigned_object_id" (or whatever the GFK id field name is) that is populated with the objects available for selection based on the type selected
- Modify add_error to also match on the assigned_object fieldgroup
This obviously wouldn't be do-able in this FR but something to think about.
netbox/ipam/forms/model_forms.py
Outdated
if self.instance.pk: | ||
prev_interface = self.instance.interface.first() or self.instance.vminterface.first() | ||
# If the prev interface exists and does not match the new interface, we need to validate it isn't set as primary | ||
# for the parent | ||
if prev_interface and prev_interface != interface: | ||
prev_parent = prev_interface.device or prev_interface.virtual_machine | ||
# Check that the parent exists and if it is set as a primary ip. | ||
if prev_parent and prev_parent.primary_ip4 == self.instance or prev_parent.primary_ip6 == self.instance: | ||
self.add_error( | ||
selected_objects[0], | ||
_("Cannot reassign IP address while it is designated as the primary IP for the parent object") | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed? Decoupling the ValidationError from a specific field under the model's clean()
seems sufficient to address the bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It likely isn't needed, but it was an attempt to maintain the field highlighting. However you are correct that it likely isn't needed with just the decoupling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @DanSheps!
Fixes: #14482
When an Primary IP address is moved, it should result in a validation error. However, it does not normally due to the fact that the
clean()
method on the model returns with the fieldassigned_object
instead ofinterface
,vminterface
, orfhrpgroup
. When the_post_clean()
method tries to resolve the fields, it will fail because the form does not containassigned_object
as a field and returns a ValueError.This will correctly map the
assigned_object
field to the correct field, however we should maybe look at instead providing a method to haveassigned_object
(or similar GFK fields) as proper form fields in the future, perhaps using a custom form field.