1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Fixes #2777: Fix cable validation to handle duplicate connections on import

This commit is contained in:
Jeremy Stretch
2019-01-11 10:17:06 -05:00
parent c89735cd4e
commit dd5f37391f
2 changed files with 46 additions and 42 deletions

View File

@ -15,6 +15,7 @@ v2.5.3 (FUTURE)
* [#2742](https://github.com/digitalocean/netbox/issues/2742) - Preserve cluster assignment when editing a device * [#2742](https://github.com/digitalocean/netbox/issues/2742) - Preserve cluster assignment when editing a device
* [#2757](https://github.com/digitalocean/netbox/issues/2757) - Always treat first/last IPs within a /31 or /127 as usable * [#2757](https://github.com/digitalocean/netbox/issues/2757) - Always treat first/last IPs within a /31 or /127 as usable
* [#2762](https://github.com/digitalocean/netbox/issues/2762) - Add missing DCIM field values to API `_choices` endpoint * [#2762](https://github.com/digitalocean/netbox/issues/2762) - Add missing DCIM field values to API `_choices` endpoint
* [#2777](https://github.com/digitalocean/netbox/issues/2777) - Fix cable validation to handle duplicate connections on import
--- ---

View File

@ -2558,52 +2558,55 @@ class Cable(ChangeLoggedModel):
def clean(self): def clean(self):
# Check that termination types are compatible if self.termination_a and self.termination_b:
type_a = self.termination_a_type.model
type_b = self.termination_b_type.model
if type_b not in COMPATIBLE_TERMINATION_TYPES.get(type_a):
raise ValidationError("Incompatible termination types: {} and {}".format(
self.termination_a_type, self.termination_b_type
))
# A termination point cannot be connected to itself type_a = self.termination_a_type.model
if self.termination_a == self.termination_b: type_b = self.termination_b_type.model
raise ValidationError("Cannot connect {} to itself".format(self.termination_a_type))
# A front port cannot be connected to its corresponding rear port # Check that termination types are compatible
if ( if type_b not in COMPATIBLE_TERMINATION_TYPES.get(type_a):
type_a in ['frontport', 'rearport'] and raise ValidationError("Incompatible termination types: {} and {}".format(
type_b in ['frontport', 'rearport'] and self.termination_a_type, self.termination_b_type
( ))
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 termination point cannot be connected to itself
if self.termination_a.cable not in (None, self): if self.termination_a == self.termination_b:
raise ValidationError("{} already has a cable attached (#{})".format( raise ValidationError("Cannot connect {} to itself".format(self.termination_a_type))
self.termination_a, self.termination_a.cable_id
))
if self.termination_b.cable not in (None, self):
raise ValidationError("{} already has a cable attached (#{})".format(
self.termination_b, self.termination_b.cable_id
))
# Virtual interfaces cannot be connected # A front port cannot be connected to its corresponding rear port
endpoint_a, endpoint_b, _ = self.get_path_endpoints() if (
if ( type_a in ['frontport', 'rearport'] and
( type_b in ['frontport', 'rearport'] and
isinstance(endpoint_a, Interface) and (
endpoint_a.form_factor == IFACE_FF_VIRTUAL getattr(self.termination_a, 'rear_port', None) == self.termination_b or
) or getattr(self.termination_b, 'rear_port', None) == self.termination_a
( )
isinstance(endpoint_b, Interface) and ):
endpoint_b.form_factor == IFACE_FF_VIRTUAL raise ValidationError("A front port cannot be connected to it corresponding rear port")
)
): # Check for an existing Cable connected to either termination object
raise ValidationError("Cannot connect to a virtual interface") if self.termination_a.cable not in (None, self):
raise ValidationError("{} already has a cable attached (#{})".format(
self.termination_a, self.termination_a.cable_id
))
if self.termination_b.cable not in (None, self):
raise ValidationError("{} already has a cable attached (#{})".format(
self.termination_b, self.termination_b.cable_id
))
# Virtual interfaces cannot be connected
endpoint_a, endpoint_b, _ = self.get_path_endpoints()
if (
(
isinstance(endpoint_a, Interface) and
endpoint_a.form_factor == IFACE_FF_VIRTUAL
) or
(
isinstance(endpoint_b, Interface) and
endpoint_b.form_factor == IFACE_FF_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: