"""Use secret values sourced from Vault in ``sdb://`` URIs... important:: This module requires the general :ref:`Vault setup <vault-setup>`.Setup-----Like all SDB modules, this module requires a configuration profile in eitherthe minion configuration file or a pillar:.. code-block:: yaml myvault: driver: vaultOnce configured, you can access data using a URL such as:.. code-block:: yaml password: sdb://myvault/secret/passwords/mypasswordIn this URL, ``myvault`` refers to the configuration profile,``secret/passwords`` is the path where the data resides, and ``mypassword`` isthe key of the data to return.The above URI is analogous to running the following vault command:.. code-block:: bash $ vault read -field=mypassword secret/passwordsFurther configuration---------------------The following options can be set in the profile:.. vconf:: sdb.patch``patch`` When writing data, partially update the secret instead of overwriting it completely. This is usually the expected behavior, since without this option, each secret path can only contain a single mapping key safely. Currently defaults to ``False`` for backwards-compatibility reasons. Beginning with version 2 of this extension, will default to ``True``."""importloggingimportsalt.exceptionsfromsaltext.vault.utilsimportvaultfromsaltext.vault.utils.versionsimportwarn_untillog=logging.getLogger(__name__)__func_alias__={"set_":"set"}
[docs]defset_(key,value,profile=None):# pylint: disable=unused-argument""" Set a key/value pair in the vault service """if"?"inkey:path,key=key.split("?")else:path,key=key.rsplit("/",1)data={key:value}curr_data={}profile=profileor{}patch=profile.get("patch")ifpatchisNone:try:warn_until(2,("Beginning with version {version}, the Vault SDB module will ""partially update secrets instead of overwriting it completely. ""You can switch to the new behavior explicitly by specifying ""patch: true in your Vault SDB configuration."),)patch=FalseexceptRuntimeError:patch=Trueifpatch:try:# Patching only works on existing secrets.# Save the current data if patching is enabled# to write it back later, if any errors happen in patch_kv.# This also checks that the path exists, otherwise patching fails as well.curr_data=vault.read_kv(path,__opts__,__context__)vault.patch_kv(path,data,__opts__,__context__)returnTrueexcept(vault.VaultNotFoundError,vault.VaultPermissionDeniedError):passcurr_data.update(data)try:vault.write_kv(path,data,__opts__,__context__)returnTrueexceptExceptionaserr:# pylint: disable=broad-exceptlog.error("Failed to write secret! %s: %s",type(err).__name__,err)raisesalt.exceptions.CommandExecutionError(err)fromerr
[docs]defget(key,profile=None):# pylint: disable=unused-argument""" Get a value from the vault service """full_path=keyif"?"inkey:path,key=key.split("?")else:path,key=key.rsplit("/",1)try:try:res=vault.read_kv(path,__opts__,__context__)ifkeyinres:returnres[key]returnNoneexceptvault.VaultNotFoundError:returnvault.read_kv(full_path,__opts__,__context__)exceptvault.VaultNotFoundError:returnNoneexceptExceptionaserr:# pylint: disable=broad-exceptlog.error("Failed to read secret! %s: %s",type(err).__name__,err)raisesalt.exceptions.CommandExecutionError(err)fromerr