|
@@ -401,8 +401,11 @@ class Rack(CreatedUpdatedModel, CustomFieldModel):
|
|
|
if top_device:
|
|
|
min_height = top_device.position + top_device.device_type.u_height - 1
|
|
|
if self.u_height < min_height:
|
|
|
- raise ValidationError("Rack must be at least {}U tall with currently installed devices."
|
|
|
- .format(min_height))
|
|
|
+ raise ValidationError({
|
|
|
+ 'u_height': "Rack must be at least {}U tall to house currently installed devices.".format(
|
|
|
+ min_height
|
|
|
+ )
|
|
|
+ })
|
|
|
|
|
|
def to_csv(self):
|
|
|
return ','.join([
|
|
@@ -596,27 +599,39 @@ class DeviceType(models.Model):
|
|
|
u_available = d.rack.get_available_units(u_height=self.u_height, rack_face=face_required,
|
|
|
exclude=[d.pk])
|
|
|
if d.position not in u_available:
|
|
|
- raise ValidationError("Device {} in rack {} does not have sufficient space to accommodate a height "
|
|
|
- "of {}U".format(d, d.rack, self.u_height))
|
|
|
+ raise ValidationError({
|
|
|
+ 'u_height': "Device {} in rack {} does not have sufficient space to accommodate a height of "
|
|
|
+ "{}U".format(d, d.rack, self.u_height)
|
|
|
+ })
|
|
|
|
|
|
if not self.is_console_server and self.cs_port_templates.count():
|
|
|
- raise ValidationError("Must delete all console server port templates associated with this device before "
|
|
|
- "declassifying it as a console server.")
|
|
|
+ raise ValidationError({
|
|
|
+ 'is_console_server': "Must delete all console server port templates associated with this device before "
|
|
|
+ "declassifying it as a console server."
|
|
|
+ })
|
|
|
|
|
|
if not self.is_pdu and self.power_outlet_templates.count():
|
|
|
- raise ValidationError("Must delete all power outlet templates associated with this device before "
|
|
|
- "declassifying it as a PDU.")
|
|
|
+ raise ValidationError({
|
|
|
+ 'is_pdu': "Must delete all power outlet templates associated with this device before declassifying it "
|
|
|
+ "as a PDU."
|
|
|
+ })
|
|
|
|
|
|
if not self.is_network_device and self.interface_templates.filter(mgmt_only=False).count():
|
|
|
- raise ValidationError("Must delete all non-management-only interface templates associated with this device "
|
|
|
- "before declassifying it as a network device.")
|
|
|
+ raise ValidationError({
|
|
|
+ 'is_network_device': "Must delete all non-management-only interface templates associated with this "
|
|
|
+ "device before declassifying it as a network device."
|
|
|
+ })
|
|
|
|
|
|
if self.subdevice_role != SUBDEVICE_ROLE_PARENT and self.device_bay_templates.count():
|
|
|
- raise ValidationError("Must delete all device bay templates associated with this device before "
|
|
|
- "declassifying it as a parent device.")
|
|
|
+ raise ValidationError({
|
|
|
+ 'subdevice_role': "Must delete all device bay templates associated with this device before "
|
|
|
+ "declassifying it as a parent device."
|
|
|
+ })
|
|
|
|
|
|
if self.u_height and self.subdevice_role == SUBDEVICE_ROLE_CHILD:
|
|
|
- raise ValidationError("Child device types must be 0U.")
|
|
|
+ raise ValidationError({
|
|
|
+ 'u_height': "Child device types must be 0U."
|
|
|
+ })
|
|
|
|
|
|
@property
|
|
|
def is_parent_device(self):
|
|
@@ -824,29 +839,39 @@ class Device(CreatedUpdatedModel, CustomFieldModel):
|
|
|
|
|
|
def clean(self):
|
|
|
|
|
|
- # Validate device type assignment
|
|
|
- if not hasattr(self, 'device_type'):
|
|
|
- raise ValidationError("Must specify device type.")
|
|
|
-
|
|
|
- # Child devices cannot be assigned to a rack face/unit
|
|
|
- if self.device_type.is_child_device and (self.face is not None or self.position):
|
|
|
- raise ValidationError("Child device types cannot be assigned a rack face or position.")
|
|
|
-
|
|
|
# Validate position/face combination
|
|
|
if self.position and self.face is None:
|
|
|
- raise ValidationError("Must specify rack face with rack position.")
|
|
|
-
|
|
|
- # Validate rack space
|
|
|
- rack_face = self.face if not self.device_type.is_full_depth else None
|
|
|
- exclude_list = [self.pk] if self.pk else []
|
|
|
- try:
|
|
|
- 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("U{} is already occupied or does not have sufficient space to accommodate a(n) "
|
|
|
- "{} ({}U).".format(self.position, self.device_type, self.device_type.u_height))
|
|
|
- except Rack.DoesNotExist:
|
|
|
- pass
|
|
|
+ raise ValidationError({
|
|
|
+ 'face': "Must specify rack face when defining rack position."
|
|
|
+ })
|
|
|
+
|
|
|
+ if self.device_type:
|
|
|
+
|
|
|
+ # Child devices cannot be assigned to a rack face/unit
|
|
|
+ if self.device_type.is_child_device and self.face is not None:
|
|
|
+ raise ValidationError({
|
|
|
+ 'face': "Child device types cannot be assigned to a rack face. This is an attribute of the parent "
|
|
|
+ "device."
|
|
|
+ })
|
|
|
+ if self.device_type.is_child_device and self.position:
|
|
|
+ raise ValidationError({
|
|
|
+ 'position': "Child device types cannot be assigned to a rack position. This is an attribute of the "
|
|
|
+ "parent device."
|
|
|
+ })
|
|
|
+
|
|
|
+ # Validate rack space
|
|
|
+ rack_face = self.face if not self.device_type.is_full_depth else None
|
|
|
+ exclude_list = [self.pk] if self.pk else []
|
|
|
+ try:
|
|
|
+ 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': "U{} is already occupied or does not have sufficient space to accommodate a(n) {} "
|
|
|
+ "({}U).".format(self.position, self.device_type, self.device_type.u_height)
|
|
|
+ })
|
|
|
+ except Rack.DoesNotExist:
|
|
|
+ pass
|
|
|
|
|
|
def save(self, *args, **kwargs):
|
|
|
|
|
@@ -1094,9 +1119,10 @@ class Interface(models.Model):
|
|
|
def clean(self):
|
|
|
|
|
|
if self.form_factor == IFACE_FF_VIRTUAL and self.is_connected:
|
|
|
- raise ValidationError({'form_factor': "Virtual interfaces cannot be connected to another interface or "
|
|
|
- "circuit. Disconnect the interface or choose a physical form "
|
|
|
- "factor."})
|
|
|
+ raise ValidationError({
|
|
|
+ 'form_factor': "Virtual interfaces cannot be connected to another interface or circuit. Disconnect the "
|
|
|
+ "interface or choose a physical form factor."
|
|
|
+ })
|
|
|
|
|
|
@property
|
|
|
def is_physical(self):
|
|
@@ -1147,7 +1173,9 @@ class InterfaceConnection(models.Model):
|
|
|
|
|
|
def clean(self):
|
|
|
if self.interface_a == self.interface_b:
|
|
|
- raise ValidationError("Cannot connect an interface to itself")
|
|
|
+ raise ValidationError({
|
|
|
+ 'interface_b': "Cannot connect an interface to itself."
|
|
|
+ })
|
|
|
|
|
|
# Used for connections export
|
|
|
def to_csv(self):
|
|
@@ -1180,8 +1208,9 @@ class DeviceBay(models.Model):
|
|
|
|
|
|
# Validate that the parent Device can have DeviceBays
|
|
|
if not self.device.device_type.is_parent_device:
|
|
|
- raise ValidationError("This type of device ({}) does not support device bays."
|
|
|
- .format(self.device.device_type))
|
|
|
+ raise ValidationError("This type of device ({}) does not support device bays.".format(
|
|
|
+ self.device.device_type
|
|
|
+ ))
|
|
|
|
|
|
# Cannot install a device into itself, obviously
|
|
|
if self.device == self.installed_device:
|