2021-06-05 09:26:32 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Classes;
|
|
|
|
|
|
|
|
use App\Models\Egg;
|
|
|
|
use App\Models\Nest;
|
|
|
|
use App\Models\Node;
|
|
|
|
use App\Models\Server;
|
|
|
|
use Exception;
|
|
|
|
use Illuminate\Http\Client\PendingRequest;
|
|
|
|
use Illuminate\Http\Client\Response;
|
|
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
|
|
|
|
class Pterodactyl
|
|
|
|
{
|
2021-11-13 10:56:34 +00:00
|
|
|
/**
|
|
|
|
* @description per_page option to pull more than the default 50 from pterodactyl
|
|
|
|
*/
|
2021-12-23 13:48:04 +00:00
|
|
|
public const PER_PAGE = 200;
|
2021-11-13 10:56:34 +00:00
|
|
|
|
2021-06-09 18:53:58 +00:00
|
|
|
//TODO: Extend error handling (maybe logger for more errors when debugging)
|
2021-06-06 10:11:35 +00:00
|
|
|
|
2021-06-05 09:26:32 +00:00
|
|
|
/**
|
2021-11-07 00:47:16 +00:00
|
|
|
* @return PendingRequest
|
2021-06-05 09:26:32 +00:00
|
|
|
*/
|
2021-11-07 00:47:16 +00:00
|
|
|
public static function client()
|
2021-06-05 09:26:32 +00:00
|
|
|
{
|
2021-11-07 00:47:16 +00:00
|
|
|
return Http::withHeaders([
|
2022-01-15 17:16:51 +00:00
|
|
|
'Authorization' => 'Bearer ' . config("SETTINGS::SYSTEM:PTERODACTYL:TOKEN"),
|
2021-11-07 00:47:16 +00:00
|
|
|
'Content-type' => 'application/json',
|
|
|
|
'Accept' => 'Application/vnd.pterodactyl.v1+json',
|
2022-01-15 17:16:51 +00:00
|
|
|
])->baseUrl(config("SETTINGS::SYSTEM:PTERODACTYL:URL") . '/api');
|
2021-06-05 09:26:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-11-07 00:47:16 +00:00
|
|
|
* @return Exception
|
2021-06-05 09:26:32 +00:00
|
|
|
*/
|
2022-02-07 17:15:17 +00:00
|
|
|
private static function getException(string $message = "", int $status = 0): Exception
|
2021-06-05 09:26:32 +00:00
|
|
|
{
|
2022-02-07 17:15:17 +00:00
|
|
|
if ($status == 404) {
|
2022-02-08 08:30:42 +00:00
|
|
|
return new Exception("Ressource does not exist on pterodactyl - " . $message, 404);
|
2022-02-07 17:15:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ($status == 403) {
|
|
|
|
return new Exception("No permission on pterodactyl, check pterodactyl token and permissions - " . $message, 403);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($status == 401) {
|
|
|
|
return new Exception("No pterodactyl token set - " . $message, 401);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($status == 500) {
|
|
|
|
return new Exception("Pterodactyl server error - " . $message, 500);
|
|
|
|
}
|
|
|
|
|
|
|
|
return new Exception('Request Failed, is pterodactyl set-up correctly? - ' . $message);
|
2021-06-05 09:26:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Nest $nest
|
|
|
|
* @return mixed
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public static function getEggs(Nest $nest)
|
|
|
|
{
|
2021-12-22 14:11:13 +00:00
|
|
|
try {
|
|
|
|
$response = self::client()->get("/application/nests/{$nest->id}/eggs?include=nest,variables&per_page=" . self::PER_PAGE);
|
|
|
|
} catch (Exception $e) {
|
2022-02-07 17:15:17 +00:00
|
|
|
throw self::getException($e->getMessage());
|
2021-12-22 14:11:13 +00:00
|
|
|
}
|
2022-02-07 17:15:17 +00:00
|
|
|
if ($response->failed()) throw self::getException("Failed to get eggs from pterodactyl - ", $response->status());
|
2021-06-05 09:26:32 +00:00
|
|
|
return $response->json()['data'];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return mixed
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public static function getNodes()
|
|
|
|
{
|
2021-12-22 14:11:13 +00:00
|
|
|
try {
|
|
|
|
$response = self::client()->get('/application/nodes?per_page=' . self::PER_PAGE);
|
|
|
|
} catch (Exception $e) {
|
2022-02-07 17:15:17 +00:00
|
|
|
throw self::getException($e->getMessage());
|
2021-12-22 14:11:13 +00:00
|
|
|
}
|
2022-02-07 17:15:17 +00:00
|
|
|
if ($response->failed()) throw self::getException("Failed to get nodes from pterodactyl - ", $response->status());
|
2021-06-05 09:26:32 +00:00
|
|
|
return $response->json()['data'];
|
|
|
|
}
|
2022-08-11 06:06:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return mixed
|
|
|
|
* @throws Exception
|
|
|
|
* @description Returns the infos of a single node
|
|
|
|
*/
|
|
|
|
public static function getNode($id) {
|
|
|
|
try {
|
|
|
|
$response = self::client()->get('/application/nodes/' . $id);
|
|
|
|
} catch(Exception $e) {
|
|
|
|
throw self::getException($e->getMessage());
|
|
|
|
}
|
|
|
|
if($response->failed()) throw self::getException("Failed to get node id " . $id . " - " . $response->status());
|
|
|
|
return $response->json()['attributes'];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static function getServers() {
|
|
|
|
try {
|
|
|
|
$response = self::client()->get('/application/servers');
|
|
|
|
} catch (Exception $e) {
|
|
|
|
throw self::getException($e->getMessage());
|
|
|
|
}
|
|
|
|
if($response->failed()) throw self::getException("Failed to get list of servers - ", $response->status());
|
|
|
|
return $response->json()['data'];
|
|
|
|
}
|
2021-06-05 09:26:32 +00:00
|
|
|
|
2021-11-07 11:10:46 +00:00
|
|
|
/**
|
|
|
|
* @return null
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public static function getNests()
|
|
|
|
{
|
2021-12-22 14:11:13 +00:00
|
|
|
try {
|
|
|
|
$response = self::client()->get('/application/nests?per_page=' . self::PER_PAGE);
|
|
|
|
} catch (Exception $e) {
|
2022-02-07 17:15:17 +00:00
|
|
|
throw self::getException($e->getMessage());
|
2021-12-22 14:11:13 +00:00
|
|
|
}
|
2022-02-07 17:15:17 +00:00
|
|
|
if ($response->failed()) throw self::getException("Failed to get nests from pterodactyl", $response->status());
|
2021-11-07 11:10:46 +00:00
|
|
|
return $response->json()['data'];
|
|
|
|
}
|
|
|
|
|
2021-06-05 09:26:32 +00:00
|
|
|
/**
|
|
|
|
* @return mixed
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public static function getLocations()
|
|
|
|
{
|
2021-12-22 14:11:13 +00:00
|
|
|
try {
|
|
|
|
$response = self::client()->get('/application/locations?per_page=' . self::PER_PAGE);
|
|
|
|
} catch (Exception $e) {
|
2022-02-07 17:15:17 +00:00
|
|
|
throw self::getException($e->getMessage());
|
2021-12-22 14:11:13 +00:00
|
|
|
}
|
2022-02-07 17:15:17 +00:00
|
|
|
if ($response->failed()) throw self::getException("Failed to get locations from pterodactyl - ", $response->status());
|
2021-12-22 14:11:13 +00:00
|
|
|
|
2021-06-05 09:26:32 +00:00
|
|
|
return $response->json()['data'];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Node $node
|
|
|
|
* @return mixed
|
2021-11-07 11:10:46 +00:00
|
|
|
* @throws Exception
|
2021-06-05 09:26:32 +00:00
|
|
|
*/
|
|
|
|
public static function getFreeAllocationId(Node $node)
|
|
|
|
{
|
2021-06-30 21:53:28 +00:00
|
|
|
return self::getFreeAllocations($node)[0]['attributes']['id'] ?? null;
|
2021-06-05 09:26:32 +00:00
|
|
|
}
|
|
|
|
|
2021-11-07 00:47:16 +00:00
|
|
|
/**
|
|
|
|
* @param Node $node
|
|
|
|
* @return array|mixed|null
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public static function getFreeAllocations(Node $node)
|
|
|
|
{
|
|
|
|
$response = self::getAllocations($node);
|
|
|
|
$freeAllocations = [];
|
|
|
|
|
|
|
|
if (isset($response['data'])) {
|
|
|
|
if (!empty($response['data'])) {
|
|
|
|
foreach ($response['data'] as $allocation) {
|
|
|
|
if (!$allocation['attributes']['assigned']) array_push($freeAllocations, $allocation);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $freeAllocations;
|
|
|
|
}
|
2021-06-05 09:26:32 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Node $node
|
2021-11-07 11:10:46 +00:00
|
|
|
* @return array|mixed
|
2021-06-05 09:26:32 +00:00
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public static function getAllocations(Node $node)
|
|
|
|
{
|
2022-01-15 17:16:51 +00:00
|
|
|
$per_page = config('SETTINGS::SERVER:ALLOCATION_LIMIT', 200);
|
2021-12-22 14:11:13 +00:00
|
|
|
try {
|
|
|
|
$response = self::client()->get("/application/nodes/{$node->id}/allocations?per_page={$per_page}");
|
|
|
|
} catch (Exception $e) {
|
2022-02-07 17:15:17 +00:00
|
|
|
throw self::getException($e->getMessage());
|
2021-12-22 14:11:13 +00:00
|
|
|
}
|
2022-02-07 17:15:17 +00:00
|
|
|
if ($response->failed()) throw self::getException("Failed to get allocations from pterodactyl - ", $response->status());
|
2021-12-22 14:11:13 +00:00
|
|
|
|
2021-06-05 09:26:32 +00:00
|
|
|
return $response->json();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param String $route
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public static function url(string $route): string
|
|
|
|
{
|
2022-01-15 17:16:51 +00:00
|
|
|
return config("SETTINGS::SYSTEM:PTERODACTYL:URL") . $route;
|
2021-06-05 09:26:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Server $server
|
|
|
|
* @param Egg $egg
|
2021-06-30 21:53:28 +00:00
|
|
|
* @param int $allocationId
|
2021-06-05 09:26:32 +00:00
|
|
|
* @return Response
|
|
|
|
*/
|
2021-06-30 21:53:28 +00:00
|
|
|
public static function createServer(Server $server, Egg $egg, int $allocationId)
|
2021-06-05 09:26:32 +00:00
|
|
|
{
|
|
|
|
return self::client()->post("/application/servers", [
|
2021-11-07 11:10:46 +00:00
|
|
|
"name" => $server->name,
|
|
|
|
"external_id" => $server->id,
|
|
|
|
"user" => $server->user->pterodactyl_id,
|
|
|
|
"egg" => $egg->id,
|
|
|
|
"docker_image" => $egg->docker_image,
|
|
|
|
"startup" => $egg->startup,
|
|
|
|
"environment" => $egg->getEnvironmentVariables(),
|
|
|
|
"limits" => [
|
2021-06-05 09:26:32 +00:00
|
|
|
"memory" => $server->product->memory,
|
2021-06-06 10:11:35 +00:00
|
|
|
"swap" => $server->product->swap,
|
|
|
|
"disk" => $server->product->disk,
|
|
|
|
"io" => $server->product->io,
|
|
|
|
"cpu" => $server->product->cpu
|
2021-06-05 09:26:32 +00:00
|
|
|
],
|
2021-11-07 11:10:46 +00:00
|
|
|
"feature_limits" => [
|
2021-06-06 10:11:35 +00:00
|
|
|
"databases" => $server->product->databases,
|
|
|
|
"backups" => $server->product->backups,
|
2021-08-09 22:49:28 +00:00
|
|
|
"allocations" => $server->product->allocations,
|
2021-06-05 09:26:32 +00:00
|
|
|
],
|
2021-06-06 10:11:35 +00:00
|
|
|
"allocation" => [
|
2021-06-30 21:53:28 +00:00
|
|
|
"default" => $allocationId
|
2021-06-05 09:26:32 +00:00
|
|
|
]
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
2021-06-06 10:11:35 +00:00
|
|
|
public static function suspendServer(Server $server)
|
|
|
|
{
|
2021-12-22 14:11:13 +00:00
|
|
|
try {
|
|
|
|
$response = self::client()->post("/application/servers/$server->pterodactyl_id/suspend");
|
|
|
|
} catch (Exception $e) {
|
2022-02-07 17:15:17 +00:00
|
|
|
throw self::getException($e->getMessage());
|
2021-12-22 14:11:13 +00:00
|
|
|
}
|
2022-02-07 17:15:17 +00:00
|
|
|
if ($response->failed()) throw self::getException("Failed to suspend server from pterodactyl - ", $response->status());
|
2021-12-22 14:11:13 +00:00
|
|
|
|
2021-06-05 09:26:32 +00:00
|
|
|
return $response;
|
|
|
|
}
|
|
|
|
|
2021-06-06 10:11:35 +00:00
|
|
|
public static function unSuspendServer(Server $server)
|
|
|
|
{
|
2021-12-22 14:11:13 +00:00
|
|
|
try {
|
|
|
|
$response = self::client()->post("/application/servers/$server->pterodactyl_id/unsuspend");
|
|
|
|
} catch (Exception $e) {
|
2022-02-07 17:15:17 +00:00
|
|
|
throw self::getException($e->getMessage());
|
2021-12-22 14:11:13 +00:00
|
|
|
}
|
2022-02-07 17:15:17 +00:00
|
|
|
if ($response->failed()) throw self::getException("Failed to unsuspend server from pterodactyl - ", $response->status());
|
2021-12-22 14:11:13 +00:00
|
|
|
|
2021-06-05 09:26:32 +00:00
|
|
|
return $response;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-11-07 00:47:16 +00:00
|
|
|
* Get user by pterodactyl id
|
|
|
|
* @param int $pterodactylId
|
|
|
|
* @return mixed
|
2021-06-05 09:26:32 +00:00
|
|
|
*/
|
2021-11-07 00:47:16 +00:00
|
|
|
public function getUser(int $pterodactylId)
|
2021-06-05 09:26:32 +00:00
|
|
|
{
|
2021-12-22 14:11:13 +00:00
|
|
|
try {
|
|
|
|
$response = self::client()->get("/application/users/{$pterodactylId}");
|
|
|
|
} catch (Exception $e) {
|
2022-02-07 17:15:17 +00:00
|
|
|
throw self::getException($e->getMessage());
|
2021-12-22 14:11:13 +00:00
|
|
|
}
|
2022-02-07 17:15:17 +00:00
|
|
|
if ($response->failed()) throw self::getException("Failed to get user from pterodactyl - ", $response->status());
|
2021-12-22 14:11:13 +00:00
|
|
|
|
|
|
|
return $response->json()['attributes'];
|
|
|
|
}
|
2021-11-07 00:47:16 +00:00
|
|
|
|
2021-12-22 14:11:13 +00:00
|
|
|
/**
|
|
|
|
* Get serverAttributes by pterodactyl id
|
|
|
|
* @param int $pterodactylId
|
|
|
|
* @return mixed
|
|
|
|
*/
|
2022-02-07 14:04:57 +00:00
|
|
|
public static function getServerAttributes(int $pterodactylId)
|
2021-12-22 14:11:13 +00:00
|
|
|
{
|
|
|
|
try {
|
2021-12-23 13:48:04 +00:00
|
|
|
$response = self::client()->get("/application/servers/{$pterodactylId}?include=egg,node,nest,location");
|
2021-12-22 14:11:13 +00:00
|
|
|
} catch (Exception $e) {
|
2022-02-07 17:15:17 +00:00
|
|
|
throw self::getException($e->getMessage());
|
2021-12-22 14:11:13 +00:00
|
|
|
}
|
2022-02-07 17:15:17 +00:00
|
|
|
|
|
|
|
//print response body
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ($response->failed()) throw self::getException("Failed to get server attributes from pterodactyl - ", $response->status());
|
2021-11-07 00:47:16 +00:00
|
|
|
return $response->json()['attributes'];
|
2021-06-05 09:26:32 +00:00
|
|
|
}
|
|
|
|
}
|