saltstack/salt — pull request #5854 by terminalmage (2013-07-01 21:09:06+00:00)
Title: Allow matching of delimiter character ':' in subdict matches

When matching of multi-level dicts in grains and pillar was added, it
established a match format of 'foo:bar:baz' to match
grains['foo']['bar'] == 'baz' (or pillar['foo']['bar'] == 'baz'). In
other words, the same delimiter character is used to separate subdict
levels from each other as is used to separate the subdict "path" from
the value being matched.

However, the problem with this change was that values containing the
delimiter character could not be matched, because the matcher would
assume that this was just another subdict. So, a grain 'foo' with a
value of 'bar:baz' could never be matched.

This commit changes match behavior so that a series of attempts are
made. The match string is split on the first occurrence of the delimiter
character, and 'foo' is checked for a value of 'bar:baz'. If there is no
match, the match string is split on the second occurrence of the
delimiter character, and 'foo:bar' (grains/pillar['foo']['bar']) is
checked for a value of 'baz'. This is done for as many occurrences of
the delimiter character exist in the match string, until a match is
found or all attempts have been made without a match being found.

Additionally, this commit consolidates common logic in the matcher, as
well as the salt.utils.minions.CkMinions class, into a new function:
salt.utils.subdict_match().

This change affects the following matchers: grain, grain_pcre, pillar

Fixes #5799.