Просмотр исходного кода

Introduce CablePath.retrace() to handle deleted cables

jeremystretch 3 лет назад
Родитель
Сommit
8bc6d8cb23
2 измененных файлов с 33 добавлено и 30 удалено
  1. 21 2
      netbox/dcim/models/cables.py
  2. 12 28
      netbox/dcim/signals.py

+ 21 - 2
netbox/dcim/models/cables.py

@@ -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:
-                # No attached link; abort
+            if link is None and len(path) == 1:
+                # 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.

+ 12 - 28
netbox/dcim/signals.py

@@ -126,34 +126,18 @@ def update_connected_endpoints(instance, created, raw=False, **kwargs):
 
 
 
 
 @receiver(post_delete, sender=Cable)
 @receiver(post_delete, sender=Cable)
-def nullify_connected_endpoints(instance, **kwargs):
+def retrace_cable_paths(instance, **kwargs):
     """
     """
-    When a Cable is deleted, check for and update its two connected endpoints
+    When a Cable is deleted, check for and update its connected endpoints
     """
     """
-    logger = logging.getLogger('netbox.dcim.cable')
-
-    # # 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):
     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()
+        cablepath.retrace()
+
+
+@receiver(post_delete, sender=CableTermination)
+def nullify_connected_endpoints(instance, **kwargs):
+    """
+    Disassociate the Cable from the termination object.
+    """
+    model = instance.termination_type.model_class()
+    model.objects.filter(pk=instance.termination_id).update(_link_peer_type=None, _link_peer_id=None)