Closed TheHack42 closed 4 weeks ago
@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?
@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.
Hello,
First of all, thank you @jdrew82 for your interest in my issue. Indeed, I mistakenly inverted the link citing the line of code in the examples I provided. My apologies for that.
controller_managed_device_groups
, which is a ManyRelation to retrieve the associated CMDGs. The line self.job.apic.controller_managed_device_groups
returns a ManyRelation that cannot have a name attribute. Additionally, it is illogical to have a condition that checks if self.job.apic.controller_managed_device_groups
returns "True", knowing that its type is a ManyRelation. https://github.com/nautobot/nautobot-app-ssot/blob/develop/nautobot_ssot/integrations/aci/diffsync/adapters/aci.py#L438ControllerManagedDeviceGroup.objects.get(name=attrs["controller_group"])
will inevitably raise a DoesNotExist exception because no CMDG has an empty name. https://github.com/nautobot/nautobot-app-ssot/blob/develop/nautobot_ssot/integrations/aci/diffsync/models/nautobot.py#L182I hope my explanations are clear.
Thanks in advance.
@TheHack42 Thanks for the response. I've actually made the correction for the ManyField in #574 so the fix should be in the next release we cut. As for your second point, we should never actually have an empty string in that field though from the way the integration is designed.
@TheHack42 This should be resolved now with 3.2.0. Please let me know if you're seeing instances where the CMDG get happens with a blank string. That shouldn't be possible with how things are structured but maybe there's something that's been missed.
Environment
Expected Behavior
The devices should be properly synchronized into Nautobot without exceptions. The
controller_group
should be set correctly, and the relatedControllerManagedDeviceGroup
should be retrieved based on the provided value or gracefully handled if empty.Observed Behavior
There are two issues observed:
In the following code: https://github.com/nautobot/nautobot-app-ssot/blob/develop/nautobot_ssot/integrations/aci/diffsync/models/nautobot.py#L182
The variable
self.job.apic.controller_managed_device_groups
is aManyRelation
, not an instance ofControllerManagedDeviceGroup
. As a result:name
attribute on aManyRelation
return a None value.if self.job.apic.controller_managed_device_groups
will always evaluate to true, which makes the current logic invalid.None
is not allowed, and since the Pydantic validation requires a valid string, it throws an error:"Input should be a valid string"
.In the following code: https://github.com/nautobot/nautobot-app-ssot/blob/develop/nautobot_ssot/integrations/aci/diffsync/adapters/aci.py#L438
The value of
attrs["controller_group"]
can be an empty string, and if so, the query forControllerManagedDeviceGroup.objects.get(name=attrs["controller_group"])
will fail and raise aDoesNotExist
exception.Steps to Reproduce
controller_group
field.DoesNotExist
exception will occur.Potential Fix
For the first issue:
controller_managed_device_groups
being aManyRelation
should be handled accordingly, either by iterating through the related objects or adjusting the logic to handle the collection properly.For the second issue:
attrs["controller_group"]
is not empty orNone
before attempting to retrieve theControllerManagedDeviceGroup
. If it’s empty, either set a default value or skip the retrieval.Thanks