Source code for management.models.backup

"""Backup Options Model."""
from __future__ import annotations

from typing import Any

from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import gettext_lazy as _


[docs] class BackupOptions(models.Model): """A singleton model (we always operate with pk=1) for backup settings. We store host/port/user/local_storage, plus either a password or an SSH key. """
[docs] class AuthMethod(models.TextChoices): """Authentication methods for backup options."""
[docs] PASSWORD = 'password', 'Password'
[docs] SSH_KEY = 'ssh_key', 'SSH Key'
[docs] enable_sftp_storage = models.BooleanField(default=False, verbose_name=_('Use SFTP storage'))
[docs] host = models.CharField(max_length=255, verbose_name=_('Host'), blank=True)
[docs] port = models.PositiveIntegerField(default=2222, verbose_name=_('Port'), blank=True)
[docs] user = models.CharField(max_length=128, verbose_name=_('Username'), blank=True)
[docs] auth_method = models.CharField( max_length=10, choices=AuthMethod.choices, default=AuthMethod.PASSWORD, verbose_name=_('Authentication Method') )
# TODO (Dome): Storing passwords in plain text # noqa: FIX002
[docs] password = models.CharField( max_length=128, blank=True, verbose_name=_('Password'), help_text=_('Plain-text password for SFTP.') )
[docs] private_key = models.TextField( blank=True, verbose_name=_('SSH Private Key (PEM format)'), help_text=_('Paste the private key here (PEM).') )
[docs] key_passphrase = models.CharField( max_length=128, blank=True, verbose_name=_('Key Passphrase'), help_text=_('Passphrase for the private key, if any.') )
[docs] remote_directory = models.CharField( max_length=512, blank=True, default='/upload/trustpoint/', verbose_name=_('Remote Directory'), help_text=_('Remote directory (e.g. /backups/) where files should be uploaded. ' 'Trailing slash is optional.'), )
[docs] class Meta: """Meta options for the BackupOptions model."""
[docs] verbose_name = 'Backup Option'
def __str__(self) -> str: """Return a string representation of the backup options.""" return f'{self.user}@{self.host}:{self.port} ({self.auth_method})'
[docs] def save(self, *args: Any, **kwargs: Any) -> None: """Ensure only one instance exists (singleton pattern).""" self.full_clean() super().save(*args, **kwargs)
[docs] def clean(self) -> None: """Prevent the creation of more than one instance.""" if BackupOptions.objects.exists() and not self.pk: msg = 'Only one BackupOptions instance is allowed.' raise ValidationError(msg) return super().clean()