# Buggy code
def read_secret(path, key=None):
    """
    Return the value of key at path in vault, or entire secret

    Jinja Example:

    .. code-block:: jinja

        my-secret: {{ salt['vault'].read_secret('secret/my/secret', 'some-key') }}

    .. code-block:: jinja

        {% set supersecret = salt['vault'].read_secret('secret/my/secret') %}
        secrets:
            first: {{ supersecret.first }}
            second: {{ supersecret.second }}
    """
    log.debug("Reading Vault secret for %s at %s", __grains__["id"], path)
    try:
        url = "v1/{0}".format(path)
        response = __utils__["vault.make_request"]("GET", url)
        if response.status_code != 200:
            response.raise_for_status()
        data = response.json()["data"]

        if key is not None:
            return data[key]
        return data
    except Exception as err:  # pylint: disable=broad-except
        log.error("Failed to read secret! %s: %s", type(err).__name__, err)
        return None


# Traceback (CommandExecutionError)
$ sudo salt-run sdb.get 'sdb://sdb_vault/secret/data/salt/pillar_data/wew'
[ERROR   ] Failed to read secret! KeyError: u'wew'
Exception occurred in runner sdb.get: Traceback (most recent call last):
File "/opt/saltstack/lib/python2.7/site-packages/salt/client/mixins.py", line 387, in _low
data['return'] = self.functions[fun](*args, **kwargs)
File "/opt/saltstack/lib/python2.7/site-packages/salt/runners/sdb.py", line 27, in get
return salt.utils.sdb.sdb_get(uri, __opts__, __utils__)
File "/opt/saltstack/lib/python2.7/site-packages/salt/utils/sdb.py", line 46, in sdb_get
return loaded_db[fun](query, profile=profile)
File "/opt/saltstack/lib/python2.7/site-packages/salt/sdb/vault.py", line 122, in get
raise salt.exceptions.CommandExecutionError(e)
CommandExecutionError: u'wew'
[INFO    ] Runner completed: 20181023165316837868

# Fixed code
def read_secret(path, key=None, metadata=False):
    """
    Return the value of key at path in vault, or entire secret

    :param metadata: Optional - If using KV v2 backend, display full results, including metadata

        .. versionadded:: Sodium

    Jinja Example:

    .. code-block:: jinja

        my-secret: {{ salt['vault'].read_secret('secret/my/secret', 'some-key') }}

        {{ salt['vault'].read_secret('/secret/my/secret', 'some-key', metadata=True)['data'] }}

    .. code-block:: jinja

        {% set supersecret = salt['vault'].read_secret('secret/my/secret') %}
        secrets:
            first: {{ supersecret.first }}
            second: {{ supersecret.second }}
    """
    version2 = __utils__["vault.is_v2"](path)
    if version2["v2"]:
        path = version2["data"]
    log.debug("Reading Vault secret for %s at %s", __grains__["id"], path)
    try:
        url = "v1/{0}".format(path)
        response = __utils__["vault.make_request"]("GET", url)
        if response.status_code != 200:
            response.raise_for_status()
        data = response.json()["data"]

        # Return data of subkey if requested
        if key is not None:
            if version2["v2"]:
                return data["data"][key]
            else:
                return data[key]
        # Just return data from KV V2 if metadata isn't needed
        if version2["v2"]:
            if not metadata:
                return data["data"]

        return data
    except Exception as err:  # pylint: disable=broad-except
        log.error("Failed to read secret! %s: %s", type(err).__name__, err)
        return None