Przeglądaj źródła

Fixes #5395: Fix cable tracing for rear ports with no corresponding front port

Jeremy Stretch 5 lat temu
rodzic
commit
8461832a7b

+ 1 - 0
docs/release-notes/version-2.10.md

@@ -13,6 +13,7 @@
 * [#5358](https://github.com/netbox-community/netbox/issues/5358) - Fix user table configuration for VM interfaces
 * [#5374](https://github.com/netbox-community/netbox/issues/5374) - Fix exception thrown when tracing mid-point
 * [#5376](https://github.com/netbox-community/netbox/issues/5376) - Correct invalid custom field filter logic values
+* [#5395](https://github.com/netbox-community/netbox/issues/5395) - Fix cable tracing for rear ports with no corresponding front port
 
 ---
 

+ 11 - 5
netbox/dcim/models/cables.py

@@ -411,21 +411,27 @@ class CablePath(models.Model):
                     position_stack.append(peer_termination.rear_port_position)
                 path.append(object_to_path_node(node))
 
-            # Follow a RearPort to its corresponding FrontPort
+            # Follow a RearPort to its corresponding FrontPort (if any)
             elif isinstance(peer_termination, RearPort):
                 path.append(object_to_path_node(peer_termination))
+
+                # Determine the peer FrontPort's position
                 if peer_termination.positions == 1:
-                    node = FrontPort.objects.get(rear_port=peer_termination, rear_port_position=1)
-                    path.append(object_to_path_node(node))
+                    position = 1
                 elif position_stack:
                     position = position_stack.pop()
-                    node = FrontPort.objects.get(rear_port=peer_termination, rear_port_position=position)
-                    path.append(object_to_path_node(node))
                 else:
                     # No position indicated: path has split, so we stop at the RearPort
                     is_split = True
                     break
 
+                try:
+                    node = FrontPort.objects.get(rear_port=peer_termination, rear_port_position=position)
+                    path.append(object_to_path_node(node))
+                except ObjectDoesNotExist:
+                    # No corresponding FrontPort found for the RearPort
+                    break
+
             # Anything else marks the end of the path
             else:
                 destination = peer_termination

+ 24 - 0
netbox/dcim/tests/test_cablepaths.py

@@ -796,6 +796,30 @@ class CablePathTestCase(TestCase):
         )
         self.assertEqual(CablePath.objects.count(), 2)
 
+    def test_207_rearport_without_frontport(self):
+        """
+        [IF1] --C1-- [FP1] [RP1] --C2-- [RP2]
+        """
+        interface1 = Interface.objects.create(device=self.device, name='Interface 1')
+        rearport1 = RearPort.objects.create(device=self.device, name='Rear Port 1', positions=1)
+        rearport2 = RearPort.objects.create(device=self.device, name='Rear Port 2', positions=1)
+        frontport1 = FrontPort.objects.create(
+            device=self.device, name='Front Port 1', rear_port=rearport1, rear_port_position=1
+        )
+
+        # Create cables
+        cable1 = Cable(termination_a=interface1, termination_b=frontport1)
+        cable1.save()
+        cable2 = Cable(termination_a=rearport1, termination_b=rearport2)
+        cable2.save()
+        self.assertPathExists(
+            origin=interface1,
+            destination=None,
+            path=(cable1, frontport1, rearport1, cable2, rearport2),
+            is_active=False
+        )
+        self.assertEqual(CablePath.objects.count(), 1)
+
     def test_301_create_path_via_existing_cable(self):
         """
         [IF1] --C1-- [FP1] [RP2] --C2-- [RP2] [FP2] --C3-- [IF2]