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
e192ac34d0
commit
06b75d1b0e
@ -758,16 +758,7 @@ class Device(NetBoxModel, ConfigContextModel):
|
|||||||
})
|
})
|
||||||
|
|
||||||
# Validate rack space
|
# Validate rack space
|
||||||
rack_face = self.face if not self.device_type.is_full_depth else None
|
rack.check_for_space([self, ])
|
||||||
exclude_list = [self.pk] if self.pk else []
|
|
||||||
available_units = self.rack.get_available_units(
|
|
||||||
u_height=self.device_type.u_height, rack_face=rack_face, exclude=exclude_list
|
|
||||||
)
|
|
||||||
if self.position and self.position not in available_units:
|
|
||||||
raise ValidationError({
|
|
||||||
'position': f"U{self.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)"
|
|
||||||
})
|
|
||||||
|
|
||||||
except DeviceType.DoesNotExist:
|
except DeviceType.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
|
@ -319,18 +319,18 @@ class Rack(NetBoxModel):
|
|||||||
|
|
||||||
return [u for u in elevation.values()]
|
return [u for u in elevation.values()]
|
||||||
|
|
||||||
def get_available_units(self, u_height=1, rack_face=None, exclude=None):
|
def check_available_units(self, devices, u_height=1, rack_face=None, exclude=None):
|
||||||
"""
|
"""
|
||||||
Return a list of units within the rack available to accommodate a device of a given U height (default 1).
|
Return a list of units within the rack available to accommodate a device of a given U height (default 1).
|
||||||
Optionally exclude one or more devices when calculating empty units (needed when moving a device from one
|
Optionally exclude one or more devices when calculating empty units (needed when moving a device from one
|
||||||
position to another within a rack).
|
position to another within a rack). This is used to check when adding multiple devices to check
|
||||||
|
against each other and the rack, for single device use get_available_units
|
||||||
|
|
||||||
|
:param devices: list of devices currently within the rack
|
||||||
:param u_height: Minimum number of contiguous free units required
|
:param u_height: Minimum number of contiguous free units required
|
||||||
:param rack_face: The face of the rack (front or rear) required; 'None' if device is full depth
|
:param rack_face: The face of the rack (front or rear) required; 'None' if device is full depth
|
||||||
: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
|
|
||||||
devices = self.devices.prefetch_related('device_type').filter(position__gte=1)
|
|
||||||
if exclude is not None:
|
if exclude is not None:
|
||||||
devices = devices.exclude(pk__in=exclude)
|
devices = devices.exclude(pk__in=exclude)
|
||||||
|
|
||||||
@ -355,6 +355,39 @@ class Rack(NetBoxModel):
|
|||||||
|
|
||||||
return list(reversed(available_units))
|
return list(reversed(available_units))
|
||||||
|
|
||||||
|
def get_all_devices(self):
|
||||||
|
return self.devices.prefetch_related('device_type').filter(position__gte=1)
|
||||||
|
|
||||||
|
def get_available_units(self, u_height=1, rack_face=None, exclude=None):
|
||||||
|
"""
|
||||||
|
Return a list of units within the rack available to accommodate a device of a given U height (default 1).
|
||||||
|
Optionally exclude one or more devices when calculating empty units (needed when moving a device from one
|
||||||
|
position to another within a rack).
|
||||||
|
|
||||||
|
:param u_height: Minimum number of contiguous free units required
|
||||||
|
:param rack_face: The face of the rack (front or rear) required; 'None' if device is full depth
|
||||||
|
: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
|
||||||
|
devices = self.get_all_devices()
|
||||||
|
return self.check_available_units(devices, u_height, rack_face, exclude)
|
||||||
|
|
||||||
|
def check_for_space(self, devices):
|
||||||
|
rack_devices = list(self.get_all_devices())
|
||||||
|
for device in devices:
|
||||||
|
rack_face = device.face if not device.device_type.is_full_depth else None
|
||||||
|
exclude_list = [device.pk] if device.pk else []
|
||||||
|
available_units = rack.check_available_units(
|
||||||
|
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:
|
||||||
|
raise ValidationError({
|
||||||
|
'position': f"U{self.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)"
|
||||||
|
})
|
||||||
|
|
||||||
|
rack_devices.append(device)
|
||||||
|
|
||||||
def get_reserved_units(self):
|
def get_reserved_units(self):
|
||||||
"""
|
"""
|
||||||
Return a dictionary mapping all reserved units within the rack to their reservation.
|
Return a dictionary mapping all reserved units within the rack to their reservation.
|
||||||
|
Loading…
Reference in New Issue
Block a user