From 633bba6d6ec52ccebd6a17c13152509b23a249dc Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 24 Feb 2018 11:57:12 -0600 Subject: [PATCH] Add support for external_id on servers, closes #975 --- CHANGELOG.md | 1 + .../Controllers/Admin/ServersController.php | 2 +- .../Servers/StoreServerRequest.php | 1 + app/Models/Server.php | 15 +++++---- .../Servers/DetailsModificationService.php | 1 + .../Servers/ServerCreationService.php | 1 + .../Api/Application/ServerTransformer.php | 6 ++-- ...dd_external_id_column_to_servers_table.php | 32 +++++++++++++++++++ .../admin/servers/view/details.blade.php | 9 ++++-- .../admin/servers/view/index.blade.php | 16 ++++++++-- .../DetailsModificationServiceTest.php | 4 ++- 11 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 database/migrations/2018_02_24_112356_add_external_id_column_to_servers_table.php diff --git a/CHANGELOG.md b/CHANGELOG.md index dbb5c7c38..cf3161d61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ This project follows [Semantic Versioning](http://semver.org) guidelines. ### Added * Adds ability to include egg variables on an API request. +* Added `external_id` column to servers that allows for easier linking with external services such as WHMCS. ## v0.7.1 (Derelict Dermodactylus) ### Fixed diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index 9e22bc1ed..6b9d44cbb 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -406,7 +406,7 @@ class ServersController extends Controller public function setDetails(Request $request, Server $server) { $this->detailsModificationService->handle($server, $request->only([ - 'owner_id', 'name', 'description', + 'owner_id', 'external_id', 'name', 'description', ])); $this->alert->success(trans('admin/server.alerts.details_updated'))->flash(); diff --git a/app/Http/Requests/Api/Application/Servers/StoreServerRequest.php b/app/Http/Requests/Api/Application/Servers/StoreServerRequest.php index ff389e05e..997c2e396 100644 --- a/app/Http/Requests/Api/Application/Servers/StoreServerRequest.php +++ b/app/Http/Requests/Api/Application/Servers/StoreServerRequest.php @@ -31,6 +31,7 @@ class StoreServerRequest extends ApplicationApiRequest $rules = Server::getCreateRules(); return [ + 'external_id' => $rules['external_id'], 'name' => $rules['name'], 'description' => array_merge(['nullable'], $rules['description']), 'user' => $rules['owner_id'], diff --git a/app/Models/Server.php b/app/Models/Server.php index f10e52b1d..458bff1d6 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -53,6 +53,7 @@ class Server extends Model implements CleansAttributes, ValidableContract * @var array */ protected static $applicationRules = [ + 'external_id' => 'sometimes', 'owner_id' => 'required', 'name' => 'required', 'memory' => 'required', @@ -74,6 +75,7 @@ class Server extends Model implements CleansAttributes, ValidableContract * @var array */ protected static $dataIntegrityRules = [ + 'external_id' => 'nullable|string|between:1,191|unique:servers', 'owner_id' => 'integer|exists:users,id', 'name' => 'string|min:1|max:255', 'node_id' => 'exists:nodes,id', @@ -122,13 +124,14 @@ class Server extends Model implements CleansAttributes, ValidableContract * @var array */ protected $searchableColumns = [ - 'name' => 50, - 'uuidShort' => 10, - 'uuid' => 10, - 'pack.name' => 5, - 'user.email' => 20, - 'user.username' => 20, + 'name' => 100, + 'uuid' => 80, + 'uuidShort' => 80, + 'external_id' => 50, + 'user.email' => 40, + 'user.username' => 30, 'node.name' => 10, + 'pack.name' => 10, ]; /** diff --git a/app/Services/Servers/DetailsModificationService.php b/app/Services/Servers/DetailsModificationService.php index 78d8eb31e..523185f2e 100644 --- a/app/Services/Servers/DetailsModificationService.php +++ b/app/Services/Servers/DetailsModificationService.php @@ -69,6 +69,7 @@ class DetailsModificationService $this->connection->beginTransaction(); $response = $this->repository->setFreshModel($this->getUpdatedModel())->update($server->id, [ + 'external_id' => array_get($data, 'external_id'), 'owner_id' => array_get($data, 'owner_id'), 'name' => array_get($data, 'name'), 'description' => array_get($data, 'description') ?? '', diff --git a/app/Services/Servers/ServerCreationService.php b/app/Services/Servers/ServerCreationService.php index a57e7712b..0c5ecd0d4 100644 --- a/app/Services/Servers/ServerCreationService.php +++ b/app/Services/Servers/ServerCreationService.php @@ -211,6 +211,7 @@ class ServerCreationService private function createModel(array $data): Server { return $this->repository->create([ + 'external_id' => array_get($data, 'external_id'), 'uuid' => Uuid::uuid4()->toString(), 'uuidShort' => str_random(8), 'node_id' => array_get($data, 'node_id'), diff --git a/app/Transformers/Api/Application/ServerTransformer.php b/app/Transformers/Api/Application/ServerTransformer.php index 914449ef2..69115d1ed 100644 --- a/app/Transformers/Api/Application/ServerTransformer.php +++ b/app/Transformers/Api/Application/ServerTransformer.php @@ -2,7 +2,6 @@ namespace Pterodactyl\Transformers\Api\Application; -use Cake\Chronos\Chronos; use Pterodactyl\Models\Server; use Pterodactyl\Services\Acl\Api\AdminAcl; use Pterodactyl\Services\Servers\EnvironmentService; @@ -63,6 +62,7 @@ class ServerTransformer extends BaseTransformer { return [ 'id' => $server->getKey(), + 'external_id' => $server->external_id, 'uuid' => $server->uuid, 'identifier' => $server->uuidShort, 'name' => $server->name, @@ -87,8 +87,8 @@ class ServerTransformer extends BaseTransformer 'installed' => (int) $server->installed === 1, 'environment' => $this->environmentService->handle($server), ], - 'created_at' => Chronos::createFromFormat(Chronos::DEFAULT_TO_STRING_FORMAT, $server->created_at)->setTimezone('UTC')->toIso8601String(), - 'updated_at' => Chronos::createFromFormat(Chronos::DEFAULT_TO_STRING_FORMAT, $server->updated_at)->setTimezone('UTC')->toIso8601String(), + $server->getUpdatedAtColumn() => $this->formatTimestamp($server->updated_at), + $server->getCreatedAtColumn() => $this->formatTimestamp($server->created_at), ]; } diff --git a/database/migrations/2018_02_24_112356_add_external_id_column_to_servers_table.php b/database/migrations/2018_02_24_112356_add_external_id_column_to_servers_table.php new file mode 100644 index 000000000..2c8af99e2 --- /dev/null +++ b/database/migrations/2018_02_24_112356_add_external_id_column_to_servers_table.php @@ -0,0 +1,32 @@ +string('external_id')->after('id')->nullable()->unique(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('servers', function (Blueprint $table) { + $table->dropColumn('external_id'); + }); + } +} diff --git a/resources/themes/pterodactyl/admin/servers/view/details.blade.php b/resources/themes/pterodactyl/admin/servers/view/details.blade.php index 60bcded6d..bd4a5aef2 100644 --- a/resources/themes/pterodactyl/admin/servers/view/details.blade.php +++ b/resources/themes/pterodactyl/admin/servers/view/details.blade.php @@ -47,12 +47,17 @@
- +

Character limits: a-zA-Z0-9_- and [Space] (max 35 characters).

- + + +

Leave empty to not assign an external identifier for this server. The external ID should be unique to this server and not be in use by any other servers.

+
+
+ diff --git a/resources/themes/pterodactyl/admin/servers/view/index.blade.php b/resources/themes/pterodactyl/admin/servers/view/index.blade.php index 58deaa924..1d377a195 100644 --- a/resources/themes/pterodactyl/admin/servers/view/index.blade.php +++ b/resources/themes/pterodactyl/admin/servers/view/index.blade.php @@ -47,6 +47,18 @@
+ + + + + + + @if(is_null($server->external_id)) + + @else + + @endif + @@ -127,7 +139,7 @@
-

{{ str_limit($server->user->username, 8) }}

+

{{ str_limit($server->user->username, 16) }}

Server Owner

@@ -139,7 +151,7 @@
-

{{ str_limit($server->node->name, 8) }}

+

{{ str_limit($server->node->name, 16) }}

Server Node

diff --git a/tests/Unit/Services/Servers/DetailsModificationServiceTest.php b/tests/Unit/Services/Servers/DetailsModificationServiceTest.php index bd049d018..bbb7ab1ff 100644 --- a/tests/Unit/Services/Servers/DetailsModificationServiceTest.php +++ b/tests/Unit/Services/Servers/DetailsModificationServiceTest.php @@ -58,6 +58,7 @@ class DetailsModificationServiceTest extends TestCase $this->connection->shouldReceive('beginTransaction')->once()->withNoArgs()->andReturnNull(); $this->repository->shouldReceive('setFreshModel')->once()->with(false)->andReturnSelf(); $this->repository->shouldReceive('update')->once()->with($server->id, [ + 'external_id' => null, 'owner_id' => $data['owner_id'], 'name' => $data['name'], 'description' => $data['description'], @@ -95,11 +96,12 @@ class DetailsModificationServiceTest extends TestCase 'owner_id' => 1, ]); - $data = ['owner_id' => 2, 'name' => 'New Name', 'description' => 'New Description']; + $data = ['owner_id' => 2, 'name' => 'New Name', 'description' => 'New Description', 'external_id' => 'abcd1234']; $this->connection->shouldReceive('beginTransaction')->once()->withNoArgs()->andReturnNull(); $this->repository->shouldReceive('setFreshModel')->once()->with(false)->andReturnSelf(); $this->repository->shouldReceive('update')->once()->with($server->id, [ + 'external_id' => 'abcd1234', 'owner_id' => $data['owner_id'], 'name' => $data['name'], 'description' => $data['description'],
Internal Identifier{{ $server->id }}
External IdentifierNot Set{{ $server->external_id }}
UUID / Docker Container ID {{ $server->uuid }}