Sanitized single-commit public mirror of recipe-maintainer. - Removed test-ssh/.testenv (live creds); added test-ssh/.testenv.example placeholders. - Removed plans/ and planned-updates/ (deployment-planning docs) so no client/ deployment domains appear in the public repo. - All other secret stores were already gitignored. - docs.coopcloud.tech retained as a submodule (public upstream).
62 lines
1.9 KiB
Python
62 lines
1.9 KiB
Python
#!/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()
|