.. versionadded:: 0.14

    Attempt to retrieve the named value from :ref:`in-memory pillar data
    <pillar-in-memory>`. If the pillar key is not present in the in-memory
    pillar, then the value specified in the ``default`` option (described
    below) will be returned.

    If the merge parameter is set to ``True``, the default will be recursively
    merged into the returned pillar data.

    The value can also represent a value in a nested dict using a ":" delimiter
    for the dict. This means that if a dict in pillar looks like this::

        {'pkg': {'apache': 'httpd'}}

    To retrieve the value associated with the ``apache`` key in the ``pkg``
    dict this key can be passed as::

        pkg:apache

    key
        The pillar key to get value from

    default
        The value specified by this option will be returned if the desired
        pillar key does not exist.

        If a default value is specified, then it will be an empty string,
        unless :conf_minion:`pillar_raise_on_missing` is set to ``True``, in
        which case an error will be raised.

    merge : ``False``
        If ``True``, the retrieved values will be merged into the passed
        default. When the default and the retrieved value are both
        dictionaries, the dictionaries will be recursively merged.

        .. versionadded:: 2014.7.0
        .. versionchanged:: 2016.3.7,2016.11.4,2017.7.0
            If the default and the retrieved value are not of the same type,
            then merging will be skipped and the retrieved value will be
            returned. Earlier releases raised an error in these cases.

    merge_nested_lists
        If set to ``False``, lists nested within the retrieved pillar
        dictionary will *overwrite* lists in ``default``. If set to ``True``,
        nested lists will be *merged* into lists in ``default``. If unspecified
        (the default), this option is inherited from the
        :conf_minion:`pillar_merge_lists` minion config option.

        .. note::
            This option is ignored when ``merge`` is set to ``False``.

        .. versionadded:: 2016.11.6

    delimiter
        Specify an alternate delimiter to use when traversing a nested dict.
        This is useful for when the desired key contains a colon. See CLI
        example below for usage.

        .. versionadded:: 2014.7.0

    pillarenv
        If specified, this function will query the master to generate fresh
        pillar data on the fly, specifically from the requested pillar
        environment. Note that this can produce different pillar data than
        executing this function without an environment, as its normal behavior
        is just to return a value from minion's pillar data in memory (which
        can be sourced from more than one pillar environment).

        Using this argument will not affect the pillar data in memory. It will
        however be slightly slower and use more resources on the master due to
        the need for the master to generate and send the minion fresh pillar
        data. This tradeoff in performance however allows for the use case
        where pillar data is desired only from a single environment.

        .. versionadded:: 2017.7.0

    saltenv
        Included only for compatibility with
        :conf_minion:`pillarenv_from_saltenv`, and is otherwise ignored.

        .. versionadded:: 2017.7.0

    CLI Example:

    .. code-block:: bash

        salt '*' pillar.get pkg:apache
        salt '*' pillar.get abc::def|ghi delimiter='|'

def get(key,
        default=KeyError,
        merge=False,
        merge_nested_lists=None,
        delimiter=DEFAULT_TARGET_DELIM,
        pillarenv=None,
        saltenv=None):
    '''
    .. versionadded:: 0.14

    Attempt to retrieve the named value from :ref:`in-memory pillar data
    <pillar-in-memory>`. If the pillar key is not present in the in-memory
    pillar, then the value specified in the ``default`` option (described
    below) will be returned.

    If the merge parameter is set to ``True``, the default will be recursively
    merged into the returned pillar data.

    The value can also represent a value in a nested dict using a ":" delimiter
    for the dict. This means that if a dict in pillar looks like this::

        {'pkg': {'apache': 'httpd'}}

    To retrieve the value associated with the ``apache`` key in the ``pkg``
    dict this key can be passed as::

        pkg:apache

    key
        The pillar key to get value from

    default
        The value specified by this option will be returned if the desired
        pillar key does not exist.

        If a default value is specified, then it will be an empty string,
        unless :conf_minion:`pillar_raise_on_missing` is set to ``True``, in
        which case an error will be raised.

    merge : ``False``
        If ``True``, the retrieved values will be merged into the passed
        default. When the default and the retrieved value are both
        dictionaries, the dictionaries will be recursively merged.

        .. versionadded:: 2014.7.0
        .. versionchanged:: 2016.3.7,2016.11.4,2017.7.0
            If the default and the retrieved value are not of the same type,
            then merging will be skipped and the retrieved value will be
            returned. Earlier releases raised an error in these cases.

    merge_nested_lists
        If set to ``False``, lists nested within the retrieved pillar
        dictionary will *overwrite* lists in ``default``. If set to ``True``,
        nested lists will be *merged* into lists in ``default``. If unspecified
        (the default), this option is inherited from the
        :conf_minion:`pillar_merge_lists` minion config option.

        .. note::
            This option is ignored when ``merge`` is set to ``False``.

        .. versionadded:: 2016.11.6

    delimiter
        Specify an alternate delimiter to use when traversing a nested dict.
        This is useful for when the desired key contains a colon. See CLI
        example below for usage.

        .. versionadded:: 2014.7.0

    pillarenv
        If specified, this function will query the master to generate fresh
        pillar data on the fly, specifically from the requested pillar
        environment. Note that this can produce different pillar data than
        executing this function without an environment, as its normal behavior
        is just to return a value from minion's pillar data in memory (which
        can be sourced from more than one pillar environment).

        Using this argument will not affect the pillar data in memory. It will
        however be slightly slower and use more resources on the master due to
        the need for the master to generate and send the minion fresh pillar
        data. This tradeoff in performance however allows for the use case
        where pillar data is desired only from a single environment.

        .. versionadded:: 2017.7.0

    saltenv
        Included only for compatibility with
        :conf_minion:`pillarenv_from_saltenv`, and is otherwise ignored.

        .. versionadded:: 2017.7.0

    CLI Example:

    .. code-block:: bash

        salt '*' pillar.get pkg:apache
        salt '*' pillar.get abc::def|ghi delimiter='|'
    '''
    if not __opts__.get('pillar_raise_on_missing'):
        if default is KeyError:
            default = ''
    opt_merge_lists = __opts__.get('pillar_merge_lists', False) if \
        merge_nested_lists is None else merge_nested_lists
    pillar_dict = __pillar__ \
        if all(x is None for x in (saltenv, pillarenv)) \
        else items(saltenv=saltenv, pillarenv=pillarenv)

    if merge:
        if isinstance(default, dict):
            ret = salt.utils.data.traverse_dict_and_list(
                pillar_dict,
                key,
                {},
                delimiter)
            if isinstance(ret, collections.Mapping):
                default = copy.deepcopy(default)
                return salt.utils.dictupdate.update(
                    default,
                    ret,
                    merge_lists=opt_merge_lists)
            else:
                log.error(
                    'pillar.get: Default (%s) is a dict, but the returned '
                    'pillar value (%s) is of type \'%s\'. Merge will be '
                    'skipped.', default, ret, type(ret).__name__
                )
        elif isinstance(default, list):
            ret = salt.utils.data.traverse_dict_and_list(  # pylint: disable=redefined-variable-type
                pillar_dict,
                key,
                [],
                delimiter)
            if isinstance(ret, list):
                default = copy.deepcopy(default)
                default.extend([x for x in ret if x not in default])
                return default
            else:
                log.error(
                    'pillar.get: Default (%s) is a list, but the returned '
                    'pillar value (%s) is of type \'%s\'. Merge will be '
                    'skipped.', default, ret, type(ret).__name__
                )
        else:
            log.error(
                'pillar.get: Default (%s) is of type \'%s\', must be a dict '
                'or list to merge. Merge will be skipped.',
                default, type(default).__name__
            )

    ret = salt.utils.data.traverse_dict_and_list(
        pillar_dict,
        key,
        default,
        delimiter)
    if ret is KeyError:
        raise KeyError('Pillar key not found: {0}'.format(key))

    return ret