Detect infinite loop condition while iterating terminations in CablePath.from_origin

This commit is contained in:
Brian Tiemann 2024-08-28 15:54:14 -04:00
parent cac92352ca
commit 3aaf5bb342

View File

@ -1,4 +1,5 @@
import itertools import itertools
import logging
from collections import defaultdict from collections import defaultdict
from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.fields import GenericForeignKey
@ -27,6 +28,8 @@ __all__ = (
'CableTermination', 'CableTermination',
) )
logger = logging.getLogger('netbox.dcim.cable')
trace_paths = Signal() trace_paths = Signal()
@ -543,6 +546,7 @@ class CablePath(models.Model):
is_split = False is_split = False
while terminations: while terminations:
prev_path = path.copy()
# Terminations must all be of the same type # Terminations must all be of the same type
assert all(isinstance(t, type(terminations[0])) for t in terminations[1:]) assert all(isinstance(t, type(terminations[0])) for t in terminations[1:])
@ -714,6 +718,14 @@ class CablePath(models.Model):
is_split = True is_split = True
break break
# Detect infinite loop in cabling topology
num_elements_added = len(path) - len(prev_path)
prev_elements_added = prev_path[-num_elements_added:]
elements_added = path[-num_elements_added:]
if elements_added == prev_elements_added:
logger.warning('Infinite loop detected while updating cable path trace')
break
return cls( return cls(
path=path, path=path,
is_complete=is_complete, is_complete=is_complete,