|
@@ -92,7 +92,13 @@ class CableTermination(models.Model):
|
|
|
|
|
|
|
|
def trace(self):
|
|
def trace(self):
|
|
|
"""
|
|
"""
|
|
|
- Return a list representing a complete cable path, with each individual segment represented as a three-tuple:
|
|
|
|
|
|
|
+ Return two items: the traceable portion of a cable path, and the termination points where it splits (if any).
|
|
|
|
|
+ This occurs when the trace is initiated from a midpoint along a path which traverses a RearPort. In cases where
|
|
|
|
|
+ the originating endpoint is unknown, it is not possible to know which corresponding FrontPort to follow.
|
|
|
|
|
+
|
|
|
|
|
+ The path is a list representing a complete cable path, with each individual segment represented as a
|
|
|
|
|
+ three-tuple:
|
|
|
|
|
+
|
|
|
[
|
|
[
|
|
|
(termination A, cable, termination B),
|
|
(termination A, cable, termination B),
|
|
|
(termination C, cable, termination D),
|
|
(termination C, cable, termination D),
|
|
@@ -157,12 +163,12 @@ class CableTermination(models.Model):
|
|
|
if not endpoint.cable:
|
|
if not endpoint.cable:
|
|
|
path.append((endpoint, None, None))
|
|
path.append((endpoint, None, None))
|
|
|
logger.debug("No cable connected")
|
|
logger.debug("No cable connected")
|
|
|
- return path
|
|
|
|
|
|
|
+ return path, None
|
|
|
|
|
|
|
|
# Check for loops
|
|
# Check for loops
|
|
|
if endpoint.cable in [segment[1] for segment in path]:
|
|
if endpoint.cable in [segment[1] for segment in path]:
|
|
|
logger.debug("Loop detected!")
|
|
logger.debug("Loop detected!")
|
|
|
- return path
|
|
|
|
|
|
|
+ return path, None
|
|
|
|
|
|
|
|
# Record the current segment in the path
|
|
# Record the current segment in the path
|
|
|
far_end = endpoint.get_cable_peer()
|
|
far_end = endpoint.get_cable_peer()
|
|
@@ -172,9 +178,13 @@ class CableTermination(models.Model):
|
|
|
))
|
|
))
|
|
|
|
|
|
|
|
# Get the peer port of the far end termination
|
|
# Get the peer port of the far end termination
|
|
|
- endpoint = get_peer_port(far_end)
|
|
|
|
|
|
|
+ try:
|
|
|
|
|
+ endpoint = get_peer_port(far_end)
|
|
|
|
|
+ except CableTraceSplit as e:
|
|
|
|
|
+ return path, e.termination.frontports.all()
|
|
|
|
|
+
|
|
|
if endpoint is None:
|
|
if endpoint is None:
|
|
|
- return path
|
|
|
|
|
|
|
+ return path, None
|
|
|
|
|
|
|
|
def get_cable_peer(self):
|
|
def get_cable_peer(self):
|
|
|
if self.cable is None:
|
|
if self.cable is None:
|
|
@@ -191,15 +201,13 @@ class CableTermination(models.Model):
|
|
|
endpoints = []
|
|
endpoints = []
|
|
|
|
|
|
|
|
# Get the far end of the last path segment
|
|
# Get the far end of the last path segment
|
|
|
- try:
|
|
|
|
|
- endpoint = self.trace()[-1][2]
|
|
|
|
|
- if endpoint is not None:
|
|
|
|
|
- endpoints.append(endpoint)
|
|
|
|
|
-
|
|
|
|
|
- # We've hit a RearPort mapped to multiple FrontPorts. Recurse to trace each of them individually.
|
|
|
|
|
- except CableTraceSplit as e:
|
|
|
|
|
- for frontport in e.termination.frontports.all():
|
|
|
|
|
- endpoints.extend(frontport.get_path_endpoints())
|
|
|
|
|
|
|
+ path, split_ends = self.trace()
|
|
|
|
|
+ endpoint = path[-1][2]
|
|
|
|
|
+ if split_ends is not None:
|
|
|
|
|
+ for termination in split_ends:
|
|
|
|
|
+ endpoints.extend(termination.get_path_endpoints())
|
|
|
|
|
+ elif endpoint is not None:
|
|
|
|
|
+ endpoints.append(endpoint)
|
|
|
|
|
|
|
|
return endpoints
|
|
return endpoints
|
|
|
|
|
|