Whats this? We can add new servers now?!

This commit is contained in:
Dane Everitt 2015-12-15 15:08:41 -05:00
parent 6289e7ae8d
commit 264431a271
10 changed files with 214 additions and 85 deletions

View file

@ -4,7 +4,9 @@ namespace Pterodactyl\Exceptions;
use Exception;
use DisplayException;
use Debugbar;
use DisplayValidationException;
use AccountNotFoundException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

View file

@ -2,15 +2,14 @@
namespace Pterodactyl\Http\Controllers\Admin;
use Alert;
use Debugbar;
use Pterodactyl\Models;
use Pterodactyl\Repositories\ServerRepository;
use Pterodactyl\Models\Server;
use Pterodactyl\Models\Node;
use Pterodactyl\Models\Location;
use Pterodactyl\Models\Allocation;
use Pterodactyl\Models\Service;
use Pterodactyl\Models\ServiceOptions;
use Pterodactyl\Models\ServiceVariables;
use Pterodactly\Exceptions\DisplayException;
use Pterodactly\Exceptions\DisplayValidationException;
use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Http\Request;
@ -33,7 +32,7 @@ class ServersController extends Controller
public function getIndex(Request $request)
{
return view('admin.servers.index', [
'servers' => Server::select('servers.*', 'nodes.name as a_nodeName', 'users.email as a_ownerEmail')
'servers' => Models\Server::select('servers.*', 'nodes.name as a_nodeName', 'users.email as a_ownerEmail')
->join('nodes', 'servers.node', '=', 'nodes.id')
->join('users', 'servers.owner', '=', 'users.id')
->paginate(20),
@ -43,8 +42,8 @@ class ServersController extends Controller
public function getNew(Request $request)
{
return view('admin.servers.new', [
'locations' => Location::all(),
'services' => Service::all()
'locations' => Models\Location::all(),
'services' => Models\Service::all()
]);
}
@ -57,14 +56,26 @@ class ServersController extends Controller
{
try {
$server = new ServerRepository;
$resp = $server->create($request->all());
echo $resp . '<br />';
} catch (\Exception $e) {
Debugbar::addException($e);
}
return json_encode($request->all());
$server = new ServerRepository;
$response = $server->create($request->all());
return redirect()->route('admin.servers.view', [ 'id' => $response ]);
} catch (\Exception $e) {
if ($e instanceof \Pterodactyl\Exceptions\DisplayValidationException) {
return redirect()->route('admin.servers.new')->withErrors(json_decode($e->getMessage()))->withInput();
} else if ($e instanceof \Pterodactyl\Exceptions\DisplayException) {
Alert::danger($e->getMessage())->flash();
} else {
Debugbar::addException($e);
Alert::danger('An unhandled exception occured while attemping to add this server. Please try again.')->flash();
}
return redirect()->route('admin.servers.new')->withInput();
}
}
@ -83,7 +94,7 @@ class ServersController extends Controller
], 500);
}
return response()->json(Node::select('id', 'name', 'public')->where('location', $request->input('location'))->get());
return response()->json(Models\Node::select('id', 'name', 'public')->where('location', $request->input('location'))->get());
}
@ -102,7 +113,7 @@ class ServersController extends Controller
], 500);
}
$ips = Allocation::where('node', $request->input('node'))->whereNull('assigned_to')->get();
$ips = Models\Allocation::where('node', $request->input('node'))->whereNull('assigned_to')->get();
$listing = [];
foreach($ips as &$ip) {
@ -131,7 +142,7 @@ class ServersController extends Controller
], 500);
}
return response()->json(ServiceOptions::select('id', 'name', 'docker_image')->where('parent_service', $request->input('service'))->orderBy('name', 'asc')->get());
return response()->json(Models\ServiceOptions::select('id', 'name', 'docker_image')->where('parent_service', $request->input('service'))->orderBy('name', 'asc')->get());
}
@ -150,7 +161,7 @@ class ServersController extends Controller
], 500);
}
return response()->json(ServiceVariables::where('option_id', $request->input('option'))->get());
return response()->json(Models\ServiceVariables::where('option_id', $request->input('option'))->get());
}

View file

@ -24,6 +24,13 @@ class Server extends Model
*/
protected $hidden = ['daemonSecret'];
/**
* Fields that are not mass assignable.
*
* @var array
*/
protected $guarded = ['id', 'installed', 'created_at', 'updated_at'];
/**
* @var array
*/

View file

@ -14,4 +14,11 @@ class ServerVariables extends Model
*/
protected $table = 'server_variables';
/**
* Fields that are not mass assignable.
*
* @var array
*/
protected $guarded = ['id', 'created_at', 'updated_at'];
}

View file

@ -3,6 +3,7 @@
namespace Pterodactyl\Repositories;
use DB;
use Debugbar;
use Validator;
use Pterodactyl\Models;
@ -64,7 +65,7 @@ class ServerRepository
// Run validator, throw catchable and displayable exception if it fails.
// Exception includes a JSON result of failed validation rules.
if ($validator->fails()) {
throw new DisplayValidationException(json_encode($validator->errors()->all()));
throw new DisplayValidationException($validator->errors());
}
// Get the User ID; user exists since we passed the 'exists:users,email' part of the validation
@ -91,6 +92,7 @@ class ServerRepository
// Check those Variables
$variables = Models\ServiceVariables::where('option_id', $data['option'])->get();
$variableList = [];
if ($variables) {
foreach($variables as $variable) {
@ -100,7 +102,11 @@ class ServerRepository
throw new DisplayException('A required service option variable field (env_' . $variable->env_variable . ') was missing from the request.');
}
$data['env_' . $variable->env_variable] = $variable->default_value;
$variableList = array_merge($variableList, [[
'var_id' => $variable->id,
'var_val' => $variable->default_value
]]);
continue;
}
@ -109,13 +115,91 @@ class ServerRepository
throw new DisplayException('Failed to validate service option variable field (env_' . $variable->env_variable . ') aganist regex (' . $variable->regex . ').');
}
continue;
$variableList = array_merge($variableList, [[
'var_id' => $variable->id,
'var_val' => $data['env_' . $variable->env_variable]
]]);
continue;
}
}
return (new UuidService)->generateShort();
//return $this->generateSFTPUsername($data['name']);
// Check Overallocation
if (is_numeric($node->memory_overallocate) || is_numeric($node->disk_overallocate)) {
$totals = Models\Server::select(DB::raw('SUM(memory) as memory, SUM(disk) as disk'))->where('node', $node->id)->first();
// Check memory limits
if (is_numeric($node->memory_overallocate)) {
$newMemory = $totals->memory + $data['memory'];
$memoryLimit = ($node->memory * (1 + ($node->memory_overallocate / 100)));
if($newMemory > $memoryLimit) {
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.');
}
}
// Check Disk Limits
if (is_numeric($node->disk_overallocate)) {
$newDisk = $totals->disk + $data['disk'];
$diskLimit = ($node->disk * (1 + ($node->disk_overallocate / 100)));
if($newDisk > $diskLimit) {
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.');
}
}
}
DB::beginTransaction();
$uuid = new UuidService;
// Add Server to the Database
$server = new Models\Server;
$server->fill([
'uuid' => $uuid->generate('servers', 'uuid'),
'uuidShort' => $uuid->generateShort(),
'node' => $data['node'],
'name' => $data['name'],
'active' => 1,
'owner' => $user->id,
'memory' => $data['memory'],
'disk' => $data['disk'],
'io' => $data['io'],
'cpu' => $data['cpu'],
'ip' => $data['ip'],
'port' => $data['port'],
'service' => $data['service'],
'option' => $data['option'],
'daemonSecret' => $uuid->generate('servers', 'daemonSecret'),
'username' => $this->generateSFTPUsername($data['name'])
]);
$server->save();
// Mark Allocation in Use
$allocation->assigned_to = $server->id;
$allocation->save();
// Add Variables
foreach($variableList as $item) {
Models\ServerVariables::create([
'server_id' => $server->id,
'variable_id' => $item['var_id'],
'variable_value' => $item['var_val']
]);
}
try {
// Add logic for communicating with Wings to make the server in here.
// We should add the server regardless of the Wings response, but
// handle the error and then allow the server to be re-deployed.
DB::commit();
return $server->id;
} catch (\Exception $e) {
DB::rollBack();
throw $e;
}
}

View file

@ -17,7 +17,7 @@ class UserRepository
/**
* Creates a user on the panel. Returns the created user's ID.
*
*
* @param string $username
* @param string $email
* @param string $password An unhashed version of the user's password.
@ -29,7 +29,7 @@ class UserRepository
$user = new User;
$uuid = new UuidService;
$user->uuid = $uuid->table('users')->generate();
$user->uuid = $uuid->generate('users', 'uuid');
$user->username = $username;
$user->email = $email;

View file

@ -8,16 +8,6 @@ use Uuid;
class UuidService
{
/**
* @var string
*/
protected $table = 'users';
/**
* @var string
*/
protected $field = 'uuid';
/**
* Constructor
*/
@ -26,45 +16,23 @@ class UuidService
//
}
/**
* Set the table that we need to be checking in the database.
*
* @param string $table
* @return void
*/
public function table($table)
{
$this->table = $table;
return $this;
}
/**
* Set the field in the given table that we want to check for a unique UUID.
*
* @param string $field
* @return void
*/
public function field($field)
{
$this->field = $field;
return $this;
}
/**
* Generate a unique UUID validating against specified table and column.
* Defaults to `users.uuid`
*
* @param string $table
* @param string $field
* @param integer $type The type of UUID to generate.
* @return string
*/
public function generate($type = 4)
public function generate($table = 'users', $field = 'uuid', $type = 4)
{
$return = false;
do {
$uuid = LaravelUUID::generate($type);
if (!DB::table($this->table)->where($this->field, $uuid)->exists()) {
$uuid = Uuid::generate($type);
if (!DB::table($table)->where($field, $uuid)->exists()) {
$return = $uuid;
}
@ -81,13 +49,15 @@ class UuidService
* @param string $field
* @return string
*/
public function generateShort($table = 'servers', $field = 'uuidShort')
public function generateShort($table = 'servers', $field = 'uuidShort', $attachedUuid = null)
{
$return = false;
do {
$short = substr(Uuid::generate(4), 0, 8);
$short = (is_null($attachedUuid)) ? substr(Uuid::generate(4), 0, 8) : substr($attachedUuid, 0, 8);
$attachedUuid = null;
if (!DB::table($table)->where($field, $short)->exists()) {
$return = $short;
}