fix: handle static DynamicGroups in job filter and repo sync - #1116
fix: handle static DynamicGroups in job filter and repo sync#1116xtinalang wants to merge 9 commits into
Conversation
…ilter
Calling generate_query() on a static DynamicGroup raises a RuntimeError
because static groups have no filter expression to generate. This fix
replaces generate_query() with group.members.values_list("pk", flat=True)
in both get_refreshed_repos (jobs.py) and get_job_filter (helper.py),
which works correctly for both static and dynamic group types.
Fixes nautobot#1029
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Coverage reportClick to see where and how coverage changed
This report was generated by python-coverage-comment-action |
||||||||||||||||||||||||||||||||||||
|
I see your point... but perhaps this should be fixed in core or core may already have a method that handles this already, @glennmatthews any thoughts? |
|
Checking against |
…ic DynamicGroups The previous implementation used a Subquery filtering on static_group_associations which only worked for static DynamicGroups and broke for filter-based groups. Replaces with GoldenConfigSettingManager.get_for_device which handles both group types via device.dynamic_groups and correctly applies weight ordering. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…icGroup Adds two tests to HelpersTestStaticGroup verifying that get_device_to_settings_map correctly resolves a device's GoldenConfigSetting when the setting uses a static DynamicGroup, and that weight ordering is respected when a device matches both static and filter-based groups. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
I initially marked this as a draft because I wasn't confident the implementation was complete or correct — I wanted to validate the approach before requesting a full review. After testing and getting feedback, I've updated the implementation to avoid |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Groups Static DynamicGroups raise RuntimeError when .members is accessed because .members internally calls generate_query(), which is not implemented for static groups. Branch on group_type and query static_group_associations directly for static groups; keep .members for filter-based groups. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nches The previous fix added an if/else inside get_job_filter, pushing the function from 12 to 14 branches and tripping pylint's R0912 too-many-branches check in CI. Extract the static-vs-filter dispatch into a small helper so get_job_filter stays at the original branch count and the dispatch logic is testable in isolation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| gcs = {gc.id: gc for gc in models.GoldenConfigSetting.objects.all()} | ||
| return {device.id: gcs[device.gc_settings] for device in annotated_queryset} | ||
| device_to_settings = {} | ||
| for device in queryset.all(): |
@glennmatthews the crux of the question is should the API for the DG be different if it is using static? Specfically, in regards to |
|
Maybe I'm missing something but it seems to me at a glance that |
…pe branching DynamicGroup.members already handles both static and dynamic-filter groups uniformly via static_group_associations as the underlying lookup, so no app-side branching is needed. Removes the _dynamic_group_device_pks helper introduced in the previous commits — the call site reduces to a single .members.values_list(...) line. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Identical setup, identical assertion to test_device_to_settings_map_static_group_weight_wins — both verified that the static-group setting maps to the device. Keeping the surviving variant since one regression test for the static-group resolution path is enough. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…equires Drop the dynamic-filter group and dynamic_filter_setting from setUp — the bug is purely about static groups, and the mixed-mode coverage isn't requested by the issue. Mixed-mode resolution is already exercised by the integration test in test_jobs.py. Rename test_device_to_settings_map_static_group_weight_wins to test_device_to_settings_map_with_static_group since it no longer asserts weight precedence (only the static-group resolution path). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Thank you @glennmatthews and @itdependsnetworks. I am grateful for the time you both took to look at this and for your knowledge of Nautobot. You pointed me in the right direction, and I missed the real intent. You were right, and I was wrong. I am humbled by this experience. Going back to look at I pushed a better refactor (834fdfd), and the helper is gone. Hopefully this is right. The helper is gone, and Again, I am humbled -- big lesson learned. It is great having you guys here to work with as I learn the ropes. Note to self: When I am working on a plugin like Golden Config, I need to read the core source for the APIs I am using, not just react to the symptom in the app. Thank you for walking me through this. This is still a work in progress and I am still open to suggestions or if I am going in the wrong direction. |
|
In general we can likely close this out, depending on how urgent this is (see work around below for more details.) We can/should update If it is urgent, this should work in the two places that it would be relevant. for obj in models.GoldenConfigSetting.objects.all():
if dynamic_group__group_type=DynamicGroupTypeChoices.TYPE_STATIC:
raw_qs = raw_qs | Q(pk__in=obj.dynamic_group.members.values_list("pk", flat=True))
else:
raw_qs = raw_qs | obj.dynamic_group.generate_query() |
Why:
and static (manually assigned members)
have no filter expression to evaluate
was linked to a static DynamicGroup
What changed:
group.members.values_list("pk", flat=True) to safely check device
membership for both group types
queryset is built from all GoldenConfigSettings
Fixes #1029
Closes: #
What was changed
jobs.py(get_refreshed_repos): replacedgenerate_query()withgroup.members.values_list("pk", flat=True)— works correctly for bothstatic and dynamic group types
helper.py(get_job_filter): same fix applied where the base devicequeryset is built across all GoldenConfigSettings
To Do