from __future__ import annotations from typing import Any from django.core.exceptions import ObjectDoesNotExist from pobsync.config.schemas import GLOBAL_SCHEMA, HOST_SCHEMA from pobsync.validate import validate_dict from .models import GlobalConfig, HostConfig class ConfigRepositoryError(RuntimeError): pass def _global_runtime_data(global_config: GlobalConfig) -> dict[str, Any]: data = { "backup_root": global_config.backup_root, "ssh": { "user": global_config.ssh_user, "port": global_config.ssh_port, "options": list(global_config.ssh_options or []), }, "rsync": { "binary": global_config.rsync_binary, "args": list(global_config.rsync_args or []), "timeout_seconds": global_config.rsync_timeout_seconds, "bwlimit_kbps": global_config.rsync_bwlimit_kbps, "extra_args": list(global_config.rsync_extra_args or []), }, "defaults": { "source_root": global_config.default_source_root, "destination_subdir": global_config.default_destination_subdir, }, "excludes_default": list(global_config.excludes_default or []), "retention_defaults": { "daily": global_config.retention_daily, "weekly": global_config.retention_weekly, "monthly": global_config.retention_monthly, "yearly": global_config.retention_yearly, }, } return validate_dict(data, GLOBAL_SCHEMA, path="global") def _host_runtime_data(host_config: HostConfig) -> dict[str, Any]: data: dict[str, Any] = { "host": host_config.host, "address": host_config.address, "includes": list(host_config.includes or []), "retention": { "daily": host_config.retention_daily, "weekly": host_config.retention_weekly, "monthly": host_config.retention_monthly, "yearly": host_config.retention_yearly, }, } if host_config.ssh_user or host_config.ssh_port: data["ssh"] = {} if host_config.ssh_user: data["ssh"]["user"] = host_config.ssh_user if host_config.ssh_port is not None: data["ssh"]["port"] = host_config.ssh_port if host_config.source_root: data["source_root"] = host_config.source_root if host_config.excludes_replace is not None: data["excludes_replace"] = list(host_config.excludes_replace or []) else: data["excludes_add"] = list(host_config.excludes_add or []) if host_config.rsync_extra_args or host_config.rsync_bwlimit_kbps is not None: data["rsync"] = {} if host_config.rsync_extra_args: data["rsync"]["extra_args"] = list(host_config.rsync_extra_args or []) if host_config.rsync_bwlimit_kbps is not None: data["rsync"]["bwlimit_kbps"] = host_config.rsync_bwlimit_kbps return validate_dict(data, HOST_SCHEMA, path="host") def global_config_object_data(global_config: GlobalConfig) -> dict[str, Any]: return _global_runtime_data(global_config) def host_config_object_data(host_config: HostConfig) -> dict[str, Any]: return _host_runtime_data(host_config) def global_config_data(name: str = "default") -> dict[str, Any]: try: global_config = GlobalConfig.objects.get(name=name) except ObjectDoesNotExist as exc: raise ConfigRepositoryError(f"Missing global config {name!r}") from exc return _global_runtime_data(global_config) def host_config_data(host: str) -> dict[str, Any]: try: host_config = HostConfig.objects.get(host=host, enabled=True) except ObjectDoesNotExist as exc: raise ConfigRepositoryError(f"Missing enabled host {host!r}") from exc return _host_runtime_data(host_config)