diff --git a/app/Contracts/Repository/ServerRepositoryInterface.php b/app/Contracts/Repository/ServerRepositoryInterface.php index 71169088c..8851c5798 100644 --- a/app/Contracts/Repository/ServerRepositoryInterface.php +++ b/app/Contracts/Repository/ServerRepositoryInterface.php @@ -171,4 +171,16 @@ interface ServerRepositoryInterface extends RepositoryInterface, SearchableInter * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator */ public function loadAllServersForNode(int $node, int $limit): LengthAwarePaginator; + + /** + * Returns every server that exists for a given node. + * + * This is different from {@see loadAllServersForNode} because + * it does not paginate the response. + * + * @param int $node + * + * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection + */ + public function loadEveryServerForNode(int $node); } diff --git a/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php b/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php index c9d9f4bc6..2e4aa8ab1 100644 --- a/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php +++ b/app/Http/Controllers/Api/Remote/Servers/ServerDetailsController.php @@ -5,6 +5,7 @@ namespace Pterodactyl\Http\Controllers\Api\Remote\Servers; use Illuminate\Http\Request; use Illuminate\Http\JsonResponse; use Pterodactyl\Http\Controllers\Controller; +use Pterodactyl\Repositories\Eloquent\NodeRepository; use Pterodactyl\Services\Eggs\EggConfigurationService; use Pterodactyl\Repositories\Eloquent\ServerRepository; use Pterodactyl\Services\Servers\ServerConfigurationStructureService; @@ -26,21 +27,29 @@ class ServerDetailsController extends Controller */ private $configurationStructureService; + /** + * @var \Pterodactyl\Repositories\Eloquent\NodeRepository + */ + private $nodeRepository; + /** * ServerConfigurationController constructor. * * @param \Pterodactyl\Repositories\Eloquent\ServerRepository $repository * @param \Pterodactyl\Services\Servers\ServerConfigurationStructureService $configurationStructureService * @param \Pterodactyl\Services\Eggs\EggConfigurationService $eggConfigurationService + * @param \Pterodactyl\Repositories\Eloquent\NodeRepository $nodeRepository */ public function __construct( ServerRepository $repository, ServerConfigurationStructureService $configurationStructureService, - EggConfigurationService $eggConfigurationService + EggConfigurationService $eggConfigurationService, + NodeRepository $nodeRepository ) { $this->eggConfigurationService = $eggConfigurationService; $this->repository = $repository; $this->configurationStructureService = $configurationStructureService; + $this->nodeRepository = $nodeRepository; } /** @@ -62,4 +71,30 @@ class ServerDetailsController extends Controller 'process_configuration' => $this->eggConfigurationService->handle($server), ]); } + + /** + * Lists all servers with their configurations that are assigned to the requesting node. + * + * @param \Illuminate\Http\Request $request + * + * @return \Illuminate\Http\JsonResponse + * + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException + */ + public function list(Request $request) + { + $node = $request->attributes->get('node'); + $servers = $this->repository->loadEveryServerForNode($node->id); + + $configurations = []; + + foreach ($servers as $server) { + $configurations[$server->uuid] = [ + 'settings' => $this->configurationStructureService->handle($server), + 'process_configuration' => $this->eggConfigurationService->handle($server), + ]; + } + + return JsonResponse::create($configurations); + } } diff --git a/app/Http/Middleware/Api/Daemon/DaemonAuthenticate.php b/app/Http/Middleware/Api/Daemon/DaemonAuthenticate.php index 8735c8d26..a2b1e716e 100644 --- a/app/Http/Middleware/Api/Daemon/DaemonAuthenticate.php +++ b/app/Http/Middleware/Api/Daemon/DaemonAuthenticate.php @@ -69,7 +69,7 @@ class DaemonAuthenticate // Ensure that all of the correct parts are provided in the header. if (count($parts) !== 2 || empty($parts[0]) || empty($parts[1])) { throw new BadRequestHttpException( - 'The Authorization headed provided was not in a valid format.', + 'The Authorization headed provided was not in a valid format.' ); } diff --git a/app/Repositories/Eloquent/ServerRepository.php b/app/Repositories/Eloquent/ServerRepository.php index 874b1cc95..e3e398d5e 100644 --- a/app/Repositories/Eloquent/ServerRepository.php +++ b/app/Repositories/Eloquent/ServerRepository.php @@ -378,4 +378,22 @@ class ServerRepository extends EloquentRepository implements ServerRepositoryInt ->where('node_id', '=', $node) ->paginate($limit); } + + /** + * Returns every server that exists for a given node. + * + * This is different from {@see loadAllServersForNode} because + * it does not paginate the response. + * + * @param int $node + * + * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection + */ + public function loadEveryServerForNode(int $node) + { + return $this->getBuilder() + ->with('nest') + ->where('node_id', '=', $node) + ->get(); + } } diff --git a/routes/api-remote.php b/routes/api-remote.php index 1d09562e8..3cf564e83 100644 --- a/routes/api-remote.php +++ b/routes/api-remote.php @@ -7,6 +7,9 @@ Route::post('/download-file', 'FileDownloadController@index'); // Routes for the Wings daemon. Route::post('/sftp/auth', 'SftpAuthenticationController'); + +Route::get('/servers', 'Servers\ServerDetailsController@list'); + Route::group(['prefix' => '/servers/{uuid}'], function () { Route::get('/', 'Servers\ServerDetailsController'); Route::get('/install', 'Servers\ServerInstallController@index');