Fixes #3269: Raise validation error when specifying non-existent cable terminationss

This commit is contained in:
Jeremy Stretch 2019-06-24 15:42:15 -04:00
parent cf770bf40c
commit 3fdb655a92
2 changed files with 58 additions and 43 deletions

View File

@ -8,6 +8,7 @@ v2.6.1 (FUTURE)
## Bug Fixes ## Bug Fixes
* [#3229](https://github.com/digitalocean/netbox/issues/3229) - Limit rack group selection by parent site on racks list * [#3229](https://github.com/digitalocean/netbox/issues/3229) - Limit rack group selection by parent site on racks list
* [#3269](https://github.com/digitalocean/netbox/issues/3269) - Raise validation error when specifying non-existent cable terminations
* [#3275](https://github.com/digitalocean/netbox/issues/3275) - Fix error when adding power outlets to a device type * [#3275](https://github.com/digitalocean/netbox/issues/3275) - Fix error when adding power outlets to a device type
* [#3279](https://github.com/digitalocean/netbox/issues/3279) - Reset the PostgreSQL sequence for Tag and TaggedItem IDs * [#3279](https://github.com/digitalocean/netbox/issues/3279) - Reset the PostgreSQL sequence for Tag and TaggedItem IDs
* [#3283](https://github.com/digitalocean/netbox/issues/3283) - Fix rack group assignment on PowerFeed CSV import * [#3283](https://github.com/digitalocean/netbox/issues/3283) - Fix rack group assignment on PowerFeed CSV import

View File

@ -2747,55 +2747,69 @@ class Cable(ChangeLoggedModel):
def clean(self): def clean(self):
if self.termination_a and self.termination_b: # Validate that termination A exists
try:
self.termination_a_type.model_class().objects.get(pk=self.termination_a_id)
except ObjectDoesNotExist:
raise ValidationError({
'termination_a': 'Invalid ID for type {}'.format(self.termination_a_type)
})
type_a = self.termination_a_type.model # Validate that termination B exists
type_b = self.termination_b_type.model try:
self.termination_b_type.model_class().objects.get(pk=self.termination_b_id)
except ObjectDoesNotExist:
raise ValidationError({
'termination_b': 'Invalid ID for type {}'.format(self.termination_b_type)
})
# Check that termination types are compatible type_a = self.termination_a_type.model
if type_b not in COMPATIBLE_TERMINATION_TYPES.get(type_a): type_b = self.termination_b_type.model
raise ValidationError("Incompatible termination types: {} and {}".format(
self.termination_a_type, self.termination_b_type
))
# A termination point cannot be connected to itself # Check that termination types are compatible
if self.termination_a == self.termination_b: if type_b not in COMPATIBLE_TERMINATION_TYPES.get(type_a):
raise ValidationError("Cannot connect {} to itself".format(self.termination_a_type)) raise ValidationError("Incompatible termination types: {} and {}".format(
self.termination_a_type, self.termination_b_type
))
# A front port cannot be connected to its corresponding rear port # A termination point cannot be connected to itself
if ( if self.termination_a == self.termination_b:
type_a in ['frontport', 'rearport'] and raise ValidationError("Cannot connect {} to itself".format(self.termination_a_type))
type_b in ['frontport', 'rearport'] and
(
getattr(self.termination_a, 'rear_port', None) == self.termination_b or
getattr(self.termination_b, 'rear_port', None) == self.termination_a
)
):
raise ValidationError("A front port cannot be connected to it corresponding rear port")
# Check for an existing Cable connected to either termination object # A front port cannot be connected to its corresponding rear port
if self.termination_a.cable not in (None, self): if (
raise ValidationError("{} already has a cable attached (#{})".format( type_a in ['frontport', 'rearport'] and
self.termination_a, self.termination_a.cable_id type_b in ['frontport', 'rearport'] and
)) (
if self.termination_b.cable not in (None, self): getattr(self.termination_a, 'rear_port', None) == self.termination_b or
raise ValidationError("{} already has a cable attached (#{})".format( getattr(self.termination_b, 'rear_port', None) == self.termination_a
self.termination_b, self.termination_b.cable_id )
)) ):
raise ValidationError("A front port cannot be connected to it corresponding rear port")
# Virtual interfaces cannot be connected # Check for an existing Cable connected to either termination object
endpoint_a, endpoint_b, _ = self.get_path_endpoints() if self.termination_a.cable not in (None, self):
if ( raise ValidationError("{} already has a cable attached (#{})".format(
( self.termination_a, self.termination_a.cable_id
isinstance(endpoint_a, Interface) and ))
endpoint_a.type == IFACE_TYPE_VIRTUAL if self.termination_b.cable not in (None, self):
) or raise ValidationError("{} already has a cable attached (#{})".format(
( self.termination_b, self.termination_b.cable_id
isinstance(endpoint_b, Interface) and ))
endpoint_b.type == IFACE_TYPE_VIRTUAL
) # Virtual interfaces cannot be connected
): endpoint_a, endpoint_b, _ = self.get_path_endpoints()
raise ValidationError("Cannot connect to a virtual interface") if (
(
isinstance(endpoint_a, Interface) and
endpoint_a.type == IFACE_TYPE_VIRTUAL
) or
(
isinstance(endpoint_b, Interface) and
endpoint_b.type == IFACE_TYPE_VIRTUAL
)
):
raise ValidationError("Cannot connect to a virtual interface")
# Validate length and length_unit # Validate length and length_unit
if self.length is not None and self.length_unit is None: if self.length is not None and self.length_unit is None: