Skip to content
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 17889: Add checkbox oob ip for ipaddress form #18057

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 41 additions & 8 deletions netbox/ipam/forms/model_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,10 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
required=False,
label=_('Make this the primary IP for the device/VM')
)
oob_for_parent = forms.BooleanField(
required=False,
label=_('Make this the out-of-band IP for the device')
)
comments = CommentField()

fieldsets = (
Expand All @@ -320,16 +324,16 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
FieldSet('vminterface', name=_('Virtual Machine')),
FieldSet('fhrpgroup', name=_('FHRP Group')),
),
'primary_for_parent', name=_('Assignment')
'primary_for_parent', 'oob_for_parent', name=_('Assignment')
),
FieldSet('nat_inside', name=_('NAT IP (Inside)')),
)

class Meta:
model = IPAddress
fields = [
'address', 'vrf', 'status', 'role', 'dns_name', 'primary_for_parent', 'nat_inside', 'tenant_group',
'tenant', 'description', 'comments', 'tags',
'address', 'vrf', 'status', 'role', 'dns_name', 'primary_for_parent', 'oob_for_parent', 'nat_inside',
'tenant_group', 'tenant', 'description', 'comments', 'tags',
]

def __init__(self, *args, **kwargs):
Expand All @@ -348,7 +352,7 @@ def __init__(self, *args, **kwargs):

super().__init__(*args, **kwargs)

# Initialize primary_for_parent if IP address is already assigned
# Initialize parent object & fields if IP address is already assigned
if self.instance.pk and self.instance.assigned_object:
parent = getattr(self.instance.assigned_object, 'parent_object', None)
if parent and (
Expand All @@ -357,6 +361,9 @@ def __init__(self, *args, **kwargs):
):
self.initial['primary_for_parent'] = True

if parent and (parent.oob_ip_id == self.instance.pk):
self.initial['oob_for_parent'] = True

if type(instance.assigned_object) is Interface:
self.fields['interface'].widget.add_query_params({
'device_id': instance.assigned_object.device.pk,
Expand Down Expand Up @@ -385,10 +392,15 @@ def clean(self):
})
elif selected_objects:
assigned_object = self.cleaned_data[selected_objects[0]]
if self.instance.pk and self.instance.assigned_object and self.cleaned_data['primary_for_parent'] and assigned_object != self.instance.assigned_object:
raise ValidationError(
_("Cannot reassign IP address while it is designated as the primary IP for the parent object")
)
if self.instance.pk and self.instance.assigned_object and assigned_object != self.instance.assigned_object:
if self.cleaned_data['primary_for_parent']:
raise ValidationError(
_("Cannot reassign primary IP address for the parent device/VM")
)
if self.cleaned_data['oob_for_parent']:
raise ValidationError(
_("Cannot reassign out-of-Band IP address for the parent device")
)
self.instance.assigned_object = assigned_object
else:
self.instance.assigned_object = None
Expand All @@ -400,6 +412,16 @@ def clean(self):
'primary_for_parent', _("Only IP addresses assigned to an interface can be designated as primary IPs.")
)

# OOB IP assignment is only available if device interface has been assigned.
interface = self.cleaned_data.get('interface')
if self.cleaned_data.get('oob_for_parent') and not interface:
self.add_error(
'oob_for_parent', _(
"Only IP addresses assigned to a device interface can be designated as the out-of-band IP for a "
"device."
)
)

def save(self, *args, **kwargs):
ipaddress = super().save(*args, **kwargs)

Expand All @@ -421,6 +443,17 @@ def save(self, *args, **kwargs):
parent.primary_ip6 = None
parent.save()

# Assign/clear this IPAddress as the OOB for the associated Device
if type(interface) is Interface:
parent = interface.parent_object
parent.snapshot()
if self.cleaned_data['oob_for_parent']:
parent.oob_ip = ipaddress
parent.save()
elif parent.oob_ip == ipaddress:
parent.oob_ip = None
parent.save()

return ipaddress


Expand Down
Loading