You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Nautobot version (Docker tag too if applicable): 1.5.15b1
Python version: 3.8
Database platform, version: PostGreSQL
Middleware(s): Docker
Steps to Reproduce
Create 2 sites: site1 and site2
Create 2 racks: rack 1 in site1, and rack 2 in site2
Create 1 tenant: tenant1
Create 1 device with the following parameters (all others are irrelevant):
Site: - site1
Name - example
Rack - 1
Tenant - tenant1
Create 1 device with the following parameters (name and tenant are identical):
Site: - site2
Name - example
Rack - 2
Tenant - tenant1
Attempt to move rack 2 from site2 to site1 by editing it and changing the Site variable
Expected Behavior
Rack 2 to move to site1 and automatically assign any devices in it to site1 as well, like it normally does.
Observed Behavior
Nautobot crashed with an IntegrityError. I believe this is because Nautobot does not allow a Device to have the same name and the same Tenant in the same Site.
I would like to see either:
Preferably have the Edit action fail with a prompt to the user stating the reason, or
Have the error handled a little more gracefully with better error reporting to the end user
Should handle the RackGroup edit as well, which will recurse through the Rack
Traceback
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8080/dcim/racks/a54b87c8-5c82-4489-b1ed-3fd826343eb0/edit/
Django Version: 3.2.18
Python Version: 3.8.16
Installed Applications:
['django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
'cacheops',
'corsheaders',
'django_filters',
'django_jinja',
'django_tables2',
'django_prometheus',
'mptt',
'social_django',
'taggit',
'timezone_field',
'nautobot.core.apps.NautobotConstanceConfig',
'nautobot.core',
'django.contrib.admin',
'django_celery_beat',
'rest_framework',
'db_file_storage',
'nautobot.circuits',
'nautobot.dcim',
'nautobot.ipam',
'nautobot.extras',
'nautobot.tenancy',
'nautobot.users',
'nautobot.utilities',
'nautobot.virtualization',
'django_rq',
'drf_spectacular',
'drf_spectacular_sidecar',
'graphene_django',
'health_check',
'health_check.storage',
'django_extensions',
'constance.backends.database',
'django_ajax_tables',
'debug_toolbar',
'acme.AcmeConfig']
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',
'nautobot.core.middleware.ExceptionHandlingMiddleware',
'nautobot.core.middleware.RemoteUserMiddleware',
'nautobot.core.middleware.ExternalAuthMiddleware',
'nautobot.core.middleware.ObjectChangeMiddleware',
'django_prometheus.middleware.PrometheusAfterMiddleware']
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.8/site-packages/django_prometheus/db/common.py", line 71, in execute
return super().execute(*args, **kwargs)
The above exception (duplicate key value violates unique constraint "dcim_device_site_id_tenant_id_name_93f4f962_uniq"
DETAIL: Key (site_id, tenant_id, name)=(67d80af5-2811-4732-97fa-e0e42d331b66, 355ed849-1c84-4dcc-8f8f-9811ed686f69, example) already exists.
) was the direct cause of the following exception:
File "/usr/local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.8/site-packages/nautobot/core/views/generic.py", line 412, in dispatch
return super().dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.8/site-packages/nautobot/utilities/views.py", line 116, in dispatch
return super().dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.8/site-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/usr/local/lib/python3.8/site-packages/nautobot/core/views/generic.py", line 446, in post
obj = form.save()
File "/usr/local/lib/python3.8/site-packages/nautobot/extras/forms/mixins.py", line 642, in save
obj = super().save(commit)
File "/usr/local/lib/python3.8/site-packages/django/forms/models.py", line 468, in save
self.instance.save()
File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 739, in save
self.save_base(using=using, force_insert=force_insert,
File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 787, in save_base
post_save.send(
File "/usr/local/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 180, in send
return [
File "/usr/local/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 181, in <listcomp>
(receiver, receiver(signal=self, sender=sender, **named))
File "/usr/local/lib/python3.8/site-packages/nautobot/dcim/signals.py", line 170, in handle_rack_site_location_change
device.save()
File "/usr/local/lib/python3.8/site-packages/nautobot/dcim/models/devices.py", line 818, in save
super().save(*args, **kwargs)
File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 739, in save
self.save_base(using=using, force_insert=force_insert,
File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 776, in save_base
updated = self._save_table(
File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 858, in _save_table
updated = self._do_update(base_qs, using, pk_val, values, update_fields,
File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 912, in _do_update
return filtered._update(values) > 0
File "/usr/local/lib/python3.8/site-packages/django/db/models/query.py", line 802, in _update
return query.get_compiler(self.db).execute_sql(CURSOR)
File "/usr/local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1559, in execute_sql
cursor = super().execute_sql(result_type)
File "/usr/local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1175, in execute_sql
cursor.execute(sql, params)
File "/usr/local/lib/python3.8/site-packages/debug_toolbar/panels/sql/tracking.py", line 230, in execute
return self._record(self.cursor.execute, sql, params)
File "/usr/local/lib/python3.8/site-packages/debug_toolbar/panels/sql/tracking.py", line 154, in _record
return method(sql, params)
File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 98, in execute
return super().execute(sql, params)
File "/usr/local/lib/python3.8/site-packages/cacheops/transaction.py", line 97, in execute
result = self._no_monkey.execute(self, sql, params)
File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 66, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.8/site-packages/django_prometheus/db/common.py", line 71, in execute
return super().execute(*args, **kwargs)
Exception Type: IntegrityError at /dcim/racks/a54b87c8-5c82-4489-b1ed-3fd826343eb0/edit/
Exception Value: duplicate key value violates unique constraint "dcim_device_site_id_tenant_id_name_93f4f962_uniq"
DETAIL: Key (site_id, tenant_id, name)=(67d80af5-2811-4732-97fa-e0e42d331b66, 355ed849-1c84-4dcc-8f8f-9811ed686f69, example) already exists.
The text was updated successfully, but these errors were encountered:
Does it leave the data in a partially corrupted state? I feel like better error handling here would be sufficient but we're looking at improving uniqueness in v2.0 for a potentially more ideal fix.
Environment
Steps to Reproduce
site1
andsite2
1
insite1
, and rack2
insite2
tenant1
site1
example
1
tenant1
site2
example
2
tenant1
2
fromsite2
tosite1
by editing it and changing the Site variableExpected Behavior
Rack
2
to move tosite1
and automatically assign any devices in it tosite1
as well, like it normally does.Observed Behavior
Nautobot crashed with an
IntegrityError
. I believe this is because Nautobot does not allow a Device to have the same name and the same Tenant in the same Site.I would like to see either:
Should handle the
RackGroup
edit as well, which will recurse through theRack
Traceback
The text was updated successfully, but these errors were encountered: