from __future__ import annotations from typing import Any, Dict, Optional from ansible.errors import AnsibleError from ansible.plugins.lookup import LookupBase from utils.docker_paths_utils import get_docker_paths def _as_str(v: Any) -> str: return "" if v is None else str(v).strip() def _deep_get(d: Dict[str, Any], path: str) -> Any: cur: Any = d for key in path.split("."): if not isinstance(cur, dict) or key not in cur: raise AnsibleError(f"lookup('container'): invalid path '{path}'") cur = cur[key] return cur class LookupModule(LookupBase): """ lookup('container', application_id[, path]) path can be: - 'directories' / 'files' (returns sub-dict) - 'directories.instance' (returns leaf) """ def run(self, terms, variables: Optional[Dict[str, Any]] = None, **kwargs): if not terms or len(terms) > 2: raise AnsibleError("lookup('container', application_id[, path])") application_id = _as_str(terms[0]) if not application_id: raise AnsibleError("lookup('container'): application_id is empty") base = _as_str((variables or {}).get("DIR_COMPOSITIONS")) if not base: raise AnsibleError("lookup('container'): DIR_COMPOSITIONS not set") paths = get_docker_paths(application_id, base) if len(terms) == 2: path = _as_str(terms[1]) if not path: raise AnsibleError("lookup('container'): path is empty") return [_deep_get(paths, path)] return [paths]