Fixes #2994: Prevent modifying termination points of existing cable to ensure end-to-end path integrity

This commit is contained in:
Jeremy Stretch 2020-04-21 13:41:38 -04:00
parent 5eef6bc527
commit b362c6a967
2 changed files with 33 additions and 0 deletions

View File

@ -8,6 +8,7 @@
### Bug Fixes
* [#2994](https://github.com/netbox-community/netbox/issues/2994) - Prevent modifying termination points of existing cable to ensure end-to-end path integrity
* [#4361](https://github.com/netbox-community/netbox/issues/4361) - Fix Type of `connection_state` in Swagger schema
* [#4388](https://github.com/netbox-community/netbox/issues/4388) - Fix detection of connected endpoints when connecting rear ports
* [#4489](https://github.com/netbox-community/netbox/issues/4489) - Fix display of parent/child role on device type view

View File

@ -2070,6 +2070,20 @@ class Cable(ChangeLoggedModel):
# A copy of the PK to be used by __str__ in case the object is deleted
self._pk = self.pk
@classmethod
def from_db(cls, db, field_names, values):
"""
Cache the original A and B terminations of existing Cable instances for later reference inside clean().
"""
instance = super().from_db(db, field_names, values)
instance._orig_termination_a_type = instance.termination_a_type
instance._orig_termination_a_id = instance.termination_a_id
instance._orig_termination_b_type = instance.termination_b_type
instance._orig_termination_b_id = instance.termination_b_id
return instance
def __str__(self):
return self.label or '#{}'.format(self._pk)
@ -2098,6 +2112,24 @@ class Cable(ChangeLoggedModel):
'termination_b': 'Invalid ID for type {}'.format(self.termination_b_type)
})
# If editing an existing Cable instance, check that neither termination has been modified.
if self.pk:
err_msg = 'Cable termination points may not be modified. Delete and recreate the cable instead.'
if (
self.termination_a_type != self._orig_termination_a_type or
self.termination_a_id != self._orig_termination_a_id
):
raise ValidationError({
'termination_a': err_msg
})
if (
self.termination_b_type != self._orig_termination_b_type or
self.termination_b_id != self._orig_termination_b_id
):
raise ValidationError({
'termination_b': err_msg
})
type_a = self.termination_a_type.model
type_b = self.termination_b_type.model