Просмотр исходного кода

Fixes 17889: Add checkbox oob ip for ipaddress form (#18057)

* fixes 17889 : add checkbox oob ip for ipaddress

* Minor cleanup

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
Pl0xym0r 1 год назад
Родитель
Сommit
7a92c20576
1 измененных файлов с 41 добавлено и 8 удалено
  1. 41 8
      netbox/ipam/forms/model_forms.py

+ 41 - 8
netbox/ipam/forms/model_forms.py

@@ -309,6 +309,10 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
         required=False,
         required=False,
         label=_('Make this the primary IP for the device/VM')
         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()
     comments = CommentField()
 
 
     fieldsets = (
     fieldsets = (
@@ -320,7 +324,7 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
                 FieldSet('vminterface', name=_('Virtual Machine')),
                 FieldSet('vminterface', name=_('Virtual Machine')),
                 FieldSet('fhrpgroup', name=_('FHRP Group')),
                 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)')),
         FieldSet('nat_inside', name=_('NAT IP (Inside)')),
     )
     )
@@ -328,8 +332,8 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
     class Meta:
     class Meta:
         model = IPAddress
         model = IPAddress
         fields = [
         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):
     def __init__(self, *args, **kwargs):
@@ -348,7 +352,7 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
 
 
         super().__init__(*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:
         if self.instance.pk and self.instance.assigned_object:
             parent = getattr(self.instance.assigned_object, 'parent_object', None)
             parent = getattr(self.instance.assigned_object, 'parent_object', None)
             if parent and (
             if parent and (
@@ -357,6 +361,9 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
             ):
             ):
                 self.initial['primary_for_parent'] = True
                 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:
             if type(instance.assigned_object) is Interface:
                 self.fields['interface'].widget.add_query_params({
                 self.fields['interface'].widget.add_query_params({
                     'device_id': instance.assigned_object.device.pk,
                     'device_id': instance.assigned_object.device.pk,
@@ -385,10 +392,15 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
             })
             })
         elif selected_objects:
         elif selected_objects:
             assigned_object = self.cleaned_data[selected_objects[0]]
             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
             self.instance.assigned_object = assigned_object
         else:
         else:
             self.instance.assigned_object = None
             self.instance.assigned_object = None
@@ -400,6 +412,16 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
                 'primary_for_parent', _("Only IP addresses assigned to an interface can be designated as primary IPs.")
                 '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):
     def save(self, *args, **kwargs):
         ipaddress = super().save(*args, **kwargs)
         ipaddress = super().save(*args, **kwargs)
 
 
@@ -421,6 +443,17 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
                 parent.primary_ip6 = None
                 parent.primary_ip6 = None
                 parent.save()
                 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
         return ipaddress