From 4969aed3832ad9be9329804c028c03d01fb7d613 Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sat, 16 Mar 2024 15:11:10 -0400 Subject: [PATCH] Remove daemon command repo --- .../Api/Client/Servers/CommandController.php | 10 +----- .../Api/Client/SubstituteClientBindings.php | 11 ++++--- app/Jobs/Schedule/RunTaskJob.php | 5 +-- app/Models/Server.php | 21 ++++++++++++ app/Providers/AppServiceProvider.php | 13 ++++++++ .../Daemon/DaemonCommandRepository.php | 33 ------------------- .../Client/Server/CommandControllerTest.php | 17 ++++++---- 7 files changed, 53 insertions(+), 57 deletions(-) delete mode 100644 app/Repositories/Daemon/DaemonCommandRepository.php diff --git a/app/Http/Controllers/Api/Client/Servers/CommandController.php b/app/Http/Controllers/Api/Client/Servers/CommandController.php index a0e1134b6..95f49fa9c 100644 --- a/app/Http/Controllers/Api/Client/Servers/CommandController.php +++ b/app/Http/Controllers/Api/Client/Servers/CommandController.php @@ -15,14 +15,6 @@ use App\Exceptions\Http\Connection\DaemonConnectionException; class CommandController extends ClientApiController { - /** - * CommandController constructor. - */ - public function __construct(private DaemonCommandRepository $repository) - { - parent::__construct(); - } - /** * Send a command to a running server. * @@ -31,7 +23,7 @@ class CommandController extends ClientApiController public function index(SendCommandRequest $request, Server $server): Response { try { - $this->repository->setServer($server)->send($request->input('command')); + $server->send($request->input('command')); } catch (DaemonConnectionException $exception) { $previous = $exception->getPrevious(); diff --git a/app/Http/Middleware/Api/Client/SubstituteClientBindings.php b/app/Http/Middleware/Api/Client/SubstituteClientBindings.php index 3abf9eb09..06f58cd81 100644 --- a/app/Http/Middleware/Api/Client/SubstituteClientBindings.php +++ b/app/Http/Middleware/Api/Client/SubstituteClientBindings.php @@ -3,19 +3,22 @@ namespace App\Http\Middleware\Api\Client; use App\Models\Server; +use Illuminate\Contracts\Routing\Registrar; use Illuminate\Routing\Middleware\SubstituteBindings; class SubstituteClientBindings extends SubstituteBindings { - /** - * @param \Illuminate\Http\Request $request - */ + public function __construct(Registrar $router, private Server $server) + { + parent::__construct($router); + } + public function handle($request, \Closure $next): mixed { // Override default behavior of the model binding to use a specific table // column rather than the default 'id'. $this->router->bind('server', function ($value) { - return Server::query()->where(strlen($value) === 8 ? 'uuidShort' : 'uuid', $value)->firstOrFail(); + return $this->server->query()->where(strlen($value) === 8 ? 'uuidShort' : 'uuid', $value)->firstOrFail(); }); $this->router->bind('user', function ($value, $route) { diff --git a/app/Jobs/Schedule/RunTaskJob.php b/app/Jobs/Schedule/RunTaskJob.php index 86ad808b4..e9d51e185 100644 --- a/app/Jobs/Schedule/RunTaskJob.php +++ b/app/Jobs/Schedule/RunTaskJob.php @@ -2,7 +2,6 @@ namespace App\Jobs\Schedule; -use Exception; use App\Jobs\Job; use Carbon\CarbonImmutable; use App\Models\Task; @@ -12,7 +11,6 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\DispatchesJobs; use App\Services\Backups\InitiateBackupService; use App\Repositories\Daemon\DaemonPowerRepository; -use App\Repositories\Daemon\DaemonCommandRepository; use App\Exceptions\Http\Connection\DaemonConnectionException; class RunTaskJob extends Job implements ShouldQueue @@ -35,7 +33,6 @@ class RunTaskJob extends Job implements ShouldQueue * @throws \Throwable */ public function handle( - DaemonCommandRepository $commandRepository, InitiateBackupService $backupService, DaemonPowerRepository $powerRepository ) { @@ -65,7 +62,7 @@ class RunTaskJob extends Job implements ShouldQueue $powerRepository->setServer($server)->send($this->task->payload); break; case Task::ACTION_COMMAND: - $commandRepository->setServer($server)->send($this->task->payload); + $server->send($this->task->payload); break; case Task::ACTION_BACKUP: $backupService->setIgnoredFiles(explode(PHP_EOL, $this->task->payload))->handle($server, null, true); diff --git a/app/Models/Server.php b/app/Models/Server.php index f22470e1b..908ac02bc 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -2,8 +2,13 @@ namespace App\Models; +use App\Exceptions\Http\Connection\DaemonConnectionException; +use GuzzleHttp\Exception\GuzzleException; +use GuzzleHttp\Exception\TransferException; use Illuminate\Notifications\Notifiable; use Illuminate\Database\Query\JoinClause; +use Illuminate\Support\Facades\Http; +use Psr\Http\Message\ResponseInterface; use Znck\Eloquent\Traits\BelongsToThrough; use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -365,4 +370,20 @@ class Server extends Model return $server; } + + /** + * Sends a command or multiple commands to a running server instance. + * + * @throws DaemonConnectionException|GuzzleException + */ + public function send(array|string $command): ResponseInterface + { + try { + return Http::daemon($this->node)->post("/api/servers/{$this->uuid}/commands", [ + 'commands' => is_array($command) ? $command : [$command], + ])->toPsrResponse(); + } catch (TransferException $exception) { + throw new DaemonConnectionException($exception); + } + } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 4cd45fc54..a931859de 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -3,6 +3,8 @@ namespace App\Providers; use App\Models; +use App\Models\Node; +use Illuminate\Support\Facades\Http; use Illuminate\Support\Str; use Illuminate\Support\Facades\URL; use Illuminate\Pagination\Paginator; @@ -47,6 +49,17 @@ class AppServiceProvider extends ServiceProvider 'task' => Models\Task::class, 'user' => Models\User::class, ]); + + Http::macro( + 'daemon', + fn (Node $node, array $headers = []) => Http::acceptJson()->withHeaders([ + 'Authorization' => 'Bearer ' . $node->getDecryptedKey(), + ] + $headers) + ->withOptions(['verify' => (bool) app()->environment('production')]) + ->timeout(config('pterodactyl.guzzle.timeout')) + ->connectTimeout(config('pterodactyl.guzzle.connect_timeout')) + ->baseUrl($node->getConnectionAddress()) + ); } /** diff --git a/app/Repositories/Daemon/DaemonCommandRepository.php b/app/Repositories/Daemon/DaemonCommandRepository.php deleted file mode 100644 index 9bb818a7c..000000000 --- a/app/Repositories/Daemon/DaemonCommandRepository.php +++ /dev/null @@ -1,33 +0,0 @@ -server, Server::class); - - try { - return $this->getHttpClient()->post( - sprintf('/api/servers/%s/commands', $this->server->uuid), - [ - 'json' => ['commands' => is_array($command) ? $command : [$command]], - ] - ); - } catch (TransferException $exception) { - throw new DaemonConnectionException($exception); - } - } -} diff --git a/tests/Integration/Api/Client/Server/CommandControllerTest.php b/tests/Integration/Api/Client/Server/CommandControllerTest.php index 787b0c705..b80393e0d 100644 --- a/tests/Integration/Api/Client/Server/CommandControllerTest.php +++ b/tests/Integration/Api/Client/Server/CommandControllerTest.php @@ -52,12 +52,12 @@ class CommandControllerTest extends ClientApiIntegrationTestCase { [$user, $server] = $this->generateTestAccount([Permission::ACTION_CONTROL_CONSOLE]); - $mock = $this->mock(DaemonCommandRepository::class); - $mock->expects('setServer') - ->with(\Mockery::on(fn (Server $value) => $value->is($server))) - ->andReturnSelf(); + $server = \Mockery::mock($server)->makePartial(); + $server->expects('query->where->firstOrFail')->andReturns($server); - $mock->expects('send')->with('say Test')->andReturn(new GuzzleResponse()); + $this->instance(Server::class, $server); + + $server->expects('send')->with('say Test')->andReturn(new GuzzleResponse()); $response = $this->actingAs($user)->postJson("/api/client/servers/$server->uuid/command", [ 'command' => 'say Test', @@ -74,13 +74,16 @@ class CommandControllerTest extends ClientApiIntegrationTestCase { [$user, $server] = $this->generateTestAccount(); - $mock = $this->mock(DaemonCommandRepository::class); - $mock->expects('setServer->send')->andThrows( + $server = \Mockery::mock($server)->makePartial(); + $server->expects('query->where->firstOrFail')->andReturns($server); + $server->expects('send')->andThrows( new DaemonConnectionException( new BadResponseException('', new Request('GET', 'test'), new GuzzleResponse(Response::HTTP_BAD_GATEWAY)) ) ); + $this->instance(Server::class, $server); + $response = $this->actingAs($user)->postJson("/api/client/servers/$server->uuid/command", [ 'command' => 'say Test', ]);