from __future__ import annotations from typing import Any from django.core.management.base import BaseCommand, CommandError from pobsync.cli import parse_retention from pobsync.util import sanitize_host from pobsync_backend.models import GlobalConfig, HostConfig class Command(BaseCommand): help = "Create or update a SQL-backed host pobsync configuration." def add_arguments(self, parser) -> None: parser.add_argument("host") parser.add_argument("--address", required=True) parser.add_argument("--ssh-user", default="") parser.add_argument("--ssh-port", type=int, default=None) parser.add_argument("--source-root", default="") parser.add_argument("--include", action="append", default=[]) parser.add_argument("--exclude-add", action="append", default=[]) parser.add_argument("--exclude-replace", action="append", default=None) parser.add_argument("--rsync-extra-arg", action="append", default=[]) parser.add_argument("--retention", default=None) parser.add_argument("--disabled", action="store_true") parser.add_argument("--force", action="store_true", help="Update existing host") def handle(self, *args: Any, **options: Any) -> None: host = sanitize_host(options["host"]) if HostConfig.objects.filter(host=host).exists() and not options["force"]: raise CommandError(f"HostConfig {host!r} already exists; use --force to update") retention = self._retention(options["retention"]) defaults = { "address": options["address"], "enabled": not options["disabled"], "ssh_user": options["ssh_user"], "ssh_port": options["ssh_port"], "source_root": options["source_root"], "includes": list(options["include"]), "excludes_add": [] if options["exclude_replace"] is not None else list(options["exclude_add"]), "excludes_replace": options["exclude_replace"], "rsync_extra_args": list(options["rsync_extra_arg"]), "retention_daily": retention["daily"], "retention_weekly": retention["weekly"], "retention_monthly": retention["monthly"], "retention_yearly": retention["yearly"], } _obj, created = HostConfig.objects.update_or_create(host=host, defaults=defaults) action = "Created" if created else "Updated" self.stdout.write(self.style.SUCCESS(f"{action} HostConfig {host!r}.")) def _retention(self, value: str | None) -> dict[str, int]: if value: return parse_retention(value) global_config = GlobalConfig.objects.filter(name="default").first() if global_config is None: return {"daily": 14, "weekly": 8, "monthly": 12, "yearly": 0} return { "daily": global_config.retention_daily, "weekly": global_config.retention_weekly, "monthly": global_config.retention_monthly, "yearly": global_config.retention_yearly, }