94 lines
2.4 KiB
Python
94 lines
2.4 KiB
Python
# 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)
|