Skip to content

Commit 264431a

Browse files
committed
Whats this? We can add new servers now?!
1 parent 6289e7a commit 264431a

File tree

10 files changed

+211
-82
lines changed

10 files changed

+211
-82
lines changed

app/Exceptions/Handler.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
use Exception;
66
use DisplayException;
7-
use Debugbar;
7+
use DisplayValidationException;
8+
use AccountNotFoundException;
9+
810
use Illuminate\Database\Eloquent\ModelNotFoundException;
911
use Symfony\Component\HttpKernel\Exception\HttpException;
1012
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

app/Http/Controllers/Admin/ServersController.php

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@
22

33
namespace Pterodactyl\Http\Controllers\Admin;
44

5+
use Alert;
56
use Debugbar;
7+
8+
use Pterodactyl\Models;
69
use Pterodactyl\Repositories\ServerRepository;
7-
use Pterodactyl\Models\Server;
8-
use Pterodactyl\Models\Node;
9-
use Pterodactyl\Models\Location;
10-
use Pterodactyl\Models\Allocation;
11-
use Pterodactyl\Models\Service;
12-
use Pterodactyl\Models\ServiceOptions;
13-
use Pterodactyl\Models\ServiceVariables;
10+
11+
use Pterodactly\Exceptions\DisplayException;
12+
use Pterodactly\Exceptions\DisplayValidationException;
1413

1514
use Pterodactyl\Http\Controllers\Controller;
1615
use Illuminate\Http\Request;
@@ -33,7 +32,7 @@ public function __construct()
3332
public function getIndex(Request $request)
3433
{
3534
return view('admin.servers.index', [
36-
'servers' => Server::select('servers.*', 'nodes.name as a_nodeName', 'users.email as a_ownerEmail')
35+
'servers' => Models\Server::select('servers.*', 'nodes.name as a_nodeName', 'users.email as a_ownerEmail')
3736
->join('nodes', 'servers.node', '=', 'nodes.id')
3837
->join('users', 'servers.owner', '=', 'users.id')
3938
->paginate(20),
@@ -43,8 +42,8 @@ public function getIndex(Request $request)
4342
public function getNew(Request $request)
4443
{
4544
return view('admin.servers.new', [
46-
'locations' => Location::all(),
47-
'services' => Service::all()
45+
'locations' => Models\Location::all(),
46+
'services' => Models\Service::all()
4847
]);
4948
}
5049

@@ -57,14 +56,26 @@ public function postNewServer(Request $request)
5756
{
5857

5958
try {
59+
6060
$server = new ServerRepository;
61-
$resp = $server->create($request->all());
62-
echo $resp . '<br />';
61+
$response = $server->create($request->all());
62+
63+
return redirect()->route('admin.servers.view', [ 'id' => $response ]);
64+
6365
} catch (\Exception $e) {
64-
Debugbar::addException($e);
65-
}
6666

67-
return json_encode($request->all());
67+
if ($e instanceof \Pterodactyl\Exceptions\DisplayValidationException) {
68+
return redirect()->route('admin.servers.new')->withErrors(json_decode($e->getMessage()))->withInput();
69+
} else if ($e instanceof \Pterodactyl\Exceptions\DisplayException) {
70+
Alert::danger($e->getMessage())->flash();
71+
} else {
72+
Debugbar::addException($e);
73+
Alert::danger('An unhandled exception occured while attemping to add this server. Please try again.')->flash();
74+
}
75+
76+
return redirect()->route('admin.servers.new')->withInput();
77+
78+
}
6879

6980
}
7081

@@ -83,7 +94,7 @@ public function postNewServerGetNodes(Request $request)
8394
], 500);
8495
}
8596

86-
return response()->json(Node::select('id', 'name', 'public')->where('location', $request->input('location'))->get());
97+
return response()->json(Models\Node::select('id', 'name', 'public')->where('location', $request->input('location'))->get());
8798

8899
}
89100

@@ -102,7 +113,7 @@ public function postNewServerGetIps(Request $request)
102113
], 500);
103114
}
104115

105-
$ips = Allocation::where('node', $request->input('node'))->whereNull('assigned_to')->get();
116+
$ips = Models\Allocation::where('node', $request->input('node'))->whereNull('assigned_to')->get();
106117
$listing = [];
107118

108119
foreach($ips as &$ip) {
@@ -131,7 +142,7 @@ public function postNewServerServiceOptions(Request $request)
131142
], 500);
132143
}
133144

134-
return response()->json(ServiceOptions::select('id', 'name', 'docker_image')->where('parent_service', $request->input('service'))->orderBy('name', 'asc')->get());
145+
return response()->json(Models\ServiceOptions::select('id', 'name', 'docker_image')->where('parent_service', $request->input('service'))->orderBy('name', 'asc')->get());
135146

136147
}
137148

@@ -150,7 +161,7 @@ public function postNewServerServiceVariables(Request $request)
150161
], 500);
151162
}
152163

153-
return response()->json(ServiceVariables::where('option_id', $request->input('option'))->get());
164+
return response()->json(Models\ServiceVariables::where('option_id', $request->input('option'))->get());
154165

155166
}
156167

app/Models/Server.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ class Server extends Model
2424
*/
2525
protected $hidden = ['daemonSecret'];
2626

27+
/**
28+
* Fields that are not mass assignable.
29+
*
30+
* @var array
31+
*/
32+
protected $guarded = ['id', 'installed', 'created_at', 'updated_at'];
33+
2734
/**
2835
* @var array
2936
*/

app/Models/ServerVariables.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,11 @@ class ServerVariables extends Model
1414
*/
1515
protected $table = 'server_variables';
1616

17+
/**
18+
* Fields that are not mass assignable.
19+
*
20+
* @var array
21+
*/
22+
protected $guarded = ['id', 'created_at', 'updated_at'];
23+
1724
}

app/Repositories/ServerRepository.php

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Pterodactyl\Repositories;
44

55
use DB;
6+
use Debugbar;
67
use Validator;
78

89
use Pterodactyl\Models;
@@ -64,7 +65,7 @@ public function create(array $data)
6465
// Run validator, throw catchable and displayable exception if it fails.
6566
// Exception includes a JSON result of failed validation rules.
6667
if ($validator->fails()) {
67-
throw new DisplayValidationException(json_encode($validator->errors()->all()));
68+
throw new DisplayValidationException($validator->errors());
6869
}
6970

7071
// Get the User ID; user exists since we passed the 'exists:users,email' part of the validation
@@ -91,6 +92,7 @@ public function create(array $data)
9192

9293
// Check those Variables
9394
$variables = Models\ServiceVariables::where('option_id', $data['option'])->get();
95+
$variableList = [];
9496
if ($variables) {
9597
foreach($variables as $variable) {
9698

@@ -100,7 +102,11 @@ public function create(array $data)
100102
throw new DisplayException('A required service option variable field (env_' . $variable->env_variable . ') was missing from the request.');
101103
}
102104

103-
$data['env_' . $variable->env_variable] = $variable->default_value;
105+
$variableList = array_merge($variableList, [[
106+
'var_id' => $variable->id,
107+
'var_val' => $variable->default_value
108+
]]);
109+
104110
continue;
105111
}
106112

@@ -109,13 +115,91 @@ public function create(array $data)
109115
throw new DisplayException('Failed to validate service option variable field (env_' . $variable->env_variable . ') aganist regex (' . $variable->regex . ').');
110116
}
111117

118+
$variableList = array_merge($variableList, [[
119+
'var_id' => $variable->id,
120+
'var_val' => $data['env_' . $variable->env_variable]
121+
]]);
122+
112123
continue;
124+
}
125+
}
126+
127+
// Check Overallocation
128+
if (is_numeric($node->memory_overallocate) || is_numeric($node->disk_overallocate)) {
113129

130+
$totals = Models\Server::select(DB::raw('SUM(memory) as memory, SUM(disk) as disk'))->where('node', $node->id)->first();
131+
132+
// Check memory limits
133+
if (is_numeric($node->memory_overallocate)) {
134+
$newMemory = $totals->memory + $data['memory'];
135+
$memoryLimit = ($node->memory * (1 + ($node->memory_overallocate / 100)));
136+
if($newMemory > $memoryLimit) {
137+
throw new DisplayException('The amount of memory allocated to this server would put the node over its allocation limits. This node is allowed ' . ($node->memory_overallocate + 100) . '% of its assigned ' . $node->memory . 'Mb of memory (' . $memoryLimit . 'Mb) of which ' . (($totals->memory / $node->memory) * 100) . '% (' . $totals->memory . 'Mb) is in use already. By allocating this server the node would be at ' . (($newMemory / $node->memory) * 100) . '% (' . $newMemory . 'Mb) usage.');
138+
}
114139
}
140+
141+
// Check Disk Limits
142+
if (is_numeric($node->disk_overallocate)) {
143+
$newDisk = $totals->disk + $data['disk'];
144+
$diskLimit = ($node->disk * (1 + ($node->disk_overallocate / 100)));
145+
if($newDisk > $diskLimit) {
146+
throw new DisplayException('The amount of disk allocated to this server would put the node over its allocation limits. This node is allowed ' . ($node->disk_overallocate + 100) . '% of its assigned ' . $node->disk . 'Mb of disk (' . $diskLimit . 'Mb) of which ' . (($totals->disk / $node->disk) * 100) . '% (' . $totals->disk . 'Mb) is in use already. By allocating this server the node would be at ' . (($newDisk / $node->disk) * 100) . '% (' . $newDisk . 'Mb) usage.');
147+
}
148+
}
149+
150+
}
151+
152+
DB::beginTransaction();
153+
154+
$uuid = new UuidService;
155+
156+
// Add Server to the Database
157+
$server = new Models\Server;
158+
$server->fill([
159+
'uuid' => $uuid->generate('servers', 'uuid'),
160+
'uuidShort' => $uuid->generateShort(),
161+
'node' => $data['node'],
162+
'name' => $data['name'],
163+
'active' => 1,
164+
'owner' => $user->id,
165+
'memory' => $data['memory'],
166+
'disk' => $data['disk'],
167+
'io' => $data['io'],
168+
'cpu' => $data['cpu'],
169+
'ip' => $data['ip'],
170+
'port' => $data['port'],
171+
'service' => $data['service'],
172+
'option' => $data['option'],
173+
'daemonSecret' => $uuid->generate('servers', 'daemonSecret'),
174+
'username' => $this->generateSFTPUsername($data['name'])
175+
]);
176+
$server->save();
177+
178+
// Mark Allocation in Use
179+
$allocation->assigned_to = $server->id;
180+
$allocation->save();
181+
182+
// Add Variables
183+
foreach($variableList as $item) {
184+
Models\ServerVariables::create([
185+
'server_id' => $server->id,
186+
'variable_id' => $item['var_id'],
187+
'variable_value' => $item['var_val']
188+
]);
115189
}
116190

117-
return (new UuidService)->generateShort();
118-
//return $this->generateSFTPUsername($data['name']);
191+
try {
192+
193+
// Add logic for communicating with Wings to make the server in here.
194+
// We should add the server regardless of the Wings response, but
195+
// handle the error and then allow the server to be re-deployed.
196+
197+
DB::commit();
198+
return $server->id;
199+
} catch (\Exception $e) {
200+
DB::rollBack();
201+
throw $e;
202+
}
119203

120204
}
121205

app/Repositories/UserRepository.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public function __construct()
1717

1818
/**
1919
* Creates a user on the panel. Returns the created user's ID.
20-
*
20+
*
2121
* @param string $username
2222
* @param string $email
2323
* @param string $password An unhashed version of the user's password.
@@ -29,7 +29,7 @@ public function create($username, $email, $password)
2929
$user = new User;
3030
$uuid = new UuidService;
3131

32-
$user->uuid = $uuid->table('users')->generate();
32+
$user->uuid = $uuid->generate('users', 'uuid');
3333

3434
$user->username = $username;
3535
$user->email = $email;

app/Services/UuidService.php

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,6 @@
88
class UuidService
99
{
1010

11-
/**
12-
* @var string
13-
*/
14-
protected $table = 'users';
15-
16-
/**
17-
* @var string
18-
*/
19-
protected $field = 'uuid';
20-
2111
/**
2212
* Constructor
2313
*/
@@ -26,45 +16,23 @@ public function __construct()
2616
//
2717
}
2818

29-
/**
30-
* Set the table that we need to be checking in the database.
31-
*
32-
* @param string $table
33-
* @return void
34-
*/
35-
public function table($table)
36-
{
37-
$this->table = $table;
38-
return $this;
39-
}
40-
41-
/**
42-
* Set the field in the given table that we want to check for a unique UUID.
43-
*
44-
* @param string $field
45-
* @return void
46-
*/
47-
public function field($field)
48-
{
49-
$this->field = $field;
50-
return $this;
51-
}
52-
5319
/**
5420
* Generate a unique UUID validating against specified table and column.
5521
* Defaults to `users.uuid`
5622
*
23+
* @param string $table
24+
* @param string $field
5725
* @param integer $type The type of UUID to generate.
5826
* @return string
5927
*/
60-
public function generate($type = 4)
28+
public function generate($table = 'users', $field = 'uuid', $type = 4)
6129
{
6230

6331
$return = false;
6432
do {
6533

66-
$uuid = LaravelUUID::generate($type);
67-
if (!DB::table($this->table)->where($this->field, $uuid)->exists()) {
34+
$uuid = Uuid::generate($type);
35+
if (!DB::table($table)->where($field, $uuid)->exists()) {
6836
$return = $uuid;
6937
}
7038

@@ -81,13 +49,15 @@ public function generate($type = 4)
8149
* @param string $field
8250
* @return string
8351
*/
84-
public function generateShort($table = 'servers', $field = 'uuidShort')
52+
public function generateShort($table = 'servers', $field = 'uuidShort', $attachedUuid = null)
8553
{
8654

8755
$return = false;
8856
do {
8957

90-
$short = substr(Uuid::generate(4), 0, 8);
58+
$short = (is_null($attachedUuid)) ? substr(Uuid::generate(4), 0, 8) : substr($attachedUuid, 0, 8);
59+
$attachedUuid = null;
60+
9161
if (!DB::table($table)->where($field, $short)->exists()) {
9262
$return = $short;
9363
}

0 commit comments

Comments
 (0)