WIP
This commit is contained in:
parent
dd82a95cf1
commit
558192c404
23 changed files with 367 additions and 353 deletions
|
@ -1,4 +0,0 @@
|
|||
# Copyright: (c) 2024, Luca Bilke <luca@bil.ke>
|
||||
# MIT License (see LICENSE)
|
||||
|
||||
"""A collection to ease the creation of docker compose files using ansible."""
|
19
plugins/doc_fragments/common.py
Normal file
19
plugins/doc_fragments/common.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Copyright: (c) 2024, Luca Bilke <luca@bil.ke>
|
||||
# MIT License (see LICENSE)
|
||||
|
||||
|
||||
class ModuleDocFragment:
|
||||
DOCUMENTATION = r"""
|
||||
options:
|
||||
project_name:
|
||||
description:
|
||||
- The name of the project.
|
||||
type: str
|
||||
required: true
|
||||
project_dir:
|
||||
description:
|
||||
- The directory to place compose files in.
|
||||
type: path
|
||||
required: false
|
||||
default: /var/lib/ez_compose
|
||||
"""
|
18
plugins/doc_fragments/service.py
Normal file
18
plugins/doc_fragments/service.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Copyright: (c) 2024, Luca Bilke <luca@bil.ke>
|
||||
# MIT License (see LICENSE)
|
||||
|
||||
|
||||
class ModuleDocFragment:
|
||||
DOCUMENTATION = r"""
|
||||
options:
|
||||
image:
|
||||
description:
|
||||
- The Docker image to run.
|
||||
type: str
|
||||
required: true
|
||||
defaults:
|
||||
description:
|
||||
- Defaults to be overwritten in the compose service definition
|
||||
type: dict
|
||||
required: false
|
||||
"""
|
|
@ -1,4 +0,0 @@
|
|||
# Copyright: (c) 2024, Luca Bilke <luca@bil.ke>
|
||||
# MIT License (see LICENSE)
|
||||
|
||||
"""Module utilities for ez_compose modules."""
|
|
@ -1,49 +1,38 @@
|
|||
# Copyright: (c) 2024, Luca Bilke <luca@bil.ke>
|
||||
# MIT License (see LICENSE)
|
||||
|
||||
"""Common module utilities."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
from dataclasses import asdict, dataclass, field, replace
|
||||
from dataclasses import dataclass, field, replace
|
||||
from pathlib import Path
|
||||
from typing import Any, Callable
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
import yaml
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
PROJECTS_DIR = "/var/lib/ez_compose"
|
||||
if TYPE_CHECKING:
|
||||
from ansible.module_utils.basic import AnsibleModule # type: ignore[reportMissingStubFile]
|
||||
|
||||
BASE_ARGS = {
|
||||
"project_name": {
|
||||
"type": "str",
|
||||
"required": True,
|
||||
},
|
||||
"name": {
|
||||
"type": "str",
|
||||
"required": True,
|
||||
},
|
||||
"project_dir": {
|
||||
"type": "path",
|
||||
"default": "/var/lib/ez_compose",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Result:
|
||||
"""Module result object."""
|
||||
|
||||
changed: bool = False
|
||||
diff: dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
|
||||
# @dataclass(frozen=True)
|
||||
# class Settings:
|
||||
# projects_dir: str = "/usr/local/share/ez_compose/"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class State:
|
||||
"""Execution state object."""
|
||||
|
||||
module: AnsibleModule
|
||||
result: Result
|
||||
compose_filepath: str
|
||||
|
@ -55,7 +44,6 @@ def recursive_update(
|
|||
default: dict[Any, Any],
|
||||
update: dict[Any, Any],
|
||||
) -> dict[Any, Any]:
|
||||
"""Recursively update a dictionary."""
|
||||
for key in update: # noqa: PLC0206
|
||||
if isinstance(update[key], dict) and isinstance(default.get(key), dict):
|
||||
default[key] = recursive_update(default[key], update[key])
|
||||
|
@ -73,14 +61,11 @@ def recursive_update(
|
|||
|
||||
def get_state(module: AnsibleModule) -> State:
|
||||
"""Create a new state object, loading the compose file into "before" if it exists."""
|
||||
compose_filepath = (
|
||||
f"{PROJECTS_DIR}/{module.params['project_name']}/docker-compose.yml"
|
||||
)
|
||||
compose_filepath = f"{module.params['project_dir']}/{module.params['name']}/docker-compose.yml"
|
||||
|
||||
try:
|
||||
with Path(compose_filepath).open("r") as fp:
|
||||
before = yaml.safe_load(fp)
|
||||
|
||||
except FileNotFoundError:
|
||||
before: dict[str, Any] = {}
|
||||
|
||||
|
@ -89,9 +74,12 @@ def get_state(module: AnsibleModule) -> State:
|
|||
result=Result(),
|
||||
compose_filepath=compose_filepath,
|
||||
before=before,
|
||||
after={},
|
||||
after={
|
||||
"name": module.params["name"],
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def update_project(state: State) -> State:
|
||||
"""Ensure that networks/volumes that exist in services also exist in the project."""
|
||||
project = copy.deepcopy(state.after)
|
||||
|
@ -124,30 +112,9 @@ def update_project(state: State) -> State:
|
|||
|
||||
|
||||
def write_compose(state: State) -> State:
|
||||
"""Write the compose file to disk."""
|
||||
file = state.compose_filepath
|
||||
|
||||
with Path(file).open(mode="w") as stream:
|
||||
yaml.dump(state.after, stream)
|
||||
|
||||
return state
|
||||
|
||||
|
||||
def run_module(
|
||||
args: dict[str, Any] | None = None,
|
||||
execute: Callable[[State], State] = lambda _: _,
|
||||
) -> None:
|
||||
"""Handle module setup and teardown."""
|
||||
module = AnsibleModule(
|
||||
argument_spec={**BASE_ARGS, **(args or {})},
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
state = get_state(module)
|
||||
|
||||
state = execute(state)
|
||||
|
||||
if not state.module.check_mode:
|
||||
write_compose(state)
|
||||
|
||||
state.module.exit_json(**asdict(state.result)) # type: ignore[reportUnkownMemberType]
|
||||
|
|
|
@ -1,4 +1,18 @@
|
|||
# Copyright: (c) 2024, Luca Bilke <luca@bil.ke>
|
||||
# MIT License (see LICENSE)
|
||||
|
||||
"""Module utilities for ez_compose label modules."""
|
||||
__all__ = [
|
||||
"common",
|
||||
"docker_volume_backupper",
|
||||
"traefik_middleware",
|
||||
"traefik_router",
|
||||
"traefik_service",
|
||||
]
|
||||
|
||||
from . import (
|
||||
common,
|
||||
docker_volume_backupper,
|
||||
traefik_middleware,
|
||||
traefik_router,
|
||||
traefik_service,
|
||||
)
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
# Copyright: (c) 2024, Luca Bilke <luca@bil.ke>
|
||||
# MIT License (see LICENSE)
|
||||
|
||||
"""Label module utilities."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Callable
|
||||
from typing import TYPE_CHECKING, Callable
|
||||
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.common import (
|
||||
State,
|
||||
run_module,
|
||||
)
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.common import ( # type: ignore[reportMissingTypeStubs]
|
||||
State,
|
||||
)
|
||||
|
||||
|
||||
def run(
|
||||
extra_args: dict[str, Any] | None = None,
|
||||
BASE_ARGS = {
|
||||
"name": {"type": "str", "required": True},
|
||||
}
|
||||
|
||||
|
||||
def run_helper(
|
||||
state: State,
|
||||
helper: Callable[[State], State] = lambda _: _,
|
||||
) -> None:
|
||||
"""Wrap module execution function for label helpers."""
|
||||
run_module(extra_args or {}, helper)
|
||||
) -> State:
|
||||
return helper(state)
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
# Copyright: (c) 2024, Luca Bilke <luca@bil.ke>
|
||||
# MIT License (see LICENSE)
|
||||
|
||||
"""Docker Volume Backup label helper."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
import ansible_collections.snailed.ez_compose.plugins.module_utils.label.common as label
|
||||
import ansible_collections.snailed.ez_compose.plugins.module_utils.service.common as service
|
||||
import ansible_collections.ssnailed.ez_compose.plugins.module_utils.service.common as service # type: ignore[reportMissingTypeStubs]
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.common import State
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.common import ( # type: ignore[reportMissingTypeStubs]
|
||||
State,
|
||||
)
|
||||
|
||||
EXTRA_ARGS = {
|
||||
"stop": {"type": "bool"},
|
||||
}
|
||||
|
||||
|
||||
def helper(state: State) -> State:
|
||||
"""Add labels to the service to stop it during backup."""
|
||||
stop = state.module.params.get("stop", True)
|
||||
project_name = state.module.params["project_name"]
|
||||
|
||||
|
@ -27,11 +29,3 @@ def helper(state: State) -> State:
|
|||
}
|
||||
|
||||
return service.update(state, update)
|
||||
|
||||
|
||||
def run() -> None:
|
||||
"""Run the backupper label helper."""
|
||||
extra_args = {
|
||||
"stop": {"type": "bool"},
|
||||
}
|
||||
label.run(extra_args, helper)
|
||||
|
|
|
@ -5,11 +5,19 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import ansible_collections.snailed.ez_compose.plugins.module_utils.label.common as label
|
||||
import ansible_collections.snailed.ez_compose.plugins.module_utils.service.common as service
|
||||
import ansible_collections.ssnailed.ez_compose.plugins.module_utils.service.common as service # type: ignore[reportMissingTypeStubs]
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.common import State
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.common import ( # type: ignore[reportMissingTypeStubs]
|
||||
State,
|
||||
)
|
||||
|
||||
EXTRA_ARGS = {
|
||||
"proxy_type": {"type": "str"},
|
||||
"middleware_name": {"type": "string"},
|
||||
"middleware": {"type": "str", "required": True},
|
||||
"settings": {"type": "list", "required": True},
|
||||
}
|
||||
|
||||
|
||||
def helper(state: State) -> State:
|
||||
|
@ -32,17 +40,3 @@ def helper(state: State) -> State:
|
|||
}
|
||||
|
||||
return service.update(state, update)
|
||||
|
||||
|
||||
def main():
|
||||
extra_args = {
|
||||
"proxy_type": {"type": "str"},
|
||||
"middleware_name": {"type": "string"},
|
||||
"middleware": {"type": "str", "required": True},
|
||||
"settings": {"type": "list", "required": True},
|
||||
}
|
||||
label.run(extra_args, helper)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -5,11 +5,22 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import ansible_collections.snailed.ez_compose.plugins.module_utils.label.common as label
|
||||
import ansible_collections.snailed.ez_compose.plugins.module_utils.service.common as service
|
||||
import ansible_collections.ssnailed.ez_compose.plugins.module_utils.service.common as service # type: ignore[reportMissingTypeStubs]
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.common import State
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.common import ( # type: ignore[reportMissingTypeStubs]
|
||||
State,
|
||||
)
|
||||
|
||||
EXTRA_ARGS = {
|
||||
"proxy_type": {"type": "str"},
|
||||
"router_name": {"type": "str"},
|
||||
"rule": {"type": "str", "required": True},
|
||||
"service": {"type": "str"},
|
||||
"certresolver": {"type": "str"},
|
||||
"entrypoints": {"type": "list"},
|
||||
"middlewares": {"type": "list"},
|
||||
}
|
||||
|
||||
|
||||
def helper(state: State) -> State:
|
||||
|
@ -50,22 +61,3 @@ def helper(state: State) -> State:
|
|||
}
|
||||
|
||||
return service.update(state, update)
|
||||
|
||||
|
||||
def main():
|
||||
extra_args = {
|
||||
"proxy_type": {"type": "str"},
|
||||
"router_name": {
|
||||
"type": "str",
|
||||
},
|
||||
"rule": {"type": "str", "required": True},
|
||||
"service": {"type": "str"},
|
||||
"certresolver": {"type": "str"},
|
||||
"entrypoints": {"type": "list"},
|
||||
"middlewares": {"type": "list"},
|
||||
}
|
||||
label.run(extra_args, helper)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -3,16 +3,20 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
import ansible_collections.snailed.ez_compose.plugins.module_utils.label.common as label
|
||||
import ansible_collections.snailed.ez_compose.plugins.module_utils.service.common as service
|
||||
import ansible_collections.ssnailed.ez_compose.plugins.module_utils.service.common as service # type: ignore[reportMissingTypeStubs]
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.common import State
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.common import ( # type: ignore[reportMissingTypeStubs]
|
||||
State,
|
||||
)
|
||||
|
||||
|
||||
from typing import Any
|
||||
EXTRA_ARGS = {
|
||||
"proxy_type": {"type": "str"},
|
||||
"service_name": {"type": "string"},
|
||||
"port": {"type": "int"},
|
||||
}
|
||||
|
||||
|
||||
def helper(state: State) -> State:
|
||||
|
@ -37,16 +41,3 @@ def helper(state: State) -> State:
|
|||
}
|
||||
|
||||
return service.update(state, update)
|
||||
|
||||
|
||||
def main():
|
||||
extra_args = {
|
||||
"proxy_type": {"type": "str"},
|
||||
"service_name": {"type": "string"},
|
||||
"port": {"type": "int"},
|
||||
}
|
||||
label.run(extra_args, helper)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -1,4 +1,21 @@
|
|||
# Copyright: (c) 2024, Luca Bilke <luca@bil.ke>
|
||||
# MIT License (see LICENSE)
|
||||
__all__ = [
|
||||
"common",
|
||||
"custom",
|
||||
"docker_in_docker",
|
||||
"docker_socket_proxy",
|
||||
"docker_volume_backupper",
|
||||
"mariadb",
|
||||
"postgres",
|
||||
"redis",
|
||||
]
|
||||
|
||||
"""Module utilities for ez_compose service modules."""
|
||||
from . import (
|
||||
common,
|
||||
custom,
|
||||
docker_in_docker,
|
||||
docker_socket_proxy,
|
||||
docker_volume_backupper,
|
||||
mariadb,
|
||||
postgres,
|
||||
redis,
|
||||
)
|
||||
|
|
|
@ -1,65 +1,51 @@
|
|||
# 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 typing import TYPE_CHECKING, Any, Callable
|
||||
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.common import (
|
||||
State,
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.common import ( # type: ignore[reportMissingTypeStubs]
|
||||
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",
|
||||
},
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.common import ( # type: ignore[reportMissingTypeStubs]
|
||||
State,
|
||||
)
|
||||
|
||||
BASE_ARGS = {
|
||||
"name": {"type": "str", "required": True},
|
||||
"image": {"type": "str", "required": True},
|
||||
"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"]
|
||||
def apply_base(state: State, params: dict[str, Any]) -> State:
|
||||
project_name = state.module.params["name"]
|
||||
|
||||
new: dict[str, Any] = {
|
||||
"service_name": f"{project_name}_{service_name}",
|
||||
"hostname": f"{project_name}_{service_name}",
|
||||
"image": image,
|
||||
"container_name": f"{project_name}_{params["name"]}",
|
||||
"hostname": f"{project_name}_{params["name"]}",
|
||||
"image": params["image"],
|
||||
"restart": "unless-stopped",
|
||||
"environment": {},
|
||||
"labels": {},
|
||||
"volumes": [],
|
||||
"networks": {
|
||||
f"{project_name}_internal": None,
|
||||
"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"]
|
||||
def set_defaults(state: State, params: dict[str, Any]) -> State:
|
||||
container_name = params["name"]
|
||||
defaults = params.get("defaults", {})
|
||||
project = copy.deepcopy(state.after)
|
||||
services = project["services"]
|
||||
service = services[container_name]
|
||||
|
@ -72,7 +58,6 @@ def set_defaults(state: State) -> State:
|
|||
|
||||
|
||||
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"]
|
||||
|
||||
|
@ -81,14 +66,12 @@ def update(state: State, update: dict[str, Any]) -> State:
|
|||
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)
|
||||
def run_helper(
|
||||
state: State,
|
||||
params: dict[str, Any],
|
||||
helper: Callable[[State, dict[str, Any]], State] = lambda x, _: x,
|
||||
) -> State:
|
||||
state = apply_base(state, params)
|
||||
state = set_defaults(state, params)
|
||||
state = helper(state, params)
|
||||
return update_project(state)
|
||||
|
|
|
@ -4,70 +4,34 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.common import (
|
||||
finish,
|
||||
get_state,
|
||||
update_project,
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.service import ( # type: ignore[reportMissingTypeStubs]
|
||||
common as service,
|
||||
)
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.service import common as service
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.common import State
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.common import ( # type: ignore[reportMissingTypeStubs]
|
||||
State,
|
||||
)
|
||||
|
||||
def helper(state: State) -> State:
|
||||
project_name = state.module.params["project_name"]
|
||||
definition = state.module.params["definition"]
|
||||
internal_network = state.module.params.get("internal_network", False)
|
||||
EXTRA_ARGS = {
|
||||
"internal_network": {"type": "bool", "default": False},
|
||||
"definition": {"type": "dict", "required": True},
|
||||
}
|
||||
|
||||
|
||||
def helper(state: State, params: dict[str, Any]) -> State:
|
||||
definition = params["definition"]
|
||||
internal_network = params["internal_network"]
|
||||
|
||||
update = copy.deepcopy(definition)
|
||||
|
||||
networks = update.get("networks", {})
|
||||
|
||||
if internal_network:
|
||||
networks[f"{project_name}_internal"] = None
|
||||
networks["internal"] = None
|
||||
|
||||
update["networks"] = networks
|
||||
|
||||
return service.update(state, update)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec={
|
||||
"project_name": {
|
||||
"type": "str",
|
||||
"required": True,
|
||||
},
|
||||
"name": {
|
||||
"type": "str",
|
||||
"required": True,
|
||||
},
|
||||
"internal_network": {
|
||||
"type": "bool",
|
||||
},
|
||||
"state": {
|
||||
"type": "str",
|
||||
"default": "present",
|
||||
"choices": ["present", "absent"],
|
||||
},
|
||||
"definition": {
|
||||
"type": "dict",
|
||||
"required": True,
|
||||
},
|
||||
},
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
state = get_state(module)
|
||||
|
||||
for f in [helper, update_project]:
|
||||
state = f(state)
|
||||
|
||||
finish(state)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -3,15 +3,24 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.service import common as service
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.service import ( # type: ignore[reportMissingTypeStubs]
|
||||
common as service,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.common import State
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.common import ( # type: ignore[reportMissingTypeStubs]
|
||||
State,
|
||||
)
|
||||
|
||||
def helper(state: State) -> State:
|
||||
command = state.module.params.get("command")
|
||||
EXTRA_ARGS = {
|
||||
"command": {"type": "list"},
|
||||
}
|
||||
|
||||
|
||||
def helper(state: State, params: dict[str, Any]) -> State:
|
||||
command = params.get("command")
|
||||
|
||||
update = {
|
||||
"privileged": True,
|
||||
|
@ -21,14 +30,3 @@ def helper(state: State) -> State:
|
|||
update["command"] = command
|
||||
|
||||
return service.update(state, update)
|
||||
|
||||
|
||||
def main():
|
||||
extra_args = {
|
||||
"command": {"type": "list"},
|
||||
}
|
||||
service.run(extra_args, helper)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -3,16 +3,24 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.service import common as service
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.service import ( # type: ignore[reportMissingTypeStubs]
|
||||
common as service,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.common import State
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.common import ( # type: ignore[reportMissingTypeStubs]
|
||||
State,
|
||||
)
|
||||
|
||||
EXTRA_ARGS = {
|
||||
"read_only": {"type": "bool"},
|
||||
}
|
||||
|
||||
|
||||
def helper(state: State) -> State:
|
||||
read_only = state.module.params.get("read_only", True)
|
||||
def helper(state: State, params: dict[str, Any]) -> State:
|
||||
read_only = params.get("read_only", True)
|
||||
|
||||
volumes = [
|
||||
{
|
||||
|
@ -20,7 +28,7 @@ def helper(state: State) -> State:
|
|||
"source": "/var/run/docker.sock",
|
||||
"target": "/var/run/docker.sock",
|
||||
"read_only": read_only,
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
update = {
|
||||
|
@ -28,14 +36,3 @@ def helper(state: State) -> State:
|
|||
}
|
||||
|
||||
return service.update(state, update)
|
||||
|
||||
|
||||
def main():
|
||||
extra_args = {
|
||||
"read_only": {"type": "bool"},
|
||||
}
|
||||
service.run(extra_args, helper)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -3,19 +3,28 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.service import common as service
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.service import ( # type: ignore[reportMissingTypeStubs]
|
||||
common as service,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.common import State
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.common import ( # type: ignore[reportMissingTypeStubs]
|
||||
State,
|
||||
)
|
||||
|
||||
EXTRA_ARGS = {
|
||||
"archive": {"type": "str"},
|
||||
"backup_volumes": {"type": "list"},
|
||||
}
|
||||
|
||||
|
||||
def helper(state: State) -> State:
|
||||
archive = state.module.params.get("archive")
|
||||
backup_volumes = state.module.params.get("backup_volumes", [])
|
||||
service_name = state.module.params["name"]
|
||||
project_name = state.module.params["project_name"]
|
||||
def helper(state: State, params: dict[str, Any]) -> State:
|
||||
archive = params.get("archive")
|
||||
backup_volumes = params.get("backup_volumes", [])
|
||||
service_name = params["name"]
|
||||
project_name = params["project_name"]
|
||||
|
||||
volumes = [
|
||||
{
|
||||
|
@ -43,7 +52,7 @@ def helper(state: State) -> State:
|
|||
"source": f"{archive}/{project_name}",
|
||||
"target": "/archive",
|
||||
"bind": {"create_host_path": True},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
update = {
|
||||
|
@ -52,15 +61,3 @@ def helper(state: State) -> State:
|
|||
}
|
||||
|
||||
return service.update(state, update)
|
||||
|
||||
|
||||
def main():
|
||||
extra_args = {
|
||||
"archive": {"type": "str"},
|
||||
"backup_volumes": {"type": "list"},
|
||||
}
|
||||
service.run(extra_args, helper)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -4,22 +4,34 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import shlex
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.service import common as service
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.service import ( # type: ignore[reportMissingTypeStubs]
|
||||
common as service,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.common import State
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.common import ( # type: ignore[reportMissingTypeStubs]
|
||||
State,
|
||||
)
|
||||
|
||||
EXTRA_ARGS = {
|
||||
"archive": {"type": "bool"},
|
||||
"database": {"type": "str", "required": True},
|
||||
"username": {"type": "str", "required": True},
|
||||
"password": {"type": "str", "required": True},
|
||||
"root_password": {"type": "str"},
|
||||
}
|
||||
|
||||
|
||||
def helper(state: State) -> State:
|
||||
backup = state.module.params.get("backup", True)
|
||||
database = state.module.params["database"]
|
||||
username = state.module.params["username"]
|
||||
password = state.module.params["password"]
|
||||
root_password = state.module.params["root_password"]
|
||||
service_name = state.module.params["name"]
|
||||
project_name = state.module.params["project_name"]
|
||||
def helper(state: State, params: dict[str, Any]) -> State:
|
||||
backup = params.get("backup", True)
|
||||
database = params["database"]
|
||||
username = params["username"]
|
||||
password = params["password"]
|
||||
root_password = params["root_password"]
|
||||
service_name = params["name"]
|
||||
project_name = params["project_name"]
|
||||
|
||||
volumes = [
|
||||
{
|
||||
|
@ -73,18 +85,3 @@ def helper(state: State) -> State:
|
|||
}
|
||||
|
||||
return service.update(state, update)
|
||||
|
||||
|
||||
def main():
|
||||
extra_args = {
|
||||
"archive": {"type": "bool"},
|
||||
"database": {"type": "str", "required": True},
|
||||
"username": {"type": "str", "required": True},
|
||||
"password": {"type": "str", "required": True},
|
||||
"root_password": {"type": "str"},
|
||||
}
|
||||
service.run(extra_args, helper)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -4,21 +4,32 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import shlex
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.service import common as service
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.service import ( # type: ignore[reportMissingTypeStubs]
|
||||
common as service,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.common import State
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.common import ( # type: ignore[reportMissingTypeStubs]
|
||||
State,
|
||||
)
|
||||
|
||||
EXTRA_ARGS = {
|
||||
"archive": {"type": "bool"},
|
||||
"database": {"type": "str", "required": True},
|
||||
"username": {"type": "str", "required": True},
|
||||
"password": {"type": "str", "required": True},
|
||||
}
|
||||
|
||||
|
||||
def helper(state: State) -> State:
|
||||
backup = state.module.params.get("backup", True)
|
||||
database = state.module.params["database"]
|
||||
username = state.module.params["username"]
|
||||
password = state.module.params["password"]
|
||||
service_name = state.module.params["name"]
|
||||
project_name = state.module.params["project_name"]
|
||||
def helper(state: State, params: dict[str, Any]) -> State:
|
||||
backup = params.get("backup", True)
|
||||
database = params["database"]
|
||||
username = params["username"]
|
||||
password = params["password"]
|
||||
service_name = params["name"]
|
||||
project_name = params["project_name"]
|
||||
|
||||
volumes = [
|
||||
{
|
||||
|
@ -65,17 +76,3 @@ def helper(state: State) -> State:
|
|||
}
|
||||
|
||||
return service.update(state, update)
|
||||
|
||||
|
||||
def main():
|
||||
extra_args = {
|
||||
"archive": {"type": "bool"},
|
||||
"database": {"type": "str", "required": True},
|
||||
"username": {"type": "str", "required": True},
|
||||
"password": {"type": "str", "required": True},
|
||||
}
|
||||
service.run(extra_args, helper)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.service import common as service
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.common import ( # type: ignore[reportMissingTypeStubs]
|
||||
State,
|
||||
)
|
||||
|
||||
EXTRA_ARGS = {}
|
||||
|
||||
|
||||
def main():
|
||||
service.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
def helper(state: State) -> State:
|
||||
return state
|
||||
|
|
79
plugins/modules/compose.py
Normal file
79
plugins/modules/compose.py
Normal file
|
@ -0,0 +1,79 @@
|
|||
# Copyright: (c) 2024, Luca Bilke <luca@bil.ke>
|
||||
# MIT License (see LICENSE)
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule # type: ignore[reportMissingStubFile]
|
||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils import ( # type: ignore[reportMissingStubFile]
|
||||
common,
|
||||
label,
|
||||
service,
|
||||
)
|
||||
|
||||
|
||||
def label_argument_spec() -> dict[str, Any]:
|
||||
label_args: dict[str, Any] = {
|
||||
"type": "dict",
|
||||
"options": {},
|
||||
}
|
||||
|
||||
for module in label.__all__:
|
||||
if module == "common":
|
||||
continue
|
||||
|
||||
options = {
|
||||
**label.common.BASE_ARGS,
|
||||
**getattr(label, module).EXTRA_ARGS,
|
||||
}
|
||||
|
||||
label_args["options"][module] = {
|
||||
"type": "dict",
|
||||
"options": options,
|
||||
}
|
||||
|
||||
return label_args
|
||||
|
||||
|
||||
def service_argument_spec() -> dict[str, Any]:
|
||||
service_args: dict[str, Any] = {
|
||||
"type": "dict",
|
||||
"options": {},
|
||||
"required": True,
|
||||
}
|
||||
|
||||
for module in service.__all__:
|
||||
if module == "common":
|
||||
continue
|
||||
|
||||
options = {
|
||||
**service.common.BASE_ARGS,
|
||||
**getattr(service, module).EXTRA_ARGS,
|
||||
}
|
||||
|
||||
if module == "custom":
|
||||
options["label_helpers"] = label_argument_spec()
|
||||
|
||||
service_args["options"][module] = {
|
||||
"type": "list",
|
||||
"elements": "dict",
|
||||
"options": options,
|
||||
}
|
||||
|
||||
return service_args
|
||||
|
||||
|
||||
def main() -> None:
|
||||
module = AnsibleModule(
|
||||
argument_spec={
|
||||
**common.BASE_ARGS,
|
||||
"services": service_argument_spec(),
|
||||
},
|
||||
)
|
||||
|
||||
state = common.get_state(module)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -5,7 +5,7 @@ output-format = "grouped"
|
|||
|
||||
[tool.ruff.lint]
|
||||
select = ["ALL"]
|
||||
ignore = ["ERA001", "TD002", "TD003"]
|
||||
ignore = ["ERA001", "TD002", "TD003", "INP001", "D100", "D101", "D103", "D104"]
|
||||
|
||||
[tool.ruff.format]
|
||||
line-ending = "lf"
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
ansible-core==2.17.*
|
||||
pydantic==2.9.*
|
||||
|
|
Loading…
Add table
Reference in a new issue