Fix saltclass literal '^' list-override marker for single class#69759
Open
ggiesen wants to merge 1 commit into
Open
Fix saltclass literal '^' list-override marker for single class#69759ggiesen wants to merge 1 commit into
ggiesen wants to merge 1 commit into
Conversation
The '^' list-override marker was only stripped when the target dict already contained a matching list to override. When a class defined an override list with no prior list present, dict_merge plain-assigned the value (including the nested "pillars" dict) by reference and never descended to the list, leaving a literal '^' element in the merged pillar. Descend into dicts and honour a leading '^' on a list in the key-absent branch as well. Fixes saltstack#50755
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Fixes saltclass leaving a literal
^element in the merged pillar when a list override is defined by a single class and no existing list is present to override.In
salt/utils/saltclass.py,dict_mergeonly stripped the leading^override marker inside the key-present list+list branch. When the key was absent from the target, control fell toelse: a[key] = b[key], which plain-assigned the value verbatim. In real usage the override list is nested (pillarsdict ->pkgslist), so the absent key is actually thepillarsdict; the whole subtree was assigned by reference and the code never descended to the list, so the^survived.The key-absent branch now descends into dicts (processing nested override lists at any depth) and honours a leading
^on a list. An empty-list guard avoids anIndexError, and the marker is stripped with non-mutating slicing.What issues does this PR fix or reference?
Fixes #50755
Previous Behavior
A class defining only an override list, for example:
produced
pkgs == ['^', 'three'], so the literal^leaked into state runs (e.g.The following packages would be installed/updated: ^).New Behavior
The same class produces
pkgs == ['three']; the^marker is stripped whether or not a prior list exists to override. Values with no^marker are unchanged.Merge requirements satisfied?
changelog/50755.fixed.md)Tests added in
tests/pytests/unit/utils/test_saltclass.py: a direct-altitude test using the production-exact nested shape fromexpanded_dict_from_minion, a deeper-nesting variant, an inverse test proving the existing key-present override path is unchanged, a marker-free key-absent test, an empty-list guard test, and a plain-extend test.Commits signed with GPG?: No