Introduce CablePath.retrace() to handle deleted cables

This commit is contained in:
jeremystretch 2022-05-10 11:58:48 -04:00
parent eb4984afe6
commit 8bc6d8cb23
2 changed files with 33 additions and 30 deletions

View File

@ -356,8 +356,11 @@ class CablePath(models.Model):
# Step 2: Determine the attached link (Cable or WirelessLink), if any # Step 2: Determine the attached link (Cable or WirelessLink), if any
link = terminations[0].link link = terminations[0].link
assert all(t.link is link for t in terminations[1:]) assert all(t.link is link for t in terminations[1:])
if link is None: if link is None and len(path) == 1:
# No attached link; abort # If this is the start of the path and no link exists, return None
return None
elif link is None:
# Otherwise, halt the trace if no link exists
break break
assert type(link) in (Cable, WirelessLink) assert type(link) in (Cable, WirelessLink)
@ -463,6 +466,22 @@ class CablePath(models.Model):
is_split=is_split is_split=is_split
) )
def retrace(self):
"""
Retrace the path from the currently-defined originating termination(s)
"""
_new = self.from_origin([
path_node_to_object(node) for node in self.path[0]
])
if _new:
self.path = _new.path
self.is_complete = _new.is_complete
self.is_active = _new.is_active
self.is_split = _new.is_split
self.save()
else:
self.delete()
def get_path(self): def get_path(self):
""" """
Return the path as a list of prefetched objects. Return the path as a list of prefetched objects.

View File

@ -126,34 +126,18 @@ def update_connected_endpoints(instance, created, raw=False, **kwargs):
@receiver(post_delete, sender=Cable) @receiver(post_delete, sender=Cable)
def retrace_cable_paths(instance, **kwargs):
"""
When a Cable is deleted, check for and update its connected endpoints
"""
for cablepath in CablePath.objects.filter(_nodes__contains=instance):
cablepath.retrace()
@receiver(post_delete, sender=CableTermination)
def nullify_connected_endpoints(instance, **kwargs): def nullify_connected_endpoints(instance, **kwargs):
""" """
When a Cable is deleted, check for and update its two connected endpoints Disassociate the Cable from the termination object.
""" """
logger = logging.getLogger('netbox.dcim.cable') model = instance.termination_type.model_class()
model.objects.filter(pk=instance.termination_id).update(_link_peer_type=None, _link_peer_id=None)
# # Disassociate the Cable from its termination points
# if instance.termination_a:
# logger.debug(f"Nullifying termination A for cable {instance}")
# model = instance.termination_a_type.model_class()
# model.objects.filter(pk__in=instance.termination_a_ids).update(_link_peer_type=None, _link_peer_id=None)
# if instance.termination_b:
# logger.debug(f"Nullifying termination B for cable {instance}")
# model = instance.termination_b_type.model_class()
# model.objects.filter(pk__in=instance.termination_b_ids).update(_link_peer_type=None, _link_peer_id=None)
# Delete and retrace any dependent cable paths
for cablepath in CablePath.objects.filter(_nodes__contains=instance):
cablepath.delete()
# TODO: Create new traces
# cp = CablePath.from_origin(cablepath.origin)
# if cp:
# CablePath.objects.filter(pk=cablepath.pk).update(
# _nodes=cp._nodes,
# destination_type=ContentType.objects.get_for_model(cp.destination) if cp.destination else None,
# destination_id=cp.destination.pk if cp.destination else None,
# is_active=cp.is_active,
# is_split=cp.is_split
# )
# else:
# cablepath.delete()