Cleanup remote api requests (#1579)

This commit is contained in:
Boy132 2025-08-09 23:53:45 +02:00 committed by GitHub
parent 6a4ac515a7
commit 900f8d0fe1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 58 additions and 50 deletions

View File

@ -2,6 +2,7 @@
namespace App\Http\Controllers\Api\Remote; namespace App\Http\Controllers\Api\Remote;
use App\Models\Node;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use App\Models\User; use App\Models\User;
@ -14,7 +15,7 @@ class ActivityProcessingController extends Controller
{ {
public function __invoke(ActivityEventRequest $request): void public function __invoke(ActivityEventRequest $request): void
{ {
/** @var \App\Models\Node $node */ /** @var Node $node */
$node = $request->attributes->get('node'); $node = $request->attributes->get('node');
$servers = $node->servers()->whereIn('uuid', $request->servers())->get()->keyBy('uuid'); $servers = $node->servers()->whereIn('uuid', $request->servers())->get()->keyBy('uuid');
@ -22,7 +23,7 @@ class ActivityProcessingController extends Controller
$logs = []; $logs = [];
foreach ($request->input('data') as $datum) { foreach ($request->input('data') as $datum) {
/** @var \App\Models\Server|null $server */ /** @var Server|null $server */
$server = $servers->get($datum['server']); $server = $servers->get($datum['server']);
if (is_null($server) || !Str::startsWith($datum['event'], 'server:')) { if (is_null($server) || !Str::startsWith($datum['event'], 'server:')) {
continue; continue;

View File

@ -2,7 +2,7 @@
namespace App\Http\Controllers\Api\Remote\Servers; namespace App\Http\Controllers\Api\Remote\Servers;
use Illuminate\Http\Request; use App\Http\Requests\Api\Remote\ServerRequest;
use App\Models\Server; use App\Models\Server;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
@ -12,11 +12,11 @@ class ServerContainersController extends Controller
/** /**
* Updates the server container's status on the Panel * Updates the server container's status on the Panel
*/ */
public function status(Server $server, Request $request): JsonResponse public function status(ServerRequest $request, Server $server): JsonResponse
{ {
$status = fluent($request->json()->all())->get('data.new_state'); $status = fluent($request->json()->all())->get('data.new_state');
cache()->put("servers.$server->uuid.container.status", $status, now()->addHour()); cache()->put("servers.$server->uuid.status", $status, now()->addHour());
return new JsonResponse([]); return new JsonResponse([]);
} }

View File

@ -3,7 +3,10 @@
namespace App\Http\Controllers\Api\Remote\Servers; namespace App\Http\Controllers\Api\Remote\Servers;
use App\Enums\ServerState; use App\Enums\ServerState;
use App\Http\Requests\Api\Remote\ServerRequest;
use App\Models\ActivityLog;
use App\Models\Backup; use App\Models\Backup;
use App\Models\Node;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Models\Server; use App\Models\Server;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
@ -29,7 +32,7 @@ class ServerDetailsController extends Controller
* Returns details about the server that allows daemon to self-recover and ensure * Returns details about the server that allows daemon to self-recover and ensure
* that the state of the server matches the Panel at all times. * that the state of the server matches the Panel at all times.
*/ */
public function __invoke(Server $server): JsonResponse public function __invoke(ServerRequest $request, Server $server): JsonResponse
{ {
return new JsonResponse([ return new JsonResponse([
'settings' => $this->configurationStructureService->handle($server), 'settings' => $this->configurationStructureService->handle($server),
@ -42,7 +45,7 @@ class ServerDetailsController extends Controller
*/ */
public function list(Request $request): ServerConfigurationCollection public function list(Request $request): ServerConfigurationCollection
{ {
/** @var \App\Models\Node $node */ /** @var Node $node */
$node = $request->attributes->get('node'); $node = $request->attributes->get('node');
// Avoid run-away N+1 SQL queries by preloading the relationships that are used // Avoid run-away N+1 SQL queries by preloading the relationships that are used
@ -85,9 +88,9 @@ class ServerDetailsController extends Controller
->get(); ->get();
$this->connection->transaction(function () use ($node, $servers) { $this->connection->transaction(function () use ($node, $servers) {
/** @var \App\Models\Server $server */ /** @var Server $server */
foreach ($servers as $server) { foreach ($servers as $server) {
/** @var \App\Models\ActivityLog|null $activity */ /** @var ActivityLog|null $activity */
$activity = $server->activity->first(); $activity = $server->activity->first();
if (!$activity) { if (!$activity) {
continue; continue;

View File

@ -3,6 +3,7 @@
namespace App\Http\Controllers\Api\Remote\Servers; namespace App\Http\Controllers\Api\Remote\Servers;
use App\Enums\ServerState; use App\Enums\ServerState;
use App\Http\Requests\Api\Remote\ServerRequest;
use Illuminate\Http\Response; use Illuminate\Http\Response;
use App\Models\Server; use App\Models\Server;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
@ -15,14 +16,12 @@ class ServerInstallController extends Controller
/** /**
* Returns installation information for a server. * Returns installation information for a server.
*/ */
public function index(Server $server): JsonResponse public function index(ServerRequest $request, Server $server): JsonResponse
{ {
$egg = $server->egg;
return new JsonResponse([ return new JsonResponse([
'container_image' => $egg->copy_script_container, 'container_image' => $server->egg->copy_script_container,
'entrypoint' => $egg->copy_script_entry, 'entrypoint' => $server->egg->copy_script_entry,
'script' => $egg->copy_script_install, 'script' => $server->egg->copy_script_install,
]); ]);
} }

View File

@ -2,12 +2,12 @@
namespace App\Http\Controllers\Api\Remote\Servers; namespace App\Http\Controllers\Api\Remote\Servers;
use App\Http\Requests\Api\Remote\ServerRequest;
use App\Models\Server; use App\Models\Server;
use App\Repositories\Daemon\DaemonServerRepository; use App\Repositories\Daemon\DaemonServerRepository;
use Illuminate\Http\Response; use Illuminate\Http\Response;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use App\Models\Allocation; use App\Models\Allocation;
use App\Models\ServerTransfer;
use Illuminate\Database\ConnectionInterface; use Illuminate\Database\ConnectionInterface;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use Symfony\Component\HttpKernel\Exception\ConflictHttpException; use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
@ -28,14 +28,23 @@ class ServerTransferController extends Controller
* *
* @throws \Throwable * @throws \Throwable
*/ */
public function failure(Server $server): JsonResponse public function failure(ServerRequest $request, Server $server): JsonResponse
{ {
$transfer = $server->transfer; $transfer = $server->transfer;
if (is_null($transfer)) { if (is_null($transfer)) {
throw new ConflictHttpException('Server is not being transferred.'); throw new ConflictHttpException('Server is not being transferred.');
} }
return $this->processFailedTransfer($transfer); $this->connection->transaction(function () use ($transfer) {
$transfer->forceFill(['successful' => false])->saveOrFail();
if ($transfer->new_allocation || $transfer->new_additional_allocations) {
$allocations = array_merge([$transfer->new_allocation], $transfer->new_additional_allocations);
Allocation::query()->whereIn('id', $allocations)->update(['server_id' => null]);
}
});
return new JsonResponse([], Response::HTTP_NO_CONTENT);
} }
/** /**
@ -43,16 +52,17 @@ class ServerTransferController extends Controller
* *
* @throws \Throwable * @throws \Throwable
*/ */
public function success(Server $server): JsonResponse public function success(ServerRequest $request, Server $server): JsonResponse
{ {
$transfer = $server->transfer; $transfer = $server->transfer;
if (is_null($transfer)) { if (is_null($transfer)) {
throw new ConflictHttpException('Server is not being transferred.'); throw new ConflictHttpException('Server is not being transferred.');
} }
/** @var Server $server */
$server = $this->connection->transaction(function () use ($server, $transfer) {
$data = []; $data = [];
/** @var \App\Models\Server $server */
$server = $this->connection->transaction(function () use ($server, $transfer, $data) {
if ($transfer->old_allocation || $transfer->old_additional_allocations) { if ($transfer->old_allocation || $transfer->old_additional_allocations) {
$allocations = array_merge([$transfer->old_allocation], $transfer->old_additional_allocations); $allocations = array_merge([$transfer->old_allocation], $transfer->old_additional_allocations);
// Remove the old allocations for the server and re-assign the server to the new // Remove the old allocations for the server and re-assign the server to the new
@ -60,6 +70,7 @@ class ServerTransferController extends Controller
Allocation::query()->whereIn('id', $allocations)->update(['server_id' => null]); Allocation::query()->whereIn('id', $allocations)->update(['server_id' => null]);
$data['allocation_id'] = $transfer->new_allocation; $data['allocation_id'] = $transfer->new_allocation;
} }
$data['node_id'] = $transfer->new_node; $data['node_id'] = $transfer->new_node;
$server->update($data); $server->update($data);
@ -82,24 +93,4 @@ class ServerTransferController extends Controller
return new JsonResponse([], Response::HTTP_NO_CONTENT); return new JsonResponse([], Response::HTTP_NO_CONTENT);
} }
/**
* Release all the reserved allocations for this transfer and mark it as failed in
* the database.
*
* @throws \Throwable
*/
protected function processFailedTransfer(ServerTransfer $transfer): JsonResponse
{
$this->connection->transaction(function () use (&$transfer) {
$transfer->forceFill(['successful' => false])->saveOrFail();
if ($transfer->new_allocation || $transfer->new_additional_allocations) {
$allocations = array_merge([$transfer->new_allocation], $transfer->new_additional_allocations);
Allocation::query()->whereIn('id', $allocations)->update(['server_id' => null]);
}
});
return new JsonResponse([], Response::HTTP_NO_CONTENT);
}
} }

View File

@ -2,15 +2,8 @@
namespace App\Http\Requests\Api\Remote; namespace App\Http\Requests\Api\Remote;
use Illuminate\Foundation\Http\FormRequest; class InstallationDataRequest extends ServerRequest
class InstallationDataRequest extends FormRequest
{ {
public function authorize(): bool
{
return true;
}
/** /**
* @return array<string, string|string[]> * @return array<string, string|string[]>
*/ */

View File

@ -0,0 +1,21 @@
<?php
namespace App\Http\Requests\Api\Remote;
use App\Models\Node;
use App\Models\Server;
use Illuminate\Foundation\Http\FormRequest;
class ServerRequest extends FormRequest
{
public function authorize(): bool
{
/** @var Node $node */
$node = $this->attributes->get('node');
/** @var ?Server $server */
$server = $this->route()->parameter('server');
return $server && $server->node_id === $node->id;
}
}