#!/usr/bin/env python3 """Sync Docker secrets from running containers to local files. For each deployed recipe on an instance, SSHes into the server, reads /run/secrets/ from containers, and saves locally. Usage: python3 scripts/sync_secrets.py # sync all recipes python3 scripts/sync_secrets.py --recipe keycloak # sync one recipe python3 scripts/sync_secrets.py --instance t1cc # sync on specific instance """ import argparse import os import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from lib.config import paths from lib.models import load_default_instance, load_instance, load_deployment from lib.secrets import sync_secrets_for_deployment, sync_all_secrets from lib.log import SkillLogger def main(): parser = argparse.ArgumentParser( description="Sync secrets from running containers" ) parser.add_argument("--recipe", default=None, help="Sync only this recipe (default: all)") parser.add_argument("--instance", default=None, help="Instance name (default: active)") args = parser.parse_args() log = SkillLogger("sync-secrets", args.recipe) if args.instance: inst = load_instance(args.instance) else: inst = load_default_instance() log.info(f"Instance: {inst.name} ({inst.server})") if args.recipe: # Sync one recipe dep = load_deployment(args.recipe, instance=inst.name) log.step(f"Sync secrets for {args.recipe}") secrets = sync_secrets_for_deployment(inst.server, dep.domain) log.info(f"Synced {len(secrets)} secrets for {dep.domain}") else: # Sync all log.step("Sync all secrets") results = sync_all_secrets(inst.server) total = sum(len(s) for s in results.values()) log.info(f"Synced {total} secrets across {len(results)} deployments") log.save() if __name__ == "__main__": main()