mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 08:58:59 +00:00
Merge pull request #37489 from lorengordon/issue-18836
Creates `filter_by` as a utils function
This commit is contained in:
commit
713607c0ee
@ -13,7 +13,6 @@ import logging
|
||||
import operator
|
||||
import collections
|
||||
import json
|
||||
import fnmatch
|
||||
from functools import reduce # pylint: disable=redefined-builtin
|
||||
|
||||
# Import 3rd-party libs
|
||||
@ -25,7 +24,6 @@ from salt.ext.six.moves import range # pylint: disable=import-error,no-name-in-
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.dictupdate
|
||||
from salt.defaults import DEFAULT_TARGET_DELIM
|
||||
from salt.exceptions import SaltException
|
||||
|
||||
@ -569,44 +567,12 @@ def filter_by(lookup_dict, grain='os_family', merge=None, default='default', bas
|
||||
salt '*' grains.filter_by '{default: {A: {B: C}, D: E}, F: {A: {B: G}}, H: {D: I}}' 'xxx' '{D: J}' 'F' 'default'
|
||||
# next same as above when default='H' instead of 'F' renders {A: {B: C}, D: J}
|
||||
'''
|
||||
|
||||
ret = None
|
||||
# Default value would be an empty list if grain not found
|
||||
val = salt.utils.traverse_dict_and_list(__grains__, grain, [])
|
||||
|
||||
# Iterate over the list of grain values to match against patterns in the lookup_dict keys
|
||||
for each in val if isinstance(val, list) else [val]:
|
||||
for key in sorted(lookup_dict):
|
||||
if fnmatch.fnmatchcase(each, key):
|
||||
ret = lookup_dict[key]
|
||||
break
|
||||
if ret is not None:
|
||||
break
|
||||
|
||||
if ret is None:
|
||||
ret = lookup_dict.get(default, None)
|
||||
|
||||
if base and base in lookup_dict:
|
||||
base_values = lookup_dict[base]
|
||||
if ret is None:
|
||||
ret = base_values
|
||||
|
||||
elif isinstance(base_values, collections.Mapping):
|
||||
if not isinstance(ret, collections.Mapping):
|
||||
raise SaltException(
|
||||
'filter_by default and look-up values must both be dictionaries.')
|
||||
ret = salt.utils.dictupdate.update(copy.deepcopy(base_values), ret)
|
||||
|
||||
if merge:
|
||||
if not isinstance(merge, collections.Mapping):
|
||||
raise SaltException('filter_by merge argument must be a dictionary.')
|
||||
|
||||
if ret is None:
|
||||
ret = merge
|
||||
else:
|
||||
salt.utils.dictupdate.update(ret, copy.deepcopy(merge))
|
||||
|
||||
return ret
|
||||
return salt.utils.filter_by(lookup_dict=lookup_dict,
|
||||
lookup=grain,
|
||||
traverse=__grains__,
|
||||
merge=merge,
|
||||
default=default,
|
||||
base=base)
|
||||
|
||||
|
||||
def _dict_from_path(path, val, delimiter=DEFAULT_TARGET_DELIM):
|
||||
|
@ -361,3 +361,63 @@ def file_exists(path, saltenv=None):
|
||||
|
||||
# Provide a jinja function call compatible get aliased as fetch
|
||||
fetch = get
|
||||
|
||||
|
||||
def filter_by(lookup_dict,
|
||||
pillar,
|
||||
merge=None,
|
||||
default='default',
|
||||
base=None):
|
||||
'''
|
||||
.. versionadded:: Nitrogen
|
||||
|
||||
Look up the given pillar in a given dictionary and return the result
|
||||
|
||||
:param lookup_dict: A dictionary, keyed by a pillar, containing a value or
|
||||
values relevant to systems matching that pillar. For example, a key
|
||||
could be a pillar for a role and the value could the name of a package
|
||||
on that particular OS.
|
||||
|
||||
The dictionary key can be a globbing pattern. The function will return
|
||||
the corresponding ``lookup_dict`` value where the pilalr value matches
|
||||
the pattern. For example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# this will render 'got some salt' if ``role`` begins with 'salt'
|
||||
salt '*' pillar.filter_by '{salt*: got some salt, default: salt is not here}' role
|
||||
|
||||
:param pillar: The name of a pillar to match with the system's pillar. For
|
||||
example, the value of the "role" pillar could be used to pull values
|
||||
from the ``lookup_dict`` dictionary.
|
||||
|
||||
The pillar value can be a list. The function will return the
|
||||
``lookup_dict`` value for a first found item in the list matching
|
||||
one of the ``lookup_dict`` keys.
|
||||
|
||||
:param merge: A dictionary to merge with the results of the pillar
|
||||
selection from ``lookup_dict``. This allows another dictionary to
|
||||
override the values in the ``lookup_dict``.
|
||||
|
||||
:param default: default lookup_dict's key used if the pillar does not exist
|
||||
or if the pillar value has no match on lookup_dict. If unspecified
|
||||
the value is "default".
|
||||
|
||||
:param base: A lookup_dict key to use for a base dictionary. The
|
||||
pillar-selected ``lookup_dict`` is merged over this and then finally
|
||||
the ``merge`` dictionary is merged. This allows common values for
|
||||
each case to be collected in the base and overridden by the pillar
|
||||
selection dictionary and the merge dictionary. Default is unset.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' pillar.filter_by '{web: Serve it up, db: I query, default: x_x}' role
|
||||
'''
|
||||
return salt.utils.filter_by(lookup_dict=lookup_dict,
|
||||
lookup=pillar,
|
||||
traverse=__pillar__,
|
||||
merge=merge,
|
||||
default=default,
|
||||
base=base)
|
||||
|
@ -117,13 +117,14 @@ except (ImportError, OSError, AttributeError, TypeError):
|
||||
from salt.defaults import DEFAULT_TARGET_DELIM
|
||||
import salt.defaults.exitcodes
|
||||
import salt.log
|
||||
import salt.utils.dictupdate
|
||||
import salt.version
|
||||
from salt.utils.decorators import memoize as real_memoize
|
||||
from salt.textformat import TextFormat
|
||||
from salt.exceptions import (
|
||||
CommandExecutionError, SaltClientError,
|
||||
CommandNotFoundError, SaltSystemExit,
|
||||
SaltInvocationError
|
||||
SaltInvocationError, SaltException
|
||||
)
|
||||
|
||||
|
||||
@ -3162,3 +3163,53 @@ def substr_in_list(string_to_search_for, list_to_search):
|
||||
string is present in any of the strings which comprise a list
|
||||
'''
|
||||
return any(string_to_search_for in s for s in list_to_search)
|
||||
|
||||
|
||||
def filter_by(lookup_dict,
|
||||
lookup,
|
||||
traverse,
|
||||
merge=None,
|
||||
default='default',
|
||||
base=None):
|
||||
'''
|
||||
'''
|
||||
ret = None
|
||||
# Default value would be an empty list if lookup not found
|
||||
val = traverse_dict_and_list(traverse, lookup, [])
|
||||
|
||||
# Iterate over the list of values to match against patterns in the
|
||||
# lookup_dict keys
|
||||
for each in val if isinstance(val, list) else [val]:
|
||||
for key in sorted(lookup_dict):
|
||||
if fnmatch.fnmatchcase(each, key):
|
||||
ret = lookup_dict[key]
|
||||
break
|
||||
if ret is not None:
|
||||
break
|
||||
|
||||
if ret is None:
|
||||
ret = lookup_dict.get(default, None)
|
||||
|
||||
if base and base in lookup_dict:
|
||||
base_values = lookup_dict[base]
|
||||
if ret is None:
|
||||
ret = base_values
|
||||
|
||||
elif isinstance(base_values, collections.Mapping):
|
||||
if not isinstance(ret, collections.Mapping):
|
||||
raise SaltException(
|
||||
'filter_by default and look-up values must both be '
|
||||
'dictionaries.')
|
||||
ret = salt.utils.dictupdate.update(copy.deepcopy(base_values), ret)
|
||||
|
||||
if merge:
|
||||
if not isinstance(merge, collections.Mapping):
|
||||
raise SaltException(
|
||||
'filter_by merge argument must be a dictionary.')
|
||||
|
||||
if ret is None:
|
||||
ret = merge
|
||||
else:
|
||||
salt.utils.dictupdate.update(ret, copy.deepcopy(merge))
|
||||
|
||||
return ret
|
||||
|
Loading…
Reference in New Issue
Block a user