nautobot / nautobot-app-golden-config

Golden Configuration App for Nautobot.
https://docs.nautobot.com/projects/golden-config/en/latest/
Other
100 stars 57 forks source link

Error executing Config Plan migrations #781

Open nkallergis opened 3 months ago

nkallergis commented 3 months ago

Environment

Expected Behavior

Migrations are applied with no errors when upgrading Nautobot to version 2.x.

Observed Behavior

Getting UniqueViolation error when applying migration nautobot_golden_config.0029_alter_configplan_unique_together.

Running migrations:
  Applying nautobot_golden_config.0029_alter_configplan_unique_together...Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django_prometheus/db/common.py", line 69, in execute
    return super().execute(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
psycopg2.errors.UniqueViolation: could not create unique index "nautobot_golden_config_c_plan_type_device_id_crea_dc70e69e_uniq"
DETAIL:  Key (plan_type, device_id, created)=(remediation, 2630e072-de7f-4391-bf0c-aa77171ba1b4, 2024-02-23 00:00:00+00) is duplicated.

Steps to Reproduce

  1. While still in Nautobot v1.6, create two Config Plans for the same Device, both with the same type (e.g. remediation). Make sure that both are created on the same date.
  2. Upgrade Nautobot.
  3. During migration 0028_auto_20230916_1712_part2, the field created for model ConfigPlan is changed from DateField to DateTimeField.
  4. The migrated ConfigPlans that were created on the same date have the same value under DateTimeField too.
  5. When the migration nautobot_golden_config_c_plan_type_device_id_crea_dc70e69e_uniq is subsequently applied, the tuple that determines uniqueness (plan type, device, created) fails as the plans created in step 1 have all three factors identical.

Workaround used, maybe inspiration for a fix

The time portion of the freshly created DateTimeField "created" was randomized in order to have a unique (type, device, created) tuple for every entry. I suppose that something similar to that should be incorporated in a migration after 0028 but before 0029.