# Copyright: (c) 2024, Luca Bilke <luca@bil.ke> # MIT License (see LICENSE) """Service module utilities.""" from __future__ import annotations import copy from dataclasses import replace from typing import Any, Callable from ansible_collections.snailed.ez_compose.plugins.module_utils.common import ( State, recursive_update, run_module, update_project, ) BASE_SERVICE_ARGS = { "project_name": { "type": "str", "required": True, }, "name": { "type": "str", "required": True, }, "image": { "type": "str", }, "defaults": { "type": "dict", }, } def apply_base(state: State) -> State: """Apply base service configuration.""" service_name = state.module.params["name"] project_name = state.module.params["project_name"] image = state.module.params["image"] new: dict[str, Any] = { "service_name": f"{project_name}_{service_name}", "hostname": f"{project_name}_{service_name}", "image": image, "restart": "unless-stopped", "environment": {}, "labels": {}, "volumes": [], "networks": { f"{project_name}_internal": None, }, } return update(state, new) def set_defaults(state: State) -> State: """Set default values for a service.""" container_name = state.module.params["name"] defaults = state.module.params["defaults"] project = copy.deepcopy(state.after) services = project["services"] service = services[container_name] _ = recursive_update(service, defaults) services.update({container_name: service}) return replace(state, after=project) def update(state: State, update: dict[str, Any]) -> State: """Update a service with the given dictionary.""" project = copy.deepcopy(state.after) service_name = state.module.params["name"] _ = recursive_update(project["services"][service_name], update) return replace(state, after=project) def run( extra_args: dict[str, Any] | None = None, helper: Callable[[State], State] = lambda _: _, ) -> None: """Wrap module execution function for service helpers.""" def execute(state: State) -> State: for f in [apply_base, set_defaults, helper, update_project]: state = f(state) return state run_module({**BASE_SERVICE_ARGS, **(extra_args or {})}, execute)