diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 2ed3ee454..ff997667a 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -91,7 +91,11 @@ class Kernel extends ConsoleKernel private function pullImages(): void { - $servers = $this->allServers->whereRelation('settings', 'is_usable', true)->whereRelation('settings', 'is_reachable', true)->get(); + if (isCloud()) { + $servers = $this->allServers->whereRelation('team.subscription', 'stripe_invoice_paid', true)->whereRelation('settings', 'is_usable', true)->whereRelation('settings', 'is_reachable', true)->get(); + } else { + $servers = $this->allServers->whereRelation('settings', 'is_usable', true)->whereRelation('settings', 'is_reachable', true)->get(); + } foreach ($servers as $server) { if ($server->isSentinelEnabled()) { $this->scheduleInstance->job(function () use ($server) { @@ -124,7 +128,7 @@ class Kernel extends ConsoleKernel private function checkResources(): void { if (isCloud()) { - $servers = $this->allServers->whereHas('team.subscription')->get(); + $servers = $this->allServers->whereRelation('team.subscription', 'stripe_invoice_paid', true)->get(); $own = Team::find(0)->servers; $servers = $servers->merge($own); } else { @@ -175,22 +179,43 @@ class Kernel extends ConsoleKernel if ($scheduled_backups->isEmpty()) { return; } + $finalScheduledBackups = collect(); foreach ($scheduled_backups as $scheduled_backup) { - if (is_null(data_get($scheduled_backup, 'database'))) { + if (blank(data_get($scheduled_backup, 'database'))) { $scheduled_backup->delete(); continue; } - $server = $scheduled_backup->server(); + if (blank($server)) { + $scheduled_backup->delete(); - if (is_null($server)) { continue; } + if ($server->isFunctional() === false) { + continue; + } + if (isCloud() && data_get($server->team->subscription, 'stripe_invoice_paid', false) === false) { + continue; + } + $finalScheduledBackups->push($scheduled_backup); + } + $own = Team::find(0)->servers; + $finalScheduledBackups = $finalScheduledBackups->merge($own); + + foreach ($finalScheduledBackups as $scheduled_backup) { if (isset(VALID_CRON_STRINGS[$scheduled_backup->frequency])) { $scheduled_backup->frequency = VALID_CRON_STRINGS[$scheduled_backup->frequency]; } + + $server = $scheduled_backup->server(); + $serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone); + + if (validate_timezone($serverTimezone) === false) { + $serverTimezone = config('app.timezone'); + } + $this->scheduleInstance->job(new DatabaseBackupJob( backup: $scheduled_backup ))->cron($scheduled_backup->frequency)->timezone($this->instanceTimezone)->onOneServer(); @@ -203,34 +228,55 @@ class Kernel extends ConsoleKernel if ($scheduled_tasks->isEmpty()) { return; } + $finalScheduledTasks = collect(); foreach ($scheduled_tasks as $scheduled_task) { $service = $scheduled_task->service; $application = $scheduled_task->application; - if (! $application && ! $service) { + $server = $scheduled_task->server(); + if (blank($server)) { $scheduled_task->delete(); continue; } - if ($application) { - if (str($application->status)->contains('running') === false) { - continue; - } - } - if ($service) { - if (str($service->status)->contains('running') === false) { - continue; - } - } - $server = $scheduled_task->server(); - if (! $server) { + if ($server->isFunctional() === false) { continue; } + if (isCloud() && data_get($server->team->subscription, 'stripe_invoice_paid', false) === false) { + continue; + } + + if (! $service && ! $application) { + $scheduled_task->delete(); + + continue; + } + + if ($application && str($application->status)->contains('running') === false) { + continue; + } + if ($service && str($service->status)->contains('running') === false) { + continue; + } + + $finalScheduledTasks->push($scheduled_task); + } + + $own = Team::find(0)->servers; + $finalScheduledTasks = $finalScheduledTasks->merge($own); + + foreach ($finalScheduledTasks as $scheduled_task) { + $server = $scheduled_task->server(); if (isset(VALID_CRON_STRINGS[$scheduled_task->frequency])) { $scheduled_task->frequency = VALID_CRON_STRINGS[$scheduled_task->frequency]; } + $serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone); + + if (validate_timezone($serverTimezone) === false) { + $serverTimezone = config('app.timezone'); + } $this->scheduleInstance->job(new ScheduledTaskJob( task: $scheduled_task ))->cron($scheduled_task->frequency)->timezone($this->instanceTimezone)->onOneServer(); diff --git a/app/Jobs/PushServerUpdateJob.php b/app/Jobs/PushServerUpdateJob.php index 24f8d1e6b..93b203fcb 100644 --- a/app/Jobs/PushServerUpdateJob.php +++ b/app/Jobs/PushServerUpdateJob.php @@ -19,6 +19,7 @@ use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; +use Illuminate\Queue\Middleware\WithoutOverlapping; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Collection; @@ -68,6 +69,11 @@ class PushServerUpdateJob implements ShouldBeEncrypted, ShouldQueue public bool $foundLogDrainContainer = false; + public function middleware(): array + { + return [(new WithoutOverlapping($this->server->uuid))->dontRelease()]; + } + public function backoff(): int { return isDev() ? 1 : 3; diff --git a/routes/api.php b/routes/api.php index 9ad64c40c..fd983d370 100644 --- a/routes/api.php +++ b/routes/api.php @@ -132,18 +132,35 @@ Route::group([ 'prefix' => 'v1', ], function () { Route::post('/sentinel/push', function () { + // return response()->json(['message' => 'temporary unavailable'], 503); $token = request()->header('Authorization'); if (! $token) { return response()->json(['message' => 'Unauthorized'], 401); } $naked_token = str_replace('Bearer ', '', $token); - $decrypted = decrypt($naked_token); - $decrypted_token = json_decode($decrypted, true); + try { + $decrypted = decrypt($naked_token); + $decrypted_token = json_decode($decrypted, true); + } catch (\Exception $e) { + return response()->json(['message' => 'Invalid token'], 401); + } $server_uuid = data_get($decrypted_token, 'server_uuid'); + if (! $server_uuid) { + return response()->json(['message' => 'Invalid token'], 401); + } $server = Server::where('uuid', $server_uuid)->first(); if (! $server) { return response()->json(['message' => 'Server not found'], 404); } + + if (isCloud() && data_get($server->team->subscription, 'stripe_invoice_paid', false) === false && $server->team->id !== 0) { + return response()->json(['message' => 'Unauthorized'], 401); + } + + if ($server->isFunctional() === false) { + return response()->json(['message' => 'Server is not functional'], 401); + } + if ($server->settings->sentinel_token !== $naked_token) { return response()->json(['message' => 'Unauthorized'], 401); }