Get data from the mine based on the target, function and tgt_type

    Targets can be matched based on any standard matching system that can be
    matched on the master via these keywords:

    - glob
    - pcre
    - grain
    - grain_pcre
    - compound
    - pillar
    - pillar_pcre

    Note that all pillar matches, whether using the compound matching system or
    the pillar matching system, will be exact matches, with globbing disabled.

    exclude_minion
        Excludes the current minion from the result set

    CLI Example:

    .. code-block:: bash

        salt '*' mine.get '*' network.interfaces
        salt '*' mine.get '*' network.interfaces,network.ipaddrs
        salt '*' mine.get '*' '["network.interfaces", "network.ipaddrs"]'
        salt '*' mine.get 'os:Fedora' network.interfaces grain
        salt '*' mine.get 'G@os:Fedora and S@192.168.5.0/24' network.ipaddrs compound

    .. seealso:: Retrieving Mine data from Pillar and Orchestrate

        This execution module is intended to be executed on minions.
        Master-side operations such as Pillar or Orchestrate that require Mine
        data should use the :py:mod:`Mine Runner module <salt.runners.mine>`
        instead; it can be invoked from a Pillar SLS file using the
        :py:func:`saltutil.runner <salt.modules.saltutil.runner>` module. For
        example:

        .. code-block:: jinja

            {% set minion_ips = salt.saltutil.runner('mine.get',
                tgt='*',
                fun='network.ip_addrs',
                tgt_type='glob') %}

def get(tgt,
        fun,
        tgt_type='glob',
        exclude_minion=False):
    '''
    Get data from the mine based on the target, function and tgt_type

    Targets can be matched based on any standard matching system that can be
    matched on the master via these keywords:

    - glob
    - pcre
    - grain
    - grain_pcre
    - compound
    - pillar
    - pillar_pcre

    Note that all pillar matches, whether using the compound matching system or
    the pillar matching system, will be exact matches, with globbing disabled.

    exclude_minion
        Excludes the current minion from the result set

    CLI Example:

    .. code-block:: bash

        salt '*' mine.get '*' network.interfaces
        salt '*' mine.get '*' network.interfaces,network.ipaddrs
        salt '*' mine.get '*' '["network.interfaces", "network.ipaddrs"]'
        salt '*' mine.get 'os:Fedora' network.interfaces grain
        salt '*' mine.get 'G@os:Fedora and S@192.168.5.0/24' network.ipaddrs compound

    .. seealso:: Retrieving Mine data from Pillar and Orchestrate

        This execution module is intended to be executed on minions.
        Master-side operations such as Pillar or Orchestrate that require Mine
        data should use the :py:mod:`Mine Runner module <salt.runners.mine>`
        instead; it can be invoked from a Pillar SLS file using the
        :py:func:`saltutil.runner <salt.modules.saltutil.runner>` module. For
        example:

        .. code-block:: jinja

            {% set minion_ips = salt.saltutil.runner('mine.get',
                tgt='*',
                fun='network.ip_addrs',
                tgt_type='glob') %}
    '''
    if __opts__['file_client'] == 'local':
        ret = {}
        is_target = {'glob': __salt__['match.glob'],
                     'pcre': __salt__['match.pcre'],
                     'list': __salt__['match.list'],
                     'grain': __salt__['match.grain'],
                     'grain_pcre': __salt__['match.grain_pcre'],
                     'ipcidr': __salt__['match.ipcidr'],
                     'compound': __salt__['match.compound'],
                     'pillar': __salt__['match.pillar'],
                     'pillar_pcre': __salt__['match.pillar_pcre'],
                     }[tgt_type](tgt)
        if is_target:
            data = __salt__['data.get']('mine_cache')

            if isinstance(data, dict):
                if isinstance(fun, six.string_types):
                    functions = list(set(fun.split(',')))
                    _ret_dict = len(functions) > 1
                elif isinstance(fun, list):
                    functions = fun
                    _ret_dict = True
                else:
                    return {}

                if not _ret_dict and functions and functions[0] in data:
                    ret[__opts__['id']] = data.get(functions)
                elif _ret_dict:
                    for fun in functions:
                        if fun in data:
                            ret.setdefault(fun, {})[__opts__['id']] = data.get(fun)

        return ret
    load = {
            'cmd': '_mine_get',
            'id': __opts__['id'],
            'tgt': tgt,
            'fun': fun,
            'tgt_type': tgt_type,
    }
    ret = _mine_get(load, __opts__)
    if exclude_minion:
        if __opts__['id'] in ret:
            del ret[__opts__['id']]
    return ret