@@ -465,11 +465,27 @@ def delete(client_obj: client.VaultClientBase, name: str, key: Optional[str]) ->
465465 formerly deprecated. See command help for details.
466466 """ ,
467467)
468+ @click .option (
469+ "--file" ,
470+ multiple = True ,
471+ help = """
472+ Write a secret from this path into a file on the filesystem. Expected format is
473+ path/in/vault[:key]=/path/in/filesystem . This option is meant to be used when
474+ your command can only read its inputs from a file and not from the environment (e.g.
475+ secret keys, ...). It's highly recommended to only use the option when provided with
476+ a secure private temporary filesystem. Writing to a physical disk should be avoided
477+ when possible. If the secret a collection (object or array), it's dumped in YAML
478+ format.
479+ """ ,
480+ )
468481@click .option (
469482 "-o" ,
470483 "--omit-single-key/--no-omit-single-key" ,
471484 default = False ,
472- help = "When the secret has only one key, don't use that key to build the name of the environment variable" ,
485+ help = """
486+ When the secret has only one key, don't use that key to build the name of the
487+ environment variable. This option doesn't affect --file.
488+ """ ,
473489)
474490@click .option (
475491 "-f" ,
@@ -483,6 +499,7 @@ def delete(client_obj: client.VaultClientBase, name: str, key: Optional[str]) ->
483499def env (
484500 client_obj : client .VaultClientBase ,
485501 envvar : Sequence [str ],
502+ file : Sequence [str ],
486503 omit_single_key : bool ,
487504 force : bool ,
488505 command : Sequence [str ],
@@ -501,18 +518,19 @@ def env(
501518 By default the name is build upon the relative path to the parent of the given path (in parameter) and the name of the keys in the value mapping.
502519 Let's say that we have stored the mapping `{'username': 'me', 'password': 'xxx'}` at path `a/b/c`
503520
504- Using `--path a/b` will inject the following environment variables: B_C_USERNAME and B_C_PASSWORD
505- Using `--path a/b/c` will inject the following environment variables: C_USERNAME and C_PASSWORD
506- Using `--path a/b/c:username` will only inject `USERNAME=me` in the environment.
521+ Using `--envvar a/b` will inject the following environment variables: B_C_USERNAME and B_C_PASSWORD
522+ Using `--envvar a/b/c` will inject the following environment variables: C_USERNAME and C_PASSWORD
523+ Using `--envvar a/b/c:username` will only inject `USERNAME=me` in the environment.
507524
508525 You can customize the variable names generation by appending `=SOME_PREFIX` to the path.
509526 In this case the part corresponding to the base path is replace by your prefix.
510527
511- Using `--path a/b=FOO` will inject the following environment variables: FOO_C_USERNAME and FOO_C_PASSWORD
512- Using `--path a/b/c=FOO` will inject the following environment variables: FOO_USERNAME and FOO_PASSWORD
513- Using `--path a/b/c:username=FOO` will inject `FOO=me` in the environment.
528+ Using `--envvar a/b=FOO` will inject the following environment variables: FOO_C_USERNAME and FOO_C_PASSWORD
529+ Using `--envvar a/b/c=FOO` will inject the following environment variables: FOO_USERNAME and FOO_PASSWORD
530+ Using `--envvar a/b/c:username=FOO` will inject `FOO=me` in the environment.
514531 """
515532 envvars = list (envvar ) or []
533+ files = list (file ) or []
516534
517535 env_secrets = {}
518536
@@ -534,6 +552,22 @@ def env(
534552
535553 env_secrets .update (env_updates )
536554
555+ for file in files :
556+ path , key , filesystem_path = get_env_parts (file )
557+ if not (path and filesystem_path ):
558+ raise click .BadOptionUsage (
559+ "file" , "--file expects both a vault path and a filesystem path"
560+ )
561+ secret_obj = client_obj .get_secret (path = path , key = key or None )
562+
563+ if not isinstance (secret_obj , (list , dict )):
564+ secret = str (secret_obj ).strip () + "\n "
565+ else :
566+ secret = yaml .safe_dump (
567+ secret_obj , default_flow_style = False , explicit_start = True
568+ )
569+ pathlib .Path (filesystem_path ).write_text (secret )
570+
537571 if bool (client_obj .errors ) and not force :
538572 raise click .ClickException ("There was an error while reading the secrets." )
539573 environment .exec_command (command = command , environment = env_secrets )
0 commit comments