mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-09 04:06:42 +00:00
The entity name keys a role's instance directory, its compose project and its container name, and was derived only by stripping the longest matching category prefix. Two roles under different categories whose names share a suffix therefore collapse onto one entity and overwrite each other's rendered stack, which no provides: can repair. A literal entity_name in vars/main.yml now wins over the derivation. web-app-seaweedfs-console takes its shorter name back and declares the entity seaweedfs-console, which frees the seaweedfs key in its own services map for the engine consumer and removes the provides:, covers: and alias entries that stood in for it. A new lint pairs the declaration with the primary key it has to match, because a drift between them would drop the role from the provider set in silence. Compared across all 288 roles, exactly one entity changes, and it restores what main already keeps on disk, so no instance directory moves. The function and the filter lose their get_ prefix. Two lints read that prefix as the discriminator between the variable and the filter that fills it; both discriminate on the pipe now. Ansible's templar resolves a filter and a same-named variable independently, verified against ansible-core 2.20.2. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
228 lines
6.8 KiB
Python
228 lines
6.8 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from ansible.errors import AnsibleError
|
|
from ansible.plugins.loader import lookup_loader
|
|
from ansible.plugins.lookup import LookupBase
|
|
|
|
from utils.manager.credential_key import OVERRIDE_SECTION
|
|
from utils.roles.applications.config import get
|
|
from utils.roles.entity.name import entity_name
|
|
|
|
MINIO_PROVIDER_ROLE = "web-app-minio"
|
|
MINIO_SERVICE_KEY = entity_name(MINIO_PROVIDER_ROLE)
|
|
|
|
|
|
class LookupModule(LookupBase):
|
|
"""
|
|
Resolve MinIO object-store values for a given minio_consumer_id.
|
|
|
|
Mirrors plugins/lookup/database.py: branches on the consumer's
|
|
`services.minio.shared` flag to yield either central (shared) or
|
|
embedded (local) connection details.
|
|
|
|
API (STRICT):
|
|
- {{ lookup('minio', minio_consumer_id) }}
|
|
- {{ lookup('minio', minio_consumer_id, 'url') }}
|
|
|
|
Notes:
|
|
- want-path is optional and MUST be the second positional argument
|
|
- kwarg want= is NOT supported (use positional want-path)
|
|
"""
|
|
|
|
def run(
|
|
self,
|
|
terms: list[Any],
|
|
variables: dict[str, Any] | None = None,
|
|
**kwargs: Any,
|
|
) -> list[Any]:
|
|
terms = terms or []
|
|
if len(terms) not in (1, 2):
|
|
raise AnsibleError("minio: requires minio_consumer_id [, want_path]")
|
|
|
|
if "want" in kwargs and str(kwargs.get("want") or "").strip():
|
|
raise AnsibleError(
|
|
"minio: kwarg 'want=' is not supported; use positional want_path "
|
|
"like lookup('minio', <id>, 'url')"
|
|
)
|
|
|
|
consumer_id = str(terms[0]).strip()
|
|
if not consumer_id:
|
|
raise AnsibleError("minio: minio_consumer_id must not be empty")
|
|
|
|
want = str(terms[1]).strip() if len(terms) == 2 else ""
|
|
if not want:
|
|
want = "all"
|
|
|
|
vars_ = variables or self._templar.available_variables
|
|
applications = lookup_loader.get(
|
|
"applications", loader=self._loader, templar=getattr(self, "_templar", None)
|
|
).run([], variables=vars_)[0]
|
|
path_instances = self._require_var(vars_, "DIR_COMPOSITIONS")
|
|
|
|
consumer_entity = entity_name(consumer_id)
|
|
|
|
enabled = bool(
|
|
get(
|
|
applications,
|
|
consumer_id,
|
|
f"services.{MINIO_SERVICE_KEY}.enabled",
|
|
strict=False,
|
|
default=False,
|
|
)
|
|
)
|
|
shared = bool(
|
|
get(
|
|
applications,
|
|
consumer_id,
|
|
f"services.{MINIO_SERVICE_KEY}.shared",
|
|
strict=False,
|
|
default=False,
|
|
)
|
|
)
|
|
central_enabled = shared
|
|
|
|
central_name = get(
|
|
applications,
|
|
MINIO_PROVIDER_ROLE,
|
|
f"services.{MINIO_SERVICE_KEY}.name",
|
|
strict=False,
|
|
default=MINIO_SERVICE_KEY,
|
|
skip_missing_app=True,
|
|
)
|
|
central_name = (
|
|
str(central_name) if central_name is not None else ""
|
|
).strip() or MINIO_SERVICE_KEY
|
|
|
|
host = central_name if central_enabled else MINIO_SERVICE_KEY
|
|
network = (
|
|
entity_name(MINIO_PROVIDER_ROLE) if central_enabled else consumer_entity
|
|
)
|
|
container = (
|
|
central_name
|
|
if central_enabled
|
|
else f"{consumer_entity}-{MINIO_SERVICE_KEY}"
|
|
)
|
|
port = get(
|
|
applications,
|
|
MINIO_PROVIDER_ROLE,
|
|
f"services.{MINIO_SERVICE_KEY}.api_port",
|
|
strict=False,
|
|
default=9000,
|
|
skip_missing_app=True,
|
|
)
|
|
region = get(
|
|
applications,
|
|
MINIO_PROVIDER_ROLE,
|
|
f"services.{MINIO_SERVICE_KEY}.region",
|
|
strict=False,
|
|
default="us-east-1",
|
|
skip_missing_app=True,
|
|
)
|
|
client_image = get(
|
|
applications,
|
|
MINIO_PROVIDER_ROLE,
|
|
"services.client.image",
|
|
strict=False,
|
|
default="quay.io/minio/mc",
|
|
skip_missing_app=True,
|
|
)
|
|
client_version = get(
|
|
applications,
|
|
MINIO_PROVIDER_ROLE,
|
|
"services.client.version",
|
|
strict=False,
|
|
default="",
|
|
skip_missing_app=True,
|
|
)
|
|
mc_image = (
|
|
f"{client_image}:{client_version}" if client_version else client_image
|
|
)
|
|
|
|
access_key = consumer_entity
|
|
secret_key = get(
|
|
applications,
|
|
consumer_id,
|
|
f"{OVERRIDE_SECTION}.objstore_secret_key",
|
|
strict=False,
|
|
default="",
|
|
)
|
|
bucket = consumer_entity
|
|
|
|
public = bool(
|
|
get(
|
|
applications,
|
|
consumer_id,
|
|
f"services.{MINIO_SERVICE_KEY}.public",
|
|
strict=False,
|
|
default=False,
|
|
)
|
|
)
|
|
|
|
image = get(
|
|
applications,
|
|
MINIO_PROVIDER_ROLE,
|
|
f"services.{MINIO_SERVICE_KEY}.image",
|
|
strict=False,
|
|
default="quay.io/minio/minio",
|
|
skip_missing_app=True,
|
|
)
|
|
default_version = get(
|
|
applications,
|
|
MINIO_PROVIDER_ROLE,
|
|
f"services.{MINIO_SERVICE_KEY}.version",
|
|
strict=False,
|
|
default="latest",
|
|
skip_missing_app=True,
|
|
)
|
|
version = get(
|
|
applications,
|
|
consumer_id,
|
|
f"services.{MINIO_SERVICE_KEY}.version",
|
|
strict=False,
|
|
default=default_version,
|
|
)
|
|
|
|
env = f"{path_instances}{consumer_entity}/.env/objstore.env"
|
|
|
|
volume_prefix = "" if central_enabled else f"{consumer_entity}_"
|
|
volume = (
|
|
f"{volume_prefix}{MINIO_SERVICE_KEY}"
|
|
if bool(enabled and not shared)
|
|
else ""
|
|
)
|
|
|
|
url = f"http://{host}:{port}"
|
|
|
|
resolved = {
|
|
"id": MINIO_PROVIDER_ROLE,
|
|
"enabled": enabled,
|
|
"shared": shared,
|
|
"local": bool(enabled and not shared),
|
|
"host": host,
|
|
"port": port,
|
|
"network": network,
|
|
"container": container,
|
|
"bucket": bucket,
|
|
"public": public,
|
|
"access_key": access_key,
|
|
"secret_key": secret_key,
|
|
"image": image,
|
|
"version": version,
|
|
"region": region,
|
|
"mc_image": mc_image,
|
|
"env": env,
|
|
"volume": volume,
|
|
"url": url,
|
|
"reach_host": "127.0.0.1",
|
|
}
|
|
|
|
return [resolved if want == "all" else resolved.get(want, "")]
|
|
|
|
@staticmethod
|
|
def _require_var(vars_: dict[str, Any], key: str) -> Any:
|
|
if key not in vars_:
|
|
raise AnsibleError(f"minio: required variable '{key}' is not set")
|
|
return vars_[key]
|