Files
computer-playbook/utils/cache/domains.py
T
kevinveenbirkenbachandClaude Opus 4.8 6ce6780575 refactor(meta): split server.yml into csp/domains/networks.yml
Extract the csp, domains, and networks blocks out of roles/*/meta/server.yml
into dedicated meta files, each mapping to its own top-level applications key
via the recursive meta-walk:

  csp:      -> meta/csp.yml      -> applications.<app>.csp
  domains:  -> meta/domains.yml  -> applications.<app>.domains
  networks: -> meta/networks.yml -> applications.<app>.networks

Residual nginx/proxy keys (status_codes, client_max_body_size, locations,
ip6_enabled, config_upstream_url) stay in server.yml; an emptied server.yml is
deleted. 98 server.yml -> 249 new files, 74 deleted.

- Consumers repointed applications.<app>.server.{csp,domains,networks} ->
  applications.<app>.{csp,domains,networks} across templates, vars, tasks,
  lookups and filters.
- Infra readers migrated: canonical_domains_map, application_domain_index,
  build_ldap_role_entries, service-registry overlay discovery,
  roles_with_service, and the file-based readers utils/domains/list.py +
  utils/meta/scan.py (read the now-deleted server.yml directly).
- Detection + mapping: _META_TOPICS gains csp/domains/networks;
  ROLE_FILE_META_{CSP,DOMAINS,NETWORKS} constants + ROLE_FILES entries.
- New self-expiring lint guard (test_server_meta_no_split_fields) fails if a
  server.yml still carries a split field; auto-fails from 2026-12-28 as a
  delete reminder.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 22:45:05 +02:00

85 lines
2.5 KiB
Python

"""Domain-name cache: canonical-domains map derived from merged apps.
Owns `_MERGED_DOMAINS_CACHE`. Public API: `get_merged_domains`. The
domain map is intentionally derived from the applications view rather
than living in a parallel top-level overrides path. Per-app domain
declarations live in `applications.<app>.domains` and flow through the
regular applications-merge pipeline.
"""
from __future__ import annotations
from typing import TYPE_CHECKING, Any
from .base import (
_cache_key,
_resolve_roles_dir,
_stable_variables_signature,
)
if TYPE_CHECKING:
import os
_MERGED_DOMAINS_CACHE: dict[tuple, dict[str, Any]] = {}
def get_merged_domains(
*,
variables: dict[str, Any] | None = None,
roles_dir: str | os.PathLike[str] | None = None,
templar: Any = None,
) -> dict[str, Any]:
"""Build the canonical-domain map lazily from the merged applications view.
The result is canonical_domains_map(applications, DOMAIN_PRIMARY).
Per-app domain declarations live in `applications.<app>.domains`
(canonical/aliases) and flow through the regular applications-merge
pipeline.
Cached keyed on (roles_dir, variables_signature).
"""
# Late imports: keeps `import utils.cache.domains` cheap and avoids a
# cycle with `utils.cache.applications` (which itself late-imports
# `utils.cache.users`).
from plugins.filter.canonical_domains_map import (
FilterModule as _CanonicalDomainsFilter,
)
from .applications import get_merged_applications
variables = variables or {}
resolved_roles_dir = _resolve_roles_dir(roles_dir=roles_dir)
cache_key = (
_cache_key(resolved_roles_dir),
_stable_variables_signature(variables),
)
cached = _MERGED_DOMAINS_CACHE.get(cache_key)
if cached is not None:
return cached
primary_domain = (
variables.get("DOMAIN_PRIMARY") or variables.get("SYSTEM_EMAIL_DOMAIN") or ""
)
if not primary_domain:
raise ValueError(
"get_merged_domains: DOMAIN_PRIMARY (or SYSTEM_EMAIL_DOMAIN fallback) "
"must be set in variables."
)
apps = get_merged_applications(
variables=variables,
roles_dir=roles_dir,
templar=templar,
)
filter_instance = _CanonicalDomainsFilter()
merged = filter_instance.canonical_domains_map(apps, primary_domain)
_MERGED_DOMAINS_CACHE[cache_key] = merged
return merged
def _reset() -> None:
_MERGED_DOMAINS_CACHE.clear()