421 lines
15 KiB
Python
421 lines
15 KiB
Python
"""Database Handler — manages Coolify databases, lifecycle, and backups."""
|
|
|
|
import json
|
|
from typing import Any
|
|
|
|
from plugins.coolify.client import CoolifyClient
|
|
|
|
|
|
def _create_db_spec(db_type: str, description: str) -> dict[str, Any]:
|
|
"""Generate a create_* tool spec for a database type."""
|
|
return {
|
|
"name": f"create_{db_type}",
|
|
"category": "crud",
|
|
"method_name": f"create_{db_type}",
|
|
"description": description,
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"project_uuid": {
|
|
"type": "string",
|
|
"description": "Project UUID",
|
|
"minLength": 1,
|
|
},
|
|
"server_uuid": {
|
|
"type": "string",
|
|
"description": "Server UUID",
|
|
"minLength": 1,
|
|
},
|
|
"environment_name": {
|
|
"type": "string",
|
|
"description": "Environment name (e.g., 'production')",
|
|
"minLength": 1,
|
|
},
|
|
"name": {
|
|
"anyOf": [{"type": "string"}, {"type": "null"}],
|
|
"description": "Database name",
|
|
},
|
|
"description": {
|
|
"anyOf": [{"type": "string"}, {"type": "null"}],
|
|
"description": "Database description",
|
|
},
|
|
"instant_deploy": {
|
|
"type": "boolean",
|
|
"description": "Deploy immediately after creation",
|
|
"default": False,
|
|
},
|
|
},
|
|
"required": ["project_uuid", "server_uuid", "environment_name"],
|
|
},
|
|
"scope": "write",
|
|
}
|
|
|
|
|
|
def get_tool_specifications() -> list[dict[str, Any]]:
|
|
"""Return tool specifications for ToolGenerator."""
|
|
specs = [
|
|
{
|
|
"name": "list_databases",
|
|
"category": "read",
|
|
"method_name": "list_databases",
|
|
"description": "List all Coolify databases.",
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {},
|
|
},
|
|
"scope": "read",
|
|
},
|
|
{
|
|
"name": "get_database",
|
|
"category": "read_sensitive",
|
|
"sensitivity": "sensitive",
|
|
"method_name": "get_database",
|
|
"description": "Get details of a specific Coolify database by UUID.",
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"uuid": {
|
|
"type": "string",
|
|
"description": "Database UUID",
|
|
"minLength": 1,
|
|
},
|
|
},
|
|
"required": ["uuid"],
|
|
},
|
|
"scope": "read",
|
|
},
|
|
{
|
|
"name": "update_database",
|
|
"category": "crud",
|
|
"method_name": "update_database",
|
|
"description": "Update a Coolify database settings.",
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"uuid": {
|
|
"type": "string",
|
|
"description": "Database UUID",
|
|
"minLength": 1,
|
|
},
|
|
"name": {
|
|
"anyOf": [{"type": "string"}, {"type": "null"}],
|
|
"description": "Database name",
|
|
},
|
|
"description": {
|
|
"anyOf": [{"type": "string"}, {"type": "null"}],
|
|
"description": "Database description",
|
|
},
|
|
"image": {
|
|
"anyOf": [{"type": "string"}, {"type": "null"}],
|
|
"description": "Docker image",
|
|
},
|
|
"is_public": {
|
|
"anyOf": [{"type": "boolean"}, {"type": "null"}],
|
|
"description": "Make database publicly accessible",
|
|
},
|
|
"public_port": {
|
|
"anyOf": [{"type": "integer"}, {"type": "null"}],
|
|
"description": "Public port number",
|
|
},
|
|
},
|
|
"required": ["uuid"],
|
|
},
|
|
"scope": "write",
|
|
},
|
|
{
|
|
"name": "delete_database",
|
|
"category": "system",
|
|
"method_name": "delete_database",
|
|
"description": (
|
|
"Delete a Coolify database permanently. "
|
|
"Optionally clean up volumes and Docker resources."
|
|
),
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"uuid": {
|
|
"type": "string",
|
|
"description": "Database UUID",
|
|
"minLength": 1,
|
|
},
|
|
"delete_configurations": {
|
|
"type": "boolean",
|
|
"description": "Delete configurations",
|
|
"default": True,
|
|
},
|
|
"delete_volumes": {
|
|
"type": "boolean",
|
|
"description": "Delete volumes",
|
|
"default": True,
|
|
},
|
|
"docker_cleanup": {
|
|
"type": "boolean",
|
|
"description": "Run Docker cleanup",
|
|
"default": True,
|
|
},
|
|
},
|
|
"required": ["uuid"],
|
|
},
|
|
"scope": "admin",
|
|
},
|
|
{
|
|
"name": "start_database",
|
|
"category": "lifecycle",
|
|
"method_name": "start_database",
|
|
"description": "Start a Coolify database.",
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"uuid": {
|
|
"type": "string",
|
|
"description": "Database UUID",
|
|
"minLength": 1,
|
|
},
|
|
},
|
|
"required": ["uuid"],
|
|
},
|
|
"scope": "write",
|
|
},
|
|
{
|
|
"name": "stop_database",
|
|
"category": "lifecycle",
|
|
"method_name": "stop_database",
|
|
"description": "Stop a running Coolify database.",
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"uuid": {
|
|
"type": "string",
|
|
"description": "Database UUID",
|
|
"minLength": 1,
|
|
},
|
|
},
|
|
"required": ["uuid"],
|
|
},
|
|
"scope": "write",
|
|
},
|
|
{
|
|
"name": "restart_database",
|
|
"category": "lifecycle",
|
|
"method_name": "restart_database",
|
|
"description": "Restart a Coolify database.",
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"uuid": {
|
|
"type": "string",
|
|
"description": "Database UUID",
|
|
"minLength": 1,
|
|
},
|
|
},
|
|
"required": ["uuid"],
|
|
},
|
|
"scope": "write",
|
|
},
|
|
]
|
|
|
|
# Add create specs for each database type
|
|
db_types = [
|
|
("postgresql", "Create a PostgreSQL database on Coolify."),
|
|
("mysql", "Create a MySQL database on Coolify."),
|
|
("mariadb", "Create a MariaDB database on Coolify."),
|
|
("mongodb", "Create a MongoDB database on Coolify."),
|
|
("redis", "Create a Redis database on Coolify."),
|
|
("clickhouse", "Create a ClickHouse database on Coolify."),
|
|
]
|
|
for db_type, desc in db_types:
|
|
specs.append(_create_db_spec(db_type, desc))
|
|
|
|
# Backup tools
|
|
specs.extend(
|
|
[
|
|
{
|
|
"name": "get_database_backups",
|
|
"category": "backup",
|
|
"sensitivity": "sensitive",
|
|
"method_name": "get_database_backups",
|
|
"description": "Get backup configuration and history for a Coolify database.",
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"uuid": {
|
|
"type": "string",
|
|
"description": "Database UUID",
|
|
"minLength": 1,
|
|
},
|
|
},
|
|
"required": ["uuid"],
|
|
},
|
|
"scope": "read",
|
|
},
|
|
{
|
|
"name": "create_database_backup",
|
|
"category": "backup",
|
|
"sensitivity": "sensitive",
|
|
"method_name": "create_database_backup",
|
|
"description": "Create a manual backup of a Coolify database.",
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"uuid": {
|
|
"type": "string",
|
|
"description": "Database UUID",
|
|
"minLength": 1,
|
|
},
|
|
},
|
|
"required": ["uuid"],
|
|
},
|
|
"scope": "write",
|
|
},
|
|
{
|
|
"name": "list_backup_executions",
|
|
"category": "backup",
|
|
"sensitivity": "sensitive",
|
|
"method_name": "list_backup_executions",
|
|
"description": "List all backup executions across all databases.",
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {},
|
|
},
|
|
"scope": "read",
|
|
},
|
|
]
|
|
)
|
|
|
|
return specs
|
|
|
|
|
|
# --- Handler Functions ---
|
|
|
|
|
|
async def list_databases(client: CoolifyClient) -> str:
|
|
"""List all databases."""
|
|
databases = await client.list_databases()
|
|
result = {"success": True, "count": len(databases), "databases": databases}
|
|
return json.dumps(result, indent=2, ensure_ascii=False)
|
|
|
|
|
|
async def get_database(client: CoolifyClient, uuid: str) -> str:
|
|
"""Get database details."""
|
|
db = await client.get_database(uuid)
|
|
result = {"success": True, "database": db}
|
|
return json.dumps(result, indent=2, ensure_ascii=False)
|
|
|
|
|
|
async def update_database(client: CoolifyClient, uuid: str, **kwargs) -> str:
|
|
"""Update database settings."""
|
|
data = {k: v for k, v in kwargs.items() if v is not None and k != "uuid"}
|
|
db = await client.update_database(uuid, data)
|
|
result = {
|
|
"success": True,
|
|
"message": f"Database '{uuid}' updated successfully",
|
|
"database": db,
|
|
}
|
|
return json.dumps(result, indent=2, ensure_ascii=False)
|
|
|
|
|
|
async def delete_database(
|
|
client: CoolifyClient,
|
|
uuid: str,
|
|
delete_configurations: bool = True,
|
|
delete_volumes: bool = True,
|
|
docker_cleanup: bool = True,
|
|
) -> str:
|
|
"""Delete a database."""
|
|
result_data = await client.delete_database(
|
|
uuid,
|
|
delete_configurations=delete_configurations,
|
|
delete_volumes=delete_volumes,
|
|
docker_cleanup=docker_cleanup,
|
|
)
|
|
result = {"success": True, "message": f"Database '{uuid}' deleted", "data": result_data}
|
|
return json.dumps(result, indent=2, ensure_ascii=False)
|
|
|
|
|
|
async def start_database(client: CoolifyClient, uuid: str) -> str:
|
|
"""Start a database."""
|
|
result_data = await client.start_database(uuid)
|
|
result = {"success": True, "message": f"Database '{uuid}' starting", "data": result_data}
|
|
return json.dumps(result, indent=2, ensure_ascii=False)
|
|
|
|
|
|
async def stop_database(client: CoolifyClient, uuid: str) -> str:
|
|
"""Stop a database."""
|
|
result_data = await client.stop_database(uuid)
|
|
result = {"success": True, "message": f"Database '{uuid}' stopping", "data": result_data}
|
|
return json.dumps(result, indent=2, ensure_ascii=False)
|
|
|
|
|
|
async def restart_database(client: CoolifyClient, uuid: str) -> str:
|
|
"""Restart a database."""
|
|
result_data = await client.restart_database(uuid)
|
|
result = {"success": True, "message": f"Database '{uuid}' restarting", "data": result_data}
|
|
return json.dumps(result, indent=2, ensure_ascii=False)
|
|
|
|
|
|
async def _create_database(client: CoolifyClient, db_type: str, **kwargs) -> str:
|
|
"""Create a database of given type."""
|
|
data = {k: v for k, v in kwargs.items() if v is not None}
|
|
db = await client.create_database(db_type, data)
|
|
result = {
|
|
"success": True,
|
|
"message": f"{db_type.title()} database created successfully",
|
|
"database": db,
|
|
}
|
|
return json.dumps(result, indent=2, ensure_ascii=False)
|
|
|
|
|
|
async def create_postgresql(client: CoolifyClient, **kwargs) -> str:
|
|
"""Create a PostgreSQL database."""
|
|
return await _create_database(client, "postgresql", **kwargs)
|
|
|
|
|
|
async def create_mysql(client: CoolifyClient, **kwargs) -> str:
|
|
"""Create a MySQL database."""
|
|
return await _create_database(client, "mysql", **kwargs)
|
|
|
|
|
|
async def create_mariadb(client: CoolifyClient, **kwargs) -> str:
|
|
"""Create a MariaDB database."""
|
|
return await _create_database(client, "mariadb", **kwargs)
|
|
|
|
|
|
async def create_mongodb(client: CoolifyClient, **kwargs) -> str:
|
|
"""Create a MongoDB database."""
|
|
return await _create_database(client, "mongodb", **kwargs)
|
|
|
|
|
|
async def create_redis(client: CoolifyClient, **kwargs) -> str:
|
|
"""Create a Redis database."""
|
|
return await _create_database(client, "redis", **kwargs)
|
|
|
|
|
|
async def create_clickhouse(client: CoolifyClient, **kwargs) -> str:
|
|
"""Create a ClickHouse database."""
|
|
return await _create_database(client, "clickhouse", **kwargs)
|
|
|
|
|
|
async def get_database_backups(client: CoolifyClient, uuid: str) -> str:
|
|
"""Get database backups."""
|
|
backups = await client.get_database_backups(uuid)
|
|
result = {"success": True, "backups": backups}
|
|
return json.dumps(result, indent=2, ensure_ascii=False)
|
|
|
|
|
|
async def create_database_backup(client: CoolifyClient, uuid: str) -> str:
|
|
"""Create a manual database backup."""
|
|
result_data = await client.create_database_backup(uuid)
|
|
result = {
|
|
"success": True,
|
|
"message": f"Backup created for database '{uuid}'",
|
|
"data": result_data,
|
|
}
|
|
return json.dumps(result, indent=2, ensure_ascii=False)
|
|
|
|
|
|
async def list_backup_executions(client: CoolifyClient) -> str:
|
|
"""List all backup executions."""
|
|
executions = await client.list_backup_executions()
|
|
result = {"success": True, "count": len(executions), "executions": executions}
|
|
return json.dumps(result, indent=2, ensure_ascii=False)
|