Files
pobsync/src/pobsync_backend/management/commands/ensure_pobsync_ssh_key.py
Peter van Arkel df3dcc47c9 (feature) Generate filesystem-backed SSH credentials
Add filesystem-backed SSH credentials for the native systemd deployment
path. Generated keys are stored below POBSYNC_HOME with 0600
permissions, while Django keeps the public key, fingerprint, path, and
selection metadata.

Add a Django SSH key generation view, delete action for unused generated
keys, and a management command used by the installer to ensure a default
backup key exists.

Update runtime config to use generated key paths directly as IdentityFile,
extend host checks to verify key readability, and keep legacy uploaded
keys available for compatibility.
2026-05-19 19:41:40 +02:00

48 lines
1.9 KiB
Python

from __future__ import annotations
from django.core.management.base import BaseCommand, CommandError
from pobsync_backend.models import GlobalConfig, SshCredential
from pobsync_backend.ssh_keys import SshKeyError, generate_ssh_key
class Command(BaseCommand):
help = "Ensure a filesystem-backed SSH key exists for pobsync backups."
def add_arguments(self, parser):
parser.add_argument("--name", default="default", help="Credential name to create or reuse.")
parser.add_argument("--key-type", default="ed25519", choices=("ed25519", "rsa"))
parser.add_argument(
"--set-global-default",
action="store_true",
help="Set this key as default on the default global config when it exists.",
)
def handle(self, *args, **options):
name = options["name"]
credential, created = SshCredential.objects.get_or_create(
name=name,
defaults={
"key_type": options["key_type"],
"notes": "Generated by pobsync installer.",
},
)
if not credential.key_path and not credential.private_key:
try:
generate_ssh_key(credential, key_type=options["key_type"])
except SshKeyError as exc:
raise CommandError(str(exc)) from exc
created = True
if options["set_global_default"]:
global_config = GlobalConfig.objects.filter(name="default").first()
if global_config is not None and global_config.default_ssh_credential_id is None:
global_config.default_ssh_credential = credential
global_config.save(update_fields=["default_ssh_credential", "updated_at"])
action = "created" if created else "exists"
self.stdout.write(self.style.SUCCESS(f"SSH credential {action}: {credential.name}"))
if credential.public_key:
self.stdout.write(credential.public_key)