Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid Handling of controller_managed_device_groups and Empty controller_group Causes Sync Errors in Nautobot SSOT #563

Open
TheHack42 opened this issue Oct 3, 2024 · 2 comments
Labels
integration: ciscoaci Issues/PRs for Cisco ACI integration. type: bug Issues/PRs addressing a bug.

Comments

@TheHack42
Copy link

Environment

  • Python version: 3.11.9
  • Nautobot version: 2.3.2
  • nautobot-ssot version: develop branch

Expected Behavior

The devices should be properly synchronized into Nautobot without exceptions. The controller_group should be set correctly, and the related ControllerManagedDeviceGroup should be retrieved based on the provided value or gracefully handled if empty.

Observed Behavior

There are two issues observed:

  1. In the following code:
    https://github.com/nautobot/nautobot-app-ssot/blob/develop/nautobot_ssot/integrations/aci/diffsync/models/nautobot.py#L182

    controller_group=(
        self.job.apic.controller_managed_device_groups.name
        if self.job.apic.controller_managed_device_groups
        else ""
    )

    The variable self.job.apic.controller_managed_device_groups is a ManyRelation, not an instance of ControllerManagedDeviceGroup. As a result:

    • Accessing the name attribute on a ManyRelation return a None value.
    • The condition if self.job.apic.controller_managed_device_groups will always evaluate to true, which makes the current logic invalid.
    • Additionally, None is not allowed, and since the Pydantic validation requires a valid string, it throws an error: "Input should be a valid string".
  2. In the following code:
    https://github.com/nautobot/nautobot-app-ssot/blob/develop/nautobot_ssot/integrations/aci/diffsync/adapters/aci.py#L438

    def create(cls, adapter, ids, attrs):
        """Create Device object in Nautobot."""
        _device = OrmDevice(
            name=ids["name"],
            role=Role.objects.get(name=attrs["device_role"]),
            device_type=OrmDeviceType.objects.get(model=attrs["device_type"]),
            serial=attrs["serial"],
            comments=attrs["comments"],
            controller_managed_device_group=ControllerManagedDeviceGroup.objects.get(name=attrs["controller_group"]),
            location=Location.objects.get(name=ids["site"], location_type=LocationType.objects.get(name="Site")),
            status=Status.objects.get(name="Active"),
        )

    The value of attrs["controller_group"] can be an empty string, and if so, the query for ControllerManagedDeviceGroup.objects.get(name=attrs["controller_group"]) will fail and raise a DoesNotExist exception.

Steps to Reproduce

  1. Run the Nautobot SSOT synchronization job.
  2. Ensure the synchronization involves a device with an empty or missing controller_group field.
  3. The Pydantic validation error or DoesNotExist exception will occur.

Potential Fix

For the first issue:

  • The controller_managed_device_groups being a ManyRelation should be handled accordingly, either by iterating through the related objects or adjusting the logic to handle the collection properly.

For the second issue:

  • A check should be added to ensure attrs["controller_group"] is not empty or None before attempting to retrieve the ControllerManagedDeviceGroup. If it’s empty, either set a default value or skip the retrieval.

Thanks

@jdrew82 jdrew82 added type: bug Issues/PRs addressing a bug. integration: ciscoaci Issues/PRs for Cisco ACI integration. labels Oct 15, 2024
@jdrew82
Copy link
Contributor

jdrew82 commented Oct 17, 2024

@TheHack42 Thank you for opening this Issue. I've reviewed your comment and I think you might have some things flipped around. Specifically, it appears that the code examples you provide are flipped for the lines you cite. With that addressed, I wanted to respond to a few things:

  • Prior to either adapters or CRUD operations happening there is a helper function that is called in the Job to ensure that there is a ControllerManagedDeviceGroup (CMDG) that exists and is attached to the specified APIC here. Due to this occurring there is an assumption that the specified APIC should have a defined CMDG attached to it.

  • For point 1 you mention that controller_managed_device_groups is a ManyRelation. I wanted to correct you on that as you can see it's an FK from the ControllerManagedDeviceGroup class here. Because of the above point about expecting a CMDG exist on the APIC we should always get a resolved name for that object when loading the Device object. Also, it's explicitly written to return an empty string if for some reason there isn't a CMDG on the APIC.

  • For point 2, again the expectation is that there should be a CMDG name defined when the adapter loads the Device. If for some reason there isn't one then it sounds like the helper function isn't working as expected?

@jdrew82
Copy link
Contributor

jdrew82 commented Oct 18, 2024

@TheHack42 I think I see the ManyRelation now. That's a bit odd as the code does show it should be an FK. I'll work on getting a fix in for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
integration: ciscoaci Issues/PRs for Cisco ACI integration. type: bug Issues/PRs addressing a bug.
Projects
None yet
Development

No branches or pull requests

2 participants