Skip to content

Commit fa62a09

Browse files
committed
Refactor startup modification and environment variable services
Better setup, more flexibility, more tests.
1 parent 7022ec7 commit fa62a09

19 files changed

+642
-545
lines changed

app/Contracts/Repository/ServerRepositoryInterface.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,11 @@ public function getPrimaryAllocation($server, bool $refresh = false): Server;
6969
/**
7070
* Return enough data to be used for the creation of a server via the daemon.
7171
*
72-
* @param int $id
73-
* @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model
74-
*
75-
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
72+
* @param \Pterodactyl\Models\Server $server
73+
* @param bool $refresh
74+
* @return \Pterodactyl\Models\Server
7675
*/
77-
public function getDataForCreation($id);
76+
public function getDataForCreation(Server $server, bool $refresh = false): Server;
7877

7978
/**
8079
* Return a server as well as associated databases and their hosts.

app/Http/Controllers/Admin/ServersController.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
use Javascript;
1313
use Illuminate\Http\Request;
14+
use Pterodactyl\Models\User;
1415
use Pterodactyl\Models\Server;
1516
use Prologue\Alerts\AlertsMessageBag;
1617
use Pterodactyl\Exceptions\DisplayException;
@@ -570,10 +571,8 @@ public function delete(Request $request, Server $server)
570571
*/
571572
public function saveStartup(Request $request, Server $server)
572573
{
573-
$this->startupModificationService->isAdmin()->handle(
574-
$server,
575-
$request->except('_token')
576-
);
574+
$this->startupModificationService->setUserLevel(User::USER_LEVEL_ADMIN);
575+
$this->startupModificationService->handle($server, $request->except('_token'));
577576
$this->alert->success(trans('admin/server.alerts.startup_changed'))->flash();
578577

579578
return redirect()->route('admin.servers.view.startup', $server->id);

app/Http/Controllers/Server/Settings/StartupController.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Pterodactyl\Http\Controllers\Server\Settings;
44

55
use Illuminate\Http\Request;
6+
use Pterodactyl\Models\User;
67
use Illuminate\Http\RedirectResponse;
78
use Prologue\Alerts\AlertsMessageBag;
89
use Pterodactyl\Http\Controllers\Controller;
@@ -84,6 +85,7 @@ public function index(Request $request)
8485
*/
8586
public function update(UpdateStartupParametersFormRequest $request): RedirectResponse
8687
{
88+
$this->modificationService->setUserLevel(User::USER_LEVEL_USER);
8789
$this->modificationService->handle($request->attributes->get('server'), $request->normalize());
8890
$this->alert->success(trans('server.config.startup.edited'))->flash();
8991

app/Models/Node.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ class Node extends Model implements CleansAttributes, ValidableContract
2020
{
2121
use Eloquence, Notifiable, Validable;
2222

23+
const DAEMON_SECRET_LENGTH = 36;
24+
2325
/**
2426
* The table associated with the model.
2527
*

app/Models/User.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ class User extends Model implements
3232
{
3333
use Authenticatable, Authorizable, CanResetPassword, Eloquence, Notifiable, Validable;
3434

35+
const USER_LEVEL_USER = 0;
36+
const USER_LEVEL_ADMIN = 1;
37+
3538
/**
3639
* Level of servers to display when using access() on a user.
3740
*

app/Repositories/Eloquent/ServerRepository.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,16 +137,21 @@ public function getVariablesWithValues($id, $returnWithObject = false)
137137
}
138138

139139
/**
140-
* {@inheritdoc}
140+
* Return enough data to be used for the creation of a server via the daemon.
141+
*
142+
* @param \Pterodactyl\Models\Server $server
143+
* @param bool $refresh
144+
* @return \Pterodactyl\Models\Server
141145
*/
142-
public function getDataForCreation($id)
146+
public function getDataForCreation(Server $server, bool $refresh = false): Server
143147
{
144-
$instance = $this->getBuilder()->with(['allocation', 'allocations', 'pack', 'egg'])->find($id, $this->getColumns());
145-
if (! $instance) {
146-
throw new RecordNotFoundException();
148+
foreach (['allocation', 'allocations', 'pack', 'egg'] as $relation) {
149+
if (! $server->relationLoaded($relation) || $refresh) {
150+
$server->load($relation);
151+
}
147152
}
148153

149-
return $instance;
154+
return $server;
150155
}
151156

152157
/**
Lines changed: 53 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,37 @@
11
<?php
2-
/**
3-
* Pterodactyl - Panel
4-
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
5-
*
6-
* This software is licensed under the terms of the MIT license.
7-
* https://opensource.org/licenses/MIT
8-
*/
92

103
namespace Pterodactyl\Services\Servers;
114

125
use Pterodactyl\Models\Server;
6+
use Illuminate\Contracts\Config\Repository as ConfigRepository;
137
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
148

159
class EnvironmentService
1610
{
17-
const ENVIRONMENT_CASTS = [
18-
'STARTUP' => 'startup',
19-
'P_SERVER_LOCATION' => 'location.short',
20-
'P_SERVER_UUID' => 'uuid',
21-
];
22-
2311
/**
2412
* @var array
2513
*/
26-
protected $additional = [];
14+
private $additional = [];
15+
16+
/**
17+
* @var \Illuminate\Contracts\Config\Repository
18+
*/
19+
private $config;
2720

2821
/**
2922
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
3023
*/
31-
protected $repository;
24+
private $repository;
3225

3326
/**
3427
* EnvironmentService constructor.
3528
*
29+
* @param \Illuminate\Contracts\Config\Repository $config
3630
* @param \Pterodactyl\Contracts\Repository\ServerRepositoryInterface $repository
3731
*/
38-
public function __construct(ServerRepositoryInterface $repository)
32+
public function __construct(ConfigRepository $config, ServerRepositoryInterface $repository)
3933
{
34+
$this->config = $config;
4035
$this->repository = $repository;
4136
}
4237

@@ -46,42 +41,70 @@ public function __construct(ServerRepositoryInterface $repository)
4641
*
4742
* @param string $key
4843
* @param callable $closure
49-
* @return $this
5044
*/
51-
public function setEnvironmentKey($key, callable $closure)
45+
public function setEnvironmentKey(string $key, callable $closure)
5246
{
53-
$this->additional[] = [$key, $closure];
47+
$this->additional[$key] = $closure;
48+
}
5449

55-
return $this;
50+
/**
51+
* Return the dynamically added additional keys.
52+
*
53+
* @return array
54+
*/
55+
public function getEnvironmentKeys(): array
56+
{
57+
return $this->additional;
5658
}
5759

5860
/**
5961
* Take all of the environment variables configured for this server and return
6062
* them in an easy to process format.
6163
*
62-
* @param int|\Pterodactyl\Models\Server $server
64+
* @param \Pterodactyl\Models\Server $server
6365
* @return array
6466
*
6567
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
6668
*/
67-
public function process($server)
69+
public function handle(Server $server): array
6870
{
69-
if (! $server instanceof Server) {
70-
$server = $this->repository->find($server);
71-
}
72-
7371
$variables = $this->repository->getVariablesWithValues($server->id);
7472

75-
// Process static environment variables defined in this file.
76-
foreach (self::ENVIRONMENT_CASTS as $key => $object) {
73+
// Process environment variables defined in this file. This is done first
74+
// in order to allow run-time and config defined variables to take
75+
// priority over built-in values.
76+
foreach ($this->getEnvironmentMappings() as $key => $object) {
7777
$variables[$key] = object_get($server, $object);
7878
}
7979

80+
// Process variables set in the configuration file.
81+
foreach ($this->config->get('pterodactyl.environment_mappings', []) as $key => $object) {
82+
if (is_callable($object)) {
83+
$variables[$key] = call_user_func($object, $server);
84+
} else {
85+
$variables[$key] = object_get($server, $object);
86+
}
87+
}
88+
8089
// Process dynamically included environment variables.
81-
foreach ($this->additional as $item) {
82-
$variables[$item[0]] = call_user_func($item[1], $server);
90+
foreach ($this->additional as $key => $closure) {
91+
$variables[$key] = call_user_func($closure, $server);
8392
}
8493

8594
return $variables;
8695
}
96+
97+
/**
98+
* Return a mapping of Panel default environment variables.
99+
*
100+
* @return array
101+
*/
102+
final private function getEnvironmentMappings(): array
103+
{
104+
return [
105+
'STARTUP' => 'startup',
106+
'P_SERVER_LOCATION' => 'location.short',
107+
'P_SERVER_UUID' => 'uuid',
108+
];
109+
}
87110
}

app/Services/Servers/ServerConfigurationStructureService.php

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ class ServerConfigurationStructureService
1919
/**
2020
* @var \Pterodactyl\Services\Servers\EnvironmentService
2121
*/
22-
protected $environment;
22+
private $environment;
2323

2424
/**
2525
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
2626
*/
27-
protected $repository;
27+
private $repository;
2828

2929
/**
3030
* ServerConfigurationStructureService constructor.
@@ -41,19 +41,21 @@ public function __construct(
4141
}
4242

4343
/**
44-
* @param int|\Pterodactyl\Models\Server $server
44+
* Return a configuration array for a specific server when passed a server model.
45+
*
46+
* @param \Pterodactyl\Models\Server $server
4547
* @return array
48+
*
4649
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
4750
*/
48-
public function handle($server): array
51+
public function handle(Server $server): array
4952
{
50-
if (! $server instanceof Server || array_diff(self::REQUIRED_RELATIONS, $server->getRelations())) {
51-
$server = $this->repository->getDataForCreation(is_digit($server) ? $server : $server->id);
53+
if (array_diff(self::REQUIRED_RELATIONS, $server->getRelations())) {
54+
$server = $this->repository->getDataForCreation($server);
5255
}
5356

5457
return [
5558
'uuid' => $server->uuid,
56-
'user' => $server->username,
5759
'build' => [
5860
'default' => [
5961
'ip' => $server->allocation->ip,
@@ -62,15 +64,14 @@ public function handle($server): array
6264
'ports' => $server->allocations->groupBy('ip')->map(function ($item) {
6365
return $item->pluck('port');
6466
})->toArray(),
65-
'env' => $this->environment->process($server),
67+
'env' => $this->environment->handle($server),
6668
'memory' => (int) $server->memory,
6769
'swap' => (int) $server->swap,
6870
'io' => (int) $server->io,
6971
'cpu' => (int) $server->cpu,
7072
'disk' => (int) $server->disk,
7173
'image' => $server->image,
7274
],
73-
'keys' => [],
7475
'service' => [
7576
'egg' => $server->egg->uuid,
7677
'pack' => object_get($server, 'pack.uuid'),

0 commit comments

Comments
 (0)