netbox-community / netbox

The premier source of truth powering network automation. Open source under Apache 2. Try NetBox Cloud free: https://netboxlabs.com/free-netbox-cloud/
http://netboxlabs.com/oss/netbox/
Apache License 2.0
15.98k stars 2.56k forks source link

Deleting Circuit Termination causes error: CablePath matching query does not exist #6610

Closed Phobeus1 closed 3 years ago

Phobeus1 commented 3 years ago

NetBox version

v2.11.6

Python version

3.6

Steps to Reproduce

  1. Create Circuit
  2. Add Termination A
  3. Add Termination Z
  4. Connect interface to Termination A
  5. Connect interface to Termination Z
  6. Try to delete the circuit, device, or either termination end

I can trace the cable just fine but it doesn't seem to want to delete. This only seems to be an issue with either ends of circuits. I can delete cables to and from devices and/or patch panel ports.

We recently switched from 2.10.X to 2.11.X and I believe the issue started then. We don't delete circuit terminations that often and only noticed recently.

Attached is the Cable-Trace: image

Expected Behavior

Cable should be deleted.

Observed Behavior

image

Environment:

Request Method: POST Request URL: http://ipam-hermes-01.mlb01.us.infra.local/dcim/cables/490/delete/?return_url=/circuits/circuits/7/

Django Version: 3.2.4 Python Version: 3.6.8 Installed Applications: ['django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.humanize', 'cacheops', 'corsheaders', 'debug_toolbar', 'django_filters', 'django_tables2', 'django_prometheus', 'mptt', 'rest_framework', 'taggit', 'timezone_field', 'circuits', 'dcim', 'ipam', 'extras', 'secrets', 'tenancy', 'users', 'utilities', 'virtualization', 'django_rq', 'drf_yasg'] Installed Middleware: ['debug_toolbar.middleware.DebugToolbarMiddleware', 'django_prometheus.middleware.PrometheusBeforeMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', 'netbox.middleware.ExceptionHandlingMiddleware', 'netbox.middleware.RemoteUserMiddleware', 'netbox.middleware.LoginRequiredMiddleware', 'netbox.middleware.APIVersionMiddleware', 'netbox.middleware.ObjectChangeMiddleware', 'django_prometheus.middleware.PrometheusAfterMiddleware']

Traceback (most recent call last): File "/opt/netbox/venv/lib64/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 173, in get rel_obj = self.field.get_cached_value(instance) File "/opt/netbox/venv/lib64/python3.6/site-packages/django/db/models/fields/mixins.py", line 15, in get_cached_value return instance._state.fields_cache[cache_name]

During handling of the above exception ('_path'), another exception occurred: File "/opt/netbox/venv/lib64/python3.6/site-packages/django/core/handlers/exception.py", line 47, in inner response = get_response(request) File "/opt/netbox/venv/lib64/python3.6/site-packages/django/core/handlers/base.py", line 181, in _get_response response = wrapped_callback(request, *callback_args, callback_kwargs) File "/opt/netbox/venv/lib64/python3.6/site-packages/django/views/generic/base.py", line 70, in view return self.dispatch(request, *args, *kwargs) File "/opt/netbox/netbox/utilities/views.py", line 93, in dispatch return super().dispatch(request, args, kwargs) File "/opt/netbox/venv/lib64/python3.6/site-packages/django/views/generic/base.py", line 98, in dispatch return handler(request, *args, kwargs) File "/opt/netbox/netbox/netbox/views/generic.py", line 383, in post obj.delete() File "/opt/netbox/venv/lib64/python3.6/site-packages/django/db/models/base.py", line 954, in delete return collector.delete() File "/opt/netbox/venv/lib64/python3.6/site-packages/django/db/models/deletion.py", line 436, in delete sender=model, instance=obj, using=self.using File "/opt/netbox/venv/lib64/python3.6/site-packages/django/dispatch/dispatcher.py", line 182, in send for receiver in self._live_receivers(sender) File "/opt/netbox/venv/lib64/python3.6/site-packages/django/dispatch/dispatcher.py", line 182, in for receiver in self._live_receivers(sender) File "/opt/netbox/netbox/dcim/signals.py", line 156, in nullify_connected_endpoints instance.termination_b.save() File "/opt/netbox/netbox/dcim/models/device_components.py", line 508, in save return super().save(*args, kwargs) File "/opt/netbox/venv/lib64/python3.6/site-packages/django/db/models/base.py", line 727, in save force_update=force_update, update_fields=update_fields) File "/opt/netbox/venv/lib64/python3.6/site-packages/django/db/models/base.py", line 776, in save_base update_fields=update_fields, raw=raw, using=using, File "/opt/netbox/venv/lib64/python3.6/site-packages/django/dispatch/dispatcher.py", line 182, in send for receiver in self._live_receivers(sender) File "/opt/netbox/venv/lib64/python3.6/site-packages/django/dispatch/dispatcher.py", line 182, in for receiver in self._live_receivers(sender) File "/opt/netbox/netbox/utilities/utils.py", line 285, in _curried return _curried_func(args, moreargs, {kwargs, morekwargs}) File "/opt/netbox/netbox/extras/signals.py", line 72, in _handle_changed_object enqueue_object(webhook_queue, instance, request.user, request.id, action) File "/opt/netbox/netbox/extras/webhooks.py", line 63, in enqueue_object 'data': serialize_for_webhook(instance), File "/opt/netbox/netbox/extras/webhooks.py", line 26, in serialize_for_webhook return serializer.data File "/opt/netbox/venv/lib64/python3.6/site-packages/rest_framework/serializers.py", line 548, in data ret = super().data File "/opt/netbox/venv/lib64/python3.6/site-packages/rest_framework/serializers.py", line 246, in data self._data = self.to_representation(self.instance) File "/opt/netbox/venv/lib64/python3.6/site-packages/rest_framework/serializers.py", line 515, in to_representation ret[field.field_name] = field.to_representation(attribute) File "/opt/netbox/venv/lib64/python3.6/site-packages/rest_framework/fields.py", line 1882, in to_representation return method(value) File "/opt/netbox/netbox/dcim/api/serializers.py", line 61, in get_connected_endpoint if obj._path is not None and obj._path.destination is not None: File "/opt/netbox/venv/lib64/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 187, in get rel_obj = self.get_object(instance) File "/opt/netbox/venv/lib64/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 154, in get_object return qs.get(self.field.get_reverse_related_filter(instance)) File "/opt/netbox/venv/lib64/python3.6/site-packages/cacheops/query.py", line 351, in get return qs._no_monkey.get(qs, *args, kwargs) File "/opt/netbox/venv/lib64/python3.6/site-packages/django/db/models/query.py", line 437, in get self.model._meta.object_name

Exception Type: DoesNotExist at /dcim/cables/490/delete/ Exception Value: CablePath matching query does not exist.

jeremystretch commented 3 years ago

I'm not able to reproduce the error on v2.11.6 following the steps you've provided above. The cable and circuit termination are both deleted without error.

mtbutler07 commented 3 years ago

I'm able to reproduce this error on the https://demo.netbox.dev/ instance.

  1. Create a circuit -> https://demo.netbox.dev/circuits/circuits/31/
  2. Add Termination A
  3. Add Termination Z
  4. Connect interface to Termination A
  5. Connect interface to Termination Z
  6. Try to delete the circuit

netbox-delete-circuit-error

Another issue I'm having which seems to be related: I'm unable to delete circuits that have a termination and cable. After trying to delete the circuit, the UI shows a message saying the Circuit was deleted, but it's still present. I have to remove the cable then termination before I'm able to delete successfully delete the circuit.

netbox-delete-circuit

Hope that helps!

Phobeus1 commented 3 years ago

Hey mtbutler07,

Thanks for the steps. I was also able to recreate this issue on my own setup. I only had the circuit terminated on one end and not the other; once I added the 2nd end I was then unable to delete either devices, termination ends or cables.

jeremystretch commented 3 years ago

Thanks for the additional report @mtbutler07.

I think this was actually just fixed under #6602 (which was raised for a similar issue concerning devices rather than circuits). I'm able to replicate the reported behavior on master (v2.11.6) but not on the current develop branch. I'm going to close this out as it should already be resolved in the v2.11.7 release, to be released shortly.