From a2c012d2c4dcb1787298c1b5aa550a9ee79bb1b7 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 8 Oct 2020 16:24:08 -0400 Subject: [PATCH] Fixes #5224: Don't allow a rear port to have fewer positions than the number of mapped front ports --- docs/release-notes/version-2.9.md | 1 + netbox/dcim/models/device_components.py | 25 +++++++++++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index 264004281..538a6e2ca 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -16,6 +16,7 @@ * [#5218](https://github.com/netbox-community/netbox/issues/5218) - Raise validation error if a power port's `allocated_draw` exceeds its `maximum_draw` * [#5220](https://github.com/netbox-community/netbox/issues/5220) - Fix API patch request against IP Address endpoint with null assigned_object_type * [#5221](https://github.com/netbox-community/netbox/issues/5221) - Fix bulk component creation for virtual machines +* [#5224](https://github.com/netbox-community/netbox/issues/5224) - Don't allow a rear port to have fewer positions than the number of mapped front ports --- diff --git a/netbox/dcim/models/device_components.py b/netbox/dcim/models/device_components.py index b1da7ceec..502e6e2ce 100644 --- a/netbox/dcim/models/device_components.py +++ b/netbox/dcim/models/device_components.py @@ -851,17 +851,16 @@ class FrontPort(CableTermination, ComponentModel): # Validate rear port assignment if self.rear_port.device != self.device: - raise ValidationError( - "Rear port ({}) must belong to the same device".format(self.rear_port) - ) + raise ValidationError({ + "rear_port": f"Rear port ({self.rear_port}) must belong to the same device" + }) # Validate rear port position assignment if self.rear_port_position > self.rear_port.positions: - raise ValidationError( - "Invalid rear port position ({}); rear port {} has only {} positions".format( - self.rear_port_position, self.rear_port.name, self.rear_port.positions - ) - ) + raise ValidationError({ + "rear_port_position": f"Invalid rear port position ({self.rear_port_position}): Rear port " + f"{self.rear_port.name} has only {self.rear_port.positions} positions" + }) @extras_features('webhooks') @@ -891,6 +890,16 @@ class RearPort(CableTermination, ComponentModel): def get_absolute_url(self): return reverse('dcim:rearport', kwargs={'pk': self.pk}) + def clean(self): + + # Check that positions count is greater than or equal to the number of associated FrontPorts + frontport_count = self.frontports.count() + if self.positions < frontport_count: + raise ValidationError({ + "positions": f"The number of positions cannot be less than the number of mapped front ports " + f"({frontport_count})" + }) + def to_csv(self): return ( self.device.identifier,