mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-24 00:15:17 -06:00
#7503 initial bulk add device validation
This commit is contained in:
parent
06b75d1b0e
commit
78c8fdbebf
@ -619,6 +619,24 @@ class PlatformSerializer(NetBoxModelSerializer):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class CustomDeviceListSerializer(serializers.ListSerializer):
|
||||||
|
def validate(self, attrs):
|
||||||
|
validated_data = super().validate(attrs)
|
||||||
|
devices = [Device(**item) for item in validated_data]
|
||||||
|
# break these up into racks for space validation
|
||||||
|
racks = {}
|
||||||
|
for device in devices:
|
||||||
|
if device.rack:
|
||||||
|
if device.rack not in racks:
|
||||||
|
racks[device.rack] = []
|
||||||
|
racks[device.rack].append(device)
|
||||||
|
|
||||||
|
for rack, devices in racks.items():
|
||||||
|
units = rack.check_for_space(devices)
|
||||||
|
|
||||||
|
return validated_data
|
||||||
|
|
||||||
|
|
||||||
class DeviceSerializer(NetBoxModelSerializer):
|
class DeviceSerializer(NetBoxModelSerializer):
|
||||||
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail')
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail')
|
||||||
device_type = NestedDeviceTypeSerializer()
|
device_type = NestedDeviceTypeSerializer()
|
||||||
@ -655,6 +673,7 @@ class DeviceSerializer(NetBoxModelSerializer):
|
|||||||
'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis', 'vc_position', 'vc_priority', 'comments',
|
'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis', 'vc_position', 'vc_priority', 'comments',
|
||||||
'local_context_data', 'tags', 'custom_fields', 'created', 'last_updated',
|
'local_context_data', 'tags', 'custom_fields', 'created', 'last_updated',
|
||||||
]
|
]
|
||||||
|
list_serializer_class = CustomDeviceListSerializer
|
||||||
|
|
||||||
@swagger_serializer_method(serializer_or_field=NestedDeviceSerializer)
|
@swagger_serializer_method(serializer_or_field=NestedDeviceSerializer)
|
||||||
def get_parent_device(self, obj):
|
def get_parent_device(self, obj):
|
||||||
|
@ -758,7 +758,7 @@ class Device(NetBoxModel, ConfigContextModel):
|
|||||||
})
|
})
|
||||||
|
|
||||||
# Validate rack space
|
# Validate rack space
|
||||||
rack.check_for_space([self, ])
|
self.rack.check_for_space([self, ])
|
||||||
|
|
||||||
except DeviceType.DoesNotExist:
|
except DeviceType.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
|
@ -332,7 +332,7 @@ class Rack(NetBoxModel):
|
|||||||
:param exclude: List of devices IDs to exclude (useful when moving a device within a rack)
|
:param exclude: List of devices IDs to exclude (useful when moving a device within a rack)
|
||||||
"""
|
"""
|
||||||
if exclude is not None:
|
if exclude is not None:
|
||||||
devices = devices.exclude(pk__in=exclude)
|
devices = [device for device in devices if device.pk not in exclude]
|
||||||
|
|
||||||
# Initialize the rack unit skeleton
|
# Initialize the rack unit skeleton
|
||||||
units = list(self.units)
|
units = list(self.units)
|
||||||
@ -369,7 +369,7 @@ class Rack(NetBoxModel):
|
|||||||
:param exclude: List of devices IDs to exclude (useful when moving a device within a rack)
|
:param exclude: List of devices IDs to exclude (useful when moving a device within a rack)
|
||||||
"""
|
"""
|
||||||
# Gather all devices which consume U space within the rack
|
# Gather all devices which consume U space within the rack
|
||||||
devices = self.get_all_devices()
|
devices = list(self.get_all_devices())
|
||||||
return self.check_available_units(devices, u_height, rack_face, exclude)
|
return self.check_available_units(devices, u_height, rack_face, exclude)
|
||||||
|
|
||||||
def check_for_space(self, devices):
|
def check_for_space(self, devices):
|
||||||
@ -377,13 +377,13 @@ class Rack(NetBoxModel):
|
|||||||
for device in devices:
|
for device in devices:
|
||||||
rack_face = device.face if not device.device_type.is_full_depth else None
|
rack_face = device.face if not device.device_type.is_full_depth else None
|
||||||
exclude_list = [device.pk] if device.pk else []
|
exclude_list = [device.pk] if device.pk else []
|
||||||
available_units = rack.check_available_units(
|
available_units = self.check_available_units(
|
||||||
rack_devices, u_height=device.device_type.u_height, rack_face=rack_face, exclude=exclude_list
|
rack_devices, u_height=device.device_type.u_height, rack_face=rack_face, exclude=exclude_list
|
||||||
)
|
)
|
||||||
if device.position and device.position not in available_units:
|
if device.position and device.position not in available_units:
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
'position': f"U{self.position} is already occupied or does not have sufficient space to "
|
'position': f"U{device.position} is already occupied or does not have sufficient space to "
|
||||||
f"accommodate this device type: {self.device_type} ({self.device_type.u_height}U)"
|
f"accommodate this device type: {device.device_type} ({device.device_type.u_height}U)"
|
||||||
})
|
})
|
||||||
|
|
||||||
rack_devices.append(device)
|
rack_devices.append(device)
|
||||||
|
Loading…
Reference in New Issue
Block a user