WIP
This commit is contained in:
parent
edce5ceee0
commit
508a9db2f2
16 changed files with 674 additions and 90 deletions
|
@ -5,7 +5,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
import ansible_collections.ssnailed.ez_compose.plugins.module_utils.service.common as service
|
from ansible_collections.ssnailed.ez_compose.plugins.module_utils import service
|
||||||
|
|
||||||
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 (
|
||||||
|
@ -28,4 +28,4 @@ def helper(state: State, service_name: str, params: dict[str, Any]) -> State:
|
||||||
"docker-volume-backup.stop-during-backup": project_name,
|
"docker-volume-backup.stop-during-backup": project_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
return service.update(service_name, state, update)
|
return service.common.update(state, {"name": service_name}, update)
|
||||||
|
|
|
@ -5,7 +5,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
import ansible_collections.ssnailed.ez_compose.plugins.module_utils.service.common as service
|
from ansible_collections.ssnailed.ez_compose.plugins.module_utils import service
|
||||||
|
|
||||||
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 (
|
||||||
|
@ -38,4 +38,4 @@ def helper(state: State, service_name: str, params: dict[str, Any]) -> State:
|
||||||
"labels": labels,
|
"labels": labels,
|
||||||
}
|
}
|
||||||
|
|
||||||
return service.update(service_name, state, update)
|
return service.common.update(state, {"name": service_name}, update)
|
||||||
|
|
|
@ -5,7 +5,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
import ansible_collections.ssnailed.ez_compose.plugins.module_utils.service.common as service
|
from ansible_collections.ssnailed.ez_compose.plugins.module_utils import service
|
||||||
|
|
||||||
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 (
|
||||||
|
@ -59,4 +59,4 @@ def helper(state: State, service_name: str, params: dict[str, Any]) -> State:
|
||||||
"labels": labels,
|
"labels": labels,
|
||||||
}
|
}
|
||||||
|
|
||||||
return service.update(service_name, state, update)
|
return service.common.update(state, {"name": service_name}, update)
|
||||||
|
|
|
@ -5,7 +5,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
import ansible_collections.ssnailed.ez_compose.plugins.module_utils.service.common as service
|
from ansible_collections.ssnailed.ez_compose.plugins.module_utils import service
|
||||||
|
|
||||||
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 (
|
||||||
|
@ -39,4 +39,4 @@ def helper(state: State, service_name: str, params: dict[str, Any]) -> State:
|
||||||
"labels": labels,
|
"labels": labels,
|
||||||
}
|
}
|
||||||
|
|
||||||
return service.update(service_name, state, update)
|
return service.common.update(state, {"name": service_name}, update)
|
||||||
|
|
|
@ -20,7 +20,6 @@ if TYPE_CHECKING:
|
||||||
BASE_ARGS: dict[str, Any] = {
|
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"},
|
|
||||||
"overwrite": {"type": "dict"},
|
"overwrite": {"type": "dict"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,18 +35,16 @@ def apply_base(state: State, params: dict[str, Any]) -> State:
|
||||||
"environment": {},
|
"environment": {},
|
||||||
"labels": {},
|
"labels": {},
|
||||||
"volumes": [],
|
"volumes": [],
|
||||||
"networks": {
|
"networks": {
|
||||||
"internal": None,
|
"internal": None,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return update(params["name"], state, new)
|
return update(state, params, new)
|
||||||
|
|
||||||
|
|
||||||
def set_definition(state: State, params: dict[str, Any], param_name: str) -> State:
|
def apply_definition(state: State, params: dict[str, Any], definition: dict[str, Any]) -> State:
|
||||||
service_name: str = params["name"]
|
service_name: str = params["name"]
|
||||||
definition: dict[str, Any] = params.get(param_name, {})
|
|
||||||
|
|
||||||
project = copy.deepcopy(state.after)
|
project = copy.deepcopy(state.after)
|
||||||
services: dict[str, Any] = project["services"]
|
services: dict[str, Any] = project["services"]
|
||||||
service: dict[str, Any] = services[service_name]
|
service: dict[str, Any] = services[service_name]
|
||||||
|
@ -59,7 +56,15 @@ def set_definition(state: State, params: dict[str, Any], param_name: str) -> Sta
|
||||||
return replace(state, after=project)
|
return replace(state, after=project)
|
||||||
|
|
||||||
|
|
||||||
def update(service_name: str, state: State, update: dict[str, Any]) -> State:
|
def apply_settings(state: State, params: dict[str, Any]) -> State:
|
||||||
|
update = (
|
||||||
|
state.module.params.get("settings", {}).get("service_defaults", {}).get(params["name"], {})
|
||||||
|
)
|
||||||
|
return update(state, params, update)
|
||||||
|
|
||||||
|
|
||||||
|
def update(state: State, params: dict[str, Any], update: dict[str, Any]) -> State:
|
||||||
|
service_name: str = params["name"]
|
||||||
project = copy.deepcopy(state.after)
|
project = copy.deepcopy(state.after)
|
||||||
|
|
||||||
_ = recursive_update(project["services"][service_name], update)
|
_ = recursive_update(project["services"][service_name], update)
|
||||||
|
@ -73,7 +78,7 @@ def run_helper(
|
||||||
helper: Callable[[State, dict[str, Any]], State] = lambda x, _: x,
|
helper: Callable[[State, dict[str, Any]], State] = lambda x, _: x,
|
||||||
) -> State:
|
) -> State:
|
||||||
state = apply_base(state, params)
|
state = apply_base(state, params)
|
||||||
state = set_definition(state, params, "defaults")
|
state = apply_settings(state, params)
|
||||||
state = helper(state, params)
|
state = helper(state, params)
|
||||||
state = set_definition(state, params, "overwrite")
|
state = apply_definition(state, params, params.get("overwrite", {}))
|
||||||
return update_project(state)
|
return update_project(state)
|
||||||
|
|
|
@ -36,4 +36,4 @@ def helper(state: State, params: dict[str, Any]) -> State:
|
||||||
for name, args in params["label_helpers"].items():
|
for name, args in params["label_helpers"].items():
|
||||||
state = getattr(label, name).helper(state, params["name"], args)
|
state = getattr(label, name).helper(state, params["name"], args)
|
||||||
|
|
||||||
return service.common.update(params["name"], state, update)
|
return service.common.update(state, params, update)
|
||||||
|
|
|
@ -5,9 +5,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.service import (
|
from ansible_collections.ssnailed.ez_compose.plugins.module_utils import service
|
||||||
common as service,
|
|
||||||
)
|
|
||||||
|
|
||||||
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 (
|
||||||
|
@ -22,4 +20,4 @@ def helper(state: State, params: dict[str, Any]) -> State:
|
||||||
"privileged": True,
|
"privileged": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
return service.update(params["name"], state, update)
|
return service.common.update(state, params, update)
|
||||||
|
|
|
@ -5,9 +5,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.service import (
|
from ansible_collections.ssnailed.ez_compose.plugins.module_utils import service
|
||||||
common as service,
|
|
||||||
)
|
|
||||||
|
|
||||||
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 (
|
||||||
|
@ -35,4 +33,4 @@ def helper(state: State, params: dict[str, Any]) -> State:
|
||||||
"volumes": volumes,
|
"volumes": volumes,
|
||||||
}
|
}
|
||||||
|
|
||||||
return service.update(params["name"], state, update)
|
return service.common.update(state, params, update)
|
||||||
|
|
|
@ -5,9 +5,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.service import (
|
from ansible_collections.ssnailed.ez_compose.plugins.module_utils import service
|
||||||
common as service,
|
|
||||||
)
|
|
||||||
|
|
||||||
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 (
|
||||||
|
@ -60,4 +58,4 @@ def helper(state: State, params: dict[str, Any]) -> State:
|
||||||
"volumes": volumes,
|
"volumes": volumes,
|
||||||
}
|
}
|
||||||
|
|
||||||
return service.update(params["name"], state, update)
|
return service.common.update(state, params, update)
|
||||||
|
|
|
@ -6,9 +6,7 @@ from __future__ import annotations
|
||||||
import shlex
|
import shlex
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.service import (
|
from ansible_collections.ssnailed.ez_compose.plugins.module_utils import service
|
||||||
common as service,
|
|
||||||
)
|
|
||||||
|
|
||||||
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 (
|
||||||
|
@ -84,4 +82,4 @@ def helper(state: State, params: dict[str, Any]) -> State:
|
||||||
"labels": labels,
|
"labels": labels,
|
||||||
}
|
}
|
||||||
|
|
||||||
return service.update(params["name"], state, update)
|
return service.common.update(state, params, update)
|
||||||
|
|
|
@ -6,9 +6,7 @@ from __future__ import annotations
|
||||||
import shlex
|
import shlex
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
from ansible_collections.ssnailed.ez_compose.plugins.module_utils.service import (
|
from ansible_collections.ssnailed.ez_compose.plugins.module_utils import service
|
||||||
common as service,
|
|
||||||
)
|
|
||||||
|
|
||||||
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 (
|
||||||
|
@ -75,4 +73,4 @@ def helper(state: State, params: dict[str, Any]) -> State:
|
||||||
"labels": labels,
|
"labels": labels,
|
||||||
}
|
}
|
||||||
|
|
||||||
return service.update(params["name"], state, update)
|
return service.common.update(state, params, update)
|
||||||
|
|
|
@ -6,36 +6,15 @@
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
SERVICE_BASE_DOCS = """
|
DOCUMENTATION = """
|
||||||
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
|
module: compose
|
||||||
|
version_added: 1.0.0
|
||||||
short_description: Simplify docker-compose deployments
|
short_description: Simplify docker-compose deployments
|
||||||
|
seealso:
|
||||||
|
- name: Compose file reference
|
||||||
|
description: Complete reference of the compose file spec.
|
||||||
|
link: https://docs.docker.com/reference/compose-file/
|
||||||
description:
|
description:
|
||||||
- Easily create docker-compose files using a single module
|
- Easily create docker-compose files using a single module
|
||||||
author:
|
author:
|
||||||
|
@ -55,16 +34,75 @@ options:
|
||||||
description:
|
description:
|
||||||
- Path to store project directory under.
|
- Path to store project directory under.
|
||||||
type: path
|
type: path
|
||||||
|
settings:
|
||||||
|
description:
|
||||||
|
- Settings/Defaults for the module.
|
||||||
|
type: dict
|
||||||
|
suboptions:
|
||||||
|
default_definition:
|
||||||
|
description:
|
||||||
|
- Default definition for all containers.
|
||||||
|
- Overwritten by per-service defaults.
|
||||||
|
type: dict
|
||||||
|
service_defaults:
|
||||||
|
description:
|
||||||
|
- Default definitions for each service
|
||||||
|
type: dict
|
||||||
|
suboptions:
|
||||||
|
custom:
|
||||||
|
description:
|
||||||
|
- Default definitions for custom services.
|
||||||
|
type: dict
|
||||||
|
docker_in_docker:
|
||||||
|
description:
|
||||||
|
- Default definitions for docker in docker services.
|
||||||
|
type: dict
|
||||||
|
docker_socket_proxy:
|
||||||
|
description:
|
||||||
|
- Default definitions for docker socket proxy services.
|
||||||
|
type: dict
|
||||||
|
docker_volume_backupper:
|
||||||
|
description:
|
||||||
|
- Default definitions for docker volume backupper services.
|
||||||
|
type: dict
|
||||||
|
mariadb:
|
||||||
|
description:
|
||||||
|
- Default definitions for MariaDB services.
|
||||||
|
type: dict
|
||||||
|
postgres:
|
||||||
|
description:
|
||||||
|
- Default definitions for PostgreSQL services.
|
||||||
|
type: dict
|
||||||
|
redis:
|
||||||
|
description:
|
||||||
|
- Default definitions for Redis services.
|
||||||
|
type: dict
|
||||||
services:
|
services:
|
||||||
description:
|
description:
|
||||||
- Services to create in the project.
|
- Services to create in the project.
|
||||||
type: list
|
type: dict
|
||||||
elements: dict
|
|
||||||
suboptions:
|
suboptions:
|
||||||
custom:
|
custom:
|
||||||
description:
|
description:
|
||||||
- Custom service definition.
|
- Custom service definition.
|
||||||
{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
|
||||||
internal_network:
|
internal_network:
|
||||||
description:
|
description:
|
||||||
- If true, add internal network to service.
|
- If true, add internal network to service.
|
||||||
|
@ -78,7 +116,8 @@ options:
|
||||||
docker_volume_backupper:
|
docker_volume_backupper:
|
||||||
description:
|
description:
|
||||||
- Docker Volume Backupper label helper configuration.
|
- Docker Volume Backupper label helper configuration.
|
||||||
{LABEL_BASE_DOCS}
|
type: dict
|
||||||
|
suboptions:
|
||||||
stop:
|
stop:
|
||||||
description:
|
description:
|
||||||
- If true, stop the container when backing up.
|
- If true, stop the container when backing up.
|
||||||
|
@ -87,7 +126,8 @@ options:
|
||||||
traefik_middleware:
|
traefik_middleware:
|
||||||
description:
|
description:
|
||||||
- Traefik Middleware label helper configuration.
|
- Traefik Middleware label helper configuration.
|
||||||
{LABEL_BASE_DOCS}
|
type: dict
|
||||||
|
suboptions:
|
||||||
proxy_type:
|
proxy_type:
|
||||||
description:
|
description:
|
||||||
- Traefik proxy type.
|
- Traefik proxy type.
|
||||||
|
@ -97,8 +137,6 @@ options:
|
||||||
name:
|
name:
|
||||||
description:
|
description:
|
||||||
- Name of the middleware.
|
- Name of the middleware.
|
||||||
- Default is generated dynamically like so:
|
|
||||||
- [project_name]_[service_name]_[proxy_type]_[middleware]
|
|
||||||
type: string
|
type: string
|
||||||
middleware:
|
middleware:
|
||||||
description:
|
description:
|
||||||
|
@ -113,7 +151,8 @@ options:
|
||||||
traefik_router:
|
traefik_router:
|
||||||
description:
|
description:
|
||||||
- Traefik Router label helper configuration.
|
- Traefik Router label helper configuration.
|
||||||
{LABEL_BASE_DOCS}
|
type: dict
|
||||||
|
suboptions:
|
||||||
proxy_type:
|
proxy_type:
|
||||||
description:
|
description:
|
||||||
- Traefik proxy type.
|
- Traefik proxy type.
|
||||||
|
@ -123,8 +162,6 @@ options:
|
||||||
name:
|
name:
|
||||||
description:
|
description:
|
||||||
- Name of the middleware.
|
- Name of the middleware.
|
||||||
- Default is generated dynamically like so:
|
|
||||||
- [project_name]_[service_name]_[proxy_type]
|
|
||||||
type: string
|
type: string
|
||||||
rule:
|
rule:
|
||||||
description:
|
description:
|
||||||
|
@ -152,7 +189,8 @@ options:
|
||||||
traefik_service:
|
traefik_service:
|
||||||
description:
|
description:
|
||||||
- Traefik Service label helper configuration.
|
- Traefik Service label helper configuration.
|
||||||
{LABEL_BASE_DOCS}
|
type: dict
|
||||||
|
suboptions:
|
||||||
proxy_type:
|
proxy_type:
|
||||||
description:
|
description:
|
||||||
- Traefik proxy type.
|
- Traefik proxy type.
|
||||||
|
@ -162,8 +200,6 @@ options:
|
||||||
name:
|
name:
|
||||||
description:
|
description:
|
||||||
- Name of the middleware.
|
- Name of the middleware.
|
||||||
- Default is generated dynamically like so:
|
|
||||||
- [project_name]_[service_name]_[proxy_type]
|
|
||||||
type: string
|
type: string
|
||||||
port:
|
port:
|
||||||
description:
|
description:
|
||||||
|
@ -172,11 +208,45 @@ options:
|
||||||
docker_in_docker:
|
docker_in_docker:
|
||||||
description:
|
description:
|
||||||
- Docker-in-Docker service definition.
|
- Docker-in-Docker service definition.
|
||||||
{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
|
||||||
docker_socket_proxy:
|
docker_socket_proxy:
|
||||||
description:
|
description:
|
||||||
- Docker Socket Proxy service definition.
|
- Docker Socket Proxy service definition.
|
||||||
{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
|
||||||
read_only:
|
read_only:
|
||||||
description:
|
description:
|
||||||
- If true, only allow read access to the docker socket.
|
- If true, only allow read access to the docker socket.
|
||||||
|
@ -185,7 +255,24 @@ options:
|
||||||
docker_volume_backupper:
|
docker_volume_backupper:
|
||||||
description:
|
description:
|
||||||
- Docker Socket Proxy service definition.
|
- Docker Socket Proxy service definition.
|
||||||
{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
|
||||||
archive:
|
archive:
|
||||||
description:
|
description:
|
||||||
- Directory to store backups in.
|
- Directory to store backups in.
|
||||||
|
@ -198,7 +285,24 @@ options:
|
||||||
mariadb:
|
mariadb:
|
||||||
description:
|
description:
|
||||||
- MariaDB service definition.
|
- MariaDB service definition.
|
||||||
{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
|
||||||
backup:
|
backup:
|
||||||
description:
|
description:
|
||||||
- If true, add labels for the docker volume backupper.
|
- If true, add labels for the docker volume backupper.
|
||||||
|
@ -225,7 +329,24 @@ options:
|
||||||
postgres:
|
postgres:
|
||||||
description:
|
description:
|
||||||
- PostgreSQL service definition.
|
- PostgreSQL service definition.
|
||||||
{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
|
||||||
backup:
|
backup:
|
||||||
description:
|
description:
|
||||||
- If true, add labels for the docker volume backupper.
|
- If true, add labels for the docker volume backupper.
|
||||||
|
@ -248,8 +369,26 @@ options:
|
||||||
redis:
|
redis:
|
||||||
description:
|
description:
|
||||||
- Redis service definition.
|
- Redis service definition.
|
||||||
{SERVICE_BASE_DOCS}
|
type: dict
|
||||||
""" # noqa: E501
|
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
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
@ -287,7 +426,7 @@ def label_argument_spec() -> dict[str, Any]:
|
||||||
def service_argument_spec() -> dict[str, Any]:
|
def service_argument_spec() -> dict[str, Any]:
|
||||||
service_args: dict[str, Any] = {
|
service_args: dict[str, Any] = {
|
||||||
"type": "dict",
|
"type": "dict",
|
||||||
"options": {},
|
"suboptions": {},
|
||||||
"required": True,
|
"required": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,18 +439,43 @@ def service_argument_spec() -> dict[str, Any]:
|
||||||
**getattr(service, module).EXTRA_ARGS,
|
**getattr(service, module).EXTRA_ARGS,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# TODO: move to service.common
|
||||||
if module == "custom":
|
if module == "custom":
|
||||||
options["label_helpers"] = label_argument_spec()
|
options["label_helpers"] = label_argument_spec()
|
||||||
|
|
||||||
service_args["options"][module] = {
|
service_args["suboptions"][module] = {
|
||||||
"type": "list",
|
"type": "dict",
|
||||||
"elements": "dict",
|
"suboptions": options,
|
||||||
"options": options,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return service_args
|
return service_args
|
||||||
|
|
||||||
|
|
||||||
|
def settings_spec() -> dict[str, Any]:
|
||||||
|
settings: dict[str, Any] = {
|
||||||
|
"type": "dict",
|
||||||
|
"suboptions": {
|
||||||
|
"default_definition": {
|
||||||
|
"type": "dict",
|
||||||
|
},
|
||||||
|
"service_defaults": {
|
||||||
|
"type": "dict",
|
||||||
|
"suboptions": {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for module in service.__all__:
|
||||||
|
if module == "common":
|
||||||
|
continue
|
||||||
|
|
||||||
|
settings["suboptions"]["service_defaults"]["suboptions"][module] = {
|
||||||
|
"type": "dict",
|
||||||
|
}
|
||||||
|
|
||||||
|
return settings
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
argument_spec={
|
argument_spec={
|
||||||
|
@ -324,6 +488,7 @@ def main() -> None:
|
||||||
"type": "path",
|
"type": "path",
|
||||||
"default": "/var/lib/ez_compose",
|
"default": "/var/lib/ez_compose",
|
||||||
},
|
},
|
||||||
|
"settings": settings_spec(),
|
||||||
"services": service_argument_spec(),
|
"services": service_argument_spec(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
75
roles/compose/tasks/main.yml
Normal file
75
roles/compose/tasks/main.yml
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
---
|
||||||
|
- name: Login in to registries
|
||||||
|
community.docker.docker_login:
|
||||||
|
registry_url: "{{ item.registry }}"
|
||||||
|
username: "{{ item.username }}"
|
||||||
|
password: "{{ item.password }}"
|
||||||
|
loop: "{{ compose_registry_logins }}"
|
||||||
|
no_log: true
|
||||||
|
when: >-
|
||||||
|
ez_compose_state | default(None) == "present"
|
||||||
|
and ez_compose_shared_registry_logins is defined
|
||||||
|
and ez_compose_shared_registry_logins
|
||||||
|
|
||||||
|
- name: Ensure shared networks exist
|
||||||
|
community.docker.docker_network:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
attachable: "{{ item.attachable | default(omit) }}"
|
||||||
|
connected: "{{ item.connected | default(omit) }}"
|
||||||
|
driver: "{{ item.driver | default(omit) }}"
|
||||||
|
driver_options: "{{ item.driver_options | default(omit) }}"
|
||||||
|
enable_ipv6: "{{ item.enable_ipv6 | default(omit) }}"
|
||||||
|
force: "{{ item.force | default(omit) }}"
|
||||||
|
ipam_config: "{{ item.ipam_config | default(omit) }}"
|
||||||
|
ipam_driver: "{{ item.ipam_driver | default(omit) }}"
|
||||||
|
labels: "{{ item.labels | default(omit) }}"
|
||||||
|
scope: "{{ item.scope | default(omit) }}"
|
||||||
|
state: "{{ item.state | default(omit) }}"
|
||||||
|
loop: "{{ ez_compose_shared_networks }}"
|
||||||
|
when: >-
|
||||||
|
ez_compose_state | default(None) == "present"
|
||||||
|
and ez_compose_shared_networks is defined
|
||||||
|
and ez_compose_shared_networks
|
||||||
|
|
||||||
|
- name: Ensure shared volumes exist
|
||||||
|
community.docker.docker_network:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
driver: "{{ item.driver | default(omit) }}"
|
||||||
|
driver_options: "{{ item.driver_options | default(omit) }}"
|
||||||
|
labels: "{{ item.labels | default(omit) }}"
|
||||||
|
recreate: "{{ item.recreate | default(omit) }}"
|
||||||
|
state: "{{ item.state | default(omit) }}"
|
||||||
|
loop: "{{ ez_compose_shared_volumes }}"
|
||||||
|
when: >-
|
||||||
|
ez_compose_state | default(None) == "present"
|
||||||
|
and ez_compose_shared_volumes is defined
|
||||||
|
and ez_compose_shared_volumes
|
||||||
|
|
||||||
|
- name: Discover project definitions
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
_project_keys: >-
|
||||||
|
{{
|
||||||
|
hostvars[inventory_hostname].keys()
|
||||||
|
| select('match', '^ez_compose_project_')
|
||||||
|
}}
|
||||||
|
ez_compose_projects: >-
|
||||||
|
{{
|
||||||
|
hostvars[inventory_hostname]
|
||||||
|
| dict2items
|
||||||
|
| selectattr('key', 'in', _project_keys)
|
||||||
|
| items2dict
|
||||||
|
}}
|
||||||
|
when: >-
|
||||||
|
ez_compose_projects is not defined
|
||||||
|
or not ez_compose_projects
|
||||||
|
|
||||||
|
- name: Import project tasks
|
||||||
|
ansible.builtin.include_tasks: project.yml
|
||||||
|
when: >-
|
||||||
|
[project.name, 'compose-all'] | intersect(ansible_run_tags) | length > 0
|
||||||
|
and not
|
||||||
|
[project.name, 'compose-all'] | intersect(ansible_skip_tags) | length > 0
|
||||||
|
loop: "{{ ez_compose_projects }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: project
|
||||||
|
no_log: true
|
7
roles/compose/tasks/project.yml
Normal file
7
roles/compose/tasks/project.yml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
- name: "project | Write compose file: {{ project.name }}"
|
||||||
|
ssnailed.ez_compose.compose:
|
||||||
|
name: "{{ project.name }}"
|
||||||
|
services: "{{ project.services }}"
|
||||||
|
settings: "{{ ez_compose_settings }}"
|
||||||
|
project_dir: "{{ ez_compose_project_dir }}"
|
342
test.yml
Normal file
342
test.yml
Normal file
|
@ -0,0 +1,342 @@
|
||||||
|
---
|
||||||
|
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.
|
||||||
|
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
|
||||||
|
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.
|
||||||
|
|
||||||
|
type: dict
|
||||||
|
suboptions:
|
||||||
|
|
||||||
|
stop:
|
||||||
|
description:
|
||||||
|
- If true, stop the container when backing up.
|
||||||
|
type: bool
|
||||||
|
default: true
|
||||||
|
traefik_middleware:
|
||||||
|
description:
|
||||||
|
- Traefik Middleware label helper configuration.
|
||||||
|
type: dict
|
||||||
|
suboptions:
|
||||||
|
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.
|
||||||
|
type: dict
|
||||||
|
suboptions:
|
||||||
|
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.
|
||||||
|
type: dict
|
||||||
|
suboptions:
|
||||||
|
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.
|
||||||
|
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
|
||||||
|
docker_socket_proxy:
|
||||||
|
description:
|
||||||
|
- Docker Socket Proxy service definition.
|
||||||
|
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
|
||||||
|
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.
|
||||||
|
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
|
||||||
|
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.
|
||||||
|
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
|
||||||
|
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.
|
||||||
|
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
|
||||||
|
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.
|
||||||
|
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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue