Add API endpoint for getting server resource utilization, closes

This endpoint is throttled to 15 requests per minute to avoid destroying the daemon since clients can use it.
This commit is contained in:
Dane Everitt 2018-03-17 14:01:53 -05:00
parent bac02f64e3
commit 3e2ac981a9
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
3 changed files with 115 additions and 0 deletions
app
Http/Controllers/Api/Client/Servers
Transformers/Api/Client
routes

View file

@ -0,0 +1,24 @@
<?php
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
use Pterodactyl\Models\Server;
use Pterodactyl\Transformers\Api\Client\StatsTransformer;
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
use Pterodactyl\Http\Requests\Api\Client\Servers\GetServerRequest;
class ResourceUtilizationController extends ClientApiController
{
/**
* Return the current resource utilization for a server.
*
* @param \Pterodactyl\Http\Requests\Api\Client\Servers\GetServerRequest $request
* @return array
*/
public function index(GetServerRequest $request): array
{
return $this->fractal->item($request->getModel(Server::class))
->transformWith($this->getTransformer(StatsTransformer::class))
->toArray();
}
}

View file

@ -0,0 +1,88 @@
<?php
namespace Pterodactyl\Transformers\Api\Client;
use Pterodactyl\Models\Server;
use Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface;
class StatsTransformer extends BaseClientTransformer
{
/**
* @var \Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface
*/
private $repository;
/**
* Perform dependency injection.
*
* @param \Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface $repository
*/
public function handle(ServerRepositoryInterface $repository)
{
$this->repository = $repository;
}
/**
* @return string
*/
public function getResourceName(): string
{
return 'stats';
}
/**
* Transform stats from the daemon into a result set that can be used in
* the client API.
*
* @param \Pterodactyl\Models\Server $model
* @return array
*/
public function transform(Server $model)
{
try {
$stats = $this->repository->setServer($model)->details();
} catch (RequestException $exception) {
throw new DaemonConnectionException($exception);
}
$object = json_decode($stats->getBody()->getContents());
return [
'state' => $this->transformState(object_get($object, 'status', 0)),
'memory' => [
'current' => round(object_get($object, 'proc.memory.total', 0) / 1024 / 1024),
'limit' => floatval($model->memory),
],
'cpu' => [
'current' => object_get($object, 'proc.cpu.total', 0),
'cores' => object_get($object, 'proc.cpu.cores', []),
'limit' => floatval($model->cpu),
],
'disk' => [
'current' => round(object_get($object, 'proc.disk.used', 0)),
'limit' => floatval($model->disk),
],
];
}
/**
* Transform the state returned by the daemon into a human readable string.
*
* @param int $state
* @return string
*/
private function transformState(int $state): string
{
switch ($state) {
case 1:
return 'on';
case 2:
return 'starting';
case 3:
return 'stopping';
case 0:
default:
return 'off';
}
}
}

View file

@ -22,6 +22,9 @@ Route::get('/', 'ClientController@index')->name('api.client.index');
*/
Route::group(['prefix' => '/servers/{server}', 'middleware' => [AuthenticateClientAccess::class]], function () {
Route::get('/', 'Servers\ServerController@index')->name('api.client.servers.view');
Route::get('/utilization', 'Servers\ResourceUtilizationController@index')
->middleware(['throttle:15,1'])
->name('api.client.servers.resources');
Route::post('/command', 'Servers\CommandController@index')->name('api.client.servers.command');
Route::post('/power', 'Servers\PowerController@index')->name('api.client.servers.power');