mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-11 13:17:07 +00:00
Seven lookups read application_id out of the play's variables and every one of them has to template it, because sys-stk-full defines application_id from sys_stk_full_application_id and a dict read returns that unrendered. They did it in five spellings: a public resolve_var, two byte-identical private copies, and inline variants. Nothing named the rule, so it survived as folklore, and a lookup written without knowing it took down three jobs of one run. resolve_var now lives in utils/templating, which is where the six lookups that import it can reach it without pulling in a networking module for a concern that is not networking. utils/networks/lookup_context re-exports it under the alias form, so its own importers are untouched and autodoc still resolves one target. The two private copies go, and so does the fourth copy this branch added to webserver_resource a few commits ago. The private copies guarded value is not None and the public one did not. The canonical keeps the guard: it is narrower than every live caller, each of which passes a defaulted value, so no existing call can reach the branch. The helper had no test at all. Its six behaviours are characterised first, including that a templar raising on an undefined variable leaves the value alone rather than failing the play, which is what the suppression is for. Four inline copies stay. compose_volumes lets a template error propagate where this suppresses it, and mcp_servers only templates a str containing a template marker. Folding those in would change behaviour, which is not a refactor. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
85 lines
2.8 KiB
Python
85 lines
2.8 KiB
Python
"""Shared Ansible-side assembly for the network lookup plugins.
|
|
|
|
Every one of them needs the same four things before it can call into
|
|
:mod:`utils.networks.render`: the resolved variables, the deployment mode, a
|
|
service registry built from the merged applications, and closures over the
|
|
``config`` and ``database`` lookups. Building that once means a change to how
|
|
the registry or the closures are obtained cannot reach one lookup and miss
|
|
another.
|
|
|
|
Args of :func:`build_context` are documented on the function.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import TYPE_CHECKING, Any
|
|
|
|
from ansible.plugins.loader import lookup_loader
|
|
|
|
from utils.roles.applications.services.registry import (
|
|
build_service_registry_from_applications,
|
|
)
|
|
from utils.templating.vars import resolve_var as resolve_var
|
|
|
|
if TYPE_CHECKING:
|
|
from collections.abc import Callable
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class NetworkLookupContext:
|
|
"""What a network lookup needs to call the renderers."""
|
|
|
|
vars: dict[str, Any]
|
|
templar: Any
|
|
deployment_mode: str
|
|
registry: dict[str, dict[str, Any]]
|
|
lookup_config: Callable[[str, str, Any], Any]
|
|
lookup_database: Callable[[str, str], Any]
|
|
|
|
|
|
def build_context(
|
|
lookup: Any,
|
|
variables: dict[str, Any] | None,
|
|
*,
|
|
honour_mode_force: bool = True,
|
|
) -> NetworkLookupContext:
|
|
"""Assemble the shared context for a network lookup.
|
|
|
|
Args:
|
|
lookup: the LookupModule instance, for its templar and loader.
|
|
variables: the variables Ansible passed to ``run``.
|
|
honour_mode_force: let ``compose_mode_force`` override DEPLOYMENT_MODE.
|
|
"""
|
|
templar = getattr(lookup, "_templar", None)
|
|
vars_ = variables or getattr(templar, "available_variables", {}) or {}
|
|
|
|
deployment_mode = str(resolve_var(templar, vars_.get("DEPLOYMENT_MODE", "compose")))
|
|
if honour_mode_force:
|
|
mode_force = resolve_var(templar, vars_.get("compose_mode_force", ""))
|
|
deployment_mode = str(mode_force or deployment_mode).strip()
|
|
|
|
applications = lookup_loader.get(
|
|
"applications", loader=lookup._loader, templar=templar
|
|
).run([], variables=vars_)[0]
|
|
|
|
config_lookup = lookup_loader.get("config", loader=lookup._loader, templar=templar)
|
|
database_lookup = lookup_loader.get(
|
|
"database", loader=lookup._loader, templar=templar
|
|
)
|
|
|
|
def _lookup_config(app: str, path: str, default: Any) -> Any:
|
|
return config_lookup.run([app, path, default], variables=vars_)[0]
|
|
|
|
def _lookup_database(app: str, key: str) -> Any:
|
|
return database_lookup.run([app, key], variables=vars_)[0]
|
|
|
|
return NetworkLookupContext(
|
|
vars=vars_,
|
|
templar=templar,
|
|
deployment_mode=deployment_mode,
|
|
registry=build_service_registry_from_applications(applications),
|
|
lookup_config=_lookup_config,
|
|
lookup_database=_lookup_database,
|
|
)
|