diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e8459076..40acb31cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ v2.5.1 (FUTURE) * [#2676](https://github.com/digitalocean/netbox/issues/2676) - Fix exception when passing dictionary value to a ChoiceField * [#2678](https://github.com/digitalocean/netbox/issues/2678) - Fix error when viewing webhook in admin UI without write permission * [#2680](https://github.com/digitalocean/netbox/issues/2680) - Disallow POST requests to `/dcim/interface-connections/` API endpoint +* [#2683](https://github.com/digitalocean/netbox/issues/2683) - Fix exception when connecting a cable to a RearPort with no corresponding FrontPort * [#2684](https://github.com/digitalocean/netbox/issues/2684) - Fix custom field filtering --- diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 5dcf8a492..756ae9be2 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -110,11 +110,14 @@ class CableTermination(models.Model): raise Exception("Invalid position for {} ({} positions): {})".format( termination, termination.positions, position )) - peer_port = FrontPort.objects.get( - rear_port=termination, - rear_port_position=position, - ) - return peer_port, 1 + try: + peer_port = FrontPort.objects.get( + rear_port=termination, + rear_port_position=position, + ) + return peer_port, 1 + except ObjectDoesNotExist: + return None, None # Follow a circuit to its other termination elif isinstance(termination, CircuitTermination) and follow_circuits: @@ -2629,5 +2632,7 @@ class Cable(ChangeLoggedModel): path_status = CONNECTION_STATUS_PLANNED break - # (A path end, B path end, connected/planned) - return a_path[-1][2], b_path[-1][2], path_status + a_endpoint = a_path[-1][2] + b_endpoint = b_path[-1][2] + + return a_endpoint, b_endpoint, path_status diff --git a/netbox/dcim/signals.py b/netbox/dcim/signals.py index 2ac3bee06..f95ede579 100644 --- a/netbox/dcim/signals.py +++ b/netbox/dcim/signals.py @@ -37,7 +37,7 @@ def update_connected_endpoints(instance, **kwargs): # Check if this Cable has formed a complete path. If so, update both endpoints. endpoint_a, endpoint_b, path_status = instance.get_path_endpoints() - if endpoint_a is not None and endpoint_b is not None: + if hasattr(endpoint_a, 'connected_endpoint') and hasattr(endpoint_b, 'connected_endpoint'): endpoint_a.connected_endpoint = endpoint_b endpoint_a.connection_status = path_status endpoint_a.save() @@ -62,7 +62,7 @@ def nullify_connected_endpoints(instance, **kwargs): instance.termination_b.save() # If this Cable was part of a complete path, tear it down - if endpoint_a is not None and endpoint_b is not None: + if hasattr(endpoint_a, 'connected_endpoint') and hasattr(endpoint_b, 'connected_endpoint'): endpoint_a.connected_endpoint = None endpoint_a.connection_status = None endpoint_a.save()