Skip to content

Commit

Permalink
Merge pull request #20 from pmuller/fix/nested-pillar
Browse files Browse the repository at this point in the history
fix: add support for nested pillar data
  • Loading branch information
pmuller authored Apr 30, 2024
2 parents 46ef5b2 + 7a6202f commit c1bf1af
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 27 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
# saltstack-age change log

## Unreleased

* fix: add support for nested pillar data
7 changes: 4 additions & 3 deletions example/pillar/test.sls
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#!jinja|yaml|age

prefix: /tmp
test:
prefix: /tmp

private: ENC[age-identity,YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkWHZYRkU2bjc4M2VtaElEZGxudmkwNW95ZHlNZy84K3U4MmlXejIzRkJNCktPbkhLU0h4VXBFYTZUUDlzbFFzdUx5R1VyaDZhd2doNkE2QnFpUmV6OFEKLS0tIFd3Wlg1UWQ3NHEwKyt6bTZkdmp3bWRCTTZkakppTFovbkhBcDhFeGdJazgKnf48DyGjBm2wOpM11YZ0+1btASDDSdgqXiM4SXXEMHhylmW8G9pSoTtovj0aZu9QVA==]
private: ENC[age-identity,YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkWHZYRkU2bjc4M2VtaElEZGxudmkwNW95ZHlNZy84K3U4MmlXejIzRkJNCktPbkhLU0h4VXBFYTZUUDlzbFFzdUx5R1VyaDZhd2doNkE2QnFpUmV6OFEKLS0tIFd3Wlg1UWQ3NHEwKyt6bTZkdmp3bWRCTTZkakppTFovbkhBcDhFeGdJazgKnf48DyGjBm2wOpM11YZ0+1btASDDSdgqXiM4SXXEMHhylmW8G9pSoTtovj0aZu9QVA==]

public: that's not a secret
public: that's not a secret
6 changes: 3 additions & 3 deletions example/states/test.sls
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{% set prefix = salt.pillar.get('prefix') %}
{% set prefix = salt.pillar.get('test:prefix') %}

{{ prefix }}/test-public:
file.managed:
- contents_pillar: public
- contents_pillar: test:public

{{ prefix }}/test-private:
file.managed:
- contents_pillar: private
- contents_pillar: test:private
15 changes: 10 additions & 5 deletions src/saltstack_age/renderers/age.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from collections import OrderedDict
from importlib import import_module
from pathlib import Path
from typing import Any
from typing import Any, cast

import pyrage
from salt.exceptions import SaltRenderError
Expand Down Expand Up @@ -73,13 +73,18 @@ def _decrypt(string: str) -> str:
return secure_value.decrypt(_get_passphrase())


def _render_value(value: Any) -> Any: # noqa: ANN401
if is_secure_value(value):
return _decrypt(value)
if isinstance(value, OrderedDict):
return render(cast(Data, value))
return value


def render(
data: Data,
_saltenv: str = "base",
_sls: str = "",
**_kwargs: None,
) -> Data:
return OrderedDict(
(key, _decrypt(value) if is_secure_value(value) else value)
for key, value in data.items()
)
return OrderedDict((key, _render_value(value)) for key, value in data.items())
5 changes: 3 additions & 2 deletions src/saltstack_age/secure_value.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import re
from base64 import b64decode
from dataclasses import dataclass
from typing import Any

import pyrage

Expand All @@ -24,8 +25,8 @@
)


def is_secure_value(string: str) -> bool:
return bool(RE_SECURE_VALUE.match(string))
def is_secure_value(value: Any) -> bool: # noqa: ANN401
return bool(RE_SECURE_VALUE.match(value)) if isinstance(value, str) else False


@dataclass
Expand Down
13 changes: 13 additions & 0 deletions tests/integration/_test_renderer_identity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import json
from pathlib import Path

from saltfactories.cli.call import SaltCall


def test(salt_call_cli: SaltCall, tmp_path: Path) -> None:
_ = salt_call_cli.run(
"state.apply",
pillar=json.dumps({"test": {"prefix": str(tmp_path)}}),
)
assert (tmp_path / "test-public").read_text() == "that's not a secret\n"
assert (tmp_path / "test-private").read_text() == "test-secret-value\n"
9 changes: 2 additions & 7 deletions tests/integration/test_renderer_identity_from_config.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from pathlib import Path

import pytest
from saltfactories.cli.call import SaltCall
from saltfactories.daemons.minion import SaltMinion
from saltfactories.manager import FactoriesManager
from saltfactories.utils import random_string

from tests.integration import _test_renderer_identity
from tests.integration.conftest import MINION_CONFIG


Expand All @@ -19,7 +17,4 @@ def minion(salt_factories: FactoriesManager, example_age_key: str) -> SaltMinion
)


def test(salt_call_cli: SaltCall, tmp_path: Path) -> None:
_ = salt_call_cli.run("state.apply", pillar=f'{{"prefix": "{tmp_path}"}}')
assert (tmp_path / "test-public").read_text() == "that's not a secret\n"
assert (tmp_path / "test-private").read_text() == "test-secret-value\n"
test = _test_renderer_identity.test
9 changes: 2 additions & 7 deletions tests/integration/test_renderer_identity_from_environment.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from pathlib import Path

import pytest
from saltfactories.cli.call import SaltCall
from saltfactories.daemons.minion import SaltMinion
from saltfactories.manager import FactoriesManager
from saltfactories.utils import random_string

from tests.integration import _test_renderer_identity
from tests.integration.conftest import MINION_CONFIG


Expand All @@ -22,7 +20,4 @@ def minion(
)


def test(salt_call_cli: SaltCall, tmp_path: Path) -> None:
_ = salt_call_cli.run("state.apply", pillar=f'{{"prefix": "{tmp_path}"}}')
assert (tmp_path / "test-public").read_text() == "that's not a secret\n"
assert (tmp_path / "test-private").read_text() == "test-secret-value\n"
test = _test_renderer_identity.test

0 comments on commit c1bf1af

Please sign in to comment.