Add API endpoint for getting server resource utilization, closes #900
This endpoint is throttled to 15 requests per minute to avoid destroying the daemon since clients can use it.
This commit is contained in:
parent
bac02f64e3
commit
3e2ac981a9
3 changed files with 115 additions and 0 deletions
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
88
app/Transformers/Api/Client/StatsTransformer.php
Normal file
88
app/Transformers/Api/Client/StatsTransformer.php
Normal 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';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,9 @@ Route::get('/', 'ClientController@index')->name('api.client.index');
|
||||||
*/
|
*/
|
||||||
Route::group(['prefix' => '/servers/{server}', 'middleware' => [AuthenticateClientAccess::class]], function () {
|
Route::group(['prefix' => '/servers/{server}', 'middleware' => [AuthenticateClientAccess::class]], function () {
|
||||||
Route::get('/', 'Servers\ServerController@index')->name('api.client.servers.view');
|
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('/command', 'Servers\CommandController@index')->name('api.client.servers.command');
|
||||||
Route::post('/power', 'Servers\PowerController@index')->name('api.client.servers.power');
|
Route::post('/power', 'Servers\PowerController@index')->name('api.client.servers.power');
|
||||||
|
|
Loading…
Reference in a new issue