Skip to content

Commit 3ba3955

Browse files
author
Joachim Jablon
authored
Merge pull request #198 from peopledoc/templates
2 parents fbde0c3 + 2abe845 commit 3ba3955

13 files changed

+41
-350
lines changed

README.rst

-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ Some features
4242
- Launch processes with your secrets as environment variables
4343
- Launch processes with ``ssh-agent`` configured from your vault
4444
- Write templated files with secrets inside
45-
- Combine multiple secrets into a single one (e.g. a DSN string from components)
4645

4746
``vault-cli`` tries to make accessing secrets both secure and painless.
4847

docs/howto/environment.rst

-5
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,3 @@ even if it will be missing some secrets.
124124
.. code:: console
125125
126126
$ vault-cli env --envvar myapp --force -- myapp
127-
128-
.. warning::
129-
130-
Even if just a single key for a secret produces an error (e.g. a template rendering
131-
error), the whole secret will be missing.

docs/howto/systemd.rst

-8
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,6 @@ Vault-cli aims at helping you launch your application with the secrets
1818
it needs without writing them on disk. This page lists a few scenarios
1919
that may be useful.
2020

21-
If the value you need to pass is directly a secret that is stored in the
22-
vault, perfect. Otherwise, you may want to create a `templated
23-
value`__
24-
to recreate your secret value by combining static strings and other
25-
secrets.
26-
27-
.. __: https://github.com/peopledoc/vault-cli/#create-a-templated-value
28-
2921
Let’s assume the value you need to pass is the value you get with:
3022

3123
.. code:: console

docs/howto/templated_secrets.rst

-84
This file was deleted.

docs/howto/upgrade.rst

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
Upgrade ``vault-cli`` from previous version
22
===========================================
33

4+
From 2.x to 3.x
5+
~~~~~~~~~~~~~~~
6+
7+
Templated values (``!template!{{ vault("a").b }}``) aren't supported anymore.
8+
If you were using those, you will get a warning starting on ``vault-cli~=2.2.1``.
9+
10+
On 3.x, a ``--render/--no-render`` flag is still available but it does nothing.
11+
412
From 1.x to 2.x
513
~~~~~~~~~~~~~~~
614

docs/howto_index.rst

-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ How-to...
1212
howto/write
1313
howto/environment
1414
howto/template
15-
howto/templated_secrets
1615
howto/ssh
1716
howto/systemd
1817
howto/organize

tests/unit/test_cli.py

-3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ def test_options(cli_runner, mocker):
2424
"bla",
2525
"--ca-bundle",
2626
"yay",
27-
"--no-render",
2827
"--login-cert",
2928
"puc",
3029
"--login-cert-key",
@@ -47,7 +46,6 @@ def test_options(cli_runner, mocker):
4746
assert set(kwargs) == {
4847
"base_path",
4948
"ca_bundle",
50-
"render",
5149
"login_cert",
5250
"login_cert_key",
5351
"password",
@@ -66,7 +64,6 @@ def test_options(cli_runner, mocker):
6664
assert kwargs["url"] == "https://foo"
6765
assert kwargs["username"] == "user"
6866
assert kwargs["verify"] is True
69-
assert kwargs["render"] is False
7067

7168

7269
@pytest.fixture

tests/unit/test_client_base.py

+2-134
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
import itertools
2-
31
import pytest
42

5-
from vault_cli import client, exceptions, testing
3+
from vault_cli import client, exceptions
64

75

86
def test_get_client(mocker):
@@ -476,44 +474,6 @@ def test_vault_client_base_render_template_path_not_found(vault, template):
476474
({"a": {"value": "b"}}, {"value": "b"}),
477475
# Secret not a string
478476
({"a": {"value": ["yay"]}}, {"value": ["yay"]}),
479-
# Secret is a template without variable expansion
480-
({"a": {"value": "!template!b"}, "b": {"value": "c"}}, {"value": "b"}),
481-
# Secret is a template
482-
(
483-
{"a": {"value": "!template!{{ vault('b').value }}"}, "b": {"value": "c"}},
484-
{"value": "c"},
485-
),
486-
# Secret is a dict with containing a template
487-
(
488-
{
489-
"a": {"x": "!template!{{ vault('b').value }}", "y": "yay"},
490-
"b": {"value": "c"},
491-
},
492-
{"x": "c", "y": "yay"},
493-
),
494-
# Finite recursion
495-
(
496-
{
497-
"a": {"value": "!template!{{ vault('b').value }}"},
498-
"b": {"value": "!template!{{ vault('c').value }}"},
499-
"c": {"value": "d"},
500-
},
501-
{"value": "d"},
502-
),
503-
# Infinite Recursion
504-
(
505-
{
506-
"a": {"value": "!template!{{ vault('b').value }}"},
507-
"b": {"value": "!template!{{ vault('c').value }}"},
508-
"c": {"value": "!template!{{ vault('a').value }}"},
509-
},
510-
{"value": '<recursive value "a">'},
511-
),
512-
# Direct Recursion
513-
(
514-
{"a": {"value": "!template!{{ vault('a').value }}"}},
515-
{"value": '<recursive value "a">'},
516-
),
517477
],
518478
)
519479
def test_vault_client_base_get_secret(vault, vault_contents, expected):
@@ -522,23 +482,6 @@ def test_vault_client_base_get_secret(vault, vault_contents, expected):
522482
assert vault.get_secret("a") == expected
523483

524484

525-
def test_vault_client_base_get_secret_deprecation_warning(vault, caplog):
526-
vault.db = {"a": {"value": "!template!b"}}
527-
caplog.set_level("WARNING")
528-
529-
vault.get_secret("a")
530-
assert "Templated values are deprecated" in caplog.records[0].message
531-
532-
533-
def test_vault_client_base_get_secret_template_root(vault):
534-
vault.base_path = "base"
535-
vault.db = {"/base/a": {"value": '!template!{{ vault("a").value }} yay'}}
536-
537-
# In case of erroneous caching, e.g. a different cache entry
538-
# for /base/a and base/a, we would find '<recursive value "a"> yay yay'
539-
assert vault.get_secret("/base/a") == {"value": '<recursive value "a"> yay'}
540-
541-
542485
def test_vault_client_base_get_secret_multiple_keys(vault):
543486
vault.db = {"rabbitmq/creds/role": {"username": "foo", "password": "bar"}}
544487
assert vault.get_secret("rabbitmq/creds/role") == {
@@ -547,22 +490,11 @@ def test_vault_client_base_get_secret_multiple_keys(vault):
547490
}
548491

549492

550-
def test_vault_client_base_get_secret_with_dict(vault):
551-
vault.db = {
552-
"credentials": {"value": {"username": "foo", "password": "bar"}},
553-
"dsn": {
554-
"value": "!template!proto://{{ vault('credentials')['value']['username'] }}:{{ vault('credentials').value.password }}@host"
555-
},
556-
}
557-
558-
assert vault.get_secret("dsn") == {"value": "proto://foo:bar@host"}
559-
560-
561493
def test_vault_client_base_get_secret_not_found(vault):
562494
vault.db = {}
563495

564496
with pytest.raises(exceptions.VaultSecretNotFound):
565-
vault.get_secret("not-exiting")
497+
vault.get_secret("not-existing")
566498

567499

568500
def test_vault_client_base_get_secret_missing_key(vault):
@@ -572,20 +504,6 @@ def test_vault_client_base_get_secret_missing_key(vault):
572504
vault.get_secret("a", key="username")
573505

574506

575-
def test_vault_client_base_get_secret_template_error(vault, caplog):
576-
vault.db = {"a": {"key": "!template!{{"}}
577-
578-
with pytest.raises(exceptions.VaultRenderTemplateError) as exc_info:
579-
vault.get_secret("a")
580-
581-
assert str(exc_info.value) == 'Error while rendering secret at path "a"'
582-
assert (
583-
str(exc_info.value.__cause__)
584-
== 'Error while rendering secret value for key "key"'
585-
)
586-
assert str(exc_info.value.__cause__.__cause__) == "Jinja2 template syntax error"
587-
588-
589507
def test_vault_client_base_lookup_token(vault):
590508
assert vault.lookup_token() == {"data": {"expire_time": "2100-01-01T00:00:00"}}
591509

@@ -672,56 +590,6 @@ def test_vault_client_base_get_secret_implicit_cache(vault):
672590
assert vault.get_secret("a") == {"value": "b"}
673591

674592

675-
class RaceConditionTestVaultClient(testing.TestVaultClient):
676-
def __init__(self, *args, **kwargs):
677-
super().__init__(*args, **kwargs)
678-
self.counter = itertools.count()
679-
680-
def _get_secret(self, path):
681-
if path == "a":
682-
val = next(self.counter)
683-
return {"b": f"b{val}", "c": f"c{val}"}
684-
return super()._get_secret(path)
685-
686-
687-
def test_vault_client_base_get_secret_implicit_cache_no_race_condition():
688-
# In this test we check that if a value is read several times by
689-
# a template, implicit caching makes sure we have the same value
690-
# every time.
691-
692-
# Values returned by this client keep changing
693-
694-
vault = RaceConditionTestVaultClient()
695-
696-
with vault:
697-
assert vault.get_secret("a") == {"b": "b0", "c": "c0"}
698-
with vault:
699-
assert vault.get_secret("a") == {"b": "b1", "c": "c1"}
700-
701-
vault.db = {"d": {"value": """!template!{{ vault("a").b }}-{{ vault("a").c }}"""}}
702-
703-
# b2-c3 would be the value if caching didn't work.
704-
with vault:
705-
assert vault.get_secret("d") == {"value": "b2-c2"}
706-
707-
708-
def test_vault_client_base_get_secrets_implicit_cache_no_race_condition():
709-
# In this test, the same value is read twice by get-all and template
710-
# We check that 2 values are consistent
711-
712-
vault = RaceConditionTestVaultClient()
713-
714-
vault.db = {
715-
"a": {},
716-
"d": {"value": """!template!{{ vault("a").b }}-{{ vault("a").c }}"""},
717-
}
718-
719-
assert vault.get_secrets("") == {
720-
"a": {"b": "b0", "c": "c0"},
721-
"d": {"value": "b0-c0"},
722-
}
723-
724-
725593
def test_vault_client_base_get_secret_explicit_cache(vault):
726594
vault.db = {"a": {"value": "b"}}
727595
with vault:

vault_cli/cli.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ def repr_octal(value: Optional[int]) -> Optional[str]:
133133
)
134134
@click.option(
135135
"--render/--no-render",
136-
default=settings.DEFAULTS.render,
137-
help="Render templated values",
136+
default=False,
137+
help="Deprecated / unused",
138138
)
139139
@click.option(
140140
"--umask",
@@ -174,6 +174,7 @@ def cli(ctx: click.Context, verbose: int, umask: int, **kwargs) -> None:
174174
(including VAULT_CLI_PASSWORD and VAULT_CLI_TOKEN).
175175
176176
"""
177+
kwargs.pop("render")
177178
kwargs.pop("config_file")
178179
set_verbosity(verbose)
179180
set_umask(umask)

0 commit comments

Comments
 (0)