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

Fixes #10950: Fix validation of VDC primary IPs

jeremystretch 3 лет назад
Родитель
Сommit
b2f34cec19
3 измененных файлов с 36 добавлено и 1 удалено
  1. 1 0
      docs/release-notes/version-3.4.md
  2. 18 0
      netbox/dcim/forms/model_forms.py
  3. 17 1
      netbox/dcim/models/devices.py

+ 1 - 0
docs/release-notes/version-3.4.md

@@ -13,6 +13,7 @@
 
 * [#10946](https://github.com/netbox-community/netbox/issues/10946) - Fix AttributeError exception when viewing a device with a primary IP and no platform assigned
 * [#10948](https://github.com/netbox-community/netbox/issues/10948) - Linkify primary IPs for VDCs
+* [#10950](https://github.com/netbox-community/netbox/issues/10950) - Fix validation of VDC primary IPs
 * [#10957](https://github.com/netbox-community/netbox/issues/10957) - Add missing VDCs column to interface tables
 * [#10973](https://github.com/netbox-community/netbox/issues/10973) - Fix device links in VDC table
 * [#10980](https://github.com/netbox-community/netbox/issues/10980) - Fix view tabs for plugin objects

+ 18 - 0
netbox/dcim/forms/model_forms.py

@@ -1705,6 +1705,24 @@ class VirtualDeviceContextForm(TenancyForm, NetBoxModelForm):
             'rack_id': '$rack',
         }
     )
+    primary_ip4 = DynamicModelChoiceField(
+        queryset=IPAddress.objects.all(),
+        label='Primary IPv4',
+        required=False,
+        query_params={
+            'device_id': '$device',
+            'family': '4',
+        }
+    )
+    primary_ip6 = DynamicModelChoiceField(
+        queryset=IPAddress.objects.all(),
+        label='Primary IPv6',
+        required=False,
+        query_params={
+            'device_id': '$device',
+            'family': '6',
+        }
+    )
 
     fieldsets = (
         ('Assigned Device', ('region', 'site_group', 'site', 'location', 'rack', 'device')),

+ 17 - 1
netbox/dcim/models/devices.py

@@ -3,7 +3,6 @@ import yaml
 
 from functools import cached_property
 
-from django.apps import apps
 from django.contrib.contenttypes.fields import GenericRelation
 from django.core.exceptions import ValidationError
 from django.core.validators import MaxValueValidator, MinValueValidator
@@ -1175,3 +1174,20 @@ class VirtualDeviceContext(PrimaryModel):
             return self.primary_ip4
         else:
             return None
+
+    def clean(self):
+        super().clean()
+
+        # Validate primary IPv4/v6 assignment
+        for primary_ip, family in ((self.primary_ip4, 4), (self.primary_ip6, 6)):
+            if not primary_ip:
+                continue
+            if primary_ip.family != family:
+                raise ValidationError({
+                    f'primary_ip{family}': f"{primary_ip} is not an IPv{family} address."
+                })
+            device_interfaces = self.device.vc_interfaces(if_master=False)
+            if primary_ip.assigned_object not in device_interfaces:
+                raise ValidationError({
+                    f'primary_ip{family}': _('Primary IP address must belong to an interface on the assigned device.')
+                })