nautobot / nautobot-plugin-ssot-ipfabric

Nautobot SSoT IP Fabric
https://nautobot.github.io/nautobot-plugin-ssot-ipfabric/
Other
8 stars 2 forks source link

Devices with Serial Number > 50 characters cause sync to fail #82

Closed sdargoeuves closed 2 years ago

sdargoeuves commented 2 years ago

Environment

Expected Behavior

When performing the sync between IP Fabric and Nautobot, I have an error, and the sync fails: An exception occurred: DataError: value too long for type character varying(50)

Observed Behavior

Sync failure. Doing a few tests, I've added in a recent snapshot Azure devices, which have a very long SN. By removing those devices, I can sync without any problem. It seems that the limit of 50 is too small and causes this issue. Here is a couple of example of the SN we have for Azure devices:

Hostname Site Unique serial number
VNetGw.Express.WestEurope AZURE /subscriptions/7a329198-ceb1-4e25-xxxx-e98855c123456/resourceGroups/LAB-Static/providers/Microsoft.Network/virtualNetworkGateways/VNetGw.Express.WestEurope
nat-Gateway AZURE /subscriptions/7a329198-ceb1-4e25-xxxx-e98855c123456/resourceGroups/LAB-Static/providers/Microsoft.Network/natGateways/nat-Gateway

Here are the logs of the error:

Traceback (most recent call last):
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/query.py", line 573, in get_or_create
    return self.get(**kwargs), False
  File "/opt/nautobot/lib/python3.8/site-packages/cacheops/query.py", line 353, in get
    return qs._no_monkey.get(qs, *args, **kwargs)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/query.py", line 429, in get
    raise self.model.DoesNotExist(
nautobot.dcim.models.devices.Device.DoesNotExist: Device matching query does not exist.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
psycopg2.errors.StringDataRightTruncation: value too long for type character varying(50)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/opt/nautobot/lib/python3.8/site-packages/nautobot_ssot/jobs/base.py", line 326, in run
    self.sync_data()
  File "/opt/nautobot/lib/python3.8/site-packages/nautobot_ssot_ipfabric/jobs.py", line 185, in sync_data
    dest.sync_from(ipfabric_source)
  File "/opt/nautobot/lib/python3.8/site-packages/diffsync/__init__.py", line 525, in sync_from
    result = syncer.perform_sync()
  File "/opt/nautobot/lib/python3.8/site-packages/diffsync/helpers.py", line 326, in perform_sync
    changed |= self.sync_diff_element(element)
  File "/opt/nautobot/lib/python3.8/site-packages/diffsync/helpers.py", line 390, in sync_diff_element
    changed |= self.sync_diff_element(child, parent_model=dst_model)
  File "/opt/nautobot/lib/python3.8/site-packages/diffsync/helpers.py", line 366, in sync_diff_element
    changed, modified_model = self.sync_model(src_model=src_model, dst_model=dst_model, ids=ids, attrs=attrs)
  File "/opt/nautobot/lib/python3.8/site-packages/diffsync/helpers.py", line 415, in sync_model
    dst_model = self.model_class.create(diffsync=self.dst_diffsync, ids=ids, attrs=attrs)
  File "/opt/nautobot/lib/python3.8/site-packages/nautobot_ssot_ipfabric/diffsync/diffsync_models.py", line 191, in create
    new_device, _ = NautobotDevice.objects.get_or_create(
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/query.py", line 576, in get_or_create
    return self._create_object_from_params(kwargs, params)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/query.py", line 610, in _create_object_from_params
    obj = self.create(**params)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/query.py", line 447, in create
    obj.save(force_insert=True, using=self.db)
  File "/opt/nautobot/lib/python3.8/site-packages/nautobot/dcim/models/devices.py", line 735, in save
    super().save(*args, **kwargs)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/base.py", line 753, in save
    self.save_base(using=using, force_insert=force_insert,
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/base.py", line 790, in save_base
    updated = self._save_table(
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/base.py", line 895, in _save_table
    results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/base.py", line 933, in _do_insert
    return manager._insert(
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/query.py", line 1254, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1397, in execute_sql
    cursor.execute(sql, params)
  File "/opt/nautobot/lib/python3.8/site-packages/cacheops/transaction.py", line 93, in execute
    result = self._no_monkey.execute(self, sql, params)
  File "/opt/nautobot/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 "/opt/nautobot/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
django.db.utils.DataError: value too long for type character varying(50)

Steps to Reproduce

  1. add Azure devices to IP Fabric, or devices where SN is longer than 50 characters
  2. run the SSoT from Nautobot (not in Dry Run)
glennmatthews commented 2 years ago

While the SSOT job should be responsible for ensuring that the SN is appropriately handled if it exceeds Nautobot's limits, there is a 50-character SN limit in current versions of Nautobot - see https://github.com/nautobot/nautobot/issues/909. This limit has been increased to 255 characters in the upcoming 1.3 Nautobot release.

sdargoeuves commented 2 years ago

FYI @h4ndzdatm0ld @chadell - I did raise this previously, and nautobot v1.3 is going to solve this issue!

chadell commented 2 years ago

85 is also adding support for 1.2.x

chadell commented 2 years ago

fixed