Files
coolify/app/Livewire/Project/Database/CreateScheduledBackup.php
T
Andras Bacsai 2719d66042 feat: add ClickHouse backups and cloud ops tools
Enable scheduled ClickHouse backups across the job, API, and UI, and
guard unsupported database types via isBackupSolutionAvailable().
Convert Stripe subscription sync from a job to an action with clearer
discrepancy resolution, and add cloud:export-users plus
cloud:cleanup-unverified-users with tests.
2026-07-16 11:57:52 +02:00

114 lines
3.6 KiB
PHP

<?php
namespace App\Livewire\Project\Database;
use App\Models\S3Storage;
use App\Models\ScheduledDatabaseBackup;
use App\Models\ServiceDatabase;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Collection;
use Livewire\Attributes\Locked;
use Livewire\Attributes\Validate;
use Livewire\Component;
class CreateScheduledBackup extends Component
{
use AuthorizesRequests;
#[Validate(['required', 'string'])]
public $frequency;
#[Validate(['required', 'boolean'])]
public bool $saveToS3 = false;
#[Locked]
public $database;
public bool $enabled = true;
#[Validate(['nullable', 'integer'])]
public ?int $s3StorageId = null;
public Collection $definedS3s;
public function mount()
{
try {
$this->definedS3s = currentTeam()->s3s;
if ($this->definedS3s->count() > 0) {
$this->s3StorageId = $this->definedS3s->first()->id;
}
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function submit()
{
try {
$this->authorize('manageBackups', $this->database);
if (! $this->database->isBackupSolutionAvailable()) {
$this->dispatch('error', 'Scheduled backups are not supported for this database type.');
return;
}
$this->validate();
if ($this->saveToS3) {
$s3StorageExists = ! is_null($this->s3StorageId)
&& S3Storage::where('team_id', currentTeam()->id)
->where('is_usable', true)
->whereKey($this->s3StorageId)
->exists();
if (! $s3StorageExists) {
$this->dispatch('error', 'Please select a valid S3 storage to enable S3 backups.');
return;
}
}
$isValid = validate_cron_expression($this->frequency);
if (! $isValid) {
$this->dispatch('error', 'Invalid Cron / Human expression.');
return;
}
$payload = [
'enabled' => true,
'frequency' => $this->frequency,
'save_s3' => $this->saveToS3,
's3_storage_id' => $this->s3StorageId,
'database_id' => $this->database->id,
'database_type' => $this->database->getMorphClass(),
'team_id' => currentTeam()->id,
];
if ($this->database->type() === 'standalone-postgresql') {
$payload['databases_to_backup'] = $this->database->postgres_db;
} elseif ($this->database->type() === 'standalone-mysql') {
$payload['databases_to_backup'] = $this->database->mysql_database;
} elseif ($this->database->type() === 'standalone-mariadb') {
$payload['databases_to_backup'] = $this->database->mariadb_database;
} elseif ($this->database->type() === 'standalone-clickhouse') {
$payload['databases_to_backup'] = $this->database->clickhouse_db;
}
$databaseBackup = ScheduledDatabaseBackup::create($payload);
if ($this->database->getMorphClass() === ServiceDatabase::class) {
$this->dispatch('refreshScheduledBackups', $databaseBackup->id);
} else {
$this->dispatch('refreshScheduledBackups');
}
} catch (\Throwable $e) {
return handleError($e, $this);
} finally {
$this->frequency = '';
}
}
}