From c6592faeb291f4dae8e5499287f47fac1d44d9c9 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 28 Sep 2016 14:19:52 -0400 Subject: [PATCH] Fixes #466: Validate available free space for all instances when increasing the U height of a device type --- netbox/dcim/models.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 5627ebde1..2cfbbcc70 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -576,11 +576,29 @@ class DeviceType(models.Model): def __unicode__(self): return u'{} {}'.format(self.manufacturer, self.model) + def __init__(self, *args, **kwargs): + super(DeviceType, self).__init__(*args, **kwargs) + + # Save a copy of u_height for validation in clean() + self._original_u_height = self.u_height + def get_absolute_url(self): return reverse('dcim:devicetype', args=[self.pk]) def clean(self): + # If editing an existing DeviceType to have a larger u_height, first validate that *all* instances of it have + # room to expand within their racks. This validation will impose a very high performance penalty when there are + # many instances to check, but increasing the u_height of a DeviceType should be a very rare occurrence. + if self.pk is not None and self.u_height > self._original_u_height: + for d in Device.objects.filter(device_type=self, position__isnull=False): + face_required = None if self.is_full_depth else d.face + 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)) + 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.")