WIP
This commit is contained in:
parent
0575d65e90
commit
edce5ceee0
8 changed files with 269 additions and 25 deletions
plugins
module_utils
label
service
modules
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Callable
|
from typing import TYPE_CHECKING, Any, Callable
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.common import (
|
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.common import (
|
||||||
|
@ -11,9 +11,7 @@ if TYPE_CHECKING:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
BASE_ARGS = {
|
BASE_ARGS: dict[str, Any] = {}
|
||||||
"name": {"type": "str", "required": True},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def run_helper(
|
def run_helper(
|
||||||
|
|
|
@ -13,8 +13,8 @@ if TYPE_CHECKING:
|
||||||
)
|
)
|
||||||
|
|
||||||
EXTRA_ARGS = {
|
EXTRA_ARGS = {
|
||||||
"proxy_type": {"type": "str"},
|
"proxy_type": {"type": "str", "default": "http"},
|
||||||
"middleware_name": {"type": "string"},
|
"name": {"type": "string"},
|
||||||
"middleware": {"type": "str", "required": True},
|
"middleware": {"type": "str", "required": True},
|
||||||
"settings": {"type": "list", "required": True},
|
"settings": {"type": "list", "required": True},
|
||||||
}
|
}
|
||||||
|
@ -24,13 +24,13 @@ def helper(state: State, service_name: str, params: dict[str, Any]) -> State:
|
||||||
project_name: str = state.module.params["name"]
|
project_name: str = state.module.params["name"]
|
||||||
middleware: str = params["middleware"]
|
middleware: str = params["middleware"]
|
||||||
settings: dict[str, str] = params["settings"]
|
settings: dict[str, str] = params["settings"]
|
||||||
proxy_type: str = state.module.params.get("proxy_type", "http")
|
proxy_type: str = state.module.params["proxy_type"]
|
||||||
middleware_name: str = state.module.params.get(
|
name: str = state.module.params.get(
|
||||||
"middleware_name",
|
"name",
|
||||||
f"{project_name}_{service_name}_{proxy_type}_{middleware.lower()}",
|
f"{project_name}_{service_name}_{proxy_type}_{middleware.lower()}",
|
||||||
)
|
)
|
||||||
|
|
||||||
prefix = f"traefik.{proxy_type}.middlewares.{middleware_name}"
|
prefix = f"traefik.{proxy_type}.middlewares.{name}"
|
||||||
|
|
||||||
labels = {f"{prefix}.{middleware}.{key}": var for key, var in settings.items()}
|
labels = {f"{prefix}.{middleware}.{key}": var for key, var in settings.items()}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ if TYPE_CHECKING:
|
||||||
)
|
)
|
||||||
|
|
||||||
EXTRA_ARGS = {
|
EXTRA_ARGS = {
|
||||||
"router_name": {"type": "str"},
|
"name": {"type": "str"},
|
||||||
"rule": {"type": "str", "required": True},
|
"rule": {"type": "str", "required": True},
|
||||||
"proxy_type": {"type": "str", "default": "http"},
|
"proxy_type": {"type": "str", "default": "http"},
|
||||||
"service": {"type": "str"},
|
"service": {"type": "str"},
|
||||||
|
@ -31,12 +31,12 @@ def helper(state: State, service_name: str, params: dict[str, Any]) -> State:
|
||||||
middlewares: list[str] | None = params.get("middlewares")
|
middlewares: list[str] | None = params.get("middlewares")
|
||||||
certresolver: str | None = params.get("certresolver")
|
certresolver: str | None = params.get("certresolver")
|
||||||
proxy_type: str = params["proxy_type"]
|
proxy_type: str = params["proxy_type"]
|
||||||
router_name: str = params.get(
|
name: str = params.get(
|
||||||
"router_name",
|
"name",
|
||||||
f"{project_name}_{service_name}_{proxy_type}",
|
f"{project_name}_{service_name}_{proxy_type}",
|
||||||
)
|
)
|
||||||
|
|
||||||
prefix = f"traefik.{proxy_type}.routers.{router_name}"
|
prefix = f"traefik.{proxy_type}.routers.{name}"
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
"traefik.enable": True,
|
"traefik.enable": True,
|
||||||
|
|
|
@ -14,7 +14,7 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
EXTRA_ARGS = {
|
EXTRA_ARGS = {
|
||||||
"proxy_type": {"type": "str", "default": "http"},
|
"proxy_type": {"type": "str", "default": "http"},
|
||||||
"service_name": {"type": "string"},
|
"name": {"type": "string"},
|
||||||
"port": {"type": "int"},
|
"port": {"type": "int"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,12 +23,12 @@ def helper(state: State, service_name: str, params: dict[str, Any]) -> State:
|
||||||
project_name: str = state.module.params["name"]
|
project_name: str = state.module.params["name"]
|
||||||
port: int | None = params.get("port")
|
port: int | None = params.get("port")
|
||||||
proxy_type: str = params["proxy_type"]
|
proxy_type: str = params["proxy_type"]
|
||||||
traefik_service_name: str = params.get(
|
name: str = params.get(
|
||||||
"service_name",
|
"name",
|
||||||
f"{project_name}_{service_name}_{proxy_type}",
|
f"{project_name}_{service_name}_{proxy_type}",
|
||||||
)
|
)
|
||||||
|
|
||||||
prefix = f"traefik.{proxy_type}.services.{traefik_service_name}"
|
prefix = f"traefik.{proxy_type}.services.{name}"
|
||||||
|
|
||||||
labels: dict[str, Any] = {}
|
labels: dict[str, Any] = {}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ if TYPE_CHECKING:
|
||||||
State,
|
State,
|
||||||
)
|
)
|
||||||
|
|
||||||
BASE_ARGS = {
|
BASE_ARGS: dict[str, Any] = {
|
||||||
"name": {"type": "str", "required": True},
|
"name": {"type": "str", "required": True},
|
||||||
"image": {"type": "str", "required": True},
|
"image": {"type": "str", "required": True},
|
||||||
"defaults": {"type": "dict"},
|
"defaults": {"type": "dict"},
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import copy
|
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils import (
|
from ansible_collections.ssnailed.ez_compose.plugins.module_utils import (
|
||||||
|
@ -19,15 +18,13 @@ if TYPE_CHECKING:
|
||||||
# NOTE: Label helper arguments are added in the compose module itself
|
# NOTE: Label helper arguments are added in the compose module itself
|
||||||
EXTRA_ARGS = {
|
EXTRA_ARGS = {
|
||||||
"internal_network": {"type": "bool", "default": False},
|
"internal_network": {"type": "bool", "default": False},
|
||||||
"definition": {"type": "dict", "required": True},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def helper(state: State, params: dict[str, Any]) -> State:
|
def helper(state: State, params: dict[str, Any]) -> State:
|
||||||
definition: dict[str, Any] = params["definition"]
|
|
||||||
internal_network: bool = params["internal_network"]
|
internal_network: bool = params["internal_network"]
|
||||||
|
|
||||||
update = copy.deepcopy(definition)
|
update: dict[str, Any] = {}
|
||||||
|
|
||||||
networks = update.get("networks", {})
|
networks = update.get("networks", {})
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ if TYPE_CHECKING:
|
||||||
)
|
)
|
||||||
|
|
||||||
EXTRA_ARGS = {
|
EXTRA_ARGS = {
|
||||||
"archive": {"type": "str"},
|
"archive": {"type": "path"},
|
||||||
"backup_volumes": {"type": "list", "elements": "str"},
|
"backup_volumes": {"type": "list", "elements": "str"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,11 +41,11 @@ def helper(state: State, params: dict[str, Any]) -> State:
|
||||||
"BACKUP_LATEST_SYMLINK": f"{project_name}-latest",
|
"BACKUP_LATEST_SYMLINK": f"{project_name}-latest",
|
||||||
"BACKUP_PRUNING_PREFIX": f"{project_name}-",
|
"BACKUP_PRUNING_PREFIX": f"{project_name}-",
|
||||||
"BACKUP_STOP_DURING_BACKUP_LABEL": project_name,
|
"BACKUP_STOP_DURING_BACKUP_LABEL": project_name,
|
||||||
"BACKUP_ARCHIVE": "/archive",
|
|
||||||
"DOCKER_HOST": f"tcp://{project_name}_{service_name}_socket_proxy:2375",
|
"DOCKER_HOST": f"tcp://{project_name}_{service_name}_socket_proxy:2375",
|
||||||
}
|
}
|
||||||
|
|
||||||
if archive:
|
if archive:
|
||||||
|
environment["BACKUP_ARCHIVE"] = "/archive"
|
||||||
volumes.append(
|
volumes.append(
|
||||||
{
|
{
|
||||||
"type": "bind",
|
"type": "bind",
|
||||||
|
|
249
plugins/modules/compose.py
Normal file → Executable file
249
plugins/modules/compose.py
Normal file → Executable file
|
@ -1,8 +1,256 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# Copyright: (c) 2024, Luca Bilke <luca@bil.ke>
|
# Copyright: (c) 2024, Luca Bilke <luca@bil.ke>
|
||||||
# MIT License (see LICENSE)
|
# MIT License (see LICENSE)
|
||||||
|
# ruff: noqa: E402
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
SERVICE_BASE_DOCS = """
|
||||||
|
type: dict
|
||||||
|
suboptions:
|
||||||
|
name:
|
||||||
|
description:
|
||||||
|
- Name of the service.
|
||||||
|
type: str
|
||||||
|
image:
|
||||||
|
description:
|
||||||
|
- Image to use for service.
|
||||||
|
type: str
|
||||||
|
defaults:
|
||||||
|
description:
|
||||||
|
- Service definition to be overwritten.
|
||||||
|
type: dict
|
||||||
|
overwrite:
|
||||||
|
description:
|
||||||
|
- Service definition to overwrite with.
|
||||||
|
type: dict
|
||||||
|
"""
|
||||||
|
|
||||||
|
LABEL_BASE_DOCS = """
|
||||||
|
type: dict
|
||||||
|
suboptions:
|
||||||
|
"""
|
||||||
|
|
||||||
|
DOCUMENTATION = f"""
|
||||||
|
---
|
||||||
|
module: compose
|
||||||
|
short_description: Simplify docker-compose deployments
|
||||||
|
description:
|
||||||
|
- Easily create docker-compose files using a single module
|
||||||
|
author:
|
||||||
|
- "Luca Bilke (@ssnailed)"
|
||||||
|
attributes:
|
||||||
|
check_mode:
|
||||||
|
support: full
|
||||||
|
diff_mode:
|
||||||
|
support: full
|
||||||
|
options:
|
||||||
|
name:
|
||||||
|
description:
|
||||||
|
- Name of the compose project to create or modify.
|
||||||
|
aliases: [project]
|
||||||
|
type: str
|
||||||
|
project_dir:
|
||||||
|
description:
|
||||||
|
- Path to store project directory under.
|
||||||
|
type: path
|
||||||
|
services:
|
||||||
|
description:
|
||||||
|
- Services to create in the project.
|
||||||
|
type: list
|
||||||
|
elements: dict
|
||||||
|
suboptions:
|
||||||
|
custom:
|
||||||
|
description:
|
||||||
|
- Custom service definition.
|
||||||
|
{SERVICE_BASE_DOCS}
|
||||||
|
internal_network:
|
||||||
|
description:
|
||||||
|
- If true, add internal network to service.
|
||||||
|
type: bool
|
||||||
|
default: false
|
||||||
|
label_helpers:
|
||||||
|
description:
|
||||||
|
- Label helper configurations.
|
||||||
|
type: dict
|
||||||
|
suboptions:
|
||||||
|
docker_volume_backupper:
|
||||||
|
description:
|
||||||
|
- Docker Volume Backupper label helper configuration.
|
||||||
|
{LABEL_BASE_DOCS}
|
||||||
|
stop:
|
||||||
|
description:
|
||||||
|
- If true, stop the container when backing up.
|
||||||
|
type: bool
|
||||||
|
default: true
|
||||||
|
traefik_middleware:
|
||||||
|
description:
|
||||||
|
- Traefik Middleware label helper configuration.
|
||||||
|
{LABEL_BASE_DOCS}
|
||||||
|
proxy_type:
|
||||||
|
description:
|
||||||
|
- Traefik proxy type.
|
||||||
|
type: str
|
||||||
|
choices: [http, tcp, udp]
|
||||||
|
default: http
|
||||||
|
name:
|
||||||
|
description:
|
||||||
|
- Name of the middleware.
|
||||||
|
- Default is generated dynamically like so:
|
||||||
|
- [project_name]_[service_name]_[proxy_type]_[middleware]
|
||||||
|
type: string
|
||||||
|
middleware:
|
||||||
|
description:
|
||||||
|
- The traefik middleware to use.
|
||||||
|
type: str
|
||||||
|
required: true
|
||||||
|
settings:
|
||||||
|
description:
|
||||||
|
- Middleware options.
|
||||||
|
type: dict
|
||||||
|
required: true
|
||||||
|
traefik_router:
|
||||||
|
description:
|
||||||
|
- Traefik Router label helper configuration.
|
||||||
|
{LABEL_BASE_DOCS}
|
||||||
|
proxy_type:
|
||||||
|
description:
|
||||||
|
- Traefik proxy type.
|
||||||
|
type: str
|
||||||
|
choices: [http, tcp, udp]
|
||||||
|
default: http
|
||||||
|
name:
|
||||||
|
description:
|
||||||
|
- Name of the middleware.
|
||||||
|
- Default is generated dynamically like so:
|
||||||
|
- [project_name]_[service_name]_[proxy_type]
|
||||||
|
type: string
|
||||||
|
rule:
|
||||||
|
description:
|
||||||
|
- Routing rule to match.
|
||||||
|
type: str
|
||||||
|
required: true
|
||||||
|
service:
|
||||||
|
description:
|
||||||
|
- Traefik service to point at.
|
||||||
|
type: str
|
||||||
|
certresolver:
|
||||||
|
description:
|
||||||
|
- Certresolver to use.
|
||||||
|
type: str
|
||||||
|
entrypoints:
|
||||||
|
description:
|
||||||
|
- Entrypoints to listen on.
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
middlewares:
|
||||||
|
description:
|
||||||
|
- Middlewares to use.
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
traefik_service:
|
||||||
|
description:
|
||||||
|
- Traefik Service label helper configuration.
|
||||||
|
{LABEL_BASE_DOCS}
|
||||||
|
proxy_type:
|
||||||
|
description:
|
||||||
|
- Traefik proxy type.
|
||||||
|
type: str
|
||||||
|
choices: [http, tcp, udp]
|
||||||
|
default: http
|
||||||
|
name:
|
||||||
|
description:
|
||||||
|
- Name of the middleware.
|
||||||
|
- Default is generated dynamically like so:
|
||||||
|
- [project_name]_[service_name]_[proxy_type]
|
||||||
|
type: string
|
||||||
|
port:
|
||||||
|
description:
|
||||||
|
- Port to forward to.
|
||||||
|
type: int
|
||||||
|
docker_in_docker:
|
||||||
|
description:
|
||||||
|
- Docker-in-Docker service definition.
|
||||||
|
{SERVICE_BASE_DOCS}
|
||||||
|
docker_socket_proxy:
|
||||||
|
description:
|
||||||
|
- Docker Socket Proxy service definition.
|
||||||
|
{SERVICE_BASE_DOCS}
|
||||||
|
read_only:
|
||||||
|
description:
|
||||||
|
- If true, only allow read access to the docker socket.
|
||||||
|
type: bool
|
||||||
|
default: true
|
||||||
|
docker_volume_backupper:
|
||||||
|
description:
|
||||||
|
- Docker Socket Proxy service definition.
|
||||||
|
{SERVICE_BASE_DOCS}
|
||||||
|
archive:
|
||||||
|
description:
|
||||||
|
- Directory to store backups in.
|
||||||
|
type: path
|
||||||
|
backup_volumes:
|
||||||
|
description:
|
||||||
|
- List of volume names of volumes to backup.
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
mariadb:
|
||||||
|
description:
|
||||||
|
- MariaDB service definition.
|
||||||
|
{SERVICE_BASE_DOCS}
|
||||||
|
backup:
|
||||||
|
description:
|
||||||
|
- If true, add labels for the docker volume backupper.
|
||||||
|
type: bool
|
||||||
|
database:
|
||||||
|
description:
|
||||||
|
- Name of database.
|
||||||
|
type: str
|
||||||
|
required: true
|
||||||
|
username:
|
||||||
|
description:
|
||||||
|
- Username for database.
|
||||||
|
type: str
|
||||||
|
required: true
|
||||||
|
password:
|
||||||
|
description:
|
||||||
|
- Password for database.
|
||||||
|
type: str
|
||||||
|
required: true
|
||||||
|
root_password:
|
||||||
|
description:
|
||||||
|
- Root password for database.
|
||||||
|
type: str
|
||||||
|
postgres:
|
||||||
|
description:
|
||||||
|
- PostgreSQL service definition.
|
||||||
|
{SERVICE_BASE_DOCS}
|
||||||
|
backup:
|
||||||
|
description:
|
||||||
|
- If true, add labels for the docker volume backupper.
|
||||||
|
type: bool
|
||||||
|
database:
|
||||||
|
description:
|
||||||
|
- Name of database.
|
||||||
|
type: str
|
||||||
|
required: true
|
||||||
|
username:
|
||||||
|
description:
|
||||||
|
- Username for database.
|
||||||
|
type: str
|
||||||
|
required: true
|
||||||
|
password:
|
||||||
|
description:
|
||||||
|
- Password for database.
|
||||||
|
type: str
|
||||||
|
required: true
|
||||||
|
redis:
|
||||||
|
description:
|
||||||
|
- Redis service definition.
|
||||||
|
{SERVICE_BASE_DOCS}
|
||||||
|
""" # noqa: E501
|
||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule # type: ignore[reportMissingStubFile]
|
from ansible.module_utils.basic import AnsibleModule # type: ignore[reportMissingStubFile]
|
||||||
|
@ -68,6 +316,7 @@ def main() -> None:
|
||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
argument_spec={
|
argument_spec={
|
||||||
"name": {
|
"name": {
|
||||||
|
"aliases": ["project"],
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"required": True,
|
"required": True,
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue