mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 19:01:54 +00:00
meta/schema.yml became meta/secrets.yml, but its content still landed at
applications.<app>.credentials — the one meta file whose payload did not sit
under a root named after the file. Every other topic obeys that rule:
meta/volumes.yml goes to volumes, meta/rbac.yml to rbac. Credentials now go to
secrets.credentials.
The path exists exactly once, in utils/manager/credential_key.py, and
OVERRIDE_SECTION is derived from its two segments rather than spelled beside
them, so the dotted form used by --set and the nested form used by the
inventory cannot drift. Six consumers read it: the loader, the generator, the
CLI override parser, the two emit helpers, and the four lookup validators.
--set now accepts exactly one key shape,
applications.<app>.secrets.credentials.<key>. The three short forms are
rejected instead of guessed at: the same short key names different credentials
on different apps. That also retired primary_app_id, which only existed to
disambiguate them.
Three defects surfaced while wiring this up. _apply_one_role_schema still wrote
to the old root, so an app's own credentials would have moved while its
providers' stayed behind. web-app-pgadmin reads through
lookup('applications', ...).credentials.<key>, an access path no regex over
lookup('config', ...) could see, and would have deployed with an empty postgres
password. And _META_NON_GENERIC_TOPICS still listed 'schema' — a bare topic
name, invisible to any path search — so the generic file-root loop assigned the
raw schema under secrets and the follow-up write landed inside the cached
document, truncating keycloak's four credentials to one for every later
reader.
tests/integration/ansible/lookups/config/test_credentials_roundtrip.py pins both
directions of the seam and the cache invariant that last defect broke.
Existing inventories still carry the pre-rename root; migrating them is
deliberately out of scope here.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
35 lines
1.1 KiB
Python
35 lines
1.1 KiB
Python
"""The one accepted ``--set`` key shape for a credential override.
|
|
|
|
Both the CLI that parses ``--set`` and the inventory manager that consumes the
|
|
parsed pairs build the key here, so a credential is addressed by exactly one
|
|
string. A short form would name different credentials on different apps.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
OVERRIDE_ROOT = "applications"
|
|
SECRETS_KEY = "secrets"
|
|
CREDENTIALS_KEY = "credentials"
|
|
OVERRIDE_SECTION = f"{SECRETS_KEY}.{CREDENTIALS_KEY}"
|
|
|
|
|
|
def override_key(app_id: str, key: str) -> str:
|
|
"""Build the override key for one credential.
|
|
|
|
Args:
|
|
app_id: application the credential belongs to.
|
|
key: dotted path inside the schema's ``credentials`` node, e.g.
|
|
``recaptcha.secret``.
|
|
"""
|
|
return f"{OVERRIDE_ROOT}.{app_id}.{OVERRIDE_SECTION}.{key}"
|
|
|
|
|
|
def split_override_key(key: str) -> tuple[str, str]:
|
|
"""Split an override key back into ``(app_id, credential path)``.
|
|
|
|
Args:
|
|
key: a key in the shape :func:`override_key` builds.
|
|
"""
|
|
app_id, credential = key[len(OVERRIDE_ROOT) + 1 :].split(f".{OVERRIDE_SECTION}.", 1)
|
|
return app_id, credential
|