diff --git a/docs/release-notes/version-3.1.md b/docs/release-notes/version-3.1.md index 2c09082af..a8b1711c9 100644 --- a/docs/release-notes/version-3.1.md +++ b/docs/release-notes/version-3.1.md @@ -3,6 +3,7 @@ ### Enhancements * [#7619](https://github.com/netbox-community/netbox/issues/7619) - Permit custom validation rules to be defined as plain data or dotted path to class +* [#7761](https://github.com/netbox-community/netbox/issues/7761) - Extend cable tracing across bridged interfaces * [#7769](https://github.com/netbox-community/netbox/issues/7769) - Enable assignment of IP addresses to an existing FHRP group * [#7775](https://github.com/netbox-community/netbox/issues/7775) - Enable dynamic config for `CHANGELOG_RETENTION`, `CUSTOM_VALIDATORS`, and `GRAPHQL_ENABLED` diff --git a/netbox/dcim/models/device_components.py b/netbox/dcim/models/device_components.py index 3896e5e83..ff10bc853 100644 --- a/netbox/dcim/models/device_components.py +++ b/netbox/dcim/models/device_components.py @@ -189,15 +189,23 @@ class PathEndpoint(models.Model): abstract = True def trace(self): - if self._path is None: - return [] + origin = self + path = [] # Construct the complete path - path = [self, *self._path.get_path()] - while (len(path) + 1) % 3: - # Pad to ensure we have complete three-tuples (e.g. for paths that end at a non-connected FrontPort) - path.append(None) - path.append(self._path.destination) + while origin is not None: + + if origin._path is None: + return path + + path.extend([origin, *origin._path.get_path()]) + while (len(path) + 1) % 3: + # Pad to ensure we have complete three-tuples (e.g. for paths that end at a non-connected FrontPort) + path.append(None) + path.append(origin._path.destination) + + # Check for bridge interface to continue the trace + origin = getattr(origin._path.destination, 'bridge', None) # Return the path as a list of three-tuples (A termination, cable, B termination) return list(zip(*[iter(path)] * 3))