Merge pull request #286 from Pterodactyl/feature/updated-models
Implementation of improved Model logic and relationships throughout code base.
This commit is contained in:
commit
6d2ffabe46
93 changed files with 1703 additions and 1512 deletions
|
@ -21,6 +21,12 @@ This project follows [Semantic Versioning](http://semver.org) guidelines.
|
||||||
* Admin API and base routes for user management now define the fields that should be passed to repositories rather than passing all fields.
|
* Admin API and base routes for user management now define the fields that should be passed to repositories rather than passing all fields.
|
||||||
* User model now defines mass assignment fields using `$fillable` rather than `$guarded`.
|
* User model now defines mass assignment fields using `$fillable` rather than `$guarded`.
|
||||||
* 2FA checkpoint on login is now its own page, and not an AJAX based call. Improves security on that front.
|
* 2FA checkpoint on login is now its own page, and not an AJAX based call. Improves security on that front.
|
||||||
|
* Updated Server model code to be more efficient, as well as make life easier for backend changes and work.
|
||||||
|
|
||||||
|
### Deprecated
|
||||||
|
* `Server::getUserDaemonSecret(Server $server)` was removed and replaced with `User::daemonSecret(Server $server)` in order to clean up models.
|
||||||
|
* `Server::getByUUID()` was replaced with `Server::byUuid()` as well as various other functions through-out the Server model.
|
||||||
|
* `Server::getHeaders()` was removed and replaced with `Server::getClient()` which returns a Guzzle Client with the correct headers already assigned.
|
||||||
|
|
||||||
## v0.5.6 (Bodacious Boreopterus)
|
## v0.5.6 (Bodacious Boreopterus)
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\API;
|
namespace Pterodactyl\Http\Controllers\API;
|
||||||
|
|
||||||
use DB;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Pterodactyl\Models\Location;
|
use Pterodactyl\Models\Location;
|
||||||
|
|
||||||
|
@ -49,11 +48,12 @@ class LocationController extends BaseController
|
||||||
*/
|
*/
|
||||||
public function lists(Request $request)
|
public function lists(Request $request)
|
||||||
{
|
{
|
||||||
return Location::select('locations.*', DB::raw('GROUP_CONCAT(nodes.id) as nodes'))
|
return Location::with('nodes')->get()->map(function ($item) {
|
||||||
->join('nodes', 'locations.id', '=', 'nodes.location')
|
$item->nodes->transform(function ($item) {
|
||||||
->groupBy('locations.id')
|
return collect($item)->only(['id', 'name', 'fqdn', 'scheme', 'daemonListen', 'daemonSFTP']);
|
||||||
->get()->each(function ($location) {
|
});
|
||||||
$location->nodes = explode(',', $location->nodes);
|
|
||||||
})->all();
|
return $item;
|
||||||
|
})->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\API;
|
namespace Pterodactyl\Http\Controllers\API;
|
||||||
|
|
||||||
|
use Log;
|
||||||
use Pterodactyl\Models;
|
use Pterodactyl\Models;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Dingo\Api\Exception\ResourceException;
|
use Dingo\Api\Exception\ResourceException;
|
||||||
|
@ -96,15 +97,21 @@ class NodeController extends BaseController
|
||||||
public function create(Request $request)
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$node = new NodeRepository;
|
$repo = new NodeRepository;
|
||||||
$new = $node->create($request->all());
|
$node = $repo->create($request->only([
|
||||||
|
'name', 'location_id', 'public', 'fqdn',
|
||||||
|
'scheme', 'memory', 'memory_overallocate',
|
||||||
|
'disk', 'disk_overallocate', 'daemonBase',
|
||||||
|
'daemonSFTP', 'daemonListen',
|
||||||
|
]));
|
||||||
|
|
||||||
return ['id' => $new];
|
return ['id' => $repo->id];
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
|
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
|
||||||
} catch (DisplayException $ex) {
|
} catch (DisplayException $ex) {
|
||||||
throw new ResourceException($ex->getMessage());
|
throw new ResourceException($ex->getMessage());
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $ex) {
|
||||||
|
Log::error($ex);
|
||||||
throw new BadRequestHttpException('There was an error while attempting to add this node to the system.');
|
throw new BadRequestHttpException('There was an error while attempting to add this node to the system.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,88 +131,35 @@ class NodeController extends BaseController
|
||||||
*/
|
*/
|
||||||
public function view(Request $request, $id, $fields = null)
|
public function view(Request $request, $id, $fields = null)
|
||||||
{
|
{
|
||||||
$node = Models\Node::where('id', $id);
|
$node = Models\Node::with('allocations')->where('id', $id)->first();
|
||||||
|
if (! $node) {
|
||||||
|
throw new NotFoundHttpException('No node by that ID was found.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$node->allocations->transform(function ($item) {
|
||||||
|
return collect($item)->only([
|
||||||
|
'id', 'ip', 'ip_alias', 'port', 'server_id',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
if (! is_null($request->input('fields'))) {
|
if (! is_null($request->input('fields'))) {
|
||||||
foreach (explode(',', $request->input('fields')) as $field) {
|
$fields = explode(',', $request->input('fields'));
|
||||||
if (! empty($field)) {
|
if (! empty($fields) && is_array($fields)) {
|
||||||
$node->addSelect($field);
|
return collect($node)->only($fields);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
return $node;
|
||||||
if (! $node->first()) {
|
|
||||||
throw new NotFoundHttpException('No node by that ID was found.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
'node' => $node->first(),
|
|
||||||
'allocations' => [
|
|
||||||
'assigned' => Models\Allocation::where('node', $id)->whereNotNull('assigned_to')->get(),
|
|
||||||
'unassigned' => Models\Allocation::where('node', $id)->whereNull('assigned_to')->get(),
|
|
||||||
],
|
|
||||||
];
|
|
||||||
} catch (NotFoundHttpException $ex) {
|
|
||||||
throw $ex;
|
|
||||||
} catch (\Exception $ex) {
|
|
||||||
throw new BadRequestHttpException('There was an issue with the fields passed in the request.');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function config(Request $request, $id)
|
public function config(Request $request, $id)
|
||||||
{
|
{
|
||||||
if (! $request->secure()) {
|
|
||||||
throw new BadRequestHttpException('This API route can only be accessed using a secure connection.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$node = Models\Node::where('id', $id)->first();
|
$node = Models\Node::where('id', $id)->first();
|
||||||
if (! $node) {
|
if (! $node) {
|
||||||
throw new NotFoundHttpException('No node by that ID was found.');
|
throw new NotFoundHttpException('No node by that ID was found.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return $node->getConfigurationAsJson();
|
||||||
'web' => [
|
|
||||||
'listen' => $node->daemonListen,
|
|
||||||
'host' => '0.0.0.0',
|
|
||||||
'ssl' => [
|
|
||||||
'enabled' => ($node->scheme === 'https'),
|
|
||||||
'certificate' => '/etc/certs/' . $node->fqdn . '/fullchain.pem',
|
|
||||||
'key' => '/etc/certs/' . $node->fqdn . '/privkey.pem',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'docker' => [
|
|
||||||
'socket' => '/var/run/docker.sock',
|
|
||||||
'autoupdate_images' => true,
|
|
||||||
],
|
|
||||||
'sftp' => [
|
|
||||||
'path' => $node->daemonBase,
|
|
||||||
'port' => (int) $node->daemonSFTP,
|
|
||||||
'container' => 'ptdl-sftp',
|
|
||||||
],
|
|
||||||
'query' => [
|
|
||||||
'kill_on_fail' => true,
|
|
||||||
'fail_limit' => 5,
|
|
||||||
],
|
|
||||||
'logger' => [
|
|
||||||
'path' => 'logs/',
|
|
||||||
'src' => false,
|
|
||||||
'level' => 'info',
|
|
||||||
'period' => '1d',
|
|
||||||
'count' => 3,
|
|
||||||
],
|
|
||||||
'remote' => [
|
|
||||||
'base' => config('app.url'),
|
|
||||||
'download' => route('remote.download'),
|
|
||||||
'installed' => route('remote.install'),
|
|
||||||
],
|
|
||||||
'uploads' => [
|
|
||||||
'size_limit' => $node->upload_size,
|
|
||||||
],
|
|
||||||
'keys' => [
|
|
||||||
$node->daemonSecret,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -219,12 +173,7 @@ class NodeController extends BaseController
|
||||||
*/
|
*/
|
||||||
public function allocations(Request $request)
|
public function allocations(Request $request)
|
||||||
{
|
{
|
||||||
$allocations = Models\Allocation::all();
|
return Models\Allocation::all()->toArray();
|
||||||
if ($allocations->count() < 1) {
|
|
||||||
throw new NotFoundHttpException('No allocations have been created.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $allocations;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -238,18 +187,7 @@ class NodeController extends BaseController
|
||||||
*/
|
*/
|
||||||
public function allocationsView(Request $request, $id)
|
public function allocationsView(Request $request, $id)
|
||||||
{
|
{
|
||||||
$query = Models\Allocation::where('assigned_to', $id)->get();
|
return Models\Allocation::where('assigned_to', $id)->get()->toArray();
|
||||||
try {
|
|
||||||
if (empty($query)) {
|
|
||||||
throw new NotFoundHttpException('No allocations for that server were found.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $query;
|
|
||||||
} catch (NotFoundHttpException $ex) {
|
|
||||||
throw $ex;
|
|
||||||
} catch (\Exception $ex) {
|
|
||||||
throw new BadRequestHttpException('There was an issue with the fields passed in the request.');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -72,10 +72,10 @@ class ServerController extends BaseController
|
||||||
public function create(Request $request)
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$server = new ServerRepository;
|
$repo = new ServerRepository;
|
||||||
$new = $server->create($request->all());
|
$server = $repo->create($request->all());
|
||||||
|
|
||||||
return ['id' => $new];
|
return ['id' => $server->id];
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
|
throw new ResourceException('A validation error occured.', json_decode($ex->getMessage(), true));
|
||||||
} catch (DisplayException $ex) {
|
} catch (DisplayException $ex) {
|
||||||
|
@ -101,58 +101,38 @@ class ServerController extends BaseController
|
||||||
*/
|
*/
|
||||||
public function view(Request $request, $id)
|
public function view(Request $request, $id)
|
||||||
{
|
{
|
||||||
$query = Models\Server::where('id', $id);
|
$server = Models\Server::with('node', 'allocations', 'pack')->where('id', $id)->first();
|
||||||
|
if (! $server) {
|
||||||
|
throw new NotFoundHttpException('No server by that ID was found.');
|
||||||
|
}
|
||||||
|
|
||||||
if (! is_null($request->input('fields'))) {
|
if (! is_null($request->input('fields'))) {
|
||||||
foreach (explode(',', $request->input('fields')) as $field) {
|
$fields = explode(',', $request->input('fields'));
|
||||||
if (! empty($field)) {
|
if (! empty($fields) && is_array($fields)) {
|
||||||
$query->addSelect($field);
|
return collect($server)->only($fields);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
if ($request->input('daemon') === 'true') {
|
||||||
if (! $query->first()) {
|
try {
|
||||||
throw new NotFoundHttpException('No server by that ID was found.');
|
$response = $server->node->guzzleClient([
|
||||||
}
|
'X-Access-Token' => $server->node->daemonSecret,
|
||||||
|
])->request('GET', '/servers');
|
||||||
|
|
||||||
// Requested Daemon Stats
|
|
||||||
$server = $query->with(
|
|
||||||
'allocations',
|
|
||||||
'pack'
|
|
||||||
)->first();
|
|
||||||
if ($request->input('daemon') === 'true') {
|
|
||||||
$node = Models\Node::findOrFail($server->node);
|
|
||||||
$client = Models\Node::guzzleRequest($node->id);
|
|
||||||
|
|
||||||
$response = $client->request('GET', '/servers', [
|
|
||||||
'headers' => [
|
|
||||||
'X-Access-Token' => $node->daemonSecret,
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Only return the daemon token if the request is using HTTPS
|
|
||||||
if ($request->secure()) {
|
|
||||||
$server->daemon_token = $server->daemonSecret;
|
|
||||||
}
|
|
||||||
$server->daemon = json_decode($response->getBody())->{$server->uuid};
|
$server->daemon = json_decode($response->getBody())->{$server->uuid};
|
||||||
|
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
||||||
return $server->toArray();
|
// Couldn't hit the daemon, return what we have though.
|
||||||
|
$server->daemon = [
|
||||||
|
'error' => 'There was an error encountered while attempting to connect to the remote daemon.',
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $server->toArray();
|
|
||||||
} catch (NotFoundHttpException $ex) {
|
|
||||||
throw $ex;
|
|
||||||
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
|
||||||
// Couldn't hit the daemon, return what we have though.
|
|
||||||
$server->daemon = [
|
|
||||||
'error' => 'There was an error encountered while attempting to connect to the remote daemon.',
|
|
||||||
];
|
|
||||||
|
|
||||||
return $server->toArray();
|
|
||||||
} catch (\Exception $ex) {
|
|
||||||
throw new BadRequestHttpException('There was an issue with the fields passed in the request.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$server->allocations->transform(function ($item) {
|
||||||
|
return collect($item)->except(['created_at', 'updated_at']);
|
||||||
|
});
|
||||||
|
|
||||||
|
return $server->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -179,7 +159,9 @@ class ServerController extends BaseController
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$server = new ServerRepository;
|
$server = new ServerRepository;
|
||||||
$server->updateDetails($id, $request->all());
|
$server->updateDetails($id, $request->only([
|
||||||
|
'owner', 'name', 'reset_token',
|
||||||
|
]));
|
||||||
|
|
||||||
return Models\Server::findOrFail($id);
|
return Models\Server::findOrFail($id);
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
|
@ -224,7 +206,10 @@ class ServerController extends BaseController
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$server = new ServerRepository;
|
$server = new ServerRepository;
|
||||||
$server->changeBuild($id, $request->all());
|
$server->changeBuild($id, $request->only([
|
||||||
|
'default', 'add_additional', 'remove_additional',
|
||||||
|
'memory', 'swap', 'io', 'cpu', 'disk',
|
||||||
|
]));
|
||||||
|
|
||||||
return Models\Server::findOrFail($id);
|
return Models\Server::findOrFail($id);
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
|
|
|
@ -45,18 +45,11 @@ class ServiceController extends BaseController
|
||||||
|
|
||||||
public function view(Request $request, $id)
|
public function view(Request $request, $id)
|
||||||
{
|
{
|
||||||
$service = Models\Service::find($id);
|
$service = Models\Service::with('options.variables', 'options.packs')->find($id);
|
||||||
if (! $service) {
|
if (! $service) {
|
||||||
throw new NotFoundHttpException('No service by that ID was found.');
|
throw new NotFoundHttpException('No service by that ID was found.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return $service->toArray();
|
||||||
'service' => $service,
|
|
||||||
'options' => Models\ServiceOptions::select('id', 'name', 'description', 'tag', 'docker_image')
|
|
||||||
->where('parent_service', $service->id)
|
|
||||||
->with('variables')
|
|
||||||
->with('packs')
|
|
||||||
->get(),
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\API\User;
|
namespace Pterodactyl\Http\Controllers\API\User;
|
||||||
|
|
||||||
use Pterodactyl\Models;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Pterodactyl\Http\Controllers\API\BaseController;
|
use Pterodactyl\Http\Controllers\API\BaseController;
|
||||||
|
|
||||||
|
@ -32,19 +31,16 @@ class InfoController extends BaseController
|
||||||
{
|
{
|
||||||
public function me(Request $request)
|
public function me(Request $request)
|
||||||
{
|
{
|
||||||
return Models\Server::getUserServers()->map(function ($server) {
|
return $request->user()->serverAccessCollection()->load('allocation', 'option')->map(function ($server) {
|
||||||
return [
|
return [
|
||||||
'id' => $server->uuidShort,
|
'id' => $server->uuidShort,
|
||||||
'uuid' => $server->uuid,
|
'uuid' => $server->uuid,
|
||||||
'name' => $server->name,
|
'name' => $server->name,
|
||||||
'node' => $server->nodeName,
|
'node' => $server->node->name,
|
||||||
'ip' => [
|
'ip' => $server->allocation->alias,
|
||||||
'set' => $server->ip,
|
'port' => $server->allocation->port,
|
||||||
'alias' => $server->ip_alias,
|
'service' => $server->service->name,
|
||||||
],
|
'option' => $server->option->name,
|
||||||
'port' => $server->port,
|
|
||||||
'service' => $server->a_serviceName,
|
|
||||||
'option' => $server->a_serviceOptionName,
|
|
||||||
];
|
];
|
||||||
})->all();
|
})->all();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
namespace Pterodactyl\Http\Controllers\API\User;
|
namespace Pterodactyl\Http\Controllers\API\User;
|
||||||
|
|
||||||
use Log;
|
use Log;
|
||||||
use Auth;
|
|
||||||
use Pterodactyl\Models;
|
use Pterodactyl\Models;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Pterodactyl\Http\Controllers\API\BaseController;
|
use Pterodactyl\Http\Controllers\API\BaseController;
|
||||||
|
@ -34,42 +33,28 @@ class ServerController extends BaseController
|
||||||
{
|
{
|
||||||
public function info(Request $request, $uuid)
|
public function info(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid)->load('allocations');
|
||||||
$node = Models\Node::findOrFail($server->node);
|
|
||||||
$client = Models\Node::guzzleRequest($node->id);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$response = $client->request('GET', '/server', [
|
$response = $server->guzzleClient()->request('GET', '/server');
|
||||||
'headers' => [
|
|
||||||
'X-Access-Token' => $server->daemonSecret,
|
|
||||||
'X-Access-Server' => $server->uuid,
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
$json = json_decode($response->getBody());
|
$json = json_decode($response->getBody());
|
||||||
$daemon = [
|
$daemon = [
|
||||||
'status' => $json->status,
|
'status' => $json->status,
|
||||||
'stats' => $json->proc,
|
'stats' => $json->proc,
|
||||||
'query' => $json->query,
|
|
||||||
];
|
];
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
$daemon = [
|
$daemon = [
|
||||||
'error' => 'An error was encountered while trying to connect to the daemon to collece information. It might be offline.',
|
'error' => 'An error was encountered while trying to connect to the daemon to collect information. It might be offline.',
|
||||||
];
|
];
|
||||||
Log::error($ex);
|
Log::error($ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
$allocations = Models\Allocation::select('id', 'ip', 'port', 'ip_alias as alias')->where('assigned_to', $server->id)->get();
|
|
||||||
foreach ($allocations as &$allocation) {
|
|
||||||
$allocation->default = ($allocation->id === $server->allocation);
|
|
||||||
unset($allocation->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'uuidShort' => $server->uuidShort,
|
'uuidShort' => $server->uuidShort,
|
||||||
'uuid' => $server->uuid,
|
'uuid' => $server->uuid,
|
||||||
'name' => $server->name,
|
'name' => $server->name,
|
||||||
'node' => $node->name,
|
'node' => $server->node->name,
|
||||||
'limits' => [
|
'limits' => [
|
||||||
'memory' => $server->memory,
|
'memory' => $server->memory,
|
||||||
'swap' => $server->swap,
|
'swap' => $server->swap,
|
||||||
|
@ -78,12 +63,18 @@ class ServerController extends BaseController
|
||||||
'cpu' => $server->cpu,
|
'cpu' => $server->cpu,
|
||||||
'oom_disabled' => (bool) $server->oom_disabled,
|
'oom_disabled' => (bool) $server->oom_disabled,
|
||||||
],
|
],
|
||||||
'allocations' => $allocations,
|
'allocations' => $server->allocations->map(function ($item) use ($server) {
|
||||||
|
return [
|
||||||
|
'ip' => $item->alias,
|
||||||
|
'port' => $item->port,
|
||||||
|
'default' => ($item->id === $server->allocation_id),
|
||||||
|
];
|
||||||
|
}),
|
||||||
'sftp' => [
|
'sftp' => [
|
||||||
'username' => (Auth::user()->can('view-sftp', $server)) ? $server->username : null,
|
'username' => ($request->user()->can('view-sftp', $server)) ? $server->username : null,
|
||||||
],
|
],
|
||||||
'daemon' => [
|
'daemon' => [
|
||||||
'token' => ($request->secure()) ? $server->daemonSecret : false,
|
'token' => $server->daemonSecret,
|
||||||
'response' => $daemon,
|
'response' => $daemon,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@ -91,16 +82,10 @@ class ServerController extends BaseController
|
||||||
|
|
||||||
public function power(Request $request, $uuid)
|
public function power(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$client = Models\Node::guzzleRequest($server->node);
|
|
||||||
|
|
||||||
Auth::user()->can('power-' . $request->input('action'), $server);
|
Auth::user()->can('power-' . $request->input('action'), $server);
|
||||||
|
|
||||||
$res = $client->request('PUT', '/server/power', [
|
$res = $server->guzzleClient()->request('PUT', '/server/power', [
|
||||||
'headers' => [
|
|
||||||
'X-Access-Server' => $server->uuid,
|
|
||||||
'X-Access-Token' => $server->daemonSecret,
|
|
||||||
],
|
|
||||||
'exceptions' => false,
|
'exceptions' => false,
|
||||||
'json' => [
|
'json' => [
|
||||||
'action' => $request->input('action'),
|
'action' => $request->input('action'),
|
||||||
|
|
|
@ -31,7 +31,6 @@ use Pterodactyl\Exceptions\DisplayException;
|
||||||
use Pterodactyl\Repositories\UserRepository;
|
use Pterodactyl\Repositories\UserRepository;
|
||||||
use Pterodactyl\Exceptions\DisplayValidationException;
|
use Pterodactyl\Exceptions\DisplayValidationException;
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
|
||||||
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
|
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,31 +74,27 @@ class UserController extends BaseController
|
||||||
*/
|
*/
|
||||||
public function view(Request $request, $id)
|
public function view(Request $request, $id)
|
||||||
{
|
{
|
||||||
$query = Models\User::where((is_numeric($id) ? 'id' : 'email'), $id);
|
$user = Models\User::with('servers')->where((is_numeric($id) ? 'id' : 'email'), $id)->first();
|
||||||
|
if (! $user->first()) {
|
||||||
|
throw new NotFoundHttpException('No user by that ID was found.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$user->servers->transform(function ($item) {
|
||||||
|
return collect($item)->only([
|
||||||
|
'id', 'node_id', 'uuidShort',
|
||||||
|
'uuid', 'name', 'suspended',
|
||||||
|
'owner_id',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
if (! is_null($request->input('fields'))) {
|
if (! is_null($request->input('fields'))) {
|
||||||
foreach (explode(',', $request->input('fields')) as $field) {
|
$fields = explode(',', $request->input('fields'));
|
||||||
if (! empty($field)) {
|
if (! empty($fields) && is_array($fields)) {
|
||||||
$query->addSelect($field);
|
return collect($user)->only($fields);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
return $user->toArray();
|
||||||
if (! $query->first()) {
|
|
||||||
throw new NotFoundHttpException('No user by that ID was found.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = $query->first();
|
|
||||||
$userArray = $user->toArray();
|
|
||||||
$userArray['servers'] = Models\Server::select('id', 'uuid', 'node', 'suspended')->where('owner', $user->id)->get();
|
|
||||||
|
|
||||||
return $userArray;
|
|
||||||
} catch (NotFoundHttpException $ex) {
|
|
||||||
throw $ex;
|
|
||||||
} catch (\Exception $ex) {
|
|
||||||
throw new BadRequestHttpException('There was an issue with the fields passed in the request.');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,7 +118,9 @@ class UserController extends BaseController
|
||||||
try {
|
try {
|
||||||
$user = new UserRepository;
|
$user = new UserRepository;
|
||||||
$create = $user->create($request->only([
|
$create = $user->create($request->only([
|
||||||
'email', 'username', 'name_first', 'name_last', 'password', 'root_admin', 'custom_id',
|
'email', 'username', 'name_first',
|
||||||
|
'name_last', 'password',
|
||||||
|
'root_admin', 'custom_id',
|
||||||
]));
|
]));
|
||||||
$create = $user->create($request->input('email'), $request->input('password'), $request->input('admin'), $request->input('custom_id'));
|
$create = $user->create($request->input('email'), $request->input('password'), $request->input('admin'), $request->input('custom_id'));
|
||||||
|
|
||||||
|
@ -160,7 +157,9 @@ class UserController extends BaseController
|
||||||
try {
|
try {
|
||||||
$user = new UserRepository;
|
$user = new UserRepository;
|
||||||
$user->update($id, $request->only([
|
$user->update($id, $request->only([
|
||||||
'username', 'email', 'name_first', 'name_last', 'password', 'root_admin', 'language',
|
'username', 'email', 'name_first',
|
||||||
|
'name_last', 'password',
|
||||||
|
'root_admin', 'language',
|
||||||
]));
|
]));
|
||||||
|
|
||||||
return Models\User::findOrFail($id);
|
return Models\User::findOrFail($id);
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\Admin;
|
namespace Pterodactyl\Http\Controllers\Admin;
|
||||||
|
|
||||||
use DB;
|
|
||||||
use Log;
|
use Log;
|
||||||
use Alert;
|
use Alert;
|
||||||
use Pterodactyl\Models;
|
use Pterodactyl\Models;
|
||||||
|
@ -47,30 +46,15 @@ class DatabaseController extends Controller
|
||||||
public function getIndex(Request $request)
|
public function getIndex(Request $request)
|
||||||
{
|
{
|
||||||
return view('admin.databases.index', [
|
return view('admin.databases.index', [
|
||||||
'databases' => Models\Database::select(
|
'databases' => Models\Database::with('server')->paginate(50),
|
||||||
'databases.*',
|
'hosts' => Models\DatabaseServer::withCount('databases')->with('node')->paginate(20),
|
||||||
'database_servers.host as a_host',
|
|
||||||
'database_servers.port as a_port',
|
|
||||||
'servers.id as a_serverId',
|
|
||||||
'servers.name as a_serverName'
|
|
||||||
)->join('database_servers', 'database_servers.id', '=', 'databases.db_server')
|
|
||||||
->join('servers', 'databases.server_id', '=', 'servers.id')
|
|
||||||
->paginate(20),
|
|
||||||
'dbh' => Models\DatabaseServer::select(
|
|
||||||
'database_servers.*',
|
|
||||||
'nodes.name as a_linkedNode',
|
|
||||||
DB::raw('(SELECT COUNT(*) FROM `databases` WHERE `databases`.`db_server` = database_servers.id) as c_databases')
|
|
||||||
)->leftJoin('nodes', 'nodes.id', '=', 'database_servers.linked_node')
|
|
||||||
->paginate(20),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getNew(Request $request)
|
public function getNew(Request $request)
|
||||||
{
|
{
|
||||||
return view('admin.databases.new', [
|
return view('admin.databases.new', [
|
||||||
'nodes' => Models\Node::select('nodes.id', 'nodes.name', 'locations.long as a_location')
|
'nodes' => Models\Node::all()->load('location'),
|
||||||
->join('locations', 'locations.id', '=', 'nodes.location')
|
|
||||||
->get(),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,15 +62,17 @@ class DatabaseController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$repo = new DatabaseRepository;
|
$repo = new DatabaseRepository;
|
||||||
$repo->add($request->except([
|
$repo->add($request->only([
|
||||||
'_token',
|
'name',
|
||||||
|
'host',
|
||||||
|
'port',
|
||||||
|
'username',
|
||||||
|
'password',
|
||||||
|
'linked_node',
|
||||||
]));
|
]));
|
||||||
|
|
||||||
Alert::success('Successfully added a new database server to the system.')->flash();
|
Alert::success('Successfully added a new database server to the system.')->flash();
|
||||||
|
|
||||||
return redirect()->route('admin.databases', [
|
return redirect()->route('admin.databases', ['tab' => 'tab_dbservers']);
|
||||||
'tab' => 'tab_dbservers',
|
|
||||||
]);
|
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
return redirect()->route('admin.databases.new')->withErrors(json_decode($ex->getMessage()))->withInput();
|
return redirect()->route('admin.databases.new')->withErrors(json_decode($ex->getMessage()))->withInput();
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\Admin;
|
namespace Pterodactyl\Http\Controllers\Admin;
|
||||||
|
|
||||||
use DB;
|
|
||||||
use Alert;
|
use Alert;
|
||||||
use Pterodactyl\Models;
|
use Pterodactyl\Models;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
@ -43,35 +42,21 @@ class LocationsController extends Controller
|
||||||
public function getIndex(Request $request)
|
public function getIndex(Request $request)
|
||||||
{
|
{
|
||||||
return view('admin.locations.index', [
|
return view('admin.locations.index', [
|
||||||
'locations' => Models\Location::select(
|
'locations' => Models\Location::withCount('nodes', 'servers')->paginate(20),
|
||||||
'locations.*',
|
|
||||||
DB::raw('(SELECT COUNT(*) FROM nodes WHERE nodes.location = locations.id) as a_nodeCount'),
|
|
||||||
DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.node IN (SELECT nodes.id FROM nodes WHERE nodes.location = locations.id)) as a_serverCount')
|
|
||||||
)->paginate(20),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteLocation(Request $request, $id)
|
public function deleteLocation(Request $request, $id)
|
||||||
{
|
{
|
||||||
$model = Models\Location::select(
|
$location = Models\Location::withCount('nodes')->findOrFail($id);
|
||||||
'locations.id',
|
|
||||||
DB::raw('(SELECT COUNT(*) FROM nodes WHERE nodes.location = locations.id) as a_nodeCount'),
|
|
||||||
DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.node IN (SELECT nodes.id FROM nodes WHERE nodes.location = locations.id)) as a_serverCount')
|
|
||||||
)->where('id', $id)->first();
|
|
||||||
|
|
||||||
if (! $model) {
|
if ($location->nodes_count > 0) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'error' => 'No location with that ID exists on the system.',
|
'error' => 'You cannot remove a location that is currently assigned to a node.',
|
||||||
], 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($model->a_nodeCount > 0 || $model->a_serverCount > 0) {
|
|
||||||
return response()->json([
|
|
||||||
'error' => 'You cannot remove a location that is currently assigned to a node or server.',
|
|
||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
|
|
||||||
$model->delete();
|
$location->delete();
|
||||||
|
|
||||||
return response('', 204);
|
return response('', 204);
|
||||||
}
|
}
|
||||||
|
@ -80,12 +65,12 @@ class LocationsController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$location = new LocationRepository;
|
$location = new LocationRepository;
|
||||||
$location->edit($id, $request->all());
|
$location->edit($id, $request->only(['long', 'short']));
|
||||||
|
|
||||||
return response('', 204);
|
return response('', 204);
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'error' => 'There was a validation error while processing this request. Location descriptions must be between 1 and 255 characters, and the location code must be between 1 and 10 characters with no spaces or special characters.',
|
'error' => 'There was a validation error while processing this request. Location descriptions must be between 1 and 255 characters, and the location code must be between 1 and 20 characters with no spaces or special characters.',
|
||||||
], 422);
|
], 422);
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
// This gets caught and processed into JSON anyways.
|
// This gets caught and processed into JSON anyways.
|
||||||
|
@ -97,9 +82,7 @@ class LocationsController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$location = new LocationRepository;
|
$location = new LocationRepository;
|
||||||
$id = $location->create($request->except([
|
$location->create($request->only(['long', 'short']));
|
||||||
'_token',
|
|
||||||
]));
|
|
||||||
Alert::success('New location successfully added.')->flash();
|
Alert::success('New location successfully added.')->flash();
|
||||||
|
|
||||||
return redirect()->route('admin.locations');
|
return redirect()->route('admin.locations');
|
||||||
|
|
|
@ -48,17 +48,15 @@ class NodesController extends Controller
|
||||||
|
|
||||||
public function getScript(Request $request, $id)
|
public function getScript(Request $request, $id)
|
||||||
{
|
{
|
||||||
return response()->view('admin.nodes.remote.deploy', ['node' => Models\Node::findOrFail($id)])->header('Content-Type', 'text/plain');
|
return response()->view('admin.nodes.remote.deploy', [
|
||||||
|
'node' => Models\Node::findOrFail($id),
|
||||||
|
])->header('Content-Type', 'text/plain');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getIndex(Request $request)
|
public function getIndex(Request $request)
|
||||||
{
|
{
|
||||||
return view('admin.nodes.index', [
|
return view('admin.nodes.index', [
|
||||||
'nodes' => Models\Node::select(
|
'nodes' => Models\Node::with('location')->withCount('servers')->paginate(20),
|
||||||
'nodes.*',
|
|
||||||
'locations.long as a_locationName',
|
|
||||||
DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.node = nodes.id) as a_serverCount')
|
|
||||||
)->join('locations', 'nodes.location', '=', 'locations.id')->paginate(20),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,15 +76,25 @@ class NodesController extends Controller
|
||||||
public function postNew(Request $request)
|
public function postNew(Request $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$node = new NodeRepository;
|
$repo = new NodeRepository;
|
||||||
$new = $node->create($request->except([
|
$node = $repo->create($request->only([
|
||||||
'_token',
|
'name',
|
||||||
|
'location',
|
||||||
|
'public',
|
||||||
|
'fqdn',
|
||||||
|
'scheme',
|
||||||
|
'memory',
|
||||||
|
'memory_overallocate',
|
||||||
|
'disk',
|
||||||
|
'disk_overallocate',
|
||||||
|
'daemonBase',
|
||||||
|
'daemonSFTP',
|
||||||
|
'daemonListen',
|
||||||
]));
|
]));
|
||||||
Alert::success('Successfully created new node. <strong>Before you can add any servers you need to first assign some IP addresses and ports.</strong>')->flash();
|
Alert::success('Successfully created new node that can be configured automatically on your remote machine by visiting the configuration tab. <strong>Before you can add any servers you need to first assign some IP addresses and ports.</strong>')->flash();
|
||||||
Alert::info('<strong>To simplify the node setup you can generate a token on the configuration tab.</strong>')->flash();
|
|
||||||
|
|
||||||
return redirect()->route('admin.nodes.view', [
|
return redirect()->route('admin.nodes.view', [
|
||||||
'id' => $new,
|
'id' => $node->id,
|
||||||
'tab' => 'tab_allocation',
|
'tab' => 'tab_allocation',
|
||||||
]);
|
]);
|
||||||
} catch (DisplayValidationException $e) {
|
} catch (DisplayValidationException $e) {
|
||||||
|
@ -103,26 +111,16 @@ class NodesController extends Controller
|
||||||
|
|
||||||
public function getView(Request $request, $id)
|
public function getView(Request $request, $id)
|
||||||
{
|
{
|
||||||
$node = Models\Node::findOrFail($id);
|
$node = Models\Node::with(
|
||||||
|
'servers.user', 'servers.service',
|
||||||
|
'servers.allocations', 'location'
|
||||||
|
)->findOrFail($id);
|
||||||
|
$node->setRelation('allocations', $node->allocations()->paginate(40));
|
||||||
|
|
||||||
return view('admin.nodes.view', [
|
return view('admin.nodes.view', [
|
||||||
'node' => $node,
|
'node' => $node,
|
||||||
'servers' => Models\Server::select('servers.*', 'users.email as a_ownerEmail', 'services.name as a_serviceName')
|
'stats' => Models\Server::select(DB::raw('SUM(memory) as memory, SUM(disk) as disk'))->where('node_id', $node->id)->first(),
|
||||||
->join('users', 'users.id', '=', 'servers.owner')
|
|
||||||
->join('services', 'services.id', '=', 'servers.service')
|
|
||||||
->where('node', $id)->paginate(10, ['*'], 'servers'),
|
|
||||||
'stats' => Models\Server::select(DB::raw('SUM(memory) as memory, SUM(disk) as disk'))->where('node', $node->id)->first(),
|
|
||||||
'locations' => Models\Location::all(),
|
'locations' => Models\Location::all(),
|
||||||
'allocations' => Models\Allocation::select('allocations.*', 'servers.name as assigned_to_name')
|
|
||||||
->where('allocations.node', $node->id)
|
|
||||||
->leftJoin('servers', 'servers.id', '=', 'allocations.assigned_to')
|
|
||||||
->orderBy('allocations.ip', 'asc')
|
|
||||||
->orderBy('allocations.port', 'asc')
|
|
||||||
->paginate(20, ['*'], 'allocations'),
|
|
||||||
'allocation_ips' => Models\Allocation::select('id', 'ip')
|
|
||||||
->where('node', $node->id)
|
|
||||||
->groupBy('ip')
|
|
||||||
->get(),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,8 +128,13 @@ class NodesController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$node = new NodeRepository;
|
$node = new NodeRepository;
|
||||||
$node->update($id, $request->except([
|
$node->update($id, $request->only([
|
||||||
'_token',
|
'name', 'location', 'public',
|
||||||
|
'fqdn', 'scheme', 'memory',
|
||||||
|
'memory_overallocate', 'disk',
|
||||||
|
'disk_overallocate', 'upload_size',
|
||||||
|
'daemonBase', 'daemonSFTP',
|
||||||
|
'daemonListen', 'reset_secret',
|
||||||
]));
|
]));
|
||||||
Alert::success('Successfully update this node\'s information. If you changed any daemon settings you will need to restart it now.')->flash();
|
Alert::success('Successfully update this node\'s information. If you changed any daemon settings you will need to restart it now.')->flash();
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\Admin;
|
namespace Pterodactyl\Http\Controllers\Admin;
|
||||||
|
|
||||||
use DB;
|
|
||||||
use Log;
|
use Log;
|
||||||
use Alert;
|
use Alert;
|
||||||
use Storage;
|
use Storage;
|
||||||
|
@ -42,64 +41,29 @@ class PackController extends Controller
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function formatServices()
|
|
||||||
{
|
|
||||||
$options = Models\ServiceOptions::select(
|
|
||||||
'services.name AS p_service',
|
|
||||||
'service_options.id',
|
|
||||||
'service_options.name'
|
|
||||||
)->join('services', 'services.id', '=', 'service_options.parent_service')->get();
|
|
||||||
|
|
||||||
$array = [];
|
|
||||||
foreach ($options as &$option) {
|
|
||||||
if (! array_key_exists($option->p_service, $array)) {
|
|
||||||
$array[$option->p_service] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$array[$option->p_service] = array_merge($array[$option->p_service], [[
|
|
||||||
'id' => $option->id,
|
|
||||||
'name' => $option->name,
|
|
||||||
]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $array;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function listAll(Request $request)
|
public function listAll(Request $request)
|
||||||
{
|
{
|
||||||
return view('admin.services.packs.index', [
|
return view('admin.services.packs.index', ['services' => Models\Service::all()]);
|
||||||
'services' => Models\Service::all(),
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function listByOption(Request $request, $id)
|
public function listByOption(Request $request, $id)
|
||||||
{
|
{
|
||||||
$option = Models\ServiceOptions::findOrFail($id);
|
|
||||||
|
|
||||||
return view('admin.services.packs.byoption', [
|
return view('admin.services.packs.byoption', [
|
||||||
'packs' => Models\ServicePack::where('option', $option->id)->get(),
|
'option' => Models\ServiceOption::with('service', 'packs')->findOrFail($id),
|
||||||
'service' => Models\Service::findOrFail($option->parent_service),
|
|
||||||
'option' => $option,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function listByService(Request $request, $id)
|
public function listByService(Request $request, $id)
|
||||||
{
|
{
|
||||||
return view('admin.services.packs.byservice', [
|
return view('admin.services.packs.byservice', [
|
||||||
'service' => Models\Service::findOrFail($id),
|
'service' => Models\Service::with('options', 'options.packs')->findOrFail($id),
|
||||||
'options' => Models\ServiceOptions::select(
|
|
||||||
'service_options.id',
|
|
||||||
'service_options.name',
|
|
||||||
DB::raw('(SELECT COUNT(id) FROM service_packs WHERE service_packs.option = service_options.id) AS p_count')
|
|
||||||
)->where('parent_service', $id)->get(),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function new(Request $request, $opt = null)
|
public function new(Request $request, $opt = null)
|
||||||
{
|
{
|
||||||
return view('admin.services.packs.new', [
|
return view('admin.services.packs.new', [
|
||||||
'services' => $this->formatServices(),
|
'services' => Models\Service::with('options')->get(),
|
||||||
'packFor' => $opt,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,12 +71,14 @@ class PackController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$repo = new Pack;
|
$repo = new Pack;
|
||||||
$id = $repo->create($request->except([
|
$pack = $repo->create($request->only([
|
||||||
'_token',
|
'name', 'version', 'description',
|
||||||
|
'option', 'selectable', 'visible',
|
||||||
|
'file_upload',
|
||||||
]));
|
]));
|
||||||
Alert::success('Successfully created new service!')->flash();
|
Alert::success('Successfully created new service!')->flash();
|
||||||
|
|
||||||
return redirect()->route('admin.services.packs.edit', $id)->withInput();
|
return redirect()->route('admin.services.packs.edit', $pack->id)->withInput();
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
return redirect()->route('admin.services.packs.new', $request->input('option'))->withErrors(json_decode($ex->getMessage()))->withInput();
|
return redirect()->route('admin.services.packs.new', $request->input('option'))->withErrors(json_decode($ex->getMessage()))->withInput();
|
||||||
} catch (DisplayException $ex) {
|
} catch (DisplayException $ex) {
|
||||||
|
@ -127,15 +93,12 @@ class PackController extends Controller
|
||||||
|
|
||||||
public function edit(Request $request, $id)
|
public function edit(Request $request, $id)
|
||||||
{
|
{
|
||||||
$pack = Models\ServicePack::findOrFail($id);
|
$pack = Models\ServicePack::with('option.service')->findOrFail($id);
|
||||||
$option = Models\ServiceOptions::select('id', 'parent_service', 'name')->where('id', $pack->option)->first();
|
|
||||||
|
|
||||||
return view('admin.services.packs.edit', [
|
return view('admin.services.packs.edit', [
|
||||||
'pack' => $pack,
|
'pack' => $pack,
|
||||||
'services' => $this->formatServices(),
|
'services' => Models\Service::all()->load('options'),
|
||||||
'files' => Storage::files('packs/' . $pack->uuid),
|
'files' => Storage::files('packs/' . $pack->uuid),
|
||||||
'service' => Models\Service::findOrFail($option->parent_service),
|
|
||||||
'option' => $option,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,8 +122,9 @@ class PackController extends Controller
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
$repo = new Pack;
|
$repo = new Pack;
|
||||||
$repo->update($id, $request->except([
|
$repo->update($id, $request->only([
|
||||||
'_token',
|
'name', 'version', 'description',
|
||||||
|
'option', 'selectable', 'visible',
|
||||||
]));
|
]));
|
||||||
Alert::success('Service pack has been successfully updated.')->flash();
|
Alert::success('Service pack has been successfully updated.')->flash();
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
|
@ -215,8 +179,7 @@ class PackController extends Controller
|
||||||
public function uploadForm(Request $request, $for = null)
|
public function uploadForm(Request $request, $for = null)
|
||||||
{
|
{
|
||||||
return view('admin.services.packs.upload', [
|
return view('admin.services.packs.upload', [
|
||||||
'services' => $this->formatServices(),
|
'services' => Models\Service::all()->load('options'),
|
||||||
'for' => $for,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,12 +187,10 @@ class PackController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$repo = new Pack;
|
$repo = new Pack;
|
||||||
$id = $repo->createWithTemplate($request->except([
|
$pack = $repo->createWithTemplate($request->only(['option', 'file_upload']));
|
||||||
'_token',
|
|
||||||
]));
|
|
||||||
Alert::success('Successfully created new service!')->flash();
|
Alert::success('Successfully created new service!')->flash();
|
||||||
|
|
||||||
return redirect()->route('admin.services.packs.edit', $id)->withInput();
|
return redirect()->route('admin.services.packs.edit', $pack->id)->withInput();
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
return redirect()->back()->withErrors(json_decode($ex->getMessage()))->withInput();
|
return redirect()->back()->withErrors(json_decode($ex->getMessage()))->withInput();
|
||||||
} catch (DisplayException $ex) {
|
} catch (DisplayException $ex) {
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\Admin;
|
namespace Pterodactyl\Http\Controllers\Admin;
|
||||||
|
|
||||||
use DB;
|
|
||||||
use Log;
|
use Log;
|
||||||
use Alert;
|
use Alert;
|
||||||
use Pterodactyl\Models;
|
use Pterodactyl\Models;
|
||||||
|
@ -47,63 +46,8 @@ class ServersController extends Controller
|
||||||
|
|
||||||
public function getIndex(Request $request)
|
public function getIndex(Request $request)
|
||||||
{
|
{
|
||||||
$query = Models\Server::withTrashed()->select(
|
|
||||||
'servers.*',
|
|
||||||
'nodes.name as a_nodeName',
|
|
||||||
'users.email as a_ownerEmail',
|
|
||||||
'allocations.ip',
|
|
||||||
'allocations.port',
|
|
||||||
'allocations.ip_alias'
|
|
||||||
)->join('nodes', 'servers.node', '=', 'nodes.id')
|
|
||||||
->join('users', 'servers.owner', '=', 'users.id')
|
|
||||||
->join('allocations', 'servers.allocation', '=', 'allocations.id');
|
|
||||||
|
|
||||||
if ($request->input('filter') && ! is_null($request->input('filter'))) {
|
|
||||||
preg_match_all('/[^\s"\']+|"([^"]*)"|\'([^\']*)\'/', urldecode($request->input('filter')), $matches);
|
|
||||||
foreach ($matches[0] as $match) {
|
|
||||||
$match = str_replace('"', '', $match);
|
|
||||||
if (strpos($match, ':')) {
|
|
||||||
list($field, $term) = explode(':', $match);
|
|
||||||
if ($field === 'node') {
|
|
||||||
$field = 'nodes.name';
|
|
||||||
} elseif ($field === 'owner') {
|
|
||||||
$field = 'users.email';
|
|
||||||
} elseif (! strpos($field, '.')) {
|
|
||||||
$field = 'servers.' . $field;
|
|
||||||
}
|
|
||||||
|
|
||||||
$query->orWhere($field, 'LIKE', '%' . $term . '%');
|
|
||||||
} else {
|
|
||||||
$query->where('servers.name', 'LIKE', '%' . $match . '%');
|
|
||||||
$query->orWhere([
|
|
||||||
['servers.username', 'LIKE', '%' . $match . '%'],
|
|
||||||
['users.email', 'LIKE', '%' . $match . '%'],
|
|
||||||
['allocations.port', 'LIKE', '%' . $match . '%'],
|
|
||||||
['allocations.ip', 'LIKE', '%' . $match . '%'],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$servers = $query->paginate(20);
|
|
||||||
} catch (\Exception $ex) {
|
|
||||||
Alert::warning('There was an error with the search parameters provided.');
|
|
||||||
$servers = Models\Server::withTrashed()->select(
|
|
||||||
'servers.*',
|
|
||||||
'nodes.name as a_nodeName',
|
|
||||||
'users.email as a_ownerEmail',
|
|
||||||
'allocations.ip',
|
|
||||||
'allocations.port',
|
|
||||||
'allocations.ip_alias'
|
|
||||||
)->join('nodes', 'servers.node', '=', 'nodes.id')
|
|
||||||
->join('users', 'servers.owner', '=', 'users.id')
|
|
||||||
->join('allocations', 'servers.allocation', '=', 'allocations.id')
|
|
||||||
->paginate(20);
|
|
||||||
}
|
|
||||||
|
|
||||||
return view('admin.servers.index', [
|
return view('admin.servers.index', [
|
||||||
'servers' => $servers,
|
'servers' => Models\Server::withTrashed()->with('node', 'user')->paginate(25),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,47 +61,21 @@ class ServersController extends Controller
|
||||||
|
|
||||||
public function getView(Request $request, $id)
|
public function getView(Request $request, $id)
|
||||||
{
|
{
|
||||||
$server = Models\Server::withTrashed()->select(
|
$server = Models\Server::withTrashed()->with(
|
||||||
'servers.*',
|
'user', 'option.variables', 'variables',
|
||||||
'users.email as a_ownerEmail',
|
'node.allocations', 'databases.host'
|
||||||
'services.name as a_serviceName',
|
)->findOrFail($id);
|
||||||
DB::raw('IFNULL(service_options.executable, services.executable) as a_serviceExecutable'),
|
|
||||||
'service_options.docker_image',
|
|
||||||
'service_options.name as a_servceOptionName',
|
|
||||||
'allocations.ip',
|
|
||||||
'allocations.port',
|
|
||||||
'allocations.ip_alias'
|
|
||||||
)->join('nodes', 'servers.node', '=', 'nodes.id')
|
|
||||||
->join('users', 'servers.owner', '=', 'users.id')
|
|
||||||
->join('services', 'servers.service', '=', 'services.id')
|
|
||||||
->join('service_options', 'servers.option', '=', 'service_options.id')
|
|
||||||
->join('allocations', 'servers.allocation', '=', 'allocations.id')
|
|
||||||
->where('servers.id', $id)
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if (! $server) {
|
$server->option->variables->transform(function ($item, $key) use ($server) {
|
||||||
return abort(404);
|
$item->server_value = $server->variables->where('variable_id', $item->id)->pluck('variable_value')->first();
|
||||||
}
|
|
||||||
|
return $item;
|
||||||
|
});
|
||||||
|
|
||||||
return view('admin.servers.view', [
|
return view('admin.servers.view', [
|
||||||
'server' => $server,
|
'server' => $server,
|
||||||
'node' => Models\Node::select(
|
'assigned' => $server->node->allocations->where('server_id', $server->id)->sortBy('port')->sortBy('ip'),
|
||||||
'nodes.*',
|
'unassigned' => $server->node->allocations->where('server_id', null)->sortBy('port')->sortBy('ip'),
|
||||||
'locations.long as a_locationName'
|
|
||||||
)->join('locations', 'nodes.location', '=', 'locations.id')
|
|
||||||
->where('nodes.id', $server->node)
|
|
||||||
->first(),
|
|
||||||
'assigned' => Models\Allocation::where('assigned_to', $id)->orderBy('ip', 'asc')->orderBy('port', 'asc')->get(),
|
|
||||||
'unassigned' => Models\Allocation::where('node', $server->node)->whereNull('assigned_to')->orderBy('ip', 'asc')->orderBy('port', 'asc')->get(),
|
|
||||||
'startup' => Models\ServiceVariables::select('service_variables.*', 'server_variables.variable_value as a_serverValue')
|
|
||||||
->join('server_variables', 'server_variables.variable_id', '=', 'service_variables.id')
|
|
||||||
->where('service_variables.option_id', $server->option)
|
|
||||||
->where('server_variables.server_id', $server->id)
|
|
||||||
->get(),
|
|
||||||
'databases' => Models\Database::select('databases.*', 'database_servers.host as a_host', 'database_servers.port as a_port')
|
|
||||||
->where('server_id', $server->id)
|
|
||||||
->join('database_servers', 'database_servers.id', '=', 'databases.db_server')
|
|
||||||
->get(),
|
|
||||||
'db_servers' => Models\DatabaseServer::all(),
|
'db_servers' => Models\DatabaseServer::all(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -166,9 +84,9 @@ class ServersController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$server = new ServerRepository;
|
$server = new ServerRepository;
|
||||||
$response = $server->create($request->all());
|
$response = $server->create($request->except('_token'));
|
||||||
|
|
||||||
return redirect()->route('admin.servers.view', ['id' => $response]);
|
return redirect()->route('admin.servers.view', ['id' => $response->id]);
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
return redirect()->route('admin.servers.new')->withErrors(json_decode($ex->getMessage()))->withInput();
|
return redirect()->route('admin.servers.new')->withErrors(json_decode($ex->getMessage()))->withInput();
|
||||||
} catch (DisplayException $ex) {
|
} catch (DisplayException $ex) {
|
||||||
|
@ -234,7 +152,7 @@ class ServersController extends Controller
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request $request
|
||||||
* @return \Illuminate\Contracts\View\View
|
* @return \Illuminate\Contracts\View\View
|
||||||
*/
|
*/
|
||||||
public function postNewServerServiceOptions(Request $request)
|
public function postNewServerServiceOption(Request $request)
|
||||||
{
|
{
|
||||||
if (! $request->input('service')) {
|
if (! $request->input('service')) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
@ -244,7 +162,7 @@ class ServersController extends Controller
|
||||||
|
|
||||||
$service = Models\Service::select('executable', 'startup')->where('id', $request->input('service'))->first();
|
$service = Models\Service::select('executable', 'startup')->where('id', $request->input('service'))->first();
|
||||||
|
|
||||||
return response()->json(Models\ServiceOptions::select('id', 'name', 'docker_image')->where('parent_service', $request->input('service'))->orderBy('name', 'asc')->get());
|
return response()->json(Models\ServiceOption::select('id', 'name', 'docker_image')->where('service_id', $request->input('service'))->orderBy('name', 'asc')->get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -261,18 +179,15 @@ class ServersController extends Controller
|
||||||
], 500);
|
], 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
$option = Models\ServiceOptions::select(
|
$option = Models\ServiceOption::with('variables')->with(['packs' => function ($query) {
|
||||||
DB::raw('COALESCE(service_options.executable, services.executable) as executable'),
|
$query->where('selectable', true);
|
||||||
DB::raw('COALESCE(service_options.startup, services.startup) as startup')
|
}])->findOrFail($request->input('option'));
|
||||||
)->leftJoin('services', 'services.id', '=', 'service_options.parent_service')
|
|
||||||
->where('service_options.id', $request->input('option'))
|
|
||||||
->first();
|
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'packs' => Models\ServicePack::select('id', 'name', 'version')->where('option', $request->input('option'))->where('selectable', true)->get(),
|
'packs' => $option->packs,
|
||||||
'variables' => Models\ServiceVariables::where('option_id', $request->input('option'))->get(),
|
'variables' => $option->variables,
|
||||||
'exec' => $option->executable,
|
'exec' => $option->display_executable,
|
||||||
'startup' => $option->startup,
|
'startup' => $option->display_startup,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,9 +224,7 @@ class ServersController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$server = new ServerRepository;
|
$server = new ServerRepository;
|
||||||
$server->updateContainer($id, [
|
$server->updateContainer($id, ['image' => $request->input('docker_image')]);
|
||||||
'image' => $request->input('docker_image'),
|
|
||||||
]);
|
|
||||||
Alert::success('Successfully updated this server\'s docker image.')->flash();
|
Alert::success('Successfully updated this server\'s docker image.')->flash();
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
return redirect()->route('admin.servers.view', [
|
return redirect()->route('admin.servers.view', [
|
||||||
|
@ -333,17 +246,13 @@ class ServersController extends Controller
|
||||||
|
|
||||||
public function postUpdateServerToggleBuild(Request $request, $id)
|
public function postUpdateServerToggleBuild(Request $request, $id)
|
||||||
{
|
{
|
||||||
$server = Models\Server::findOrFail($id);
|
$server = Models\Server::with('node')->findOrFail($id);
|
||||||
$node = Models\Node::findOrFail($server->node);
|
|
||||||
$client = Models\Node::guzzleRequest($server->node);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$res = $client->request('POST', '/server/rebuild', [
|
$res = $server->node->guzzleClient([
|
||||||
'headers' => [
|
'X-Access-Server' => $server->uuid,
|
||||||
'X-Access-Server' => $server->uuid,
|
'X-Access-Token' => $node->daemonSecret,
|
||||||
'X-Access-Token' => $node->daemonSecret,
|
])->request('POST', '/server/rebuild');
|
||||||
],
|
|
||||||
]);
|
|
||||||
Alert::success('A rebuild has been queued successfully. It will run the next time this server is booted.')->flash();
|
Alert::success('A rebuild has been queued successfully. It will run the next time this server is booted.')->flash();
|
||||||
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
||||||
Log::warning($ex);
|
Log::warning($ex);
|
||||||
|
@ -360,15 +269,11 @@ class ServersController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$server = new ServerRepository;
|
$server = new ServerRepository;
|
||||||
$server->changeBuild($id, [
|
$server->changeBuild($id, $request->only([
|
||||||
'default' => $request->input('default'),
|
'default', 'add_additional',
|
||||||
'add_additional' => $request->input('add_additional'),
|
'remove_additional', 'memory',
|
||||||
'remove_additional' => $request->input('remove_additional'),
|
'swap', 'io', 'cpu',
|
||||||
'memory' => $request->input('memory'),
|
]));
|
||||||
'swap' => $request->input('swap'),
|
|
||||||
'io' => $request->input('io'),
|
|
||||||
'cpu' => $request->input('cpu'),
|
|
||||||
]);
|
|
||||||
Alert::success('Server details were successfully updated.')->flash();
|
Alert::success('Server details were successfully updated.')->flash();
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
return redirect()->route('admin.servers.view', [
|
return redirect()->route('admin.servers.view', [
|
||||||
|
@ -458,8 +363,8 @@ class ServersController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$repo = new DatabaseRepository;
|
$repo = new DatabaseRepository;
|
||||||
$repo->create($id, $request->except([
|
$repo->create($id, $request->only([
|
||||||
'_token',
|
'db_server', 'database', 'remote',
|
||||||
]));
|
]));
|
||||||
Alert::success('Added new database to this server.')->flash();
|
Alert::success('Added new database to this server.')->flash();
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\Admin;
|
namespace Pterodactyl\Http\Controllers\Admin;
|
||||||
|
|
||||||
use DB;
|
|
||||||
use Log;
|
use Log;
|
||||||
use Alert;
|
use Alert;
|
||||||
use Storage;
|
use Storage;
|
||||||
|
@ -45,10 +44,7 @@ class ServiceController extends Controller
|
||||||
public function getIndex(Request $request)
|
public function getIndex(Request $request)
|
||||||
{
|
{
|
||||||
return view('admin.services.index', [
|
return view('admin.services.index', [
|
||||||
'services' => Models\Service::select(
|
'services' => Models\Service::withCount('servers')->get(),
|
||||||
'services.*',
|
|
||||||
DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.service = services.id) as c_servers')
|
|
||||||
)->get(),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,12 +57,13 @@ class ServiceController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$repo = new ServiceRepository\Service;
|
$repo = new ServiceRepository\Service;
|
||||||
$id = $repo->create($request->except([
|
$service = $repo->create($request->only([
|
||||||
'_token',
|
'name', 'description', 'file',
|
||||||
|
'executable', 'startup',
|
||||||
]));
|
]));
|
||||||
Alert::success('Successfully created new service!')->flash();
|
Alert::success('Successfully created new service!')->flash();
|
||||||
|
|
||||||
return redirect()->route('admin.services.service', $id);
|
return redirect()->route('admin.services.service', $service->id);
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
return redirect()->route('admin.services.new')->withErrors(json_decode($ex->getMessage()))->withInput();
|
return redirect()->route('admin.services.new')->withErrors(json_decode($ex->getMessage()))->withInput();
|
||||||
} catch (DisplayException $ex) {
|
} catch (DisplayException $ex) {
|
||||||
|
@ -82,11 +79,7 @@ class ServiceController extends Controller
|
||||||
public function getService(Request $request, $service)
|
public function getService(Request $request, $service)
|
||||||
{
|
{
|
||||||
return view('admin.services.view', [
|
return view('admin.services.view', [
|
||||||
'service' => Models\Service::findOrFail($service),
|
'service' => Models\Service::with('options', 'options.servers')->findOrFail($service),
|
||||||
'options' => Models\ServiceOptions::select(
|
|
||||||
'service_options.*',
|
|
||||||
DB::raw('(SELECT COUNT(*) FROM servers WHERE servers.option = service_options.id) as c_servers')
|
|
||||||
)->where('parent_service', $service)->get(),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,8 +87,9 @@ class ServiceController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$repo = new ServiceRepository\Service;
|
$repo = new ServiceRepository\Service;
|
||||||
$repo->update($service, $request->except([
|
$repo->update($service, $request->only([
|
||||||
'_token',
|
'name', 'description', 'file',
|
||||||
|
'executable', 'startup',
|
||||||
]));
|
]));
|
||||||
Alert::success('Successfully updated this service.')->flash();
|
Alert::success('Successfully updated this service.')->flash();
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
|
@ -130,25 +124,19 @@ class ServiceController extends Controller
|
||||||
|
|
||||||
public function getOption(Request $request, $service, $option)
|
public function getOption(Request $request, $service, $option)
|
||||||
{
|
{
|
||||||
$opt = Models\ServiceOptions::findOrFail($option);
|
$option = Models\ServiceOption::with('service', 'variables')->findOrFail($option);
|
||||||
|
$option->setRelation('servers', $option->servers()->with('user')->paginate(25));
|
||||||
|
|
||||||
return view('admin.services.options.view', [
|
return view('admin.services.options.view', ['option' => $option]);
|
||||||
'service' => Models\Service::findOrFail($opt->parent_service),
|
|
||||||
'option' => $opt,
|
|
||||||
'variables' => Models\ServiceVariables::where('option_id', $option)->get(),
|
|
||||||
'servers' => Models\Server::select('servers.*', 'users.email as a_ownerEmail')
|
|
||||||
->join('users', 'users.id', '=', 'servers.owner')
|
|
||||||
->where('option', $option)
|
|
||||||
->paginate(10),
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function postOption(Request $request, $service, $option)
|
public function postOption(Request $request, $service, $option)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$repo = new ServiceRepository\Option;
|
$repo = new ServiceRepository\Option;
|
||||||
$repo->update($option, $request->except([
|
$repo->update($option, $request->only([
|
||||||
'_token',
|
'name', 'description', 'tag',
|
||||||
|
'executable', 'docker_image', 'startup',
|
||||||
]));
|
]));
|
||||||
Alert::success('Option settings successfully updated.')->flash();
|
Alert::success('Option settings successfully updated.')->flash();
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
|
@ -164,13 +152,12 @@ class ServiceController extends Controller
|
||||||
public function deleteOption(Request $request, $service, $option)
|
public function deleteOption(Request $request, $service, $option)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$service = Models\ServiceOptions::select('parent_service')->where('id', $option)->first();
|
|
||||||
$repo = new ServiceRepository\Option;
|
$repo = new ServiceRepository\Option;
|
||||||
$repo->delete($option);
|
$repo->delete($option);
|
||||||
|
|
||||||
Alert::success('Successfully deleted that option.')->flash();
|
Alert::success('Successfully deleted that option.')->flash();
|
||||||
|
|
||||||
return redirect()->route('admin.services.service', $service->parent_service);
|
return redirect()->route('admin.services.service', $service);
|
||||||
} catch (DisplayException $ex) {
|
} catch (DisplayException $ex) {
|
||||||
Alert::danger($ex->getMessage())->flash();
|
Alert::danger($ex->getMessage())->flash();
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
|
@ -218,8 +205,7 @@ class ServiceController extends Controller
|
||||||
public function getNewVariable(Request $request, $service, $option)
|
public function getNewVariable(Request $request, $service, $option)
|
||||||
{
|
{
|
||||||
return view('admin.services.options.variable', [
|
return view('admin.services.options.variable', [
|
||||||
'service' => Models\Service::findOrFail($service),
|
'option' => Models\ServiceOption::with('service')->findOrFail($option),
|
||||||
'option' => Models\ServiceOptions::where('parent_service', $service)->where('id', $option)->firstOrFail(),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,8 +213,10 @@ class ServiceController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$repo = new ServiceRepository\Variable;
|
$repo = new ServiceRepository\Variable;
|
||||||
$repo->create($option, $request->except([
|
$repo->create($option, $request->only([
|
||||||
'_token',
|
'name', 'description', 'env_variable',
|
||||||
|
'default_value', 'user_viewable',
|
||||||
|
'user_editable', 'required', 'regex',
|
||||||
]));
|
]));
|
||||||
Alert::success('Successfully added new variable to this option.')->flash();
|
Alert::success('Successfully added new variable to this option.')->flash();
|
||||||
|
|
||||||
|
@ -305,9 +293,7 @@ class ServiceController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$repo = new ServiceRepository\Service;
|
$repo = new ServiceRepository\Service;
|
||||||
$repo->updateFile($serviceId, $request->except([
|
$repo->updateFile($serviceId, $request->only(['file', 'contents']));
|
||||||
'_token',
|
|
||||||
]));
|
|
||||||
|
|
||||||
return response('', 204);
|
return response('', 204);
|
||||||
} catch (DisplayException $ex) {
|
} catch (DisplayException $ex) {
|
||||||
|
|
|
@ -29,7 +29,6 @@ use Log;
|
||||||
use Alert;
|
use Alert;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Pterodactyl\Models\User;
|
use Pterodactyl\Models\User;
|
||||||
use Pterodactyl\Models\Server;
|
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
use Pterodactyl\Http\Controllers\Controller;
|
use Pterodactyl\Http\Controllers\Controller;
|
||||||
use Pterodactyl\Repositories\UserRepository;
|
use Pterodactyl\Repositories\UserRepository;
|
||||||
|
@ -45,35 +44,11 @@ class UserController extends Controller
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @TODO: implement nicolaslopezj/searchable to clean up this disaster.
|
||||||
public function getIndex(Request $request)
|
public function getIndex(Request $request)
|
||||||
{
|
{
|
||||||
$query = User::select('users.*');
|
|
||||||
if ($request->input('filter') && ! is_null($request->input('filter'))) {
|
|
||||||
preg_match_all('/[^\s"\']+|"([^"]*)"|\'([^\']*)\'/', urldecode($request->input('filter')), $matches);
|
|
||||||
foreach ($matches[0] as $match) {
|
|
||||||
$match = str_replace('"', '', $match);
|
|
||||||
if (strpos($match, ':')) {
|
|
||||||
list($field, $term) = explode(':', $match);
|
|
||||||
$query->orWhere($field, 'LIKE', '%' . $term . '%');
|
|
||||||
} else {
|
|
||||||
$query->where('email', 'LIKE', '%' . $match . '%');
|
|
||||||
$query->orWhere([
|
|
||||||
['uuid', 'LIKE', '%' . $match . '%'],
|
|
||||||
['root_admin', 'LIKE', '%' . $match . '%'],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$users = $query->paginate(20);
|
|
||||||
} catch (\Exception $ex) {
|
|
||||||
Alert::warning('There was an error with the search parameters provided.');
|
|
||||||
$users = User::all()->paginate(20);
|
|
||||||
}
|
|
||||||
|
|
||||||
return view('admin.users.index', [
|
return view('admin.users.index', [
|
||||||
'users' => $users,
|
'users' => User::paginate(25),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,12 +60,7 @@ class UserController extends Controller
|
||||||
public function getView(Request $request, $id)
|
public function getView(Request $request, $id)
|
||||||
{
|
{
|
||||||
return view('admin.users.view', [
|
return view('admin.users.view', [
|
||||||
'user' => User::findOrFail($id),
|
'user' => User::with('servers.node')->findOrFail($id),
|
||||||
'servers' => Server::select('servers.*', 'nodes.name as nodeName', 'locations.long as location')
|
|
||||||
->join('nodes', 'servers.node', '=', 'nodes.id')
|
|
||||||
->join('locations', 'nodes.location', '=', 'locations.id')
|
|
||||||
->where('owner', $id)
|
|
||||||
->get(),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,12 +87,8 @@ class UserController extends Controller
|
||||||
try {
|
try {
|
||||||
$user = new UserRepository;
|
$user = new UserRepository;
|
||||||
$userid = $user->create($request->only([
|
$userid = $user->create($request->only([
|
||||||
'email',
|
'email', 'password', 'name_first',
|
||||||
'password',
|
'name_last', 'username', 'root_admin',
|
||||||
'name_first',
|
|
||||||
'name_last',
|
|
||||||
'username',
|
|
||||||
'root_admin',
|
|
||||||
]));
|
]));
|
||||||
Alert::success('Account has been successfully created.')->flash();
|
Alert::success('Account has been successfully created.')->flash();
|
||||||
|
|
||||||
|
@ -142,12 +108,8 @@ class UserController extends Controller
|
||||||
try {
|
try {
|
||||||
$repo = new UserRepository;
|
$repo = new UserRepository;
|
||||||
$repo->update($user, $request->only([
|
$repo->update($user, $request->only([
|
||||||
'email',
|
'email', 'password', 'name_first',
|
||||||
'password',
|
'name_last', 'username', 'root_admin',
|
||||||
'name_first',
|
|
||||||
'name_last',
|
|
||||||
'username',
|
|
||||||
'root_admin',
|
|
||||||
]));
|
]));
|
||||||
Alert::success('User account was successfully updated.')->flash();
|
Alert::success('User account was successfully updated.')->flash();
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
|
@ -162,10 +124,6 @@ class UserController extends Controller
|
||||||
|
|
||||||
public function getJson(Request $request)
|
public function getJson(Request $request)
|
||||||
{
|
{
|
||||||
foreach (User::select('email')->get() as $user) {
|
return User::select('email')->get()->pluck('email');
|
||||||
$resp[] = $user->email;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $resp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,13 +38,8 @@ class APIController extends Controller
|
||||||
{
|
{
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$keys = Models\APIKey::where('user', $request->user()->id)->get();
|
|
||||||
foreach ($keys as &$key) {
|
|
||||||
$key->permissions = Models\APIPermission::where('key_id', $key->id)->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
return view('base.api.index', [
|
return view('base.api.index', [
|
||||||
'keys' => $keys,
|
'keys' => Models\APIKey::where('user_id', $request->user()->id)->get(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,8 +52,11 @@ class APIController extends Controller
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$repo = new APIRepository($request->user());
|
$repo = new APIRepository($request->user());
|
||||||
$secret = $repo->create($request->except(['_token']));
|
$secret = $repo->create($request->only([
|
||||||
Alert::success('An API Keypair has successfully been generated. The API secret for this public key is shown below and will not be shown again.<br /><br /><code>' . $secret . '</code>')->flash();
|
'memo', 'allowed_ips',
|
||||||
|
'adminPermissions', 'permissions',
|
||||||
|
]));
|
||||||
|
Alert::success('An API Key-Pair has successfully been generated. The API secret for this public key is shown below and will not be shown again.<br /><br /><code>' . $secret . '</code>')->flash();
|
||||||
|
|
||||||
return redirect()->route('account.api');
|
return redirect()->route('account.api');
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
namespace Pterodactyl\Http\Controllers\Base;
|
namespace Pterodactyl\Http\Controllers\Base;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Pterodactyl\Models\Server;
|
|
||||||
use Pterodactyl\Http\Controllers\Controller;
|
use Pterodactyl\Http\Controllers\Controller;
|
||||||
|
|
||||||
class IndexController extends Controller
|
class IndexController extends Controller
|
||||||
|
@ -48,7 +47,7 @@ class IndexController extends Controller
|
||||||
public function getIndex(Request $request)
|
public function getIndex(Request $request)
|
||||||
{
|
{
|
||||||
return view('base.index', [
|
return view('base.index', [
|
||||||
'servers' => Server::getUserServers(10),
|
'servers' => $request->user()->serverAccessCollection(10)->load('node', 'allocation'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,8 +118,7 @@ class SecurityController extends Controller
|
||||||
|
|
||||||
public function revoke(Request $request, $id)
|
public function revoke(Request $request, $id)
|
||||||
{
|
{
|
||||||
$session = Session::where('id', $id)->where('user_id', $request->user()->id)->firstOrFail();
|
Session::where('user_id', $request->user()->id)->findOrFail($id)->delete();
|
||||||
$session->delete();
|
|
||||||
|
|
||||||
return redirect()->route('account.security');
|
return redirect()->route('account.security');
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ use Carbon\Carbon;
|
||||||
use Pterodactyl\Models;
|
use Pterodactyl\Models;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Pterodactyl\Http\Controllers\Controller;
|
use Pterodactyl\Http\Controllers\Controller;
|
||||||
use Pterodactyl\Services\NotificationService;
|
|
||||||
|
|
||||||
class RemoteController extends Controller
|
class RemoteController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -42,7 +41,7 @@ class RemoteController extends Controller
|
||||||
|
|
||||||
public function postDownload(Request $request)
|
public function postDownload(Request $request)
|
||||||
{
|
{
|
||||||
$download = Models\Download::where('token', $request->input('token', '00'))->first();
|
$download = Models\Download::where('token', $request->input('token'))->first();
|
||||||
if (! $download) {
|
if (! $download) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'error' => 'An invalid request token was recieved with this request.',
|
'error' => 'An invalid request token was recieved with this request.',
|
||||||
|
@ -59,18 +58,17 @@ class RemoteController extends Controller
|
||||||
|
|
||||||
public function postInstall(Request $request)
|
public function postInstall(Request $request)
|
||||||
{
|
{
|
||||||
$server = Models\Server::where('uuid', $request->input('server'))->first();
|
$server = Models\Server::where('uuid', $request->input('server'))->with('node')->first();
|
||||||
if (! $server) {
|
if (! $server) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'error' => 'No server by that ID was found on the system.',
|
'error' => 'No server by that ID was found on the system.',
|
||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
|
|
||||||
$node = Models\Node::findOrFail($server->node);
|
|
||||||
$hmac = $request->input('signed');
|
$hmac = $request->input('signed');
|
||||||
$status = $request->input('installed');
|
$status = $request->input('installed');
|
||||||
|
|
||||||
if (base64_decode($hmac) !== hash_hmac('sha256', $server->uuid, $node->daemonSecret, true)) {
|
if (base64_decode($hmac) !== hash_hmac('sha256', $server->uuid, $server->node->daemonSecret, true)) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'error' => 'Signed HMAC was invalid.',
|
'error' => 'Signed HMAC was invalid.',
|
||||||
], 403);
|
], 403);
|
||||||
|
@ -86,17 +84,15 @@ class RemoteController extends Controller
|
||||||
|
|
||||||
public function event(Request $request)
|
public function event(Request $request)
|
||||||
{
|
{
|
||||||
$server = Models\Server::where('uuid', $request->input('server'))->first();
|
$server = Models\Server::where('uuid', $request->input('server'))->with('node')->first();
|
||||||
if (! $server) {
|
if (! $server) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'error' => 'No server by that ID was found on the system.',
|
'error' => 'No server by that ID was found on the system.',
|
||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
|
|
||||||
$node = Models\Node::findOrFail($server->node);
|
|
||||||
|
|
||||||
$hmac = $request->input('signed');
|
$hmac = $request->input('signed');
|
||||||
if (base64_decode($hmac) !== hash_hmac('sha256', $server->uuid, $node->daemonSecret, true)) {
|
if (base64_decode($hmac) !== hash_hmac('sha256', $server->uuid, $server->node->daemonSecret, true)) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'error' => 'Signed HMAC was invalid.',
|
'error' => 'Signed HMAC was invalid.',
|
||||||
], 403);
|
], 403);
|
||||||
|
@ -130,7 +126,6 @@ class RemoteController extends Controller
|
||||||
$token->delete();
|
$token->delete();
|
||||||
|
|
||||||
// Manually as getConfigurationAsJson() returns it in correct format already
|
// Manually as getConfigurationAsJson() returns it in correct format already
|
||||||
return response($node->getConfigurationAsJson(), 200)
|
return response()->json($node->getConfigurationAsJson(), 200);
|
||||||
->header('Content-Type', 'application/json');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,18 +67,14 @@ class AjaxController extends Controller
|
||||||
*/
|
*/
|
||||||
public function getStatus(Request $request, $uuid)
|
public function getStatus(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
|
|
||||||
if (! $server) {
|
if (! $server) {
|
||||||
return response()->json([], 404);
|
return response()->json([], 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
$client = Models\Node::guzzleRequest($server->node);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$res = $client->request('GET', '/server', [
|
$res = $server->guzzleClient()->request('GET', '/server');
|
||||||
'headers' => Models\Server::getGuzzleHeaders($uuid),
|
|
||||||
]);
|
|
||||||
if ($res->getStatusCode() === 200) {
|
if ($res->getStatusCode() === 200) {
|
||||||
return response()->json(json_decode($res->getBody()));
|
return response()->json(json_decode($res->getBody()));
|
||||||
}
|
}
|
||||||
|
@ -98,10 +94,10 @@ class AjaxController extends Controller
|
||||||
*/
|
*/
|
||||||
public function postDirectoryList(Request $request, $uuid)
|
public function postDirectoryList(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$this->directory = '/' . trim(urldecode($request->input('directory', '/')), '/');
|
|
||||||
$this->authorize('list-files', $server);
|
$this->authorize('list-files', $server);
|
||||||
|
|
||||||
|
$this->directory = '/' . trim(urldecode($request->input('directory', '/')), '/');
|
||||||
$prevDir = [
|
$prevDir = [
|
||||||
'header' => ($this->directory !== '/') ? $this->directory : '',
|
'header' => ($this->directory !== '/') ? $this->directory : '',
|
||||||
];
|
];
|
||||||
|
@ -149,7 +145,7 @@ class AjaxController extends Controller
|
||||||
*/
|
*/
|
||||||
public function postSaveFile(Request $request, $uuid)
|
public function postSaveFile(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$this->authorize('save-files', $server);
|
$this->authorize('save-files', $server);
|
||||||
|
|
||||||
$controller = new Repositories\Daemon\FileRepository($uuid);
|
$controller = new Repositories\Daemon\FileRepository($uuid);
|
||||||
|
@ -175,17 +171,17 @@ class AjaxController extends Controller
|
||||||
*/
|
*/
|
||||||
public function postSetPrimary(Request $request, $uuid)
|
public function postSetPrimary(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid)->load('allocations');
|
||||||
$this->authorize('set-connection', $server);
|
$this->authorize('set-connection', $server);
|
||||||
|
|
||||||
if ((int) $request->input('allocation') === $server->allocation) {
|
if ((int) $request->input('allocation') === $server->allocation_id) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'error' => 'You are already using this as your default connection.',
|
'error' => 'You are already using this as your default connection.',
|
||||||
], 409);
|
], 409);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$allocation = Models\Allocation::where('id', $request->input('allocation'))->where('assigned_to', $server->id)->first();
|
$allocation = $server->allocations->where('id', $request->input('allocation'))->where('assigned_to', $server->id)->first();
|
||||||
if (! $allocation) {
|
if (! $allocation) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'error' => 'No allocation matching your request was found in the system.',
|
'error' => 'No allocation matching your request was found in the system.',
|
||||||
|
@ -217,10 +213,10 @@ class AjaxController extends Controller
|
||||||
|
|
||||||
public function postResetDatabasePassword(Request $request, $uuid)
|
public function postResetDatabasePassword(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$database = Models\Database::where('id', $request->input('database'))->where('server_id', $server->id)->firstOrFail();
|
|
||||||
|
|
||||||
$this->authorize('reset-db-password', $server);
|
$this->authorize('reset-db-password', $server);
|
||||||
|
|
||||||
|
$database = Models\Database::where('id', $request->input('database'))->where('server_id', $server->id)->firstOrFail();
|
||||||
try {
|
try {
|
||||||
$repo = new Repositories\DatabaseRepository;
|
$repo = new Repositories\DatabaseRepository;
|
||||||
$password = str_random(16);
|
$password = str_random(16);
|
||||||
|
|
|
@ -28,7 +28,6 @@ use DB;
|
||||||
use Log;
|
use Log;
|
||||||
use Uuid;
|
use Uuid;
|
||||||
use Alert;
|
use Alert;
|
||||||
use Javascript;
|
|
||||||
use Pterodactyl\Models;
|
use Pterodactyl\Models;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
|
@ -55,14 +54,11 @@ class ServerController extends Controller
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request $request
|
||||||
* @return \Illuminate\Contracts\View\View
|
* @return \Illuminate\Contracts\View\View
|
||||||
*/
|
*/
|
||||||
public function getIndex(Request $request)
|
public function getIndex(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($request->route()->server);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$node = Models\Node::find($server->node);
|
|
||||||
|
|
||||||
Javascript::put([
|
$server->js([
|
||||||
'server' => collect($server->makeVisible('daemonSecret'))->only(['uuid', 'daemonSecret', 'username']),
|
|
||||||
'node' => collect($node)->only('fqdn', 'scheme', 'daemonListen'),
|
|
||||||
'meta' => [
|
'meta' => [
|
||||||
'saveFile' => route('server.files.save', $server->uuidShort),
|
'saveFile' => route('server.files.save', $server->uuidShort),
|
||||||
'csrfToken' => csrf_token(),
|
'csrfToken' => csrf_token(),
|
||||||
|
@ -71,7 +67,7 @@ class ServerController extends Controller
|
||||||
|
|
||||||
return view('server.index', [
|
return view('server.index', [
|
||||||
'server' => $server,
|
'server' => $server,
|
||||||
'node' => $node,
|
'node' => $server->node,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,14 +79,10 @@ class ServerController extends Controller
|
||||||
*/
|
*/
|
||||||
public function getFiles(Request $request, $uuid)
|
public function getFiles(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$this->authorize('list-files', $server);
|
$this->authorize('list-files', $server);
|
||||||
|
|
||||||
$node = Models\Node::find($server->node);
|
$server->js([
|
||||||
|
|
||||||
Javascript::put([
|
|
||||||
'server' => collect($server->makeVisible('daemonSecret'))->only('uuid', 'uuidShort', 'daemonSecret'),
|
|
||||||
'node' => collect($node)->only('fqdn', 'scheme', 'daemonListen'),
|
|
||||||
'meta' => [
|
'meta' => [
|
||||||
'directoryList' => route('server.files.directory-list', $server->uuidShort),
|
'directoryList' => route('server.files.directory-list', $server->uuidShort),
|
||||||
'csrftoken' => csrf_token(),
|
'csrftoken' => csrf_token(),
|
||||||
|
@ -108,7 +100,7 @@ class ServerController extends Controller
|
||||||
|
|
||||||
return view('server.files.index', [
|
return view('server.files.index', [
|
||||||
'server' => $server,
|
'server' => $server,
|
||||||
'node' => $node,
|
'node' => $server->node,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,18 +112,14 @@ class ServerController extends Controller
|
||||||
*/
|
*/
|
||||||
public function getAddFile(Request $request, $uuid)
|
public function getAddFile(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$this->authorize('add-files', $server);
|
$this->authorize('add-files', $server);
|
||||||
$node = Models\Node::find($server->node);
|
|
||||||
|
|
||||||
Javascript::put([
|
$server->js();
|
||||||
'server' => collect($server->makeVisible('daemonSecret'))->only(['uuid', 'uuidShort', 'daemonSecret', 'username']),
|
|
||||||
'node' => collect($node)->only('fqdn', 'scheme', 'daemonListen'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return view('server.files.add', [
|
return view('server.files.add', [
|
||||||
'server' => $server,
|
'server' => $server,
|
||||||
'node' => $node,
|
'node' => $server->node,
|
||||||
'directory' => (in_array($request->get('dir'), [null, '/', ''])) ? '' : trim($request->get('dir'), '/') . '/',
|
'directory' => (in_array($request->get('dir'), [null, '/', ''])) ? '' : trim($request->get('dir'), '/') . '/',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -146,9 +134,8 @@ class ServerController extends Controller
|
||||||
*/
|
*/
|
||||||
public function getEditFile(Request $request, $uuid, $file)
|
public function getEditFile(Request $request, $uuid, $file)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$this->authorize('edit-files', $server);
|
$this->authorize('edit-files', $server);
|
||||||
$node = Models\Node::find($server->node);
|
|
||||||
|
|
||||||
$fileInfo = (object) pathinfo($file);
|
$fileInfo = (object) pathinfo($file);
|
||||||
$controller = new FileRepository($uuid);
|
$controller = new FileRepository($uuid);
|
||||||
|
@ -166,15 +153,13 @@ class ServerController extends Controller
|
||||||
return redirect()->route('server.files.index', $uuid);
|
return redirect()->route('server.files.index', $uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
Javascript::put([
|
$server->js([
|
||||||
'server' => collect($server->makeVisible('daemonSecret'))->only(['uuid', 'uuidShort', 'daemonSecret', 'username']),
|
|
||||||
'node' => collect($node)->only('fqdn', 'scheme', 'daemonListen'),
|
|
||||||
'stat' => $fileContent['stat'],
|
'stat' => $fileContent['stat'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return view('server.files.edit', [
|
return view('server.files.edit', [
|
||||||
'server' => $server,
|
'server' => $server,
|
||||||
'node' => $node,
|
'node' => $server->node,
|
||||||
'file' => $file,
|
'file' => $file,
|
||||||
'stat' => $fileContent['stat'],
|
'stat' => $fileContent['stat'],
|
||||||
'contents' => $fileContent['file']->content,
|
'contents' => $fileContent['file']->content,
|
||||||
|
@ -192,9 +177,7 @@ class ServerController extends Controller
|
||||||
*/
|
*/
|
||||||
public function getDownloadFile(Request $request, $uuid, $file)
|
public function getDownloadFile(Request $request, $uuid, $file)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$node = Models\Node::find($server->node);
|
|
||||||
|
|
||||||
$this->authorize('download-files', $server);
|
$this->authorize('download-files', $server);
|
||||||
|
|
||||||
$download = new Models\Download;
|
$download = new Models\Download;
|
||||||
|
@ -205,69 +188,65 @@ class ServerController extends Controller
|
||||||
|
|
||||||
$download->save();
|
$download->save();
|
||||||
|
|
||||||
return redirect($node->scheme . '://' . $node->fqdn . ':' . $node->daemonListen . '/server/file/download/' . $download->token);
|
return redirect($server->node->scheme . '://' . $server->node->fqdn . ':' . $server->node->daemonListen . '/server/file/download/' . $download->token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAllocation(Request $request, $uuid)
|
public function getAllocation(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$this->authorize('view-allocation', $server);
|
$this->authorize('view-allocation', $server);
|
||||||
$node = Models\Node::find($server->node);
|
$server->js();
|
||||||
|
|
||||||
Javascript::put([
|
|
||||||
'server' => collect($server->makeVisible('daemonSecret'))->only(['uuid', 'uuidShort', 'daemonSecret', 'username']),
|
|
||||||
'node' => collect($node)->only('fqdn', 'scheme', 'daemonListen'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return view('server.settings.allocation', [
|
return view('server.settings.allocation', [
|
||||||
'server' => $server,
|
'server' => $server->load(['allocations' => function ($query) {
|
||||||
'allocations' => Models\Allocation::where('assigned_to', $server->id)->orderBy('ip', 'asc')->orderBy('port', 'asc')->get(),
|
$query->orderBy('ip', 'asc');
|
||||||
'node' => $node,
|
$query->orderBy('port', 'asc');
|
||||||
|
}]),
|
||||||
|
'node' => $server->node,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getStartup(Request $request, $uuid)
|
public function getStartup(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
|
$server->load(['allocations' => function ($query) use ($server) {
|
||||||
|
$query->where('id', $server->allocation_id);
|
||||||
|
}]);
|
||||||
$this->authorize('view-startup', $server);
|
$this->authorize('view-startup', $server);
|
||||||
$node = Models\Node::find($server->node);
|
|
||||||
$allocation = Models\Allocation::findOrFail($server->allocation);
|
|
||||||
|
|
||||||
Javascript::put([
|
$variables = Models\ServiceVariable::select(
|
||||||
'server' => collect($server->makeVisible('daemonSecret'))->only(['uuid', 'uuidShort', 'daemonSecret', 'username']),
|
|
||||||
'node' => collect($node)->only('fqdn', 'scheme', 'daemonListen'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$variables = Models\ServiceVariables::select(
|
|
||||||
'service_variables.*',
|
'service_variables.*',
|
||||||
DB::raw('COALESCE(server_variables.variable_value, service_variables.default_value) as a_serverValue')
|
DB::raw('COALESCE(server_variables.variable_value, service_variables.default_value) as a_serverValue')
|
||||||
)->leftJoin('server_variables', 'server_variables.variable_id', '=', 'service_variables.id')
|
)->leftJoin('server_variables', 'server_variables.variable_id', '=', 'service_variables.id')
|
||||||
->where('service_variables.option_id', $server->option)
|
->where('service_variables.option_id', $server->option_id)
|
||||||
->where('server_variables.server_id', $server->id)
|
->where('server_variables.server_id', $server->id)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
$service = Models\Service::select(
|
$service = Models\Service::select(
|
||||||
DB::raw('IFNULL(service_options.executable, services.executable) as executable')
|
DB::raw('IFNULL(service_options.executable, services.executable) as executable')
|
||||||
)->leftJoin('service_options', 'service_options.parent_service', '=', 'services.id')
|
)->leftJoin('service_options', 'service_options.service_id', '=', 'services.id')
|
||||||
->where('service_options.id', $server->option)
|
->where('service_options.id', $server->option_id)
|
||||||
->where('services.id', $server->service)
|
->where('services.id', $server->service_id)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
$serverVariables = [
|
$allocation = $server->allocations->pop();
|
||||||
|
$ServerVariable = [
|
||||||
'{{SERVER_MEMORY}}' => $server->memory,
|
'{{SERVER_MEMORY}}' => $server->memory,
|
||||||
'{{SERVER_IP}}' => $allocation->ip,
|
'{{SERVER_IP}}' => $allocation->ip,
|
||||||
'{{SERVER_PORT}}' => $allocation->port,
|
'{{SERVER_PORT}}' => $allocation->port,
|
||||||
];
|
];
|
||||||
|
|
||||||
$processed = str_replace(array_keys($serverVariables), array_values($serverVariables), $server->startup);
|
$processed = str_replace(array_keys($ServerVariable), array_values($ServerVariable), $server->startup);
|
||||||
foreach ($variables as &$variable) {
|
foreach ($variables as &$variable) {
|
||||||
$replace = ($variable->user_viewable === 1) ? $variable->a_serverValue : '**';
|
$replace = ($variable->user_viewable === 1) ? $variable->a_serverValue : '[hidden]';
|
||||||
$processed = str_replace('{{' . $variable->env_variable . '}}', $replace, $processed);
|
$processed = str_replace('{{' . $variable->env_variable . '}}', $replace, $processed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$server->js();
|
||||||
|
|
||||||
return view('server.settings.startup', [
|
return view('server.settings.startup', [
|
||||||
'server' => $server,
|
'server' => $server,
|
||||||
'node' => Models\Node::find($server->node),
|
'node' => $server->node,
|
||||||
'variables' => $variables->where('user_viewable', 1),
|
'variables' => $variables->where('user_viewable', 1),
|
||||||
'service' => $service,
|
'service' => $service,
|
||||||
'processedStartup' => $processed,
|
'processedStartup' => $processed,
|
||||||
|
@ -276,18 +255,13 @@ class ServerController extends Controller
|
||||||
|
|
||||||
public function getDatabases(Request $request, $uuid)
|
public function getDatabases(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$this->authorize('view-databases', $server);
|
$this->authorize('view-databases', $server);
|
||||||
$node = Models\Node::find($server->node);
|
$server->js();
|
||||||
|
|
||||||
Javascript::put([
|
|
||||||
'server' => collect($server->makeVisible('daemonSecret'))->only(['uuid', 'uuidShort', 'daemonSecret', 'username']),
|
|
||||||
'node' => collect($node)->only('fqdn', 'scheme', 'daemonListen'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return view('server.settings.databases', [
|
return view('server.settings.databases', [
|
||||||
'server' => $server,
|
'server' => $server,
|
||||||
'node' => $node,
|
'node' => $server->node,
|
||||||
'databases' => Models\Database::select('databases.*', 'database_servers.host as a_host', 'database_servers.port as a_port')
|
'databases' => Models\Database::select('databases.*', 'database_servers.host as a_host', 'database_servers.port as a_port')
|
||||||
->where('server_id', $server->id)
|
->where('server_id', $server->id)
|
||||||
->join('database_servers', 'database_servers.id', '=', 'databases.db_server')
|
->join('database_servers', 'database_servers.id', '=', 'databases.db_server')
|
||||||
|
@ -297,24 +271,19 @@ class ServerController extends Controller
|
||||||
|
|
||||||
public function getSFTP(Request $request, $uuid)
|
public function getSFTP(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$this->authorize('view-sftp', $server);
|
$this->authorize('view-sftp', $server);
|
||||||
$node = Models\Node::find($server->node);
|
$server->js();
|
||||||
|
|
||||||
Javascript::put([
|
|
||||||
'server' => collect($server->makeVisible('daemonSecret'))->only(['uuid', 'daemonSecret', 'username']),
|
|
||||||
'node' => collect($node)->only('fqdn', 'scheme', 'daemonListen'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return view('server.settings.sftp', [
|
return view('server.settings.sftp', [
|
||||||
'server' => $server,
|
'server' => $server,
|
||||||
'node' => $node,
|
'node' => $server->node,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function postSettingsSFTP(Request $request, $uuid)
|
public function postSettingsSFTP(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$this->authorize('reset-sftp', $server);
|
$this->authorize('reset-sftp', $server);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -335,7 +304,7 @@ class ServerController extends Controller
|
||||||
|
|
||||||
public function postSettingsStartup(Request $request, $uuid)
|
public function postSettingsStartup(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$this->authorize('edit-startup', $server);
|
$this->authorize('edit-startup', $server);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -24,11 +24,9 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\Server;
|
namespace Pterodactyl\Http\Controllers\Server;
|
||||||
|
|
||||||
use DB;
|
|
||||||
use Log;
|
use Log;
|
||||||
use Auth;
|
use Auth;
|
||||||
use Alert;
|
use Alert;
|
||||||
use Javascript;
|
|
||||||
use Pterodactyl\Models;
|
use Pterodactyl\Models;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
|
@ -50,73 +48,47 @@ class SubuserController extends Controller
|
||||||
|
|
||||||
public function getIndex(Request $request, $uuid)
|
public function getIndex(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid)->load('subusers.user');
|
||||||
$this->authorize('list-subusers', $server);
|
$this->authorize('list-subusers', $server);
|
||||||
$node = Models\Node::find($server->node);
|
|
||||||
|
|
||||||
Javascript::put([
|
$server->js();
|
||||||
'server' => collect($server->makeVisible('daemonSecret'))->only(['uuid', 'uuidShort', 'daemonSecret', 'username']),
|
|
||||||
'node' => collect($node)->only('fqdn', 'scheme', 'daemonListen'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return view('server.users.index', [
|
return view('server.users.index', [
|
||||||
'server' => $server,
|
'server' => $server,
|
||||||
'node' => $node,
|
'node' => $server->node,
|
||||||
'subusers' => Models\Subuser::select('subusers.*', 'users.email', 'users.username', 'users.use_totp')
|
'subusers' => $server->subusers,
|
||||||
->join('users', 'users.id', '=', 'subusers.user_id')
|
|
||||||
->where('server_id', $server->id)
|
|
||||||
->get(),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getView(Request $request, $uuid, $id)
|
public function getView(Request $request, $uuid, $id)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid)->load('node');
|
||||||
$this->authorize('view-subuser', $server);
|
$this->authorize('view-subuser', $server);
|
||||||
$node = Models\Node::find($server->node);
|
|
||||||
|
|
||||||
Javascript::put([
|
$subuser = Models\Subuser::with('permissions', 'user')
|
||||||
'server' => collect($server->makeVisible('daemonSecret'))->only(['uuid', 'uuidShort', 'daemonSecret', 'username']),
|
->where('server_id', $server->id)->findOrFail($id);
|
||||||
'node' => collect($node)->only('fqdn', 'scheme', 'daemonListen'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$subuser = Models\Subuser::select('subusers.*', 'users.email as a_userEmail')
|
$server->js();
|
||||||
->join('users', 'users.id', '=', 'subusers.user_id')
|
|
||||||
->where(DB::raw('md5(subusers.id)'), $id)->where('subusers.server_id', $server->id)
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if (! $subuser) {
|
|
||||||
abort(404);
|
|
||||||
}
|
|
||||||
|
|
||||||
$permissions = [];
|
|
||||||
$modelPermissions = Models\Permission::select('permission')
|
|
||||||
->where('user_id', $subuser->user_id)->where('server_id', $server->id)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
foreach ($modelPermissions as &$perm) {
|
|
||||||
$permissions[$perm->permission] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return view('server.users.view', [
|
return view('server.users.view', [
|
||||||
'server' => $server,
|
'server' => $server,
|
||||||
'node' => $node,
|
'node' => $server->node,
|
||||||
'subuser' => $subuser,
|
'subuser' => $subuser,
|
||||||
'permissions' => $permissions,
|
'permissions' => $subuser->permissions->mapWithKeys(function ($item, $key) {
|
||||||
|
return [$item->permission => true];
|
||||||
|
}),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function postView(Request $request, $uuid, $id)
|
public function postView(Request $request, $uuid, $id)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$this->authorize('edit-subuser', $server);
|
$this->authorize('edit-subuser', $server);
|
||||||
|
|
||||||
$subuser = Models\Subuser::where(DB::raw('md5(id)'), $id)->where('server_id', $server->id)->first();
|
$subuser = Models\Subuser::where('server_id', $server->id)->findOrFail($id);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (! $subuser) {
|
if ($subuser->user_id === Auth::user()->id) {
|
||||||
throw new DisplayException('Unable to locate a subuser by that ID.');
|
|
||||||
} elseif ($subuser->user_id === Auth::user()->id) {
|
|
||||||
throw new DisplayException('You are not authorized to edit you own account.');
|
throw new DisplayException('You are not authorized to edit you own account.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,36 +120,31 @@ class SubuserController extends Controller
|
||||||
|
|
||||||
public function getNew(Request $request, $uuid)
|
public function getNew(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$this->authorize('create-subuser', $server);
|
$this->authorize('create-subuser', $server);
|
||||||
$node = Models\Node::find($server->node);
|
$server->js();
|
||||||
|
|
||||||
Javascript::put([
|
|
||||||
'server' => collect($server->makeVisible('daemonSecret'))->only(['uuid', 'uuidShort', 'daemonSecret', 'username']),
|
|
||||||
'node' => collect($node)->only('fqdn', 'scheme', 'daemonListen'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return view('server.users.new', [
|
return view('server.users.new', [
|
||||||
'server' => $server,
|
'server' => $server,
|
||||||
'node' => $node,
|
'node' => $server->node,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function postNew(Request $request, $uuid)
|
public function postNew(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$this->authorize('create-subuser', $server);
|
$this->authorize('create-subuser', $server);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$repo = new SubuserRepository;
|
$repo = new SubuserRepository;
|
||||||
$id = $repo->create($server->id, $request->except([
|
$subuser = $repo->create($server->id, $request->only([
|
||||||
'_token',
|
'permissions', 'email',
|
||||||
]));
|
]));
|
||||||
Alert::success('Successfully created new subuser.')->flash();
|
Alert::success('Successfully created new subuser.')->flash();
|
||||||
|
|
||||||
return redirect()->route('server.subusers.view', [
|
return redirect()->route('server.subusers.view', [
|
||||||
'uuid' => $uuid,
|
'uuid' => $uuid,
|
||||||
'id' => md5($id),
|
'id' => $subuser->id,
|
||||||
]);
|
]);
|
||||||
} catch (DisplayValidationException $ex) {
|
} catch (DisplayValidationException $ex) {
|
||||||
return redirect()->route('server.subusers.new', $uuid)->withErrors(json_decode($ex->getMessage()))->withInput();
|
return redirect()->route('server.subusers.new', $uuid)->withErrors(json_decode($ex->getMessage()))->withInput();
|
||||||
|
@ -193,14 +160,11 @@ class SubuserController extends Controller
|
||||||
|
|
||||||
public function deleteSubuser(Request $request, $uuid, $id)
|
public function deleteSubuser(Request $request, $uuid, $id)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$this->authorize('delete-subuser', $server);
|
$this->authorize('delete-subuser', $server);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$subuser = Models\Subuser::select('id')->where(DB::raw('md5(id)'), $id)->where('server_id', $server->id)->first();
|
$subuser = Models\Subuser::where('server_id', $server->id)->findOrFail($id);
|
||||||
if (! $subuser) {
|
|
||||||
throw new DisplayException('No subuser by that ID was found on the system.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$repo = new SubuserRepository;
|
$repo = new SubuserRepository;
|
||||||
$repo->delete($subuser->id);
|
$repo->delete($subuser->id);
|
||||||
|
|
|
@ -26,7 +26,6 @@ namespace Pterodactyl\Http\Controllers\Server;
|
||||||
|
|
||||||
use Log;
|
use Log;
|
||||||
use Alert;
|
use Alert;
|
||||||
use Javascript;
|
|
||||||
use Pterodactyl\Models;
|
use Pterodactyl\Models;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Pterodactyl\Repositories;
|
use Pterodactyl\Repositories;
|
||||||
|
@ -43,19 +42,14 @@ class TaskController extends Controller
|
||||||
|
|
||||||
public function getIndex(Request $request, $uuid)
|
public function getIndex(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid)->load('tasks');
|
||||||
$this->authorize('list-tasks', $server);
|
$this->authorize('list-tasks', $server);
|
||||||
$node = Models\Node::find($server->node);
|
$server->js();
|
||||||
|
|
||||||
Javascript::put([
|
|
||||||
'server' => collect($server->makeVisible('daemonSecret'))->only(['uuid', 'uuidShort', 'daemonSecret', 'username']),
|
|
||||||
'node' => collect($node)->only('fqdn', 'scheme', 'daemonListen'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return view('server.tasks.index', [
|
return view('server.tasks.index', [
|
||||||
'server' => $server,
|
'server' => $server,
|
||||||
'node' => $node,
|
'node' => $server->node,
|
||||||
'tasks' => Models\Task::where('server', $server->id)->get(),
|
'tasks' => $server->tasks,
|
||||||
'actions' => [
|
'actions' => [
|
||||||
'command' => trans('server.tasks.actions.command'),
|
'command' => trans('server.tasks.actions.command'),
|
||||||
'power' => trans('server.tasks.actions.power'),
|
'power' => trans('server.tasks.actions.power'),
|
||||||
|
@ -65,24 +59,19 @@ class TaskController extends Controller
|
||||||
|
|
||||||
public function getNew(Request $request, $uuid)
|
public function getNew(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$this->authorize('create-task', $server);
|
$this->authorize('create-task', $server);
|
||||||
$node = Models\Node::find($server->node);
|
$server->js();
|
||||||
|
|
||||||
Javascript::put([
|
|
||||||
'server' => collect($server->makeVisible('daemonSecret'))->only(['uuid', 'uuidShort', 'daemonSecret', 'username']),
|
|
||||||
'node' => collect($node)->only('fqdn', 'scheme', 'daemonListen'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return view('server.tasks.new', [
|
return view('server.tasks.new', [
|
||||||
'server' => $server,
|
'server' => $server,
|
||||||
'node' => $node,
|
'node' => $server->node,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function postNew(Request $request, $uuid)
|
public function postNew(Request $request, $uuid)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid);
|
||||||
$this->authorize('create-task', $server);
|
$this->authorize('create-task', $server);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -106,12 +95,11 @@ class TaskController extends Controller
|
||||||
|
|
||||||
public function deleteTask(Request $request, $uuid, $id)
|
public function deleteTask(Request $request, $uuid, $id)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid)->load('tasks');
|
||||||
$this->authorize('delete-task', $server);
|
$this->authorize('delete-task', $server);
|
||||||
|
|
||||||
$task = Models\Task::findOrFail($id);
|
$task = $server->tasks->where('id', $id)->first();
|
||||||
|
if (! $task) {
|
||||||
if (! $task || $server->id !== $task->server) {
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'error' => 'No task by that ID was found associated with this server.',
|
'error' => 'No task by that ID was found associated with this server.',
|
||||||
], 404);
|
], 404);
|
||||||
|
@ -133,12 +121,11 @@ class TaskController extends Controller
|
||||||
|
|
||||||
public function toggleTask(Request $request, $uuid, $id)
|
public function toggleTask(Request $request, $uuid, $id)
|
||||||
{
|
{
|
||||||
$server = Models\Server::getByUUID($uuid);
|
$server = Models\Server::byUuid($uuid)->load('tasks');
|
||||||
$this->authorize('toggle-task', $server);
|
$this->authorize('toggle-task', $server);
|
||||||
|
|
||||||
$task = Models\Task::findOrFail($id);
|
$task = $server->tasks->where('id', $id)->first();
|
||||||
|
if (! $task) {
|
||||||
if (! $task || $server->id !== $task->server) {
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'error' => 'No task by that ID was found associated with this server.',
|
'error' => 'No task by that ID was found associated with this server.',
|
||||||
], 404);
|
], 404);
|
||||||
|
|
|
@ -121,7 +121,7 @@ class APISecretToken extends Authorization
|
||||||
// Log the Route Access
|
// Log the Route Access
|
||||||
APILogService::log($request, null, true);
|
APILogService::log($request, null, true);
|
||||||
|
|
||||||
return Auth::loginUsingId($key->user);
|
return Auth::loginUsingId($key->user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function _generateHMAC($body, $key)
|
protected function _generateHMAC($body, $key)
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace Pterodactyl\Http\Middleware;
|
||||||
|
|
||||||
use Auth;
|
use Auth;
|
||||||
use Closure;
|
use Closure;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
|
|
||||||
class CheckServer
|
class CheckServer
|
||||||
|
@ -37,22 +38,22 @@ class CheckServer
|
||||||
* @param \Closure $next
|
* @param \Closure $next
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function handle($request, Closure $next)
|
public function handle(Request $request, Closure $next)
|
||||||
{
|
{
|
||||||
if (! Auth::user()) {
|
if (! Auth::user()) {
|
||||||
return redirect()->guest('auth/login');
|
return redirect()->guest('auth/login');
|
||||||
}
|
}
|
||||||
|
|
||||||
$server = Server::getByUUID($request->route()->server);
|
$server = Server::byUuid($request->route()->server);
|
||||||
if (! $server) {
|
if (! $server) {
|
||||||
return response()->view('errors.404', [], 404);
|
return response()->view('errors.404', [], 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($server->suspended === 1) {
|
if ($server->suspended) {
|
||||||
return response()->view('errors.suspended', [], 403);
|
return response()->view('errors.suspended', [], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($server->installed !== 1) {
|
if (! $server->installed) {
|
||||||
return response()->view('errors.installing', [], 403);
|
return response()->view('errors.installing', [], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,7 @@ class AdminRoutes
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$router->post('/new/service-options', [
|
$router->post('/new/service-options', [
|
||||||
'uses' => 'Admin\ServersController@postNewServerServiceOptions',
|
'uses' => 'Admin\ServersController@postNewServerServiceOption',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$router->post('/new/option-details', [
|
$router->post('/new/option-details', [
|
||||||
|
|
|
@ -48,4 +48,14 @@ class APIKey extends Model
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $guarded = ['id', 'created_at', 'updated_at'];
|
protected $guarded = ['id', 'created_at', 'updated_at'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the permissions associated with a key.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function permissions()
|
||||||
|
{
|
||||||
|
return $this->hasMany(APIPermission::class, 'key_id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,8 +48,30 @@ class Allocation extends Model
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'node' => 'integer',
|
'node_id' => 'integer',
|
||||||
'port' => 'integer',
|
'port' => 'integer',
|
||||||
'assigned_to' => 'integer',
|
'server_id' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessor to automatically provide the IP alias if defined.
|
||||||
|
*
|
||||||
|
* @param null|string $value
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getAliasAttribute($value)
|
||||||
|
{
|
||||||
|
return (is_null($this->ip_alias)) ? $this->ip : $this->ip_alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessor to quickly determine if this allocation has an alias.
|
||||||
|
*
|
||||||
|
* @param null|string $value
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function getHasAliasAttribute($value)
|
||||||
|
{
|
||||||
|
return ! is_null($this->ip_alias);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,27 @@ class Database extends Model
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'server' => 'integer',
|
'server_id' => 'integer',
|
||||||
'db_server' => 'integer',
|
'db_server' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the host database server associated with a database.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
|
*/
|
||||||
|
public function host()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(DatabaseServer::class, 'db_server');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the server associated with a database.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
|
*/
|
||||||
|
public function server()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Server::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,4 +59,24 @@ class DatabaseServer extends Model
|
||||||
'server_id' => 'integer',
|
'server_id' => 'integer',
|
||||||
'db_server' => 'integer',
|
'db_server' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the node associated with a database host.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
|
*/
|
||||||
|
public function node()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Node::class, 'linked_node');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the databases assocaited with this host.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function databases()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Database::class, 'db_server');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,4 +41,24 @@ class Location extends Model
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $guarded = ['id', 'created_at', 'updated_at'];
|
protected $guarded = ['id', 'created_at', 'updated_at'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the nodes in a specificed location.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function nodes()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Node::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the servers within a given location.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
|
||||||
|
*/
|
||||||
|
public function servers()
|
||||||
|
{
|
||||||
|
return $this->hasManyThrough(Server::class, Node::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ class Node extends Model
|
||||||
*/
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'public' => 'integer',
|
'public' => 'integer',
|
||||||
'location' => 'integer',
|
'location_id' => 'integer',
|
||||||
'memory' => 'integer',
|
'memory' => 'integer',
|
||||||
'disk' => 'integer',
|
'disk' => 'integer',
|
||||||
'daemonListen' => 'integer',
|
'daemonListen' => 'integer',
|
||||||
|
@ -61,11 +61,18 @@ class Node extends Model
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fields that are not mass assignable.
|
* Fields that are mass assignable.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $guarded = ['id', 'created_at', 'updated_at'];
|
protected $fillable = [
|
||||||
|
'public', 'name', 'location_id',
|
||||||
|
'fqdn', 'scheme', 'memory',
|
||||||
|
'memory_overallocate', 'disk',
|
||||||
|
'disk_overallocate', 'upload_size',
|
||||||
|
'daemonSecret', 'daemonBase',
|
||||||
|
'daemonSFTP', 'daemonListen',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
|
@ -96,11 +103,28 @@ class Node extends Model
|
||||||
return self::$nodes[$id];
|
return self::$nodes[$id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an instance of the Guzzle client for this specific node.
|
||||||
|
*
|
||||||
|
* @param array $headers
|
||||||
|
* @return \GuzzleHttp\Client
|
||||||
|
*/
|
||||||
|
public function guzzleClient($headers = [])
|
||||||
|
{
|
||||||
|
return new Client([
|
||||||
|
'base_uri' => sprintf('%s://%s:%s/', $this->scheme, $this->fqdn, $this->daemonListen),
|
||||||
|
'timeout' => env('GUZZLE_TIMEOUT', 5.0),
|
||||||
|
'connect_timeout' => env('GUZZLE_CONNECT_TIMEOUT', 3.0),
|
||||||
|
'headers' => $headers,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a Guzzle Client for the node in question.
|
* Returns a Guzzle Client for the node in question.
|
||||||
*
|
*
|
||||||
* @param int $node
|
* @param int $node
|
||||||
* @return \GuzzleHttp\Client
|
* @return \GuzzleHttp\Client
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public static function guzzleRequest($node)
|
public static function guzzleRequest($node)
|
||||||
{
|
{
|
||||||
|
@ -177,4 +201,34 @@ class Node extends Model
|
||||||
|
|
||||||
return json_encode($config, $json_options);
|
return json_encode($config, $json_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the location associated with a node.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
|
*/
|
||||||
|
public function location()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Location::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the servers associated with a node.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function servers()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Server::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the allocations associated with a node.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function allocations()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Allocation::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,13 @@ use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class Permission extends Model
|
class Permission extends Model
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Should timestamps be used on this model.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $timestamps = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The table associated with the model.
|
* The table associated with the model.
|
||||||
*
|
*
|
||||||
|
@ -42,22 +49,35 @@ class Permission extends Model
|
||||||
*/
|
*/
|
||||||
protected $guarded = ['id', 'created_at', 'updated_at'];
|
protected $guarded = ['id', 'created_at', 'updated_at'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast values to correct type.
|
* Cast values to correct type.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'user_id' => 'integer',
|
'subuser_id' => 'integer',
|
||||||
'server_id' => 'integer',
|
];
|
||||||
];
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find permission by permission node.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\Query\Builder $query
|
||||||
|
* @param string $permission
|
||||||
|
* @return \Illuminate\Database\Query\Builder
|
||||||
|
*/
|
||||||
public function scopePermission($query, $permission)
|
public function scopePermission($query, $permission)
|
||||||
{
|
{
|
||||||
return $query->where('permission', $permission);
|
return $query->where('permission', $permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function scopeServer($query, $server)
|
/**
|
||||||
|
* Filter permission by server.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\Query\Builder $query
|
||||||
|
* @param \Pterodactyl\Models\Server $server
|
||||||
|
* @return \Illuminate\Database\Query\Builder
|
||||||
|
*/
|
||||||
|
public function scopeServer($query, Server $server)
|
||||||
{
|
{
|
||||||
return $query->where('server_id', $server->id);
|
return $query->where('server_id', $server->id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
namespace Pterodactyl\Models;
|
namespace Pterodactyl\Models;
|
||||||
|
|
||||||
use Auth;
|
use Auth;
|
||||||
|
use Javascript;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
@ -67,18 +68,19 @@ class Server extends Model
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'node' => 'integer',
|
'node_id' => 'integer',
|
||||||
'suspended' => 'integer',
|
'suspended' => 'integer',
|
||||||
'owner' => 'integer',
|
'owner_id' => 'integer',
|
||||||
'memory' => 'integer',
|
'memory' => 'integer',
|
||||||
'swap' => 'integer',
|
'swap' => 'integer',
|
||||||
'disk' => 'integer',
|
'disk' => 'integer',
|
||||||
'io' => 'integer',
|
'io' => 'integer',
|
||||||
'cpu' => 'integer',
|
'cpu' => 'integer',
|
||||||
'oom_disabled' => 'integer',
|
'oom_disabled' => 'integer',
|
||||||
'port' => 'integer',
|
'allocation_id' => 'integer',
|
||||||
'service' => 'integer',
|
'service_id' => 'integer',
|
||||||
'option' => 'integer',
|
'option_id' => 'integer',
|
||||||
|
'pack_id' => 'integer',
|
||||||
'installed' => 'integer',
|
'installed' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -101,62 +103,6 @@ class Server extends Model
|
||||||
self::$user = Auth::user();
|
self::$user = Auth::user();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if we need to change the server's daemonSecret value to
|
|
||||||
* match that of the user if they are a subuser.
|
|
||||||
*
|
|
||||||
* @param Illuminate\Database\Eloquent\Model\Server $server
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function getUserDaemonSecret(Server $server)
|
|
||||||
{
|
|
||||||
if (self::$user->id === $server->owner || self::$user->root_admin === 1) {
|
|
||||||
return $server->daemonSecret;
|
|
||||||
}
|
|
||||||
|
|
||||||
$subuser = Subuser::where('server_id', $server->id)->where('user_id', self::$user->id)->first();
|
|
||||||
|
|
||||||
if (is_null($subuser)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $subuser->daemonSecret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns array of all servers owned by the logged in user.
|
|
||||||
* Returns all users servers if user is a root admin.
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Database\Eloquent\Collection
|
|
||||||
*/
|
|
||||||
public static function getUserServers($paginate = null)
|
|
||||||
{
|
|
||||||
$query = self::select(
|
|
||||||
'servers.*',
|
|
||||||
'nodes.name as nodeName',
|
|
||||||
'locations.short as a_locationShort',
|
|
||||||
'allocations.ip',
|
|
||||||
'allocations.ip_alias',
|
|
||||||
'allocations.port',
|
|
||||||
'services.name as a_serviceName',
|
|
||||||
'service_options.name as a_serviceOptionName'
|
|
||||||
)->join('nodes', 'servers.node', '=', 'nodes.id')
|
|
||||||
->join('locations', 'nodes.location', '=', 'locations.id')
|
|
||||||
->join('services', 'servers.service', '=', 'services.id')
|
|
||||||
->join('service_options', 'servers.option', '=', 'service_options.id')
|
|
||||||
->join('allocations', 'servers.allocation', '=', 'allocations.id');
|
|
||||||
|
|
||||||
if (self::$user->root_admin !== 1) {
|
|
||||||
$query->whereIn('servers.id', Subuser::accessServers());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_numeric($paginate)) {
|
|
||||||
return $query->paginate($paginate);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $query->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a single server specified by UUID.
|
* Returns a single server specified by UUID.
|
||||||
* DO NOT USE THIS TO MODIFY SERVER DETAILS OR SAVE THOSE DETAILS.
|
* DO NOT USE THIS TO MODIFY SERVER DETAILS OR SAVE THOSE DETAILS.
|
||||||
|
@ -165,30 +111,23 @@ class Server extends Model
|
||||||
* @param string $uuid The Short-UUID of the server to return an object about.
|
* @param string $uuid The Short-UUID of the server to return an object about.
|
||||||
* @return \Illuminate\Database\Eloquent\Collection
|
* @return \Illuminate\Database\Eloquent\Collection
|
||||||
*/
|
*/
|
||||||
public static function getByUUID($uuid)
|
public static function byUuid($uuid)
|
||||||
{
|
{
|
||||||
if (array_key_exists($uuid, self::$serverUUIDInstance)) {
|
$query = self::with('service', 'node')->where(function ($q) use ($uuid) {
|
||||||
return self::$serverUUIDInstance[$uuid];
|
$q->where('uuidShort', $uuid)->orWhere('uuid', $uuid);
|
||||||
}
|
});
|
||||||
|
|
||||||
$query = self::select('servers.*', 'services.file as a_serviceFile')
|
if (! Auth::user()->isRootAdmin()) {
|
||||||
->join('services', 'services.id', '=', 'servers.service')
|
$query->whereIn('id', Auth::user()->serverAccessArray());
|
||||||
->where('uuidShort', $uuid)
|
|
||||||
->orWhere('uuid', $uuid);
|
|
||||||
|
|
||||||
if (self::$user->root_admin !== 1) {
|
|
||||||
$query->whereIn('servers.id', Subuser::accessServers());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $query->first();
|
$result = $query->first();
|
||||||
|
|
||||||
if (! is_null($result)) {
|
if (! is_null($result)) {
|
||||||
$result->daemonSecret = self::getUserDaemonSecret($result);
|
$result->daemonSecret = Auth::user()->daemonToken($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$serverUUIDInstance[$uuid] = $result;
|
return $result;
|
||||||
|
|
||||||
return self::$serverUUIDInstance[$uuid];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -197,16 +136,84 @@ class Server extends Model
|
||||||
* @param string $uuid
|
* @param string $uuid
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function getGuzzleHeaders($uuid)
|
public function guzzleHeaders()
|
||||||
{
|
{
|
||||||
if (array_key_exists($uuid, self::$serverUUIDInstance)) {
|
return [
|
||||||
return [
|
'X-Access-Server' => $this->uuid,
|
||||||
'X-Access-Server' => self::$serverUUIDInstance[$uuid]->uuid,
|
'X-Access-Token' => Auth::user()->daemonToken($this),
|
||||||
'X-Access-Token' => self::$serverUUIDInstance[$uuid]->daemonSecret,
|
];
|
||||||
];
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an instance of the Guzzle client for this specific server using defined access token.
|
||||||
|
*
|
||||||
|
* @return \GuzzleHttp\Client
|
||||||
|
*/
|
||||||
|
public function guzzleClient()
|
||||||
|
{
|
||||||
|
return $this->node->guzzleClient($this->guzzleHeaders());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns javascript object to be embedded on server view pages with relevant information.
|
||||||
|
*
|
||||||
|
* @return \Laracasts\Utilities\JavaScript\JavaScriptFacade
|
||||||
|
*/
|
||||||
|
public function js($additional = null, $overwrite = null)
|
||||||
|
{
|
||||||
|
$response = [
|
||||||
|
'server' => collect($this->makeVisible('daemonSecret'))->only([
|
||||||
|
'uuid',
|
||||||
|
'uuidShort',
|
||||||
|
'daemonSecret',
|
||||||
|
'username',
|
||||||
|
]),
|
||||||
|
'node' => collect($this->node)->only([
|
||||||
|
'fqdn',
|
||||||
|
'scheme',
|
||||||
|
'daemonListen',
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (is_array($additional)) {
|
||||||
|
$response = array_merge($response, $additional);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
if (is_array($overwrite)) {
|
||||||
|
$response = $overwrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Javascript::put($response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the user who owns the server.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
|
*/
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class, 'owner_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the subusers associated with a server.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function subusers()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Subuser::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the default allocation for a server.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||||
|
*/
|
||||||
|
public function allocation()
|
||||||
|
{
|
||||||
|
return $this->hasOne(Allocation::class, 'id', 'allocation_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -216,7 +223,7 @@ class Server extends Model
|
||||||
*/
|
*/
|
||||||
public function allocations()
|
public function allocations()
|
||||||
{
|
{
|
||||||
return $this->hasMany(Allocation::class, 'assigned_to');
|
return $this->hasMany(Allocation::class, 'server_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -226,27 +233,27 @@ class Server extends Model
|
||||||
*/
|
*/
|
||||||
public function pack()
|
public function pack()
|
||||||
{
|
{
|
||||||
return $this->hasOne(ServicePack::class, 'id', 'pack');
|
return $this->hasOne(ServicePack::class, 'id', 'pack_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets information for the service associated with this server.
|
* Gets information for the service associated with this server.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
*/
|
*/
|
||||||
public function service()
|
public function service()
|
||||||
{
|
{
|
||||||
return $this->hasOne(Service::class, 'id', 'service');
|
return $this->belongsTo(Service::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets information for the service option associated with this server.
|
* Gets information for the service option associated with this server.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
*/
|
*/
|
||||||
public function option()
|
public function option()
|
||||||
{
|
{
|
||||||
return $this->hasOne(ServiceOptions::class, 'id', 'option');
|
return $this->belongsTo(ServiceOption::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -256,6 +263,37 @@ class Server extends Model
|
||||||
*/
|
*/
|
||||||
public function variables()
|
public function variables()
|
||||||
{
|
{
|
||||||
return $this->hasMany(ServerVariables::class);
|
return $this->hasMany(ServerVariable::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets information for the node associated with this server.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
|
*/
|
||||||
|
public function node()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Node::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets information for the tasks associated with this server.
|
||||||
|
*
|
||||||
|
* @TODO adjust server column in tasks to be server_id
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function tasks()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Task::class, 'server', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all databases associated with a server.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function databases()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Database::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace Pterodactyl\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class ServerVariables extends Model
|
class ServerVariable extends Model
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The table associated with the model.
|
* The table associated with the model.
|
||||||
|
@ -51,4 +51,14 @@ class ServerVariables extends Model
|
||||||
'server_id' => 'integer',
|
'server_id' => 'integer',
|
||||||
'variable_id' => 'integer',
|
'variable_id' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns information about a given variables parent.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
|
*/
|
||||||
|
public function variable()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(ServiceVariable::class, 'variable_id');
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -40,5 +40,38 @@ class Service extends Model
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $guarded = ['id', 'created_at', 'updated_at'];
|
protected $fillable = ['id', 'created_at', 'updated_at'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all service options associated with this service.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function options()
|
||||||
|
{
|
||||||
|
return $this->hasMany(ServiceOption::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all of the packs associated with a service, regardless of the service option.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
|
||||||
|
*/
|
||||||
|
public function packs()
|
||||||
|
{
|
||||||
|
return $this->hasManyThrough(
|
||||||
|
'Pterodactyl\Models\ServicePack', 'Pterodactyl\Models\ServiceOption',
|
||||||
|
'service_id', 'option_id'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all servers associated with this service.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function servers()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Server::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace Pterodactyl\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class ServiceOptions extends Model
|
class ServiceOption extends Model
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The table associated with the model.
|
* The table associated with the model.
|
||||||
|
@ -48,9 +48,51 @@ class ServiceOptions extends Model
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'parent_service' => 'integer',
|
'service_id' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the display executable for the option and will use the parent
|
||||||
|
* service one if the option does not have one defined.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getDisplayExecutableAttribute($value)
|
||||||
|
{
|
||||||
|
return (is_null($this->executable)) ? $this->service->executable : $this->executable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the display startup string for the option and will use the parent
|
||||||
|
* service one if the option does not have one defined.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getDisplayStartupAttribute($value)
|
||||||
|
{
|
||||||
|
return (is_null($this->startup)) ? $this->service->startup : $this->startup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets service associated with a service option.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
|
*/
|
||||||
|
public function service()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Service::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all servers associated with this service option.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function servers()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Server::class, 'option_id');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all variables associated with this service.
|
* Gets all variables associated with this service.
|
||||||
*
|
*
|
||||||
|
@ -58,7 +100,7 @@ class ServiceOptions extends Model
|
||||||
*/
|
*/
|
||||||
public function variables()
|
public function variables()
|
||||||
{
|
{
|
||||||
return $this->hasMany(ServiceVariables::class, 'option_id');
|
return $this->hasMany(ServiceVariable::class, 'option_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,6 +110,6 @@ class ServiceOptions extends Model
|
||||||
*/
|
*/
|
||||||
public function packs()
|
public function packs()
|
||||||
{
|
{
|
||||||
return $this->hasMany(ServicePack::class, 'option');
|
return $this->hasMany(ServicePack::class, 'option_id');
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -56,4 +56,14 @@ class ServicePack extends Model
|
||||||
'selectable' => 'boolean',
|
'selectable' => 'boolean',
|
||||||
'visible' => 'boolean',
|
'visible' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets option associated with a service pack.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
|
*/
|
||||||
|
public function option()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(ServiceOption::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace Pterodactyl\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class ServiceVariables extends Model
|
class ServiceVariable extends Model
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The table associated with the model.
|
* The table associated with the model.
|
||||||
|
@ -53,4 +53,9 @@ class ServiceVariables extends Model
|
||||||
'user_editable' => 'integer',
|
'user_editable' => 'integer',
|
||||||
'required' => 'integer',
|
'required' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function serverVariable()
|
||||||
|
{
|
||||||
|
return $this->hasMany(ServerVariable::class, 'variable_id');
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Models;
|
namespace Pterodactyl\Models;
|
||||||
|
|
||||||
use Auth;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class Subuser extends Model
|
class Subuser extends Model
|
||||||
|
@ -50,38 +49,43 @@ class Subuser extends Model
|
||||||
*/
|
*/
|
||||||
protected $guarded = ['id', 'created_at', 'updated_at'];
|
protected $guarded = ['id', 'created_at', 'updated_at'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast values to correct type.
|
* Cast values to correct type.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'user_id' => 'integer',
|
'user_id' => 'integer',
|
||||||
'server_id' => 'integer',
|
'server_id' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var mixed
|
* Gets the server associated with a subuser.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
*/
|
*/
|
||||||
protected static $user;
|
public function server()
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
{
|
||||||
self::$user = Auth::user();
|
return $this->belongsTo(Server::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of each server ID that the user has access to.
|
* Gets the user associated with a subuser.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
*/
|
*/
|
||||||
public static function accessServers()
|
public function user()
|
||||||
{
|
{
|
||||||
$union = self::select('server_id')->where('user_id', self::$user->id);
|
return $this->belongsTo(User::class);
|
||||||
|
}
|
||||||
|
|
||||||
return Server::select('id')->where('owner', self::$user->id)->union($union)->pluck('id');
|
/**
|
||||||
|
* Gets the permissions associated with a subuser.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function permissions()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Permission::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,16 +87,6 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac
|
||||||
*/
|
*/
|
||||||
protected $hidden = ['password', 'remember_token', 'totp_secret'];
|
protected $hidden = ['password', 'remember_token', 'totp_secret'];
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if a user has permissions.
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function permissions()
|
|
||||||
{
|
|
||||||
return $this->hasMany(Permission::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables or disables TOTP on an account if the token is valid.
|
* Enables or disables TOTP on an account if the token is valid.
|
||||||
*
|
*
|
||||||
|
@ -156,4 +146,73 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac
|
||||||
{
|
{
|
||||||
return $this->root_admin === 1;
|
return $this->root_admin === 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the user's daemon secret for a given server.
|
||||||
|
* @param Server $server \Pterodactyl\Models\Server
|
||||||
|
* @return null|string
|
||||||
|
*/
|
||||||
|
public function daemonToken(Server $server)
|
||||||
|
{
|
||||||
|
if ($this->id === $server->owner_id || $this->isRootAdmin()) {
|
||||||
|
return $server->daemonSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
$subuser = Subuser::where('server_id', $server->id)->where('user_id', $this->id)->first();
|
||||||
|
|
||||||
|
if (is_null($subuser)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $subuser->daemonSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of all servers a user is able to access.
|
||||||
|
* Note: does not account for user admin status.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function serverAccessArray()
|
||||||
|
{
|
||||||
|
$union = Subuser::select('server_id')->where('user_id', $this->id);
|
||||||
|
|
||||||
|
return Server::select('id')->where('owner_id', $this->id)->union($union)->pluck('id')->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of all servers a user is able to access.
|
||||||
|
* Note: does not account for user admin status.
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function serverAccessCollection($paginate = null)
|
||||||
|
{
|
||||||
|
$query = Server::with('service', 'node');
|
||||||
|
if (! $this->isRootAdmin()) {
|
||||||
|
$query->whereIn('id', $this->serverAccessArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
return (is_numeric($paginate)) ? $query->paginate($paginate) : $query->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all permissions that a user has.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
|
||||||
|
*/
|
||||||
|
public function permissions()
|
||||||
|
{
|
||||||
|
return $this->hasManyThrough(Permission::class, Subuser::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all servers that a user owns.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function servers()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Server::class, 'owner_id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ namespace Pterodactyl\Observers;
|
||||||
|
|
||||||
use Carbon;
|
use Carbon;
|
||||||
use Pterodactyl\Events;
|
use Pterodactyl\Events;
|
||||||
use Pterodactyl\Models;
|
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Pterodactyl\Jobs\DeleteServer;
|
use Pterodactyl\Jobs\DeleteServer;
|
||||||
use Pterodactyl\Jobs\SuspendServer;
|
use Pterodactyl\Jobs\SuspendServer;
|
||||||
|
@ -59,20 +58,14 @@ class ServerObserver
|
||||||
event(new Events\Server\Created($server));
|
event(new Events\Server\Created($server));
|
||||||
|
|
||||||
// Queue Notification Email
|
// Queue Notification Email
|
||||||
$user = Models\User::findOrFail($server->owner);
|
$server->load('user', 'node', 'service.option');
|
||||||
$node = Models\Node::select('name')->where('id', $server->node)->first();
|
|
||||||
$service = Models\Service::select('services.name', 'service_options.name as optionName')
|
|
||||||
->join('service_options', 'service_options.parent_service', '=', 'services.id')
|
|
||||||
->where('services.id', $server->service)
|
|
||||||
->where('service_options.id', $server->option)
|
|
||||||
->first();
|
|
||||||
|
|
||||||
$user->notify((new ServerCreated([
|
$server->user->notify((new ServerCreated([
|
||||||
'name' => $server->name,
|
'name' => $server->name,
|
||||||
'memory' => $server->memory,
|
'memory' => $server->memory,
|
||||||
'node' => $node->name,
|
'node' => $server->node->name,
|
||||||
'service' => $service->name,
|
'service' => $server->service->name,
|
||||||
'option' => $service->optionName,
|
'option' => $server->service->option->name,
|
||||||
'uuidShort' => $server->uuidShort,
|
'uuidShort' => $server->uuidShort,
|
||||||
])));
|
])));
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,23 @@ class ServerPolicy
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the user has the given permission on/for the server.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\User $user
|
||||||
|
* @param \Pterodactyl\Models\Server $server
|
||||||
|
* @param $permission
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function checkPermission(User $user, Server $server, $permission)
|
||||||
|
{
|
||||||
|
if ($this->isOwner($user, $server)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $user->permissions()->server($server)->permission($permission)->exists();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if current user is the owner of a server.
|
* Determine if current user is the owner of a server.
|
||||||
*
|
*
|
||||||
|
@ -48,7 +65,7 @@ class ServerPolicy
|
||||||
*/
|
*/
|
||||||
protected function isOwner(User $user, Server $server)
|
protected function isOwner(User $user, Server $server)
|
||||||
{
|
{
|
||||||
return $server->owner === $user->id;
|
return $server->owner_id === $user->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -521,21 +538,4 @@ class ServerPolicy
|
||||||
{
|
{
|
||||||
return $this->checkPermission($user, $server, 'set-allocation');
|
return $this->checkPermission($user, $server, 'set-allocation');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the user has the given permission on/for the server.
|
|
||||||
*
|
|
||||||
* @param \Pterodactyl\Models\User $user
|
|
||||||
* @param \Pterodactyl\Models\Server $server
|
|
||||||
* @param $permission
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private function checkPermission(User $user, Server $server, $permission)
|
|
||||||
{
|
|
||||||
if ($this->isOwner($user, $server)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $user->permissions()->server($server)->permission($permission)->exists();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,8 +62,8 @@ class APIRepository
|
||||||
|
|
||||||
// Node Management Routes
|
// Node Management Routes
|
||||||
'nodes.list',
|
'nodes.list',
|
||||||
|
'nodes.view',
|
||||||
'nodes.create',
|
'nodes.create',
|
||||||
'nodes.list',
|
|
||||||
'nodes.allocations',
|
'nodes.allocations',
|
||||||
'nodes.delete',
|
'nodes.delete',
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ class APIRepository
|
||||||
{
|
{
|
||||||
$this->user = is_null($user) ? Auth::user() : $user;
|
$this->user = is_null($user) ? Auth::user() : $user;
|
||||||
if (is_null($this->user)) {
|
if (is_null($this->user)) {
|
||||||
throw new \Exception('Cannot access API Repository without passing a user to __construct().');
|
throw new \Exception('Cannot access API Repository without passing a user to constructor.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ class APIRepository
|
||||||
$secretKey = str_random(16) . '.' . str_random(7) . '.' . str_random(7);
|
$secretKey = str_random(16) . '.' . str_random(7) . '.' . str_random(7);
|
||||||
$key = new Models\APIKey;
|
$key = new Models\APIKey;
|
||||||
$key->fill([
|
$key->fill([
|
||||||
'user' => $this->user->id,
|
'user_id' => $this->user->id,
|
||||||
'public' => str_random(16),
|
'public' => str_random(16),
|
||||||
'secret' => Crypt::encrypt($secretKey),
|
'secret' => Crypt::encrypt($secretKey),
|
||||||
'allowed_ips' => empty($this->allowed) ? null : json_encode($this->allowed),
|
'allowed_ips' => empty($this->allowed) ? null : json_encode($this->allowed),
|
||||||
|
@ -178,7 +178,7 @@ class APIRepository
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->user->root_admin === 1 && isset($data['adminPermissions'])) {
|
if ($this->user->isRootAdmin() && isset($data['adminPermissions'])) {
|
||||||
foreach ($data['adminPermissions'] as $permNode) {
|
foreach ($data['adminPermissions'] as $permNode) {
|
||||||
if (! strpos($permNode, ':')) {
|
if (! strpos($permNode, ':')) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -26,7 +26,6 @@ namespace Pterodactyl\Repositories\Daemon;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
use Pterodactyl\Models\Node;
|
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
use Pterodactyl\Repositories\HelperRepository;
|
use Pterodactyl\Repositories\HelperRepository;
|
||||||
|
@ -40,28 +39,6 @@ class FileRepository
|
||||||
*/
|
*/
|
||||||
protected $server;
|
protected $server;
|
||||||
|
|
||||||
/**
|
|
||||||
* The Eloquent Model for the node corresponding with the requested server.
|
|
||||||
*
|
|
||||||
* @var \Illuminate\Database\Eloquent\Model
|
|
||||||
*/
|
|
||||||
protected $node;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Guzzle Client associated with the requested server and node.
|
|
||||||
*
|
|
||||||
* @var \GuzzleHttp\Client
|
|
||||||
*/
|
|
||||||
protected $client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Guzzle Client headers associated with the requested server and node.
|
|
||||||
* (non-administrative headers).
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $headers;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
@ -69,10 +46,7 @@ class FileRepository
|
||||||
*/
|
*/
|
||||||
public function __construct($uuid)
|
public function __construct($uuid)
|
||||||
{
|
{
|
||||||
$this->server = Server::getByUUID($uuid);
|
$this->server = Server::byUuid($uuid);
|
||||||
$this->node = Node::getByID($this->server->node);
|
|
||||||
$this->client = Node::guzzleRequest($this->server->node);
|
|
||||||
$this->headers = Server::getGuzzleHeaders($uuid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -88,12 +62,9 @@ class FileRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
$file = (object) pathinfo($file);
|
$file = (object) pathinfo($file);
|
||||||
|
|
||||||
$file->dirname = (in_array($file->dirname, ['.', './', '/'])) ? null : trim($file->dirname, '/') . '/';
|
$file->dirname = (in_array($file->dirname, ['.', './', '/'])) ? null : trim($file->dirname, '/') . '/';
|
||||||
|
|
||||||
$res = $this->client->request('GET', '/server/file/stat/' . rawurlencode($file->dirname . $file->basename), [
|
$res = $this->server->guzzleClient()->request('GET', '/server/file/stat/' . rawurlencode($file->dirname . $file->basename));
|
||||||
'headers' => $this->headers,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$stat = json_decode($res->getBody());
|
$stat = json_decode($res->getBody());
|
||||||
if ($res->getStatusCode() !== 200 || ! isset($stat->size)) {
|
if ($res->getStatusCode() !== 200 || ! isset($stat->size)) {
|
||||||
|
@ -108,9 +79,7 @@ class FileRepository
|
||||||
throw new DisplayException('That file is too large to open in the browser, consider using a SFTP client.');
|
throw new DisplayException('That file is too large to open in the browser, consider using a SFTP client.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$res = $this->client->request('GET', '/server/file/f/' . rawurlencode($file->dirname . $file->basename), [
|
$res = $this->server->guzzleClient()->request('GET', '/server/file/f/' . rawurlencode($file->dirname . $file->basename));
|
||||||
'headers' => $this->headers,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$json = json_decode($res->getBody());
|
$json = json_decode($res->getBody());
|
||||||
if ($res->getStatusCode() !== 200 || ! isset($json->content)) {
|
if ($res->getStatusCode() !== 200 || ! isset($json->content)) {
|
||||||
|
@ -137,11 +106,9 @@ class FileRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
$file = (object) pathinfo($file);
|
$file = (object) pathinfo($file);
|
||||||
|
|
||||||
$file->dirname = (in_array($file->dirname, ['.', './', '/'])) ? null : trim($file->dirname, '/') . '/';
|
$file->dirname = (in_array($file->dirname, ['.', './', '/'])) ? null : trim($file->dirname, '/') . '/';
|
||||||
|
|
||||||
$res = $this->client->request('POST', '/server/file/save', [
|
$res = $this->server->guzzleClient()->request('POST', '/server/file/save', [
|
||||||
'headers' => $this->headers,
|
|
||||||
'json' => [
|
'json' => [
|
||||||
'path' => rawurlencode($file->dirname . $file->basename),
|
'path' => rawurlencode($file->dirname . $file->basename),
|
||||||
'content' => $content,
|
'content' => $content,
|
||||||
|
@ -167,9 +134,7 @@ class FileRepository
|
||||||
throw new Exception('A valid directory must be specified in order to list its contents.');
|
throw new Exception('A valid directory must be specified in order to list its contents.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$res = $this->client->request('GET', '/server/directory/' . rawurlencode($directory), [
|
$res = $this->server->guzzleClient()->request('GET', '/server/directory/' . rawurlencode($directory));
|
||||||
'headers' => $this->headers,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$json = json_decode($res->getBody());
|
$json = json_decode($res->getBody());
|
||||||
if ($res->getStatusCode() !== 200) {
|
if ($res->getStatusCode() !== 200) {
|
||||||
|
@ -180,7 +145,7 @@ class FileRepository
|
||||||
$files = [];
|
$files = [];
|
||||||
$folders = [];
|
$folders = [];
|
||||||
foreach ($json as &$value) {
|
foreach ($json as &$value) {
|
||||||
if ($value->directory === true) {
|
if ($value->directory) {
|
||||||
// @TODO Handle Symlinks
|
// @TODO Handle Symlinks
|
||||||
$folders[] = [
|
$folders[] = [
|
||||||
'entry' => $value->name,
|
'entry' => $value->name,
|
||||||
|
@ -189,7 +154,7 @@ class FileRepository
|
||||||
'date' => strtotime($value->modified),
|
'date' => strtotime($value->modified),
|
||||||
'mime' => $value->mime,
|
'mime' => $value->mime,
|
||||||
];
|
];
|
||||||
} elseif ($value->file === true) {
|
} elseif ($value->file) {
|
||||||
$files[] = [
|
$files[] = [
|
||||||
'entry' => $value->name,
|
'entry' => $value->name,
|
||||||
'directory' => trim($directory, '/'),
|
'directory' => trim($directory, '/'),
|
||||||
|
|
|
@ -114,28 +114,27 @@ class DatabaseRepository
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the password for a given database.
|
* Updates the password for a given database.
|
||||||
* @param int $database The ID of the database to modify.
|
* @param int $id The ID of the database to modify.
|
||||||
* @param string $password The new password to use for the database.
|
* @param string $password The new password to use for the database.
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function modifyPassword($database, $password)
|
public function modifyPassword($id, $password)
|
||||||
{
|
{
|
||||||
$db = Models\Database::findOrFail($database);
|
$database = Models\Database::with('host')->findOrFail($id);
|
||||||
$dbr = Models\DatabaseServer::findOrFail($db->db_server);
|
|
||||||
|
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
try {
|
try {
|
||||||
$db->password = Crypt::encrypt($password);
|
$database->password = Crypt::encrypt($password);
|
||||||
$db->save();
|
$database->save();
|
||||||
|
|
||||||
$capsule = new Capsule;
|
$capsule = new Capsule;
|
||||||
$capsule->addConnection([
|
$capsule->addConnection([
|
||||||
'driver' => 'mysql',
|
'driver' => 'mysql',
|
||||||
'host' => $dbr->host,
|
'host' => $database->host->host,
|
||||||
'port' => $dbr->port,
|
'port' => $database->host->port,
|
||||||
'database' => 'mysql',
|
'database' => 'mysql',
|
||||||
'username' => $dbr->username,
|
'username' => $database->host->username,
|
||||||
'password' => Crypt::decrypt($dbr->password),
|
'password' => Crypt::decrypt($database->host->password),
|
||||||
'charset' => 'utf8',
|
'charset' => 'utf8',
|
||||||
'collation' => 'utf8_unicode_ci',
|
'collation' => 'utf8_unicode_ci',
|
||||||
'prefix' => '',
|
'prefix' => '',
|
||||||
|
@ -147,8 +146,8 @@ class DatabaseRepository
|
||||||
$capsule->setAsGlobal();
|
$capsule->setAsGlobal();
|
||||||
Capsule::statement(sprintf(
|
Capsule::statement(sprintf(
|
||||||
'SET PASSWORD FOR `%s`@`%s` = PASSWORD(\'%s\')',
|
'SET PASSWORD FOR `%s`@`%s` = PASSWORD(\'%s\')',
|
||||||
$db->username,
|
$database->username,
|
||||||
$db->remote,
|
$database->remote,
|
||||||
$password
|
$password
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -161,13 +160,12 @@ class DatabaseRepository
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drops a database from the associated MySQL Server.
|
* Drops a database from the associated MySQL Server.
|
||||||
* @param int $database The ID of the database to drop.
|
* @param int $id The ID of the database to drop.
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function drop($database)
|
public function drop($id)
|
||||||
{
|
{
|
||||||
$db = Models\Database::findOrFail($database);
|
$database = Models\Database::with('host')->findOrFail($id);
|
||||||
$dbr = Models\DatabaseServer::findOrFail($db->db_server);
|
|
||||||
|
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
@ -175,11 +173,11 @@ class DatabaseRepository
|
||||||
$capsule = new Capsule;
|
$capsule = new Capsule;
|
||||||
$capsule->addConnection([
|
$capsule->addConnection([
|
||||||
'driver' => 'mysql',
|
'driver' => 'mysql',
|
||||||
'host' => $dbr->host,
|
'host' => $database->host->host,
|
||||||
'port' => $dbr->port,
|
'port' => $database->host->port,
|
||||||
'database' => 'mysql',
|
'database' => 'mysql',
|
||||||
'username' => $dbr->username,
|
'username' => $database->host->username,
|
||||||
'password' => Crypt::decrypt($dbr->password),
|
'password' => Crypt::decrypt($database->host->password),
|
||||||
'charset' => 'utf8',
|
'charset' => 'utf8',
|
||||||
'collation' => 'utf8_unicode_ci',
|
'collation' => 'utf8_unicode_ci',
|
||||||
'prefix' => '',
|
'prefix' => '',
|
||||||
|
@ -190,10 +188,10 @@ class DatabaseRepository
|
||||||
|
|
||||||
$capsule->setAsGlobal();
|
$capsule->setAsGlobal();
|
||||||
|
|
||||||
Capsule::statement('DROP USER `' . $db->username . '`@`' . $db->remote . '`');
|
Capsule::statement('DROP USER `' . $database->username . '`@`' . $database->remote . '`');
|
||||||
Capsule::statement('DROP DATABASE `' . $db->database . '`');
|
Capsule::statement('DROP DATABASE `' . $database->database . '`');
|
||||||
|
|
||||||
$db->delete();
|
$database->delete();
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
|
@ -206,19 +204,19 @@ class DatabaseRepository
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a database server from the system if it is empty.
|
* Deletes a database server from the system if it is empty.
|
||||||
|
*
|
||||||
* @param int $server The ID of the Database Server.
|
* @param int $server The ID of the Database Server.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public function delete($server)
|
public function delete($server)
|
||||||
{
|
{
|
||||||
$dbh = Models\DatabaseServer::findOrFail($server);
|
$host = Models\DatabaseServer::withCount('databases')->findOrFail($server);
|
||||||
$databases = Models\Database::where('db_server', $dbh->id)->count();
|
|
||||||
|
|
||||||
if ($databases > 0) {
|
if ($host->databases_count > 0) {
|
||||||
throw new DisplayException('You cannot delete a database server that has active databases attached to it.');
|
throw new DisplayException('You cannot delete a database server that has active databases attached to it.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $dbh->delete();
|
return $host->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -268,8 +266,7 @@ class DatabaseRepository
|
||||||
// Allows us to check that we can connect to things.
|
// Allows us to check that we can connect to things.
|
||||||
Capsule::select('SELECT 1 FROM dual');
|
Capsule::select('SELECT 1 FROM dual');
|
||||||
|
|
||||||
$dbh = new Models\DatabaseServer;
|
Models\DatabaseServer::create([
|
||||||
$dbh->fill([
|
|
||||||
'name' => $data['name'],
|
'name' => $data['name'],
|
||||||
'host' => $data['host'],
|
'host' => $data['host'],
|
||||||
'port' => $data['port'],
|
'port' => $data['port'],
|
||||||
|
@ -278,7 +275,6 @@ class DatabaseRepository
|
||||||
'max_databases' => null,
|
'max_databases' => null,
|
||||||
'linked_node' => (! empty($data['linked_node']) && $data['linked_node'] > 0) ? $data['linked_node'] : null,
|
'linked_node' => (! empty($data['linked_node']) && $data['linked_node'] > 0) ? $data['linked_node'] : null,
|
||||||
]);
|
]);
|
||||||
$dbh->save();
|
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
|
|
|
@ -37,14 +37,15 @@ class LocationRepository
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new location on the system.
|
* Creates a new location on the system.
|
||||||
|
*
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @throws Pterodactyl\Exceptions\DisplayValidationException
|
* @throws \Pterodactyl\Exceptions\DisplayValidationException
|
||||||
* @return int
|
* @return \Pterodactyl\Models\Location
|
||||||
*/
|
*/
|
||||||
public function create(array $data)
|
public function create(array $data)
|
||||||
{
|
{
|
||||||
$validator = Validator::make($data, [
|
$validator = Validator::make($data, [
|
||||||
'short' => 'required|regex:/^[a-z0-9_.-]{1,10}$/i|unique:locations,short',
|
'short' => 'required|regex:/^[\w.-]{1,20}$/i|unique:locations,short',
|
||||||
'long' => 'required|string|min:1|max:255',
|
'long' => 'required|string|min:1|max:255',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -54,14 +55,12 @@ class LocationRepository
|
||||||
throw new DisplayValidationException($validator->errors());
|
throw new DisplayValidationException($validator->errors());
|
||||||
}
|
}
|
||||||
|
|
||||||
$location = new Models\Location;
|
$location = Models\Location::create([
|
||||||
$location->fill([
|
|
||||||
'long' => $data['long'],
|
'long' => $data['long'],
|
||||||
'short' => $data['short'],
|
'short' => $data['short'],
|
||||||
]);
|
]);
|
||||||
$location->save();
|
|
||||||
|
|
||||||
return $location->id;
|
return $location;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,9 +72,11 @@ class LocationRepository
|
||||||
*/
|
*/
|
||||||
public function edit($id, array $data)
|
public function edit($id, array $data)
|
||||||
{
|
{
|
||||||
|
$location = Models\Location::findOrFail($id);
|
||||||
|
|
||||||
$validator = Validator::make($data, [
|
$validator = Validator::make($data, [
|
||||||
'short' => 'regex:/^[a-z0-9_.-]{1,10}$/i',
|
'short' => 'required|regex:/^[\w.-]{1,20}$/i|unique:locations,short,' . $location->id,
|
||||||
'long' => 'string|min:1|max:255',
|
'long' => 'required|string|min:1|max:255',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Run validator, throw catchable and displayable exception if it fails.
|
// Run validator, throw catchable and displayable exception if it fails.
|
||||||
|
@ -84,15 +85,7 @@ class LocationRepository
|
||||||
throw new DisplayValidationException($validator->errors());
|
throw new DisplayValidationException($validator->errors());
|
||||||
}
|
}
|
||||||
|
|
||||||
$location = Models\Location::findOrFail($id);
|
$location->fill($data);
|
||||||
|
|
||||||
if (isset($data['short'])) {
|
|
||||||
$location->short = $data['short'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($data['long'])) {
|
|
||||||
$location->long = $data['long'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $location->save();
|
return $location->save();
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ class NodeRepository
|
||||||
// Validate Fields
|
// Validate Fields
|
||||||
$validator = Validator::make($data, [
|
$validator = Validator::make($data, [
|
||||||
'name' => 'required|regex:/^([\w .-]{1,100})$/',
|
'name' => 'required|regex:/^([\w .-]{1,100})$/',
|
||||||
'location' => 'required|numeric|min:1|exists:locations,id',
|
'location_id' => 'required|numeric|min:1|exists:locations,id',
|
||||||
'public' => 'required|numeric|between:0,1',
|
'public' => 'required|numeric|between:0,1',
|
||||||
'fqdn' => 'required|string|unique:nodes,fqdn',
|
'fqdn' => 'required|string|unique:nodes,fqdn',
|
||||||
'scheme' => 'required|regex:/^(http(s)?)$/',
|
'scheme' => 'required|regex:/^(http(s)?)$/',
|
||||||
|
@ -65,7 +65,7 @@ class NodeRepository
|
||||||
|
|
||||||
// Verify the FQDN if using SSL
|
// Verify the FQDN if using SSL
|
||||||
if (filter_var($data['fqdn'], FILTER_VALIDATE_IP) && $data['scheme'] === 'https') {
|
if (filter_var($data['fqdn'], FILTER_VALIDATE_IP) && $data['scheme'] === 'https') {
|
||||||
throw new DisplayException('A fully qualified domain name is required to use secure comunication on this node.');
|
throw new DisplayException('A fully qualified domain name is required to use a secure comunication method on this node.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify FQDN is resolvable, or if not using SSL that the IP is valid.
|
// Verify FQDN is resolvable, or if not using SSL that the IP is valid.
|
||||||
|
@ -81,12 +81,7 @@ class NodeRepository
|
||||||
$uuid = new UuidService;
|
$uuid = new UuidService;
|
||||||
$data['daemonSecret'] = (string) $uuid->generate('nodes', 'daemonSecret');
|
$data['daemonSecret'] = (string) $uuid->generate('nodes', 'daemonSecret');
|
||||||
|
|
||||||
// Store the Data
|
return Models\Node::create($data);
|
||||||
$node = new Models\Node;
|
|
||||||
$node->fill($data);
|
|
||||||
$node->save();
|
|
||||||
|
|
||||||
return $node->id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update($id, array $data)
|
public function update($id, array $data)
|
||||||
|
@ -96,7 +91,7 @@ class NodeRepository
|
||||||
// Validate Fields
|
// Validate Fields
|
||||||
$validator = $validator = Validator::make($data, [
|
$validator = $validator = Validator::make($data, [
|
||||||
'name' => 'regex:/^([\w .-]{1,100})$/',
|
'name' => 'regex:/^([\w .-]{1,100})$/',
|
||||||
'location' => 'numeric|min:1|exists:locations,id',
|
'location_id' => 'numeric|min:1|exists:locations,id',
|
||||||
'public' => 'numeric|between:0,1',
|
'public' => 'numeric|between:0,1',
|
||||||
'fqdn' => 'string|unique:nodes,fqdn,' . $id,
|
'fqdn' => 'string|unique:nodes,fqdn,' . $id,
|
||||||
'scheme' => 'regex:/^(http(s)?)$/',
|
'scheme' => 'regex:/^(http(s)?)$/',
|
||||||
|
@ -152,18 +147,12 @@ class NodeRepository
|
||||||
$oldDaemonKey = $node->daemonSecret;
|
$oldDaemonKey = $node->daemonSecret;
|
||||||
$node->update($data);
|
$node->update($data);
|
||||||
try {
|
try {
|
||||||
$client = Models\Node::guzzleRequest($node->id);
|
$node->guzzleClient(['X-Access-Token' => $oldDaemonKey])->request('PATCH', '/config', [
|
||||||
$client->request('PATCH', '/config', [
|
|
||||||
'headers' => [
|
|
||||||
'X-Access-Token' => $oldDaemonKey,
|
|
||||||
],
|
|
||||||
'json' => [
|
'json' => [
|
||||||
'web' => [
|
'web' => [
|
||||||
'listen' => $node->daemonListen,
|
'listen' => $node->daemonListen,
|
||||||
'ssl' => [
|
'ssl' => [
|
||||||
'enabled' => ($node->scheme === 'https'),
|
'enabled' => ($node->scheme === 'https'),
|
||||||
'certificate' => '/etc/letsencrypt/live/' . $node->fqdn . '/fullchain.pem',
|
|
||||||
'key' => '/etc/letsencrypt/live/' . $node->fqdn . '/privkey.pem',
|
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'sftp' => [
|
'sftp' => [
|
||||||
|
@ -221,13 +210,13 @@ class NodeRepository
|
||||||
|
|
||||||
foreach ($portBlock as $assignPort) {
|
foreach ($portBlock as $assignPort) {
|
||||||
$alloc = Models\Allocation::firstOrNew([
|
$alloc = Models\Allocation::firstOrNew([
|
||||||
'node' => $node->id,
|
'node_id' => $node->id,
|
||||||
'ip' => $ip,
|
'ip' => $ip,
|
||||||
'port' => $assignPort,
|
'port' => $assignPort,
|
||||||
]);
|
]);
|
||||||
if (! $alloc->exists) {
|
if (! $alloc->exists) {
|
||||||
$alloc->fill([
|
$alloc->fill([
|
||||||
'node' => $node->id,
|
'node_id' => $node->id,
|
||||||
'ip' => $ip,
|
'ip' => $ip,
|
||||||
'port' => $assignPort,
|
'port' => $assignPort,
|
||||||
'ip_alias' => $setAlias,
|
'ip_alias' => $setAlias,
|
||||||
|
@ -238,13 +227,13 @@ class NodeRepository
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$alloc = Models\Allocation::firstOrNew([
|
$alloc = Models\Allocation::firstOrNew([
|
||||||
'node' => $node->id,
|
'node_id' => $node->id,
|
||||||
'ip' => $ip,
|
'ip' => $ip,
|
||||||
'port' => $port,
|
'port' => $port,
|
||||||
]);
|
]);
|
||||||
if (! $alloc->exists) {
|
if (! $alloc->exists) {
|
||||||
$alloc->fill([
|
$alloc->fill([
|
||||||
'node' => $node->id,
|
'node_id' => $node->id,
|
||||||
'ip' => $ip,
|
'ip' => $ip,
|
||||||
'port' => $port,
|
'port' => $port,
|
||||||
'ip_alias' => $setAlias,
|
'ip_alias' => $setAlias,
|
||||||
|
@ -266,8 +255,8 @@ class NodeRepository
|
||||||
|
|
||||||
public function delete($id)
|
public function delete($id)
|
||||||
{
|
{
|
||||||
$node = Models\Node::findOrFail($id);
|
$node = Models\Node::withCount('servers')->findOrFail($id);
|
||||||
if (Models\Server::where('node', $id)->count() > 0) {
|
if ($node->servers_count > 0) {
|
||||||
throw new DisplayException('You cannot delete a node with servers currently attached to it.');
|
throw new DisplayException('You cannot delete a node with servers currently attached to it.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +269,7 @@ class NodeRepository
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Delete Allocations
|
// Delete Allocations
|
||||||
Models\Allocation::where('node', $node->id)->delete();
|
Models\Allocation::where('node_id', $node->id)->delete();
|
||||||
|
|
||||||
// Delete configure tokens
|
// Delete configure tokens
|
||||||
Models\NodeConfigurationToken::where('node', $node->id)->delete();
|
Models\NodeConfigurationToken::where('node', $node->id)->delete();
|
||||||
|
|
|
@ -30,6 +30,7 @@ use Crypt;
|
||||||
use Validator;
|
use Validator;
|
||||||
use Pterodactyl\Models;
|
use Pterodactyl\Models;
|
||||||
use Pterodactyl\Services\UuidService;
|
use Pterodactyl\Services\UuidService;
|
||||||
|
use GuzzleHttp\Exception\TransferException;
|
||||||
use Pterodactyl\Services\DeploymentService;
|
use Pterodactyl\Services\DeploymentService;
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
use Pterodactyl\Exceptions\DisplayValidationException;
|
use Pterodactyl\Exceptions\DisplayValidationException;
|
||||||
|
@ -89,17 +90,17 @@ class ServerRepository
|
||||||
'io' => 'required|numeric|min:10|max:1000',
|
'io' => 'required|numeric|min:10|max:1000',
|
||||||
'cpu' => 'required|numeric|min:0',
|
'cpu' => 'required|numeric|min:0',
|
||||||
'disk' => 'required|numeric|min:0',
|
'disk' => 'required|numeric|min:0',
|
||||||
'service' => 'required|numeric|min:1|exists:services,id',
|
'service_id' => 'required|numeric|min:1|exists:services,id',
|
||||||
'option' => 'required|numeric|min:1|exists:service_options,id',
|
'option_id' => 'required|numeric|min:1|exists:service_options,id',
|
||||||
'location' => 'required|numeric|min:1|exists:locations,id',
|
'location_id' => 'required|numeric|min:1|exists:locations,id',
|
||||||
'pack' => 'sometimes|nullable|numeric|min:0',
|
'pack_id' => 'sometimes|nullable|numeric|min:0',
|
||||||
'startup' => 'string',
|
'startup' => 'string',
|
||||||
'custom_image_name' => 'required_if:use_custom_image,on',
|
'custom_image_name' => 'required_if:use_custom_image,on',
|
||||||
'auto_deploy' => 'sometimes|boolean',
|
'auto_deploy' => 'sometimes|boolean',
|
||||||
'custom_id' => 'sometimes|required|numeric|unique:servers,id',
|
'custom_id' => 'sometimes|required|numeric|unique:servers,id',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$validator->sometimes('node', 'bail|required|numeric|min:1|exists:nodes,id', function ($input) {
|
$validator->sometimes('node_id', 'bail|required|numeric|min:1|exists:nodes,id', function ($input) {
|
||||||
return ! ($input->auto_deploy);
|
return ! ($input->auto_deploy);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -111,7 +112,7 @@ class ServerRepository
|
||||||
return ! $input->auto_deploy && ! $input->allocation;
|
return ! $input->auto_deploy && ! $input->allocation;
|
||||||
});
|
});
|
||||||
|
|
||||||
$validator->sometimes('allocation', 'numeric|exists:allocations,id', function ($input) {
|
$validator->sometimes('allocation_id', 'numeric|exists:allocations,id', function ($input) {
|
||||||
return ! ($input->auto_deploy || ($input->port && $input->ip));
|
return ! ($input->auto_deploy || ($input->port && $input->ip));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -121,12 +122,7 @@ class ServerRepository
|
||||||
throw new DisplayValidationException($validator->errors());
|
throw new DisplayValidationException($validator->errors());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_int($data['owner'])) {
|
$user = Models\User::select('id', 'email')->where((is_int($data['owner'])) ? 'id' : 'email', $data['owner'])->first();
|
||||||
$user = Models\User::select('id', 'email')->where('id', $data['owner'])->first();
|
|
||||||
} else {
|
|
||||||
$user = Models\User::select('id', 'email')->where('email', $data['owner'])->first();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! $user) {
|
if (! $user) {
|
||||||
throw new DisplayException('The user id or email passed to the function was not found on the system.');
|
throw new DisplayException('The user id or email passed to the function was not found on the system.');
|
||||||
}
|
}
|
||||||
|
@ -135,19 +131,19 @@ class ServerRepository
|
||||||
if (isset($data['auto_deploy']) && in_array($data['auto_deploy'], [true, 1, '1'])) {
|
if (isset($data['auto_deploy']) && in_array($data['auto_deploy'], [true, 1, '1'])) {
|
||||||
// This is an auto-deployment situation
|
// This is an auto-deployment situation
|
||||||
// Ignore any other passed node data
|
// Ignore any other passed node data
|
||||||
unset($data['node'], $data['ip'], $data['port'], $data['allocation']);
|
unset($data['node_id'], $data['ip'], $data['port'], $data['allocation_id']);
|
||||||
|
|
||||||
$autoDeployed = true;
|
$autoDeployed = true;
|
||||||
$node = DeploymentService::smartRandomNode($data['memory'], $data['disk'], $data['location']);
|
$node = DeploymentService::smartRandomNode($data['memory'], $data['disk'], $data['location_id']);
|
||||||
$allocation = DeploymentService::randomAllocation($node->id);
|
$allocation = DeploymentService::randomAllocation($node->id);
|
||||||
} else {
|
} else {
|
||||||
$node = Models\Node::getByID($data['node']);
|
$node = Models\Node::findOrFail($data['node_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify IP & Port are a.) free and b.) assigned to the node.
|
// Verify IP & Port are a.) free and b.) assigned to the node.
|
||||||
// We know the node exists because of 'exists:nodes,id' in the validation
|
// We know the node exists because of 'exists:nodes,id' in the validation
|
||||||
if (! $autoDeployed) {
|
if (! $autoDeployed) {
|
||||||
if (! isset($data['allocation'])) {
|
if (! isset($data['allocation_id'])) {
|
||||||
$allocation = Models\Allocation::where('ip', $data['ip'])->where('port', $data['port'])->where('node', $data['node'])->whereNull('assigned_to')->first();
|
$allocation = Models\Allocation::where('ip', $data['ip'])->where('port', $data['port'])->where('node', $data['node'])->whereNull('assigned_to')->first();
|
||||||
} else {
|
} else {
|
||||||
$allocation = Models\Allocation::where('id', $data['allocation'])->where('node', $data['node'])->whereNull('assigned_to')->first();
|
$allocation = Models\Allocation::where('id', $data['allocation'])->where('node', $data['node'])->whereNull('assigned_to')->first();
|
||||||
|
@ -163,28 +159,28 @@ class ServerRepository
|
||||||
// We know the service and option exists because of the validation.
|
// We know the service and option exists because of the validation.
|
||||||
// We need to verify that the option exists for the service, and then check for
|
// We need to verify that the option exists for the service, and then check for
|
||||||
// any required variable fields. (fields are labeled env_<env_variable>)
|
// any required variable fields. (fields are labeled env_<env_variable>)
|
||||||
$option = Models\ServiceOptions::where('id', $data['option'])->where('parent_service', $data['service'])->first();
|
$option = Models\ServiceOption::where('id', $data['option'])->where('service_id', $data['service'])->first();
|
||||||
if (! $option) {
|
if (! $option) {
|
||||||
throw new DisplayException('The requested service option does not exist for the specified service.');
|
throw new DisplayException('The requested service option does not exist for the specified service.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the Pack
|
// Validate the Pack
|
||||||
if ($data['pack'] == 0) {
|
if ($data['pack_id'] == 0) {
|
||||||
$data['pack'] = null;
|
$data['pack_id'] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! is_null($data['pack'])) {
|
if (! is_null($data['pack_id'])) {
|
||||||
$pack = Models\ServicePack::where('id', $data['pack'])->where('option', $data['option'])->first();
|
$pack = Models\ServicePack::where('id', $data['pack_id'])->where('option', $data['option_id'])->first();
|
||||||
if (! $pack) {
|
if (! $pack) {
|
||||||
throw new DisplayException('The requested service pack does not seem to exist for this combination.');
|
throw new DisplayException('The requested service pack does not seem to exist for this combination.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load up the Service Information
|
// Load up the Service Information
|
||||||
$service = Models\Service::find($option->parent_service);
|
$service = Models\Service::find($option->service_id);
|
||||||
|
|
||||||
// Check those Variables
|
// Check those Variables
|
||||||
$variables = Models\ServiceVariables::where('option_id', $data['option'])->get();
|
$variables = Models\ServiceVariable::where('option_id', $data['option_id'])->get();
|
||||||
$variableList = [];
|
$variableList = [];
|
||||||
if ($variables) {
|
if ($variables) {
|
||||||
foreach ($variables as $variable) {
|
foreach ($variables as $variable) {
|
||||||
|
@ -258,10 +254,10 @@ class ServerRepository
|
||||||
$server->fill([
|
$server->fill([
|
||||||
'uuid' => $genUuid,
|
'uuid' => $genUuid,
|
||||||
'uuidShort' => $genShortUuid,
|
'uuidShort' => $genShortUuid,
|
||||||
'node' => $node->id,
|
'node_id' => $node->id,
|
||||||
'name' => $data['name'],
|
'name' => $data['name'],
|
||||||
'suspended' => 0,
|
'suspended' => 0,
|
||||||
'owner' => $user->id,
|
'owner_id' => $user->id,
|
||||||
'memory' => $data['memory'],
|
'memory' => $data['memory'],
|
||||||
'swap' => $data['swap'],
|
'swap' => $data['swap'],
|
||||||
'disk' => $data['disk'],
|
'disk' => $data['disk'],
|
||||||
|
@ -269,9 +265,9 @@ class ServerRepository
|
||||||
'cpu' => $data['cpu'],
|
'cpu' => $data['cpu'],
|
||||||
'oom_disabled' => (isset($data['oom_disabled'])) ? true : false,
|
'oom_disabled' => (isset($data['oom_disabled'])) ? true : false,
|
||||||
'allocation' => $allocation->id,
|
'allocation' => $allocation->id,
|
||||||
'service' => $data['service'],
|
'service_id' => $data['service_id'],
|
||||||
'option' => $data['option'],
|
'option_id' => $data['option_id'],
|
||||||
'pack' => $data['pack'],
|
'pack_id' => $data['pack_id'],
|
||||||
'startup' => $data['startup'],
|
'startup' => $data['startup'],
|
||||||
'daemonSecret' => $uuid->generate('servers', 'daemonSecret'),
|
'daemonSecret' => $uuid->generate('servers', 'daemonSecret'),
|
||||||
'image' => (isset($data['custom_image_name'])) ? $data['custom_image_name'] : $option->docker_image,
|
'image' => (isset($data['custom_image_name'])) ? $data['custom_image_name'] : $option->docker_image,
|
||||||
|
@ -281,7 +277,7 @@ class ServerRepository
|
||||||
$server->save();
|
$server->save();
|
||||||
|
|
||||||
// Mark Allocation in Use
|
// Mark Allocation in Use
|
||||||
$allocation->assigned_to = $server->id;
|
$allocation->server_id = $server->id;
|
||||||
$allocation->save();
|
$allocation->save();
|
||||||
|
|
||||||
// Add Variables
|
// Add Variables
|
||||||
|
@ -292,18 +288,14 @@ class ServerRepository
|
||||||
foreach ($variableList as $item) {
|
foreach ($variableList as $item) {
|
||||||
$environmentVariables[$item['env']] = $item['val'];
|
$environmentVariables[$item['env']] = $item['val'];
|
||||||
|
|
||||||
Models\ServerVariables::create([
|
Models\ServerVariable::create([
|
||||||
'server_id' => $server->id,
|
'server_id' => $server->id,
|
||||||
'variable_id' => $item['id'],
|
'variable_id' => $item['id'],
|
||||||
'variable_value' => $item['val'],
|
'variable_value' => $item['val'],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$client = Models\Node::guzzleRequest($node->id);
|
$node->guzzleClient(['X-Access-Token' => $node->daemonSecret])->request('POST', '/servers', [
|
||||||
$client->request('POST', '/servers', [
|
|
||||||
'headers' => [
|
|
||||||
'X-Access-Token' => $node->daemonSecret,
|
|
||||||
],
|
|
||||||
'json' => [
|
'json' => [
|
||||||
'uuid' => (string) $server->uuid,
|
'uuid' => (string) $server->uuid,
|
||||||
'user' => $server->username,
|
'user' => $server->username,
|
||||||
|
@ -337,8 +329,8 @@ class ServerRepository
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
return $server->id;
|
return $server;
|
||||||
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
} catch (TransferException $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw new DisplayException('There was an error while attempting to connect to the daemon to add this server.', $ex);
|
throw new DisplayException('There was an error while attempting to connect to the daemon to add this server.', $ex);
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
|
@ -373,11 +365,10 @@ class ServerRepository
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$server = Models\Server::findOrFail($id);
|
$server = Models\Server::with('user')->findOrFail($id);
|
||||||
$owner = Models\User::findOrFail($server->owner);
|
|
||||||
|
|
||||||
// Update daemon secret if it was passed.
|
// Update daemon secret if it was passed.
|
||||||
if ((isset($data['reset_token']) && $data['reset_token'] === true) || (isset($data['owner']) && $data['owner'] !== $owner->email)) {
|
if ((isset($data['reset_token']) && $data['reset_token'] === true) || (isset($data['owner']) && $data['owner'] !== $server->user->email)) {
|
||||||
$oldDaemonKey = $server->daemonSecret;
|
$oldDaemonKey = $server->daemonSecret;
|
||||||
$server->daemonSecret = $uuid->generate('servers', 'daemonSecret');
|
$server->daemonSecret = $uuid->generate('servers', 'daemonSecret');
|
||||||
$resetDaemonKey = true;
|
$resetDaemonKey = true;
|
||||||
|
@ -386,7 +377,7 @@ class ServerRepository
|
||||||
// Update Server Owner if it was passed.
|
// Update Server Owner if it was passed.
|
||||||
if (isset($data['owner']) && $data['owner'] !== $owner->email) {
|
if (isset($data['owner']) && $data['owner'] !== $owner->email) {
|
||||||
$newOwner = Models\User::select('id')->where('email', $data['owner'])->first();
|
$newOwner = Models\User::select('id')->where('email', $data['owner'])->first();
|
||||||
$server->owner = $newOwner->id;
|
$server->owner_id = $newOwner->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Server Name if it was passed.
|
// Update Server Name if it was passed.
|
||||||
|
@ -404,15 +395,10 @@ class ServerRepository
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we need to update do it here.
|
$res = $server->node->guzzleClient([
|
||||||
$node = Models\Node::getByID($server->node);
|
'X-Access-Server' => $server->uuid,
|
||||||
$client = Models\Node::guzzleRequest($server->node);
|
'X-Access-Token' => $server->node->daemonSecret,
|
||||||
|
])->request('PATCH', '/server', [
|
||||||
$res = $client->request('PATCH', '/server', [
|
|
||||||
'headers' => [
|
|
||||||
'X-Access-Server' => $server->uuid,
|
|
||||||
'X-Access-Token' => $node->daemonSecret,
|
|
||||||
],
|
|
||||||
'exceptions' => false,
|
'exceptions' => false,
|
||||||
'json' => [
|
'json' => [
|
||||||
'keys' => [
|
'keys' => [
|
||||||
|
@ -461,14 +447,10 @@ class ServerRepository
|
||||||
$server->image = $data['image'];
|
$server->image = $data['image'];
|
||||||
$server->save();
|
$server->save();
|
||||||
|
|
||||||
$node = Models\Node::getByID($server->node);
|
$server->node->guzzleClient([
|
||||||
$client = Models\Node::guzzleRequest($server->node);
|
'X-Access-Server' => $server->uuid,
|
||||||
|
'X-Access-Token' => $server->node->daemonSecret,
|
||||||
$client->request('PATCH', '/server', [
|
])->request('PATCH', '/server', [
|
||||||
'headers' => [
|
|
||||||
'X-Access-Server' => $server->uuid,
|
|
||||||
'X-Access-Token' => $node->daemonSecret,
|
|
||||||
],
|
|
||||||
'json' => [
|
'json' => [
|
||||||
'build' => [
|
'build' => [
|
||||||
'image' => $server->image,
|
'image' => $server->image,
|
||||||
|
@ -479,7 +461,7 @@ class ServerRepository
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
} catch (TransferException $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw new DisplayException('An error occured while attempting to update the container image.', $ex);
|
throw new DisplayException('An error occured while attempting to update the container image.', $ex);
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
|
@ -519,27 +501,25 @@ class ServerRepository
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$server = Models\Server::findOrFail($id);
|
$server = Models\Server::with('allocation', 'allocations')->findOrFail($id);
|
||||||
$allocation = Models\Allocation::findOrFail($server->allocation);
|
|
||||||
|
|
||||||
$newBuild = [];
|
$newBuild = [];
|
||||||
|
|
||||||
if (isset($data['default'])) {
|
if (isset($data['default'])) {
|
||||||
list($ip, $port) = explode(':', $data['default']);
|
list($ip, $port) = explode(':', $data['default']);
|
||||||
if ($ip !== $allocation->ip || (int) $port !== $allocation->port) {
|
if ($ip !== $server->allocation->ip || (int) $port !== $server->allocation->port) {
|
||||||
$selection = Models\Allocation::where('ip', $ip)->where('port', $port)->where('assigned_to', $server->id)->first();
|
$selection = $server->allocations->where('ip', $ip)->where('port', $port)->first();
|
||||||
if (! $selection) {
|
if (! $selection) {
|
||||||
throw new DisplayException('The requested default connection (' . $ip . ':' . $port . ') is not allocated to this server.');
|
throw new DisplayException('The requested default connection (' . $ip . ':' . $port . ') is not allocated to this server.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$server->allocation = $selection->id;
|
$server->allocation_id = $selection->id;
|
||||||
$newBuild['default'] = [
|
$newBuild['default'] = [
|
||||||
'ip' => $ip,
|
'ip' => $ip,
|
||||||
'port' => (int) $port,
|
'port' => (int) $port,
|
||||||
];
|
];
|
||||||
|
|
||||||
// Re-Run to keep updated for rest of function
|
// Re-Run to keep updated for rest of function
|
||||||
$allocation = Models\Allocation::findOrFail($server->allocation);
|
$server->load('allocation');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,15 +534,17 @@ class ServerRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't remove the assigned IP/Port combo
|
// Can't remove the assigned IP/Port combo
|
||||||
if ($ip === $allocation->ip && (int) $port === (int) $allocation->port) {
|
if ($ip === $server->allocation->ip && (int) $port === (int) $server->allocation->port) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$newPorts = true;
|
$newPorts = true;
|
||||||
Models\Allocation::where('ip', $ip)->where('port', $port)->where('assigned_to', $server->id)->update([
|
$server->allocations->where('ip', $ip)->where('port', $port)->update([
|
||||||
'assigned_to' => null,
|
'assigned_to' => null,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$server->load('allocations');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Assignments
|
// Add Assignments
|
||||||
|
@ -575,7 +557,7 @@ class ServerRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't allow double port assignments
|
// Don't allow double port assignments
|
||||||
if (Models\Allocation::where('port', $port)->where('assigned_to', $server->id)->count() !== 0) {
|
if ($server->allocations->where('port', $port)->count() !== 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,12 +566,13 @@ class ServerRepository
|
||||||
'assigned_to' => $server->id,
|
'assigned_to' => $server->id,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$server->load('allocations');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop All Assignments
|
// Loop All Assignments
|
||||||
$additionalAssignments = [];
|
$additionalAssignments = [];
|
||||||
$assignments = Models\Allocation::where('assigned_to', $server->id)->get();
|
foreach ($server->allocations as &$assignment) {
|
||||||
foreach ($assignments as &$assignment) {
|
|
||||||
if (array_key_exists((string) $assignment->ip, $additionalAssignments)) {
|
if (array_key_exists((string) $assignment->ip, $additionalAssignments)) {
|
||||||
array_push($additionalAssignments[(string) $assignment->ip], (int) $assignment->port);
|
array_push($additionalAssignments[(string) $assignment->ip], (int) $assignment->port);
|
||||||
} else {
|
} else {
|
||||||
|
@ -635,14 +618,10 @@ class ServerRepository
|
||||||
$server->save();
|
$server->save();
|
||||||
|
|
||||||
if (! empty($newBuild)) {
|
if (! empty($newBuild)) {
|
||||||
$node = Models\Node::getByID($server->node);
|
$server->node->guzzleClient([
|
||||||
$client = Models\Node::guzzleRequest($server->node);
|
'X-Access-Server' => $server->uuid,
|
||||||
|
'X-Access-Token' => $server->node->daemonSecret,
|
||||||
$client->request('PATCH', '/server', [
|
])->request('PATCH', '/server', [
|
||||||
'headers' => [
|
|
||||||
'X-Access-Server' => $server->uuid,
|
|
||||||
'X-Access-Token' => $node->daemonSecret,
|
|
||||||
],
|
|
||||||
'json' => [
|
'json' => [
|
||||||
'build' => $newBuild,
|
'build' => $newBuild,
|
||||||
],
|
],
|
||||||
|
@ -652,7 +631,7 @@ class ServerRepository
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
} catch (TransferException $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw new DisplayException('An error occured while attempting to update the configuration.', $ex);
|
throw new DisplayException('An error occured while attempting to update the configuration.', $ex);
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
|
@ -663,7 +642,7 @@ class ServerRepository
|
||||||
|
|
||||||
public function updateStartup($id, array $data, $admin = false)
|
public function updateStartup($id, array $data, $admin = false)
|
||||||
{
|
{
|
||||||
$server = Models\Server::findOrFail($id);
|
$server = Models\Server::with('variables', 'option.variables')->findOrFail($id);
|
||||||
|
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
@ -675,22 +654,22 @@ class ServerRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check those Variables
|
// Check those Variables
|
||||||
$variables = Models\ServiceVariables::select(
|
$server->option->variables->transform(function ($item, $key) use ($server) {
|
||||||
'service_variables.*',
|
$displayValue = $server->variables->where('variable_id', $item->id)->pluck('variable_value')->first();
|
||||||
DB::raw('COALESCE(server_variables.variable_value, service_variables.default_value) as a_currentValue')
|
$item->server_value = (! is_null($displayValue)) ? $displayValue : $item->default_value;
|
||||||
)->leftJoin('server_variables', 'server_variables.variable_id', '=', 'service_variables.id')
|
|
||||||
->where('option_id', $server->option)
|
return $item;
|
||||||
->get();
|
});
|
||||||
|
|
||||||
$variableList = [];
|
$variableList = [];
|
||||||
if ($variables) {
|
if ($server->option->variables) {
|
||||||
foreach ($variables as &$variable) {
|
foreach ($server->option->variables as &$variable) {
|
||||||
// Move on if the new data wasn't even sent
|
// Move on if the new data wasn't even sent
|
||||||
if (! isset($data[$variable->env_variable])) {
|
if (! isset($data[$variable->env_variable])) {
|
||||||
$variableList[] = [
|
$variableList[] = [
|
||||||
'id' => $variable->id,
|
'id' => $variable->id,
|
||||||
'env' => $variable->env_variable,
|
'env' => $variable->env_variable,
|
||||||
'val' => $variable->a_currentValue,
|
'val' => $variable->server_value,
|
||||||
];
|
];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -708,13 +687,13 @@ class ServerRepository
|
||||||
// Is the variable required?
|
// Is the variable required?
|
||||||
// @TODO: is this even logical to perform this check?
|
// @TODO: is this even logical to perform this check?
|
||||||
if (isset($data[$variable->env_variable]) && empty($data[$variable->env_variable])) {
|
if (isset($data[$variable->env_variable]) && empty($data[$variable->env_variable])) {
|
||||||
if ($variable->required === 1) {
|
if ($variable->required) {
|
||||||
throw new DisplayException('A required service option variable field (' . $variable->env_variable . ') was included in this request but was left blank.');
|
throw new DisplayException('A required service option variable field (' . $variable->env_variable . ') was included in this request but was left blank.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Variable hidden and/or not user editable
|
// Variable hidden and/or not user editable
|
||||||
if (($variable->user_viewable === 0 || $variable->user_editable === 0) && ! $admin) {
|
if ((! $variable->user_viewable || ! $variable->user_editable) && ! $admin) {
|
||||||
throw new DisplayException('A service option variable field (' . $variable->env_variable . ') does not exist or you do not have permission to edit it.');
|
throw new DisplayException('A service option variable field (' . $variable->env_variable . ') does not exist or you do not have permission to edit it.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -739,7 +718,7 @@ class ServerRepository
|
||||||
$environmentVariables[$item['env']] = $item['val'];
|
$environmentVariables[$item['env']] = $item['val'];
|
||||||
|
|
||||||
// Update model or make a new record if it doesn't exist.
|
// Update model or make a new record if it doesn't exist.
|
||||||
$model = Models\ServerVariables::firstOrNew([
|
$model = Models\ServerVariable::firstOrNew([
|
||||||
'variable_id' => $item['id'],
|
'variable_id' => $item['id'],
|
||||||
'server_id' => $server->id,
|
'server_id' => $server->id,
|
||||||
]);
|
]);
|
||||||
|
@ -747,14 +726,10 @@ class ServerRepository
|
||||||
$model->save();
|
$model->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
$node = Models\Node::getByID($server->node);
|
$server->node->guzzleClient([
|
||||||
$client = Models\Node::guzzleRequest($server->node);
|
'X-Access-Server' => $server->uuid,
|
||||||
|
'X-Access-Token' => $server->node->daemonSecret,
|
||||||
$client->request('PATCH', '/server', [
|
])->request('PATCH', '/server', [
|
||||||
'headers' => [
|
|
||||||
'X-Access-Server' => $server->uuid,
|
|
||||||
'X-Access-Token' => $node->daemonSecret,
|
|
||||||
],
|
|
||||||
'json' => [
|
'json' => [
|
||||||
'build' => [
|
'build' => [
|
||||||
'env|overwrite' => $environmentVariables,
|
'env|overwrite' => $environmentVariables,
|
||||||
|
@ -765,7 +740,7 @@ class ServerRepository
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
} catch (TransferException $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw new DisplayException('An error occured while attempting to update the server configuration.', $ex);
|
throw new DisplayException('An error occured while attempting to update the server configuration.', $ex);
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
|
@ -780,7 +755,7 @@ class ServerRepository
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ($force === 'force' || $force === true) {
|
if ($force === 'force' || $force) {
|
||||||
$server->installed = 3;
|
$server->installed = 3;
|
||||||
$server->save();
|
$server->save();
|
||||||
}
|
}
|
||||||
|
@ -796,8 +771,7 @@ class ServerRepository
|
||||||
|
|
||||||
public function deleteNow($id, $force = false)
|
public function deleteNow($id, $force = false)
|
||||||
{
|
{
|
||||||
$server = Models\Server::withTrashed()->findOrFail($id);
|
$server = Models\Server::withTrashed()->with('node')->findOrFail($id);
|
||||||
$node = Models\Node::findOrFail($server->node);
|
|
||||||
|
|
||||||
// Handle server being restored previously or
|
// Handle server being restored previously or
|
||||||
// an accidental queue.
|
// an accidental queue.
|
||||||
|
@ -808,12 +782,12 @@ class ServerRepository
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
try {
|
try {
|
||||||
// Unassign Allocations
|
// Unassign Allocations
|
||||||
Models\Allocation::where('assigned_to', $server->id)->update([
|
Models\Allocation::where('server_id', $server->id)->update([
|
||||||
'assigned_to' => null,
|
'server_id' => null,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Remove Variables
|
// Remove Variables
|
||||||
Models\ServerVariables::where('server_id', $server->id)->delete();
|
Models\ServerVariable::where('server_id', $server->id)->delete();
|
||||||
|
|
||||||
// Remove Permissions (Foreign Key requires before Subusers)
|
// Remove Permissions (Foreign Key requires before Subusers)
|
||||||
Models\Permission::where('server_id', $server->id)->delete();
|
Models\Permission::where('server_id', $server->id)->delete();
|
||||||
|
@ -835,17 +809,14 @@ class ServerRepository
|
||||||
$repository->drop($database->id);
|
$repository->drop($database->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
$client = Models\Node::guzzleRequest($server->node);
|
$server->node->guzzleRequest([
|
||||||
$client->request('DELETE', '/servers', [
|
'X-Access-Token' => $server->node->daemonSecret,
|
||||||
'headers' => [
|
'X-Access-Server' => $server->uuid,
|
||||||
'X-Access-Token' => $node->daemonSecret,
|
])->request('DELETE', '/servers');
|
||||||
'X-Access-Server' => $server->uuid,
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
$server->forceDelete();
|
$server->forceDelete();
|
||||||
DB::commit();
|
DB::commit();
|
||||||
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
} catch (TransferException $ex) {
|
||||||
// Set installed is set to 3 when force deleting.
|
// Set installed is set to 3 when force deleting.
|
||||||
if ($server->installed === 3 || $force) {
|
if ($server->installed === 3 || $force) {
|
||||||
$server->forceDelete();
|
$server->forceDelete();
|
||||||
|
@ -875,7 +846,7 @@ class ServerRepository
|
||||||
if ($server->installed === 2) {
|
if ($server->installed === 2) {
|
||||||
throw new DisplayException('This server was marked as having a failed install, you cannot override this.');
|
throw new DisplayException('This server was marked as having a failed install, you cannot override this.');
|
||||||
}
|
}
|
||||||
$server->installed = ($server->installed === 1) ? 0 : 1;
|
$server->installed = ! $server->installed;
|
||||||
|
|
||||||
return $server->save();
|
return $server->save();
|
||||||
}
|
}
|
||||||
|
@ -887,31 +858,27 @@ class ServerRepository
|
||||||
*/
|
*/
|
||||||
public function suspend($id, $deleted = false)
|
public function suspend($id, $deleted = false)
|
||||||
{
|
{
|
||||||
$server = ($deleted) ? Models\Server::withTrashed()->findOrFail($id) : Models\Server::findOrFail($id);
|
$server = Models\Server::withTrashed()->with('node')->findOrFail($id);
|
||||||
$node = Models\Node::findOrFail($server->node);
|
|
||||||
|
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// Already suspended, no need to make more requests.
|
// Already suspended, no need to make more requests.
|
||||||
if ($server->suspended === 1) {
|
if ($server->suspended) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$server->suspended = 1;
|
$server->suspended = 1;
|
||||||
$server->save();
|
$server->save();
|
||||||
|
|
||||||
$client = Models\Node::guzzleRequest($server->node);
|
$server->node->guzzleClient([
|
||||||
$client->request('POST', '/server/suspend', [
|
'X-Access-Token' => $server->node->daemonSecret,
|
||||||
'headers' => [
|
'X-Access-Server' => $server->uuid,
|
||||||
'X-Access-Token' => $node->daemonSecret,
|
])->request('POST', '/server/suspend');
|
||||||
'X-Access-Server' => $server->uuid,
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
return DB::commit();
|
return DB::commit();
|
||||||
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
} catch (TransferException $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw new DisplayException('An error occured while attempting to contact the remote daemon to suspend this server.', $ex);
|
throw new DisplayException('An error occured while attempting to contact the remote daemon to suspend this server.', $ex);
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
|
@ -927,8 +894,7 @@ class ServerRepository
|
||||||
*/
|
*/
|
||||||
public function unsuspend($id)
|
public function unsuspend($id)
|
||||||
{
|
{
|
||||||
$server = Models\Server::findOrFail($id);
|
$server = Models\Server::with('node')->findOrFail($id);
|
||||||
$node = Models\Node::findOrFail($server->node);
|
|
||||||
|
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
@ -942,16 +908,13 @@ class ServerRepository
|
||||||
$server->suspended = 0;
|
$server->suspended = 0;
|
||||||
$server->save();
|
$server->save();
|
||||||
|
|
||||||
$client = Models\Node::guzzleRequest($server->node);
|
$server->node->guzzleClient([
|
||||||
$client->request('POST', '/server/unsuspend', [
|
'X-Access-Token' => $server->node->daemonSecret,
|
||||||
'headers' => [
|
'X-Access-Server' => $server->uuid,
|
||||||
'X-Access-Token' => $node->daemonSecret,
|
])->request('POST', '/server/unsuspend');
|
||||||
'X-Access-Server' => $server->uuid,
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
return DB::commit();
|
return DB::commit();
|
||||||
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
} catch (TransferException $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw new DisplayException('An error occured while attempting to contact the remote daemon to un-suspend this server.', $ex);
|
throw new DisplayException('An error occured while attempting to contact the remote daemon to un-suspend this server.', $ex);
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
|
@ -962,12 +925,9 @@ class ServerRepository
|
||||||
|
|
||||||
public function updateSFTPPassword($id, $password)
|
public function updateSFTPPassword($id, $password)
|
||||||
{
|
{
|
||||||
$server = Models\Server::findOrFail($id);
|
$server = Models\Server::with('node')->findOrFail($id);
|
||||||
$node = Models\Node::findOrFail($server->node);
|
|
||||||
|
|
||||||
$validator = Validator::make([
|
$validator = Validator::make(['password' => $password], [
|
||||||
'password' => $password,
|
|
||||||
], [
|
|
||||||
'password' => 'required|regex:/^((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,})$/',
|
'password' => 'required|regex:/^((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,})$/',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -981,21 +941,17 @@ class ServerRepository
|
||||||
try {
|
try {
|
||||||
$server->save();
|
$server->save();
|
||||||
|
|
||||||
$client = Models\Node::guzzleRequest($server->node);
|
$server->node->guzzleClient([
|
||||||
$client->request('POST', '/server/password', [
|
'X-Access-Token' => $server->node->daemonSecret,
|
||||||
'headers' => [
|
'X-Access-Server' => $server->uuid,
|
||||||
'X-Access-Token' => $node->daemonSecret,
|
])->request('POST', '/server/password', [
|
||||||
'X-Access-Server' => $server->uuid,
|
'json' => ['password' => $password],
|
||||||
],
|
|
||||||
'json' => [
|
|
||||||
'password' => $password,
|
|
||||||
],
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
} catch (TransferException $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw new DisplayException('There was an error while attmping to contact the remote service to change the password.', $ex);
|
throw new DisplayException('There was an error while attmping to contact the remote service to change the password.', $ex);
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
|
|
|
@ -62,8 +62,8 @@ class Option
|
||||||
$data['startup'] = null;
|
$data['startup'] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$option = new Models\ServiceOptions;
|
$option = new Models\ServiceOption;
|
||||||
$option->parent_service = $service->id;
|
$option->service_id = $service->id;
|
||||||
$option->fill($data);
|
$option->fill($data);
|
||||||
$option->save();
|
$option->save();
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ class Option
|
||||||
|
|
||||||
public function delete($id)
|
public function delete($id)
|
||||||
{
|
{
|
||||||
$option = Models\ServiceOptions::findOrFail($id);
|
$option = Models\ServiceOption::findOrFail($id);
|
||||||
$servers = Models\Server::where('option', $option->id)->get();
|
$servers = Models\Server::where('option', $option->id)->get();
|
||||||
|
|
||||||
if (count($servers) !== 0) {
|
if (count($servers) !== 0) {
|
||||||
|
@ -82,7 +82,7 @@ class Option
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Models\ServiceVariables::where('option_id', $option->id)->delete();
|
Models\ServiceVariable::where('option_id', $option->id)->delete();
|
||||||
$option->delete();
|
$option->delete();
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
@ -94,7 +94,7 @@ class Option
|
||||||
|
|
||||||
public function update($id, array $data)
|
public function update($id, array $data)
|
||||||
{
|
{
|
||||||
$option = Models\ServiceOptions::findOrFail($id);
|
$option = Models\ServiceOption::findOrFail($id);
|
||||||
|
|
||||||
$validator = Validator::make($data, [
|
$validator = Validator::make($data, [
|
||||||
'name' => 'sometimes|required|string|max:255',
|
'name' => 'sometimes|required|string|max:255',
|
||||||
|
|
|
@ -69,8 +69,8 @@ class Pack
|
||||||
try {
|
try {
|
||||||
$uuid = new UuidService;
|
$uuid = new UuidService;
|
||||||
$pack = Models\ServicePack::create([
|
$pack = Models\ServicePack::create([
|
||||||
'option' => $data['option'],
|
'option_id' => $data['option'],
|
||||||
'uuid' => $uuid->generate('servers', 'uuid'),
|
'uuid' => $uuid->generate('service_packs', 'uuid'),
|
||||||
'name' => $data['name'],
|
'name' => $data['name'],
|
||||||
'version' => $data['version'],
|
'version' => $data['version'],
|
||||||
'description' => (empty($data['description'])) ? null : $data['description'],
|
'description' => (empty($data['description'])) ? null : $data['description'],
|
||||||
|
@ -89,7 +89,7 @@ class Pack
|
||||||
throw $ex;
|
throw $ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $pack->id;
|
return $pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createWithTemplate(array $data)
|
public function createWithTemplate(array $data)
|
||||||
|
@ -123,7 +123,7 @@ class Pack
|
||||||
}
|
}
|
||||||
|
|
||||||
$json = json_decode($zip->getFromName('import.json'));
|
$json = json_decode($zip->getFromName('import.json'));
|
||||||
$id = $this->create([
|
$pack = $this->create([
|
||||||
'name' => $json->name,
|
'name' => $json->name,
|
||||||
'version' => $json->version,
|
'version' => $json->version,
|
||||||
'description' => $json->description,
|
'description' => $json->description,
|
||||||
|
@ -132,7 +132,6 @@ class Pack
|
||||||
'visible' => $json->visible,
|
'visible' => $json->visible,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$pack = Models\ServicePack::findOrFail($id);
|
|
||||||
if (! $zip->extractTo(storage_path('app/packs/' . $pack->uuid), 'archive.tar.gz')) {
|
if (! $zip->extractTo(storage_path('app/packs/' . $pack->uuid), 'archive.tar.gz')) {
|
||||||
$pack->delete();
|
$pack->delete();
|
||||||
throw new DisplayException('Unable to extract the archive file to the correct location.');
|
throw new DisplayException('Unable to extract the archive file to the correct location.');
|
||||||
|
@ -140,7 +139,7 @@ class Pack
|
||||||
|
|
||||||
$zip->close();
|
$zip->close();
|
||||||
|
|
||||||
return $pack->id;
|
return $pack;
|
||||||
} else {
|
} else {
|
||||||
$json = json_decode(file_get_contents($data['file_upload']->path()));
|
$json = json_decode(file_get_contents($data['file_upload']->path()));
|
||||||
|
|
||||||
|
@ -170,18 +169,14 @@ class Pack
|
||||||
throw new DisplayValidationException($validator->errors());
|
throw new DisplayValidationException($validator->errors());
|
||||||
}
|
}
|
||||||
|
|
||||||
DB::transaction(function () use ($id, $data) {
|
Models\ServicePack::findOrFail($id)->update([
|
||||||
Models\ServicePack::findOrFail($id)->update([
|
'option_id' => $data['option'],
|
||||||
'option' => $data['option'],
|
'name' => $data['name'],
|
||||||
'name' => $data['name'],
|
'version' => $data['version'],
|
||||||
'version' => $data['version'],
|
'description' => (empty($data['description'])) ? null : $data['description'],
|
||||||
'description' => (empty($data['description'])) ? null : $data['description'],
|
'selectable' => isset($data['selectable']),
|
||||||
'selectable' => isset($data['selectable']),
|
'visible' => isset($data['visible']),
|
||||||
'visible' => isset($data['visible']),
|
]);
|
||||||
]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete($id)
|
public function delete($id)
|
||||||
|
|
|
@ -55,23 +55,18 @@ class Service
|
||||||
|
|
||||||
$data['author'] = env('SERVICE_AUTHOR', (string) Uuid::generate(4));
|
$data['author'] = env('SERVICE_AUTHOR', (string) Uuid::generate(4));
|
||||||
|
|
||||||
$service = new Models\Service;
|
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$service->fill($data);
|
$service = Models\Service::create($data);
|
||||||
$service->save();
|
Storage::put('services/' . $service->file . '/main.json', '{}');
|
||||||
|
Storage::copy('services/.templates/index.js', 'services/' . $service->file . '/index.js');
|
||||||
Storage::put('services/' . $data['file'] . '/main.json', '{}');
|
|
||||||
Storage::copy('services/.templates/index.js', 'services/' . $data['file'] . '/index.js');
|
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw $ex;
|
throw $ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $service->id;
|
return $service;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update($id, array $data)
|
public function update($id, array $data)
|
||||||
|
@ -99,7 +94,7 @@ class Service
|
||||||
{
|
{
|
||||||
$service = Models\Service::findOrFail($id);
|
$service = Models\Service::findOrFail($id);
|
||||||
$servers = Models\Server::where('service', $service->id)->get();
|
$servers = Models\Server::where('service', $service->id)->get();
|
||||||
$options = Models\ServiceOptions::select('id')->where('parent_service', $service->id);
|
$options = Models\ServiceOption::select('id')->where('service_id', $service->id);
|
||||||
|
|
||||||
if (count($servers) !== 0) {
|
if (count($servers) !== 0) {
|
||||||
throw new DisplayException('You cannot delete a service that has servers associated with it.');
|
throw new DisplayException('You cannot delete a service that has servers associated with it.');
|
||||||
|
@ -107,7 +102,7 @@ class Service
|
||||||
|
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
try {
|
try {
|
||||||
Models\ServiceVariables::whereIn('option_id', $options->get()->toArray())->delete();
|
Models\ServiceVariable::whereIn('option_id', $options->get()->toArray())->delete();
|
||||||
$options->delete();
|
$options->delete();
|
||||||
$service->delete();
|
$service->delete();
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ class Variable
|
||||||
|
|
||||||
public function create($id, array $data)
|
public function create($id, array $data)
|
||||||
{
|
{
|
||||||
$option = Models\ServiceOptions::findOrFail($id);
|
$option = Models\ServiceOption::select('id')->findOrFail($id);
|
||||||
|
|
||||||
$validator = Validator::make($data, [
|
$validator = Validator::make($data, [
|
||||||
'name' => 'required|string|min:1|max:255',
|
'name' => 'required|string|min:1|max:255',
|
||||||
|
@ -60,28 +60,29 @@ class Variable
|
||||||
throw new DisplayException('The default value you entered cannot violate the regex requirements.');
|
throw new DisplayException('The default value you entered cannot violate the regex requirements.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Models\ServiceVariables::where('env_variable', $data['env_variable'])->where('option_id', $option->id)->first()) {
|
if (Models\ServiceVariable::where('env_variable', $data['env_variable'])->where('option_id', $option->id)->first()) {
|
||||||
throw new DisplayException('An environment variable with that name already exists for this option.');
|
throw new DisplayException('An environment variable with that name already exists for this option.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$data['user_viewable'] = (isset($data['user_viewable']) && in_array((int) $data['user_viewable'], [0, 1])) ? $data['user_viewable'] : 0;
|
$data['user_viewable'] = (isset($data['user_viewable']) && in_array((int) $data['user_viewable'], [0, 1])) ? $data['user_viewable'] : 0;
|
||||||
$data['user_editable'] = (isset($data['user_editable']) && in_array((int) $data['user_editable'], [0, 1])) ? $data['user_editable'] : 0;
|
$data['user_editable'] = (isset($data['user_editable']) && in_array((int) $data['user_editable'], [0, 1])) ? $data['user_editable'] : 0;
|
||||||
$data['required'] = (isset($data['required']) && in_array((int) $data['required'], [0, 1])) ? $data['required'] : 0;
|
$data['required'] = (isset($data['required']) && in_array((int) $data['required'], [0, 1])) ? $data['required'] : 0;
|
||||||
|
$data['option_id'] = $option->id;
|
||||||
|
|
||||||
$variable = new Models\ServiceVariables;
|
$variable = Models\ServiceVariable::create($data);
|
||||||
$variable->option_id = $option->id;
|
|
||||||
$variable->fill($data);
|
|
||||||
|
|
||||||
return $variable->save();
|
return $variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete($id)
|
public function delete($id)
|
||||||
{
|
{
|
||||||
$variable = Models\ServiceVariables::findOrFail($id);
|
$variable = Models\ServiceVariable::with('serverVariable')->findOrFail($id);
|
||||||
|
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
try {
|
try {
|
||||||
Models\ServerVariables::where('variable_id', $variable->id)->delete();
|
foreach ($variable->serverVariable as $svar) {
|
||||||
|
$svar->delete();
|
||||||
|
}
|
||||||
$variable->delete();
|
$variable->delete();
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
@ -93,7 +94,7 @@ class Variable
|
||||||
|
|
||||||
public function update($id, array $data)
|
public function update($id, array $data)
|
||||||
{
|
{
|
||||||
$variable = Models\ServiceVariables::findOrFail($id);
|
$variable = Models\ServiceVariable::findOrFail($id);
|
||||||
|
|
||||||
$validator = Validator::make($data, [
|
$validator = Validator::make($data, [
|
||||||
'name' => 'sometimes|required|string|min:1|max:255',
|
'name' => 'sometimes|required|string|min:1|max:255',
|
||||||
|
@ -117,7 +118,7 @@ class Variable
|
||||||
throw new DisplayException('The default value you entered cannot violate the regex requirements.');
|
throw new DisplayException('The default value you entered cannot violate the regex requirements.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Models\ServiceVariables::where('id', '!=', $variable->id)->where('env_variable', $data['env_variable'])->where('option_id', $variable->option_id)->first()) {
|
if (Models\ServiceVariable::where('id', '!=', $variable->id)->where('env_variable', $data['env_variable'])->where('option_id', $variable->option_id)->first()) {
|
||||||
throw new DisplayException('An environment variable with that name already exists for this option.');
|
throw new DisplayException('An environment variable with that name already exists for this option.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +126,18 @@ class Variable
|
||||||
$data['user_editable'] = (isset($data['user_editable']) && in_array((int) $data['user_editable'], [0, 1])) ? $data['user_editable'] : $variable->user_editable;
|
$data['user_editable'] = (isset($data['user_editable']) && in_array((int) $data['user_editable'], [0, 1])) ? $data['user_editable'] : $variable->user_editable;
|
||||||
$data['required'] = (isset($data['required']) && in_array((int) $data['required'], [0, 1])) ? $data['required'] : $variable->required;
|
$data['required'] = (isset($data['required']) && in_array((int) $data['required'], [0, 1])) ? $data['required'] : $variable->required;
|
||||||
|
|
||||||
$variable->fill($data);
|
// Not using $data because the function that passes into this function
|
||||||
|
// can't do $requst->only() due to the page setup.
|
||||||
|
$variable->fill([
|
||||||
|
'name' => $data['name'],
|
||||||
|
'description' => $data['description'],
|
||||||
|
'env_variable' => $data['env_variable'],
|
||||||
|
'default_value' => $data['default_value'],
|
||||||
|
'user_viewable' => $data['user_viewable'],
|
||||||
|
'user_editable' => $data['user_editable'],
|
||||||
|
'required' => $data['required'],
|
||||||
|
'regex' => $data['regex'],
|
||||||
|
]);
|
||||||
|
|
||||||
return $variable->save();
|
return $variable->save();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
namespace Pterodactyl\Repositories;
|
namespace Pterodactyl\Repositories;
|
||||||
|
|
||||||
use DB;
|
use DB;
|
||||||
use Mail;
|
|
||||||
use Settings;
|
|
||||||
use Validator;
|
use Validator;
|
||||||
use Pterodactyl\Models;
|
use Pterodactyl\Models;
|
||||||
use Pterodactyl\Services\UuidService;
|
use Pterodactyl\Services\UuidService;
|
||||||
|
@ -112,11 +110,11 @@ class SubuserRepository
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @throws DisplayValidationException
|
* @throws DisplayValidationException
|
||||||
* @throws DisplayException
|
* @throws DisplayException
|
||||||
* @return int Returns the ID of the newly created subuser.
|
* @return \Pterodactyl\Models\Subuser
|
||||||
*/
|
*/
|
||||||
public function create($sid, array $data)
|
public function create($sid, array $data)
|
||||||
{
|
{
|
||||||
$server = Models\Server::findOrFail($sid);
|
$server = Models\Server::with('node')->findOrFail($sid);
|
||||||
|
|
||||||
$validator = Validator::make($data, [
|
$validator = Validator::make($data, [
|
||||||
'permissions' => 'required|array',
|
'permissions' => 'required|array',
|
||||||
|
@ -135,32 +133,28 @@ class SubuserRepository
|
||||||
if (! $user) {
|
if (! $user) {
|
||||||
try {
|
try {
|
||||||
$repo = new UserRepository;
|
$repo = new UserRepository;
|
||||||
$uid = $repo->create([
|
$user = $repo->create([
|
||||||
'email' => $data['email'],
|
'email' => $data['email'],
|
||||||
'username' => substr(str_replace('@', '', $data['email']), 0, 8),
|
'username' => str_random(8),
|
||||||
'name_first' => 'John',
|
'name_first' => 'Unassigned',
|
||||||
'name_last' => 'Doe',
|
'name_last' => 'Name',
|
||||||
'root_admin' => false,
|
'root_admin' => false,
|
||||||
]);
|
]);
|
||||||
$user = Models\User::findOrFail($uid);
|
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
throw $ex;
|
throw $ex;
|
||||||
}
|
}
|
||||||
} elseif ($server->owner === $user->id) {
|
} elseif ($server->owner_id === $user->id) {
|
||||||
throw new DisplayException('You cannot add the owner of a server as a subuser.');
|
throw new DisplayException('You cannot add the owner of a server as a subuser.');
|
||||||
} elseif (Models\Subuser::select('id')->where('user_id', $user->id)->where('server_id', $server->id)->first()) {
|
} elseif (Models\Subuser::select('id')->where('user_id', $user->id)->where('server_id', $server->id)->first()) {
|
||||||
throw new DisplayException('A subuser with that email already exists for this server.');
|
throw new DisplayException('A subuser with that email already exists for this server.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$uuid = new UuidService;
|
$uuid = new UuidService;
|
||||||
|
$subuser = Models\Subuser::create([
|
||||||
$subuser = new Models\Subuser;
|
|
||||||
$subuser->fill([
|
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
'server_id' => $server->id,
|
'server_id' => $server->id,
|
||||||
'daemonSecret' => (string) $uuid->generate('servers', 'uuid'),
|
'daemonSecret' => (string) $uuid->generate('servers', 'uuid'),
|
||||||
]);
|
]);
|
||||||
$subuser->save();
|
|
||||||
|
|
||||||
$daemonPermissions = $this->coreDaemonPermissions;
|
$daemonPermissions = $this->coreDaemonPermissions;
|
||||||
foreach ($data['permissions'] as $permission) {
|
foreach ($data['permissions'] as $permission) {
|
||||||
|
@ -170,13 +164,10 @@ class SubuserRepository
|
||||||
array_push($daemonPermissions, $this->permissions[$permission]);
|
array_push($daemonPermissions, $this->permissions[$permission]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$model = new Models\Permission;
|
Models\Permission::create([
|
||||||
$model->fill([
|
'subuser_id' => $subuser->id,
|
||||||
'user_id' => $user->id,
|
|
||||||
'server_id' => $server->id,
|
|
||||||
'permission' => $permission,
|
'permission' => $permission,
|
||||||
]);
|
]);
|
||||||
$model->save();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,14 +175,10 @@ class SubuserRepository
|
||||||
// We contact even if they don't have any daemon permissions to overwrite
|
// We contact even if they don't have any daemon permissions to overwrite
|
||||||
// if they did have them previously.
|
// if they did have them previously.
|
||||||
|
|
||||||
$node = Models\Node::getByID($server->node);
|
$server->node->guzzleClient([
|
||||||
$client = Models\Node::guzzleRequest($server->node);
|
'X-Access-Server' => $server->uuid,
|
||||||
|
'X-Access-Token' => $node->daemonSecret,
|
||||||
$res = $client->request('PATCH', '/server', [
|
])->request('PATCH', '/server', [
|
||||||
'headers' => [
|
|
||||||
'X-Access-Server' => $server->uuid,
|
|
||||||
'X-Access-Token' => $node->daemonSecret,
|
|
||||||
],
|
|
||||||
'json' => [
|
'json' => [
|
||||||
'keys' => [
|
'keys' => [
|
||||||
$subuser->daemonSecret => $daemonPermissions,
|
$subuser->daemonSecret => $daemonPermissions,
|
||||||
|
@ -199,18 +186,9 @@ class SubuserRepository
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$email = $data['email'];
|
|
||||||
Mail::queue('emails.added-subuser', [
|
|
||||||
'serverName' => $server->name,
|
|
||||||
'url' => route('server.index', $server->uuidShort),
|
|
||||||
], function ($message) use ($email) {
|
|
||||||
$message->to($email);
|
|
||||||
$message->from(Settings::get('email_from', env('MAIL_FROM')), Settings::get('email_sender_name', env('MAIL_FROM_NAME', 'Pterodactyl Panel')));
|
|
||||||
$message->subject(Settings::get('company') . ' - Added to Server');
|
|
||||||
});
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
return $subuser->id;
|
return $subuser;
|
||||||
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw new DisplayException('There was an error attempting to connect to the daemon to add this user.', $ex);
|
throw new DisplayException('There was an error attempting to connect to the daemon to add this user.', $ex);
|
||||||
|
@ -232,22 +210,16 @@ class SubuserRepository
|
||||||
*/
|
*/
|
||||||
public function delete($id)
|
public function delete($id)
|
||||||
{
|
{
|
||||||
$subuser = Models\Subuser::findOrFail($id);
|
$subuser = Models\Subuser::with('server.node')->findOrFail($id);
|
||||||
$server = Models\Server::findOrFail($subuser->server_id);
|
$server = $subuser->server;
|
||||||
|
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Models\Permission::where('user_id', $subuser->user_id)->where('server_id', $subuser->server_id)->delete();
|
$server->node->guzzleClient([
|
||||||
|
'X-Access-Server' => $server->uuid,
|
||||||
$node = Models\Node::getByID($server->node);
|
'X-Access-Token' => $server->node->daemonSecret,
|
||||||
$client = Models\Node::guzzleRequest($server->node);
|
])->request('PATCH', '/server', [
|
||||||
|
|
||||||
$res = $client->request('PATCH', '/server', [
|
|
||||||
'headers' => [
|
|
||||||
'X-Access-Server' => $server->uuid,
|
|
||||||
'X-Access-Token' => $node->daemonSecret,
|
|
||||||
],
|
|
||||||
'json' => [
|
'json' => [
|
||||||
'keys' => [
|
'keys' => [
|
||||||
$subuser->daemonSecret => [],
|
$subuser->daemonSecret => [],
|
||||||
|
@ -255,6 +227,9 @@ class SubuserRepository
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
foreach ($subuser->permissions as &$permission) {
|
||||||
|
$permission->delete();
|
||||||
|
}
|
||||||
$subuser->delete();
|
$subuser->delete();
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
|
@ -290,13 +265,15 @@ class SubuserRepository
|
||||||
throw new DisplayValidationException(json_encode($validator->all()));
|
throw new DisplayValidationException(json_encode($validator->all()));
|
||||||
}
|
}
|
||||||
|
|
||||||
$subuser = Models\Subuser::findOrFail($id);
|
$subuser = Models\Subuser::with('server.node')->findOrFail($id);
|
||||||
$server = Models\Server::findOrFail($data['server']);
|
$server = $subuser->server;
|
||||||
|
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Models\Permission::where('user_id', $subuser->user_id)->where('server_id', $subuser->server_id)->delete();
|
foreach ($subuser->permissions as &$permission) {
|
||||||
|
$permission->delete();
|
||||||
|
}
|
||||||
|
|
||||||
$daemonPermissions = $this->coreDaemonPermissions;
|
$daemonPermissions = $this->coreDaemonPermissions;
|
||||||
foreach ($data['permissions'] as $permission) {
|
foreach ($data['permissions'] as $permission) {
|
||||||
|
@ -305,27 +282,20 @@ class SubuserRepository
|
||||||
if (! is_null($this->permissions[$permission])) {
|
if (! is_null($this->permissions[$permission])) {
|
||||||
array_push($daemonPermissions, $this->permissions[$permission]);
|
array_push($daemonPermissions, $this->permissions[$permission]);
|
||||||
}
|
}
|
||||||
$model = new Models\Permission;
|
Models\Permission::create([
|
||||||
$model->fill([
|
'subuser_id' => $subuser->id,
|
||||||
'user_id' => $data['user'],
|
|
||||||
'server_id' => $data['server'],
|
|
||||||
'permission' => $permission,
|
'permission' => $permission,
|
||||||
]);
|
]);
|
||||||
$model->save();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contact Daemon
|
// Contact Daemon
|
||||||
// We contact even if they don't have any daemon permissions to overwrite
|
// We contact even if they don't have any daemon permissions to overwrite
|
||||||
// if they did have them previously.
|
// if they did have them previously.
|
||||||
$node = Models\Node::getByID($server->node);
|
$server->node->guzzleClient([
|
||||||
$client = Models\Node::guzzleRequest($server->node);
|
'X-Access-Server' => $server->uuid,
|
||||||
|
'X-Access-Token' => $server->node->daemonSecret,
|
||||||
$res = $client->request('PATCH', '/server', [
|
])->request('PATCH', '/server', [
|
||||||
'headers' => [
|
|
||||||
'X-Access-Server' => $server->uuid,
|
|
||||||
'X-Access-Token' => $node->daemonSecret,
|
|
||||||
],
|
|
||||||
'json' => [
|
'json' => [
|
||||||
'keys' => [
|
'keys' => [
|
||||||
$subuser->daemonSecret => $daemonPermissions,
|
$subuser->daemonSecret => $daemonPermissions,
|
||||||
|
|
|
@ -111,7 +111,7 @@ class UserRepository
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
|
|
||||||
return $user->id;
|
return $user;
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
throw $ex;
|
throw $ex;
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Services;
|
namespace Pterodactyl\Services;
|
||||||
|
|
||||||
use Pterodactyl\Models\User;
|
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Pterodactyl\Notifications\Daemon;
|
use Pterodactyl\Notifications\Daemon;
|
||||||
|
|
||||||
|
@ -48,7 +47,6 @@ class NotificationService
|
||||||
public function __construct(Server $server)
|
public function __construct(Server $server)
|
||||||
{
|
{
|
||||||
$this->server = $server;
|
$this->server = $server;
|
||||||
$this->user = User::findOrFail($server->owner);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function pass(array $notification)
|
public function pass(array $notification)
|
||||||
|
|
82
database/migrations/2017_02_02_175548_UpdateColumnNames.php
Normal file
82
database/migrations/2017_02_02_175548_UpdateColumnNames.php
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class UpdateColumnNames extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('servers', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('servers_node_foreign');
|
||||||
|
$table->dropForeign('servers_owner_foreign');
|
||||||
|
$table->dropForeign('servers_allocation_foreign');
|
||||||
|
$table->dropForeign('servers_service_foreign');
|
||||||
|
$table->dropForeign('servers_option_foreign');
|
||||||
|
$table->dropForeign('servers_pack_foreign');
|
||||||
|
|
||||||
|
$table->dropIndex('servers_node_foreign');
|
||||||
|
$table->dropIndex('servers_owner_foreign');
|
||||||
|
$table->dropIndex('servers_allocation_foreign');
|
||||||
|
$table->dropIndex('servers_service_foreign');
|
||||||
|
$table->dropIndex('servers_option_foreign');
|
||||||
|
$table->dropIndex('servers_pack_foreign');
|
||||||
|
|
||||||
|
$table->renameColumn('node', 'node_id');
|
||||||
|
$table->renameColumn('owner', 'owner_id');
|
||||||
|
$table->renameColumn('allocation', 'allocation_id');
|
||||||
|
$table->renameColumn('service', 'service_id');
|
||||||
|
$table->renameColumn('option', 'option_id');
|
||||||
|
$table->renameColumn('pack', 'pack_id');
|
||||||
|
|
||||||
|
$table->foreign('node_id')->references('id')->on('nodes');
|
||||||
|
$table->foreign('owner_id')->references('id')->on('users');
|
||||||
|
$table->foreign('allocation_id')->references('id')->on('allocations');
|
||||||
|
$table->foreign('service_id')->references('id')->on('services');
|
||||||
|
$table->foreign('option_id')->references('id')->on('service_options');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('servers', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('servers_node_id_foreign');
|
||||||
|
$table->dropForeign('servers_owner_id_foreign');
|
||||||
|
$table->dropForeign('servers_allocation_id_foreign');
|
||||||
|
$table->dropForeign('servers_service_id_foreign');
|
||||||
|
$table->dropForeign('servers_option_id_foreign');
|
||||||
|
$table->dropForeign('servers_pack_id_foreign');
|
||||||
|
|
||||||
|
$table->dropIndex('servers_node_id_foreign');
|
||||||
|
$table->dropIndex('servers_owner_id_foreign');
|
||||||
|
$table->dropIndex('servers_allocation_id_foreign');
|
||||||
|
$table->dropIndex('servers_service_id_foreign');
|
||||||
|
$table->dropIndex('servers_option_id_foreign');
|
||||||
|
$table->dropIndex('servers_pack_id_foreign');
|
||||||
|
|
||||||
|
$table->renameColumn('node_id', 'node');
|
||||||
|
$table->renameColumn('owner_id', 'owner');
|
||||||
|
$table->renameColumn('allocation_id', 'allocation');
|
||||||
|
$table->renameColumn('service_id', 'service');
|
||||||
|
$table->renameColumn('option_id', 'option');
|
||||||
|
$table->renameColumn('pack_id', 'pack');
|
||||||
|
|
||||||
|
$table->foreign('node')->references('id')->on('nodes');
|
||||||
|
$table->foreign('owner')->references('id')->on('users');
|
||||||
|
$table->foreign('allocation')->references('id')->on('allocations');
|
||||||
|
$table->foreign('service')->references('id')->on('services');
|
||||||
|
$table->foreign('option')->references('id')->on('service_options');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
40
database/migrations/2017_02_03_140948_UpdateNodesTable.php
Normal file
40
database/migrations/2017_02_03_140948_UpdateNodesTable.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class UpdateNodesTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('nodes', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('nodes_location_foreign');
|
||||||
|
$table->dropIndex('nodes_location_foreign');
|
||||||
|
|
||||||
|
$table->renameColumn('location', 'location_id');
|
||||||
|
$table->foreign('location_id')->references('id')->on('locations');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('nodes', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('nodes_location_id_foreign');
|
||||||
|
$table->dropIndex('nodes_location_id_foreign');
|
||||||
|
|
||||||
|
$table->renameColumn('location_id', 'location');
|
||||||
|
$table->foreign('location')->references('id')->on('locations');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
48
database/migrations/2017_02_03_155554_RenameColumns.php
Normal file
48
database/migrations/2017_02_03_155554_RenameColumns.php
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class RenameColumns extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('allocations', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('allocations_node_foreign');
|
||||||
|
$table->dropForeign('allocations_assigned_to_foreign');
|
||||||
|
$table->dropIndex('allocations_node_foreign');
|
||||||
|
$table->dropIndex('allocations_assigned_to_foreign');
|
||||||
|
|
||||||
|
$table->renameColumn('node', 'node_id');
|
||||||
|
$table->renameColumn('assigned_to', 'server_id');
|
||||||
|
$table->foreign('node_id')->references('id')->on('nodes');
|
||||||
|
$table->foreign('server_id')->references('id')->on('servers');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('allocations', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('allocations_node_id_foreign');
|
||||||
|
$table->dropForeign('allocations_server_id_foreign');
|
||||||
|
$table->dropIndex('allocations_node_id_foreign');
|
||||||
|
$table->dropIndex('allocations_server_id_foreign');
|
||||||
|
|
||||||
|
$table->renameColumn('node_id', 'node');
|
||||||
|
$table->renameColumn('server_id', 'assigned_to');
|
||||||
|
$table->foreign('node')->references('id')->on('nodes');
|
||||||
|
$table->foreign('assigned_to')->references('id')->on('servers');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
40
database/migrations/2017_02_05_164123_AdjustColumnNames.php
Normal file
40
database/migrations/2017_02_05_164123_AdjustColumnNames.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AdjustColumnNames extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('service_options', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('service_options_parent_service_foreign');
|
||||||
|
$table->dropIndex('service_options_parent_service_foreign');
|
||||||
|
|
||||||
|
$table->renameColumn('parent_service', 'service_id');
|
||||||
|
$table->foreign('service_id')->references('id')->on('services');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('service_options', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('service_options_service_id_foreign');
|
||||||
|
$table->dropIndex('service_options_service_id_foreign');
|
||||||
|
|
||||||
|
$table->renameColumn('service_id', 'parent_service');
|
||||||
|
$table->foreign('parent_service')->references('id')->on('services');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AdjustColumnNamesForServicePacks extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('service_packs', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('service_packs_option_foreign');
|
||||||
|
$table->dropIndex('service_packs_option_foreign');
|
||||||
|
|
||||||
|
$table->renameColumn('option', 'option_id');
|
||||||
|
$table->foreign('option_id')->references('id')->on('service_options');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('service_packs', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('service_packs_option_id_foreign');
|
||||||
|
$table->dropIndex('service_packs_option_id_foreign');
|
||||||
|
|
||||||
|
$table->renameColumn('option_id', 'option');
|
||||||
|
$table->foreign('option')->references('id')->on('service_options');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Pterodactyl\Models\Subuser;
|
||||||
|
use Pterodactyl\Models\Permission;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class SetupPermissionsPivotTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('permissions', function (Blueprint $table) {
|
||||||
|
$table->unsignedInteger('subuser_id')->after('id');
|
||||||
|
});
|
||||||
|
|
||||||
|
DB::transaction(function () {
|
||||||
|
foreach (Subuser::all() as &$subuser) {
|
||||||
|
Permission::where('user_id', $subuser->user_id)->where('server_id', $subuser->server_id)->update([
|
||||||
|
'subuser_id' => $subuser->id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('permissions', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('permissions_server_id_foreign');
|
||||||
|
$table->dropIndex('permissions_server_id_foreign');
|
||||||
|
$table->dropForeign('permissions_user_id_foreign');
|
||||||
|
$table->dropIndex('permissions_user_id_foreign');
|
||||||
|
|
||||||
|
$table->dropColumn('server_id');
|
||||||
|
$table->dropColumn('user_id');
|
||||||
|
$table->dropColumn('created_at');
|
||||||
|
$table->dropColumn('updated_at');
|
||||||
|
$table->foreign('subuser_id')->references('id')->on('subusers');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('permissions', function (Blueprint $table) {
|
||||||
|
$table->unsignedInteger('server_id')->after('subuser_id');
|
||||||
|
$table->unsignedInteger('user_id')->after('server_id');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
|
||||||
|
DB::transaction(function () {
|
||||||
|
foreach (Subuser::all() as &$subuser) {
|
||||||
|
Permission::where('subuser_id', $subuser->id)->update([
|
||||||
|
'user_id' => $subuser->user_id,
|
||||||
|
'server_id' => $subuser->server_id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('permissions', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('permissions_subuser_id_foreign');
|
||||||
|
$table->dropIndex('permissions_subuser_id_foreign');
|
||||||
|
$table->dropColumn('subuser_id');
|
||||||
|
|
||||||
|
$table->foreign('server_id')->references('id')->on('servers');
|
||||||
|
$table->foreign('user_id')->references('id')->on('users');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class UpdateAPIKeyColumnNames extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('api_keys', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('api_keys_user_foreign')->dropIndex('api_keys_user_foreign');
|
||||||
|
|
||||||
|
$table->renameColumn('user', 'user_id');
|
||||||
|
$table->foreign('user_id')->references('id')->on('users');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('api_keys', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('api_keys_user_id_foreign')->dropIndex('api_keys_user_id_foreign');
|
||||||
|
|
||||||
|
$table->renameColumn('user_id', 'user');
|
||||||
|
$table->foreign('user')->references('id')->on('users');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -66,7 +66,7 @@ class MinecraftServiceTableSeeder extends Seeder
|
||||||
|
|
||||||
private function addCoreOptions()
|
private function addCoreOptions()
|
||||||
{
|
{
|
||||||
$this->option['vanilla'] = Models\ServiceOptions::create([
|
$this->option['vanilla'] = Models\ServiceOption::create([
|
||||||
'parent_service' => $this->service->id,
|
'parent_service' => $this->service->id,
|
||||||
'name' => 'Vanilla Minecraft',
|
'name' => 'Vanilla Minecraft',
|
||||||
'description' => 'Minecraft is a game about placing blocks and going on adventures. Explore randomly generated worlds and build amazing things from the simplest of homes to the grandest of castles. Play in Creative Mode with unlimited resources or mine deep in Survival Mode, crafting weapons and armor to fend off dangerous mobs. Do all this alone or with friends.',
|
'description' => 'Minecraft is a game about placing blocks and going on adventures. Explore randomly generated worlds and build amazing things from the simplest of homes to the grandest of castles. Play in Creative Mode with unlimited resources or mine deep in Survival Mode, crafting weapons and armor to fend off dangerous mobs. Do all this alone or with friends.',
|
||||||
|
@ -76,7 +76,7 @@ class MinecraftServiceTableSeeder extends Seeder
|
||||||
'startup' => null,
|
'startup' => null,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->option['spigot'] = Models\ServiceOptions::create([
|
$this->option['spigot'] = Models\ServiceOption::create([
|
||||||
'parent_service' => $this->service->id,
|
'parent_service' => $this->service->id,
|
||||||
'name' => 'Spigot',
|
'name' => 'Spigot',
|
||||||
'description' => 'Spigot is the most widely-used modded Minecraft server software in the world. It powers many of the top Minecraft server networks around to ensure they can cope with their huge player base and ensure the satisfaction of their players. Spigot works by reducing and eliminating many causes of lag, as well as adding in handy features and settings that help make your job of server administration easier.',
|
'description' => 'Spigot is the most widely-used modded Minecraft server software in the world. It powers many of the top Minecraft server networks around to ensure they can cope with their huge player base and ensure the satisfaction of their players. Spigot works by reducing and eliminating many causes of lag, as well as adding in handy features and settings that help make your job of server administration easier.',
|
||||||
|
@ -86,7 +86,7 @@ class MinecraftServiceTableSeeder extends Seeder
|
||||||
'startup' => '-Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}}',
|
'startup' => '-Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}}',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->option['sponge'] = Models\ServiceOptions::create([
|
$this->option['sponge'] = Models\ServiceOption::create([
|
||||||
'parent_service' => $this->service->id,
|
'parent_service' => $this->service->id,
|
||||||
'name' => 'Sponge (SpongeVanilla)',
|
'name' => 'Sponge (SpongeVanilla)',
|
||||||
'description' => 'SpongeVanilla is the SpongeAPI implementation for Vanilla Minecraft.',
|
'description' => 'SpongeVanilla is the SpongeAPI implementation for Vanilla Minecraft.',
|
||||||
|
@ -96,7 +96,7 @@ class MinecraftServiceTableSeeder extends Seeder
|
||||||
'startup' => null,
|
'startup' => null,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->option['bungeecord'] = Models\ServiceOptions::create([
|
$this->option['bungeecord'] = Models\ServiceOption::create([
|
||||||
'parent_service' => $this->service->id,
|
'parent_service' => $this->service->id,
|
||||||
'name' => 'Bungeecord',
|
'name' => 'Bungeecord',
|
||||||
'description' => 'For a long time, Minecraft server owners have had a dream that encompasses a free, easy, and reliable way to connect multiple Minecraft servers together. BungeeCord is the answer to said dream. Whether you are a small server wishing to string multiple game-modes together, or the owner of the ShotBow Network, BungeeCord is the ideal solution for you. With the help of BungeeCord, you will be able to unlock your community\'s full potential.',
|
'description' => 'For a long time, Minecraft server owners have had a dream that encompasses a free, easy, and reliable way to connect multiple Minecraft servers together. BungeeCord is the answer to said dream. Whether you are a small server wishing to string multiple game-modes together, or the owner of the ShotBow Network, BungeeCord is the ideal solution for you. With the help of BungeeCord, you will be able to unlock your community\'s full potential.',
|
||||||
|
@ -117,7 +117,7 @@ class MinecraftServiceTableSeeder extends Seeder
|
||||||
|
|
||||||
private function addVanillaVariables()
|
private function addVanillaVariables()
|
||||||
{
|
{
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['vanilla']->id,
|
'option_id' => $this->option['vanilla']->id,
|
||||||
'name' => 'Server Jar File',
|
'name' => 'Server Jar File',
|
||||||
'description' => 'The name of the server jarfile to run the server with.',
|
'description' => 'The name of the server jarfile to run the server with.',
|
||||||
|
@ -129,7 +129,7 @@ class MinecraftServiceTableSeeder extends Seeder
|
||||||
'regex' => '/^([\w\d._-]+)(\.jar)$/',
|
'regex' => '/^([\w\d._-]+)(\.jar)$/',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['vanilla']->id,
|
'option_id' => $this->option['vanilla']->id,
|
||||||
'name' => 'Server Version',
|
'name' => 'Server Version',
|
||||||
'description' => 'The version of Minecraft Vanilla to install. Use "latest" to install the latest version.',
|
'description' => 'The version of Minecraft Vanilla to install. Use "latest" to install the latest version.',
|
||||||
|
@ -144,7 +144,7 @@ class MinecraftServiceTableSeeder extends Seeder
|
||||||
|
|
||||||
private function addSpigotVariables()
|
private function addSpigotVariables()
|
||||||
{
|
{
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['spigot']->id,
|
'option_id' => $this->option['spigot']->id,
|
||||||
'name' => 'Server Jar File',
|
'name' => 'Server Jar File',
|
||||||
'description' => 'The name of the server jarfile to run the server with.',
|
'description' => 'The name of the server jarfile to run the server with.',
|
||||||
|
@ -156,7 +156,7 @@ class MinecraftServiceTableSeeder extends Seeder
|
||||||
'regex' => '/^([\w\d._-]+)(\.jar)$/',
|
'regex' => '/^([\w\d._-]+)(\.jar)$/',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['spigot']->id,
|
'option_id' => $this->option['spigot']->id,
|
||||||
'name' => 'Spigot Version',
|
'name' => 'Spigot Version',
|
||||||
'description' => 'The version of Spigot to download (using the --rev tag). Use "latest" for latest.',
|
'description' => 'The version of Spigot to download (using the --rev tag). Use "latest" for latest.',
|
||||||
|
@ -168,7 +168,7 @@ class MinecraftServiceTableSeeder extends Seeder
|
||||||
'regex' => '/^(latest|[a-zA-Z0-9_\.-]{3,7})$/',
|
'regex' => '/^(latest|[a-zA-Z0-9_\.-]{3,7})$/',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['spigot']->id,
|
'option_id' => $this->option['spigot']->id,
|
||||||
'name' => 'Download Path',
|
'name' => 'Download Path',
|
||||||
'description' => 'A URL to use to download Spigot rather than building it on the server. This is not user viewable. Use <code>{{DL_VERSION}}</code> in the URL to automatically insert the assigned version into the URL. If you do not enter a URL Spigot will build directly in the container (this will fail on low memory containers).',
|
'description' => 'A URL to use to download Spigot rather than building it on the server. This is not user viewable. Use <code>{{DL_VERSION}}</code> in the URL to automatically insert the assigned version into the URL. If you do not enter a URL Spigot will build directly in the container (this will fail on low memory containers).',
|
||||||
|
@ -183,7 +183,7 @@ class MinecraftServiceTableSeeder extends Seeder
|
||||||
|
|
||||||
private function addSpongeVariables()
|
private function addSpongeVariables()
|
||||||
{
|
{
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['sponge']->id,
|
'option_id' => $this->option['sponge']->id,
|
||||||
'name' => 'Sponge Version',
|
'name' => 'Sponge Version',
|
||||||
'description' => 'The version of SpongeVanilla to download and use.',
|
'description' => 'The version of SpongeVanilla to download and use.',
|
||||||
|
@ -195,7 +195,7 @@ class MinecraftServiceTableSeeder extends Seeder
|
||||||
'regex' => '/^([a-zA-Z0-9.\-_]+)$/',
|
'regex' => '/^([a-zA-Z0-9.\-_]+)$/',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['sponge']->id,
|
'option_id' => $this->option['sponge']->id,
|
||||||
'name' => 'Server Jar File',
|
'name' => 'Server Jar File',
|
||||||
'description' => 'The name of the Jarfile to use when running SpongeVanilla.',
|
'description' => 'The name of the Jarfile to use when running SpongeVanilla.',
|
||||||
|
@ -210,7 +210,7 @@ class MinecraftServiceTableSeeder extends Seeder
|
||||||
|
|
||||||
private function addBungeecordVariables()
|
private function addBungeecordVariables()
|
||||||
{
|
{
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['bungeecord']->id,
|
'option_id' => $this->option['bungeecord']->id,
|
||||||
'name' => 'Bungeecord Version',
|
'name' => 'Bungeecord Version',
|
||||||
'description' => 'The version of Bungeecord to download and use.',
|
'description' => 'The version of Bungeecord to download and use.',
|
||||||
|
@ -222,7 +222,7 @@ class MinecraftServiceTableSeeder extends Seeder
|
||||||
'regex' => '/^(latest|[\d]{1,6})$/',
|
'regex' => '/^(latest|[\d]{1,6})$/',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['bungeecord']->id,
|
'option_id' => $this->option['bungeecord']->id,
|
||||||
'name' => 'Bungeecord Jar File',
|
'name' => 'Bungeecord Jar File',
|
||||||
'description' => 'The name of the Jarfile to use when running Bungeecord.',
|
'description' => 'The name of the Jarfile to use when running Bungeecord.',
|
||||||
|
|
|
@ -66,7 +66,7 @@ class SourceServiceTableSeeder extends Seeder
|
||||||
|
|
||||||
private function addCoreOptions()
|
private function addCoreOptions()
|
||||||
{
|
{
|
||||||
$this->option['insurgency'] = Models\ServiceOptions::create([
|
$this->option['insurgency'] = Models\ServiceOption::create([
|
||||||
'parent_service' => $this->service->id,
|
'parent_service' => $this->service->id,
|
||||||
'name' => 'Insurgency',
|
'name' => 'Insurgency',
|
||||||
'description' => 'Take to the streets for intense close quarters combat, where a team\'s survival depends upon securing crucial strongholds and destroying enemy supply in this multiplayer and cooperative Source Engine based experience.',
|
'description' => 'Take to the streets for intense close quarters combat, where a team\'s survival depends upon securing crucial strongholds and destroying enemy supply in this multiplayer and cooperative Source Engine based experience.',
|
||||||
|
@ -76,7 +76,7 @@ class SourceServiceTableSeeder extends Seeder
|
||||||
'startup' => '-game {{SRCDS_GAME}} -console -port {{SERVER_PORT}} +map {{SRCDS_MAP}} -strictportbind -norestart',
|
'startup' => '-game {{SRCDS_GAME}} -console -port {{SERVER_PORT}} +map {{SRCDS_MAP}} -strictportbind -norestart',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->option['tf2'] = Models\ServiceOptions::create([
|
$this->option['tf2'] = Models\ServiceOption::create([
|
||||||
'parent_service' => $this->service->id,
|
'parent_service' => $this->service->id,
|
||||||
'name' => 'Team Fortress 2',
|
'name' => 'Team Fortress 2',
|
||||||
'description' => 'Team Fortress 2 is a team-based first-person shooter multiplayer video game developed and published by Valve Corporation. It is the sequel to the 1996 mod Team Fortress for Quake and its 1999 remake.',
|
'description' => 'Team Fortress 2 is a team-based first-person shooter multiplayer video game developed and published by Valve Corporation. It is the sequel to the 1996 mod Team Fortress for Quake and its 1999 remake.',
|
||||||
|
@ -86,7 +86,7 @@ class SourceServiceTableSeeder extends Seeder
|
||||||
'startup' => '-game {{SRCDS_GAME}} -console -port {{SERVER_PORT}} +map {{SRCDS_MAP}} -strictportbind -norestart',
|
'startup' => '-game {{SRCDS_GAME}} -console -port {{SERVER_PORT}} +map {{SRCDS_MAP}} -strictportbind -norestart',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->option['ark'] = Models\ServiceOptions::create([
|
$this->option['ark'] = Models\ServiceOption::create([
|
||||||
'parent_service' => $this->service->id,
|
'parent_service' => $this->service->id,
|
||||||
'name' => 'Ark: Survival Evolved',
|
'name' => 'Ark: Survival Evolved',
|
||||||
'description' => 'As a man or woman stranded, naked, freezing, and starving on the unforgiving shores of a mysterious island called ARK, use your skill and cunning to kill or tame and ride the plethora of leviathan dinosaurs and other primeval creatures roaming the land. Hunt, harvest resources, craft items, grow crops, research technologies, and build shelters to withstand the elements and store valuables, all while teaming up with (or preying upon) hundreds of other players to survive, dominate... and escape! — Gamepedia: ARK',
|
'description' => 'As a man or woman stranded, naked, freezing, and starving on the unforgiving shores of a mysterious island called ARK, use your skill and cunning to kill or tame and ride the plethora of leviathan dinosaurs and other primeval creatures roaming the land. Hunt, harvest resources, craft items, grow crops, research technologies, and build shelters to withstand the elements and store valuables, all while teaming up with (or preying upon) hundreds of other players to survive, dominate... and escape! — Gamepedia: ARK',
|
||||||
|
@ -96,7 +96,7 @@ class SourceServiceTableSeeder extends Seeder
|
||||||
'startup' => 'TheIsland?listen?ServerPassword={{ARK_PASSWORD}}?ServerAdminPassword={{ARK_ADMIN_PASSWORD}}?Port={{SERVER_PORT}}?MaxPlayers={{SERVER_MAX_PLAYERS}}',
|
'startup' => 'TheIsland?listen?ServerPassword={{ARK_PASSWORD}}?ServerAdminPassword={{ARK_ADMIN_PASSWORD}}?Port={{SERVER_PORT}}?MaxPlayers={{SERVER_MAX_PLAYERS}}',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->option['custom'] = Models\ServiceOptions::create([
|
$this->option['custom'] = Models\ServiceOption::create([
|
||||||
'parent_service' => $this->service->id,
|
'parent_service' => $this->service->id,
|
||||||
'name' => 'Custom Source Engine Game',
|
'name' => 'Custom Source Engine Game',
|
||||||
'description' => 'This option allows modifying the startup arguments and other details to run a custo SRCDS based game on the panel.',
|
'description' => 'This option allows modifying the startup arguments and other details to run a custo SRCDS based game on the panel.',
|
||||||
|
@ -117,7 +117,7 @@ class SourceServiceTableSeeder extends Seeder
|
||||||
|
|
||||||
private function addInsurgencyVariables()
|
private function addInsurgencyVariables()
|
||||||
{
|
{
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['insurgency']->id,
|
'option_id' => $this->option['insurgency']->id,
|
||||||
'name' => 'Game ID',
|
'name' => 'Game ID',
|
||||||
'description' => 'The ID corresponding to the game to download and run using SRCDS.',
|
'description' => 'The ID corresponding to the game to download and run using SRCDS.',
|
||||||
|
@ -129,7 +129,7 @@ class SourceServiceTableSeeder extends Seeder
|
||||||
'regex' => '/^(17705)$/',
|
'regex' => '/^(17705)$/',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['insurgency']->id,
|
'option_id' => $this->option['insurgency']->id,
|
||||||
'name' => 'Game Name',
|
'name' => 'Game Name',
|
||||||
'description' => 'The name corresponding to the game to download and run using SRCDS.',
|
'description' => 'The name corresponding to the game to download and run using SRCDS.',
|
||||||
|
@ -141,7 +141,7 @@ class SourceServiceTableSeeder extends Seeder
|
||||||
'regex' => '/^(insurgency)$/',
|
'regex' => '/^(insurgency)$/',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['insurgency']->id,
|
'option_id' => $this->option['insurgency']->id,
|
||||||
'name' => 'Default Map',
|
'name' => 'Default Map',
|
||||||
'description' => 'The default map to use when starting the server.',
|
'description' => 'The default map to use when starting the server.',
|
||||||
|
@ -156,7 +156,7 @@ class SourceServiceTableSeeder extends Seeder
|
||||||
|
|
||||||
private function addTF2Variables()
|
private function addTF2Variables()
|
||||||
{
|
{
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['tf2']->id,
|
'option_id' => $this->option['tf2']->id,
|
||||||
'name' => 'Game ID',
|
'name' => 'Game ID',
|
||||||
'description' => 'The ID corresponding to the game to download and run using SRCDS.',
|
'description' => 'The ID corresponding to the game to download and run using SRCDS.',
|
||||||
|
@ -168,7 +168,7 @@ class SourceServiceTableSeeder extends Seeder
|
||||||
'regex' => '/^(232250)$/',
|
'regex' => '/^(232250)$/',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['tf2']->id,
|
'option_id' => $this->option['tf2']->id,
|
||||||
'name' => 'Game Name',
|
'name' => 'Game Name',
|
||||||
'description' => 'The name corresponding to the game to download and run using SRCDS.',
|
'description' => 'The name corresponding to the game to download and run using SRCDS.',
|
||||||
|
@ -180,7 +180,7 @@ class SourceServiceTableSeeder extends Seeder
|
||||||
'regex' => '/^(tf)$/',
|
'regex' => '/^(tf)$/',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['tf2']->id,
|
'option_id' => $this->option['tf2']->id,
|
||||||
'name' => 'Default Map',
|
'name' => 'Default Map',
|
||||||
'description' => 'The default map to use when starting the server.',
|
'description' => 'The default map to use when starting the server.',
|
||||||
|
@ -234,7 +234,7 @@ class SourceServiceTableSeeder extends Seeder
|
||||||
|
|
||||||
private function addCustomVariables()
|
private function addCustomVariables()
|
||||||
{
|
{
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['custom']->id,
|
'option_id' => $this->option['custom']->id,
|
||||||
'name' => 'Game ID',
|
'name' => 'Game ID',
|
||||||
'description' => 'The ID corresponding to the game to download and run using SRCDS.',
|
'description' => 'The ID corresponding to the game to download and run using SRCDS.',
|
||||||
|
@ -246,7 +246,7 @@ class SourceServiceTableSeeder extends Seeder
|
||||||
'regex' => '/^(\d){1,6}$/',
|
'regex' => '/^(\d){1,6}$/',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['custom']->id,
|
'option_id' => $this->option['custom']->id,
|
||||||
'name' => 'Game Name',
|
'name' => 'Game Name',
|
||||||
'description' => 'The name corresponding to the game to download and run using SRCDS.',
|
'description' => 'The name corresponding to the game to download and run using SRCDS.',
|
||||||
|
|
|
@ -66,7 +66,7 @@ class TerrariaServiceTableSeeder extends Seeder
|
||||||
|
|
||||||
private function addCoreOptions()
|
private function addCoreOptions()
|
||||||
{
|
{
|
||||||
$this->option['tshock'] = Models\ServiceOptions::create([
|
$this->option['tshock'] = Models\ServiceOption::create([
|
||||||
'parent_service' => $this->service->id,
|
'parent_service' => $this->service->id,
|
||||||
'name' => 'Terraria Server (TShock)',
|
'name' => 'Terraria Server (TShock)',
|
||||||
'description' => 'TShock is a server modification for Terraria, written in C#, and based upon the Terraria Server API. It uses JSON for configuration management, and offers several features not present in the Terraria Server normally.',
|
'description' => 'TShock is a server modification for Terraria, written in C#, and based upon the Terraria Server API. It uses JSON for configuration management, and offers several features not present in the Terraria Server normally.',
|
||||||
|
@ -79,7 +79,7 @@ class TerrariaServiceTableSeeder extends Seeder
|
||||||
|
|
||||||
private function addVariables()
|
private function addVariables()
|
||||||
{
|
{
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['tshock']->id,
|
'option_id' => $this->option['tshock']->id,
|
||||||
'name' => 'TShock Version',
|
'name' => 'TShock Version',
|
||||||
'description' => 'Which version of TShock to install and use.',
|
'description' => 'Which version of TShock to install and use.',
|
||||||
|
@ -91,7 +91,7 @@ class TerrariaServiceTableSeeder extends Seeder
|
||||||
'regex' => '/^([0-9_\.-]{5,10})$/',
|
'regex' => '/^([0-9_\.-]{5,10})$/',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['tshock']->id,
|
'option_id' => $this->option['tshock']->id,
|
||||||
'name' => 'Maximum Slots',
|
'name' => 'Maximum Slots',
|
||||||
'description' => 'Total number of slots to allow on the server.',
|
'description' => 'Total number of slots to allow on the server.',
|
||||||
|
|
|
@ -66,7 +66,7 @@ class VoiceServiceTableSeeder extends Seeder
|
||||||
|
|
||||||
private function addCoreOptions()
|
private function addCoreOptions()
|
||||||
{
|
{
|
||||||
$this->option['mumble'] = Models\ServiceOptions::create([
|
$this->option['mumble'] = Models\ServiceOption::create([
|
||||||
'parent_service' => $this->service->id,
|
'parent_service' => $this->service->id,
|
||||||
'name' => 'Mumble Server',
|
'name' => 'Mumble Server',
|
||||||
'description' => 'Mumble is an open source, low-latency, high quality voice chat software primarily intended for use while gaming.',
|
'description' => 'Mumble is an open source, low-latency, high quality voice chat software primarily intended for use while gaming.',
|
||||||
|
@ -76,7 +76,7 @@ class VoiceServiceTableSeeder extends Seeder
|
||||||
'startup' => '-fg',
|
'startup' => '-fg',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->option['ts3'] = Models\ServiceOptions::create([
|
$this->option['ts3'] = Models\ServiceOption::create([
|
||||||
'parent_service' => $this->service->id,
|
'parent_service' => $this->service->id,
|
||||||
'name' => 'Teamspeak3 Server',
|
'name' => 'Teamspeak3 Server',
|
||||||
'description' => 'VoIP software designed with security in mind, featuring crystal clear voice quality, endless customization options, and scalabilty up to thousands of simultaneous users.',
|
'description' => 'VoIP software designed with security in mind, featuring crystal clear voice quality, endless customization options, and scalabilty up to thousands of simultaneous users.',
|
||||||
|
@ -89,7 +89,7 @@ class VoiceServiceTableSeeder extends Seeder
|
||||||
|
|
||||||
private function addVariables()
|
private function addVariables()
|
||||||
{
|
{
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['mumble']->id,
|
'option_id' => $this->option['mumble']->id,
|
||||||
'name' => 'Maximum Users',
|
'name' => 'Maximum Users',
|
||||||
'description' => 'Maximum concurrent users on the mumble server.',
|
'description' => 'Maximum concurrent users on the mumble server.',
|
||||||
|
@ -101,7 +101,7 @@ class VoiceServiceTableSeeder extends Seeder
|
||||||
'regex' => '/^(\d){1,6}$/',
|
'regex' => '/^(\d){1,6}$/',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['mumble']->id,
|
'option_id' => $this->option['mumble']->id,
|
||||||
'name' => 'Server Version',
|
'name' => 'Server Version',
|
||||||
'description' => 'Version of Mumble Server to download and use.',
|
'description' => 'Version of Mumble Server to download and use.',
|
||||||
|
@ -113,7 +113,7 @@ class VoiceServiceTableSeeder extends Seeder
|
||||||
'regex' => '/^([0-9_\.-]{5,8})$/',
|
'regex' => '/^([0-9_\.-]{5,8})$/',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Models\ServiceVariables::create([
|
Models\ServiceVariable::create([
|
||||||
'option_id' => $this->option['ts3']->id,
|
'option_id' => $this->option['ts3']->id,
|
||||||
'name' => 'Server Version',
|
'name' => 'Server Version',
|
||||||
'description' => 'The version of Teamspeak 3 to use when running the server.',
|
'description' => 'The version of Teamspeak 3 to use when running the server.',
|
||||||
|
|
File diff suppressed because one or more lines are too long
2
public/js/vendor/ace/mode-vbscript.js
vendored
2
public/js/vendor/ace/mode-vbscript.js
vendored
File diff suppressed because one or more lines are too long
|
@ -62,8 +62,8 @@
|
||||||
<tr class="dynamic-update" data-server="{{ $server->uuidShort }}">
|
<tr class="dynamic-update" data-server="{{ $server->uuidShort }}">
|
||||||
<td><code>{{ $server->uuidShort }}</code></td>
|
<td><code>{{ $server->uuidShort }}</code></td>
|
||||||
<td><a href="{{ route('server.index', $server->uuidShort) }}">{{ $server->name }}</a></td>
|
<td><a href="{{ route('server.index', $server->uuidShort) }}">{{ $server->name }}</a></td>
|
||||||
<td>{{ $server->nodeName }}</td>
|
<td>{{ $server->node->name }}</td>
|
||||||
<td><code>@if(!is_null($server->ip_alias)){{ $server->ip_alias }}@else{{ $server->ip }}@endif:{{ $server->port }}</code></td>
|
<td><code>{{ $server->allocation->alias }}:{{ $server->allocation->port }}</code></td>
|
||||||
<td class="text-center hidden-sm hidden-xs"><span data-action="memory">--</span> / {{ $server->memory === 0 ? '∞' : $server->memory }} MB</td>
|
<td class="text-center hidden-sm hidden-xs"><span data-action="memory">--</span> / {{ $server->memory === 0 ? '∞' : $server->memory }} MB</td>
|
||||||
<td class="text-center hidden-sm hidden-xs"><span data-action="cpu" data-cpumax="{{ $server->cpu }}">--</span> %</td>
|
<td class="text-center hidden-sm hidden-xs"><span data-action="cpu" data-cpumax="{{ $server->cpu }}">--</span> %</td>
|
||||||
<td class="text-center" data-action="status">
|
<td class="text-center" data-action="status">
|
||||||
|
|
|
@ -245,7 +245,7 @@
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div class="tab-pane active" id="control-sidebar-servers-tab">
|
<div class="tab-pane active" id="control-sidebar-servers-tab">
|
||||||
<ul class="control-sidebar-menu">
|
<ul class="control-sidebar-menu">
|
||||||
@foreach (Pterodactyl\Models\Server::getUserServers() as $s)
|
@foreach (Auth::user()->serverAccessCollection() as $s)
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
@if(isset($server) && isset($node))
|
@if(isset($server) && isset($node))
|
||||||
|
@ -254,7 +254,7 @@
|
||||||
@endif
|
@endif
|
||||||
@endif
|
@endif
|
||||||
href="{{ route('server.index', $s->uuidShort) }}">
|
href="{{ route('server.index', $s->uuidShort) }}">
|
||||||
@if($s->owner === Auth::user()->id)
|
@if($s->owner_id === Auth::user()->id)
|
||||||
<i class="menu-icon fa fa-user bg-blue"></i>
|
<i class="menu-icon fa fa-user bg-blue"></i>
|
||||||
@else
|
@else
|
||||||
<i class="menu-icon fa fa-user-o bg-gray"></i>
|
<i class="menu-icon fa fa-user-o bg-gray"></i>
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
<th>@lang('strings.port')</th>
|
<th>@lang('strings.port')</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
@foreach ($allocations as $allocation)
|
@foreach ($server->allocations as $allocation)
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<code>{{ $allocation->ip }}</code>
|
<code>{{ $allocation->ip }}</code>
|
||||||
|
@ -63,7 +63,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td><code>{{ $allocation->port }}</code></td>
|
<td><code>{{ $allocation->port }}</code></td>
|
||||||
<td class="col-xs-2 middle">
|
<td class="col-xs-2 middle">
|
||||||
@if($allocation->id === $server->allocation)
|
@if($allocation->id === $server->allocation_id)
|
||||||
<span class="label label-success" data-allocation="{{ $allocation->id }}">@lang('strings.primary')</span>
|
<span class="label label-success" data-allocation="{{ $allocation->id }}">@lang('strings.primary')</span>
|
||||||
@else
|
@else
|
||||||
<span class="label label-default" data-action="set-connection" data-allocation="{{ $allocation->id }}">@lang('strings.make_primary')</span>
|
<span class="label label-default" data-action="set-connection" data-allocation="{{ $allocation->id }}">@lang('strings.make_primary')</span>
|
||||||
|
|
|
@ -51,29 +51,29 @@
|
||||||
@can('view-subuser', $server)<th></th>@endcan
|
@can('view-subuser', $server)<th></th>@endcan
|
||||||
@can('delete-subuser', $server)<th></th>@endcan
|
@can('delete-subuser', $server)<th></th>@endcan
|
||||||
</tr>
|
</tr>
|
||||||
@foreach($subusers as $user)
|
@foreach($subusers as $subuser)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-center middle"><img class="img-circle" src="https://www.gravatar.com/avatar/{{ md5($user->email) }}?s=128" style="height:20px;" alt="User Image"></td>
|
<td class="text-center middle"><img class="img-circle" src="https://www.gravatar.com/avatar/{{ md5($subuser->user->email) }}?s=128" style="height:20px;" alt="User Image"></td>
|
||||||
<td class="middle">{{ $user->username }}
|
<td class="middle">{{ $subuser->user->username }}
|
||||||
<td class="middle"><code>{{ $user->email }}</code></td>
|
<td class="middle"><code>{{ $subuser->user->email }}</code></td>
|
||||||
<td class="middle text-center">
|
<td class="middle text-center">
|
||||||
@if($user->use_totp)
|
@if($subuser->user->use_totp)
|
||||||
<i class="fa fa-lock text-green"></i>
|
<i class="fa fa-lock text-green"></i>
|
||||||
@else
|
@else
|
||||||
<i class="fa fa-unlock text-red"></i>
|
<i class="fa fa-unlock text-red"></i>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td class="middle hidden-xs">{{ $user->created_at }}</td>
|
<td class="middle hidden-xs">{{ $subuser->user->created_at }}</td>
|
||||||
@can('view-subuser', $server)
|
@can('view-subuser', $server)
|
||||||
<td class="text-center middle">
|
<td class="text-center middle">
|
||||||
<a href="{{ route('server.subusers.view', ['server' => $server->uuidShort, 'id' => md5($user->id)]) }}">
|
<a href="{{ route('server.subusers.view', ['server' => $server->uuidShort, 'id' => $subuser->id]) }}">
|
||||||
<button class="btn btn-xs btn-primary">@lang('server.users.configure')</button>
|
<button class="btn btn-xs btn-primary">@lang('server.users.configure')</button>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
@endcan
|
@endcan
|
||||||
@can('delete-subuser', $server)
|
@can('delete-subuser', $server)
|
||||||
<td class="text-center middle">
|
<td class="text-center middle">
|
||||||
<a href="#/delete/{{ md5($user->id) }}" data-action="delete" data-id="{{ md5($user->id) }}">
|
<a href="#/delete/{{ $subuser->id }}" data-action="delete" data-id="{{ $subuser->id }}">
|
||||||
<button class="btn btn-xs btn-danger">@lang('strings.revoke')</button>
|
<button class="btn btn-xs btn-danger">@lang('strings.revoke')</button>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@can('edit-subuser', $server)
|
@can('edit-subuser', $server)
|
||||||
<form action="{{ route('server.subusers.view', [ 'uuid' => $server->uuidShort, 'id' => md5($subuser->id) ]) }}" method="POST">
|
<form action="{{ route('server.subusers.view', [ 'uuid' => $server->uuidShort, 'id' => $subuser->id ]) }}" method="POST">
|
||||||
@endcan
|
@endcan
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
<label class="control-label">@lang('server.users.new.email')</label>
|
<label class="control-label">@lang('server.users.new.email')</label>
|
||||||
<div>
|
<div>
|
||||||
{!! csrf_field() !!}
|
{!! csrf_field() !!}
|
||||||
<input type="email" class="form-control" disabled value="{{ $subuser->a_userEmail }}" />
|
<input type="email" class="form-control" disabled value="{{ $subuser->user->email }}" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -52,20 +52,21 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach($databases as $db)
|
@foreach($databases as $database)
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ $db->a_serverName }}</td>
|
<td>{{ $database->server->name }}</td>
|
||||||
<td>{{ $db->database }}</td>
|
<td>{{ $database->database }}</td>
|
||||||
<td>{{ $db->username }} ({{ $db->remote }})</td>
|
<td>{{ $database->username }} ({{ $database->remote }})</td>
|
||||||
<td><code>{{ $db->a_host }}:{{ $db->a_port }}</code></td>
|
<?php $host = $hosts->where('id', $database->db_server)->first(); ?>
|
||||||
<td class="text-center"><a href="/admin/servers/view/{{ $db->a_serverId }}?tab=tab_database"><i class="fa fa-search"></i></a></td>
|
<td><code>{{ $host->host }}:{{ $host->port }}</code></td>
|
||||||
<td class="text-center"><a href="#" data-action="delete" data-type="delete" data-attr="{{ $db->id }}" class="text-danger"><i class="fa fa-trash-o"></i></a></td>
|
<td class="text-center"><a href="/admin/servers/view/{{ $database->server->id }}?tab=tab_database"><i class="fa fa-search"></i></a></td>
|
||||||
|
<td class="text-center"><a href="#" data-action="delete" data-type="delete" data-attr="{{ $database->id }}" class="text-danger"><i class="fa fa-trash-o"></i></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="col-md-12 text-center">
|
<div class="col-md-12 text-center">
|
||||||
{{ $databases->appends('tab', 'tab_databases')->render() }}
|
{{ $databases->appends(['tab' => 'tab_databases'])->links() }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -86,20 +87,20 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach($dbh as $db)
|
@foreach($hosts as $database)
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ $db->name }}</td>
|
<td>{{ $database->name }}</td>
|
||||||
<td><code>{{ $db->host }}:{{ $db->port }}</code></td>
|
<td><code>{{ $database->host }}:{{ $database->port }}</code></td>
|
||||||
<td>{{ $db->username }}</td>
|
<td>{{ $database->username }}</td>
|
||||||
<td class="text-center">{{ $db->c_databases }}</td>
|
<td class="text-center">{{ $database->databases_count }}</td>
|
||||||
<td>@if(is_null($db->a_linkedNode))<em>unlinked</em>@else{{ $db->a_linkedNode }}@endif</td>
|
<td>@if(is_null($database->node))<em>unlinked</em>@else{{ $database->node->name }}@endif</td>
|
||||||
<td class="text-center"><a href="#" class="text-danger" data-action="delete" data-type="delete-server" data-attr="{{ $db->id }}"><i class="fa fa-trash-o"></i></a></td>
|
<td class="text-center"><a href="#" class="text-danger" data-action="delete" data-type="delete-server" data-attr="{{ $database->id }}"><i class="fa fa-trash-o"></i></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="col-md-12 text-center">
|
<div class="col-md-12 text-center">
|
||||||
{{ $dbh->appends('tab', 'tab_dbservers')->render() }}
|
{{ $hosts->appends('tab', 'tab_dbservers')->render() }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
<select name="linked_node" class="form-control">
|
<select name="linked_node" class="form-control">
|
||||||
<option>None</option>
|
<option>None</option>
|
||||||
@foreach($nodes as $node)
|
@foreach($nodes as $node)
|
||||||
<option value="{{ $node->id }}" @if((int) old('linked_node') === $node->id) selected="selected" @endif>{{ $node->name }} ({{ $node->a_location }})</option>
|
<option value="{{ $node->id }}" @if((int) old('linked_node') === $node->id) selected="selected" @endif>{{ $node->name }} ({{ $node->location->short }})</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
<p class="text-muted"><small>A linked node implies that this Database Server is running on that node and it will be auto-selected when adding a database to servers on that node.</small></p>
|
<p class="text-muted"><small>A linked node implies that this Database Server is running on that node and it will be auto-selected when adding a database to servers on that node.</small></p>
|
||||||
|
|
|
@ -46,8 +46,8 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>{{ $location->short }}</code></td>
|
<td><code>{{ $location->short }}</code></td>
|
||||||
<td>{{ $location->long }}</td>
|
<td>{{ $location->long }}</td>
|
||||||
<td class="text-center">{{ $location->a_nodeCount }}</td>
|
<td class="text-center">{{ $location->nodes_count }}</td>
|
||||||
<td class="text-center">{{ $location->a_serverCount }}</td>
|
<td class="text-center">{{ $location->servers_count }}</td>
|
||||||
<td class="text-center"><a href="#edit"><i class="fa fa-wrench" data-toggle="modal" data-target="#editModal" data-action="edit" data-id="{{ $location->id }}" data-short="{{ $location->short }}" data-long="{{ $location->long }}"></i></a></td>
|
<td class="text-center"><a href="#edit"><i class="fa fa-wrench" data-toggle="modal" data-target="#editModal" data-action="edit" data-id="{{ $location->id }}" data-short="{{ $location->short }}" data-long="{{ $location->long }}"></i></a></td>
|
||||||
<td class="text-center"><a href="#delete" class="text-danger" data-action="delete" data-id="{{ $location->id }}"><i class="fa fa-trash-o"></i></a></td>
|
<td class="text-center"><a href="#delete" class="text-danger" data-action="delete" data-id="{{ $location->id }}"><i class="fa fa-trash-o"></i></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -53,10 +53,10 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-center text-muted left-icon" data-action="ping" data-secret="{{ $node->daemonSecret }}" data-location="{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}"><i class="fa fa-fw fa-refresh fa-spin"></i></td>
|
<td class="text-center text-muted left-icon" data-action="ping" data-secret="{{ $node->daemonSecret }}" data-location="{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}"><i class="fa fa-fw fa-refresh fa-spin"></i></td>
|
||||||
<td><a href="/admin/nodes/view/{{ $node->id }}">{{ $node->name }}</td>
|
<td><a href="/admin/nodes/view/{{ $node->id }}">{{ $node->name }}</td>
|
||||||
<td>{{ $node->a_locationName }}</td>
|
<td>{{ $node->location->short }}</td>
|
||||||
<td class="hidden-xs">{{ $node->memory }} MB</td>
|
<td class="hidden-xs">{{ $node->memory }} MB</td>
|
||||||
<td class="hidden-xs">{{ $node->disk }} MB</td>
|
<td class="hidden-xs">{{ $node->disk }} MB</td>
|
||||||
<td class="text-center hidden-xs">{{ $node->a_serverCount }}</td>
|
<td class="text-center hidden-xs">{{ $node->servers_count }}</td>
|
||||||
<td class="text-center" style="color:{{ ($node->scheme === 'https') ? '#50af51' : '#d9534f' }}"><i class="fa fa-{{ ($node->scheme === 'https') ? 'lock' : 'unlock' }}"></i></td>
|
<td class="text-center" style="color:{{ ($node->scheme === 'https') ? '#50af51' : '#d9534f' }}"><i class="fa fa-{{ ($node->scheme === 'https') ? 'lock' : 'unlock' }}"></i></td>
|
||||||
<td class="text-center hidden-xs"><i class="fa fa-{{ ($node->public === 1) ? 'eye' : 'eye-slash' }}"></i></td>
|
<td class="text-center hidden-xs"><i class="fa fa-{{ ($node->public === 1) ? 'eye' : 'eye-slash' }}"></i></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -44,9 +44,9 @@
|
||||||
<div class="form-group col-md-4">
|
<div class="form-group col-md-4">
|
||||||
<label for="name" class="control-label">Location</label>
|
<label for="name" class="control-label">Location</label>
|
||||||
<div>
|
<div>
|
||||||
<select name="location" class="form-control">
|
<select name="location_id" class="form-control">
|
||||||
@foreach($locations as $location)
|
@foreach($locations as $location)
|
||||||
<option value="{{ $location->id }}" {{ (old('location') === $location->id) ? 'checked' : '' }}>{{ $location->long }} ({{ $location->short }})</option>
|
<option value="{{ $location->id }}" {{ (old('location_id') === $location->id) ? 'selected' : '' }}>{{ $location->long }} ({{ $location->short }})</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
<li><a href="#tab_configuration" data-toggle="tab">Configuration</a></li>
|
<li><a href="#tab_configuration" data-toggle="tab">Configuration</a></li>
|
||||||
<li><a href="#tab_allocation" data-toggle="tab">Allocation</a></li>
|
<li><a href="#tab_allocation" data-toggle="tab">Allocation</a></li>
|
||||||
<li><a href="#tab_servers" data-toggle="tab">Servers</a></li>
|
<li><a href="#tab_servers" data-toggle="tab">Servers</a></li>
|
||||||
@if(count($servers) === 0)<li><a href="#tab_delete" data-toggle="tab">Delete</a></li>@endif
|
@if(count($node->servers) === 0)<li><a href="#tab_delete" data-toggle="tab">Delete</a></li>@endif
|
||||||
</ul>
|
</ul>
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div class="tab-pane active" id="tab_about">
|
<div class="tab-pane active" id="tab_about">
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Total Servers</td>
|
<td>Total Servers</td>
|
||||||
<td>{{ count($servers) }}</td>
|
<td>{{ count($node->servers) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Memory Allocated</td>
|
<td>Memory Allocated</td>
|
||||||
|
@ -138,9 +138,9 @@
|
||||||
<div class="form-group col-md-4">
|
<div class="form-group col-md-4">
|
||||||
<label for="name" class="control-label">Location</label>
|
<label for="name" class="control-label">Location</label>
|
||||||
<div>
|
<div>
|
||||||
<select name="location" class="form-control">
|
<select name="location_id" class="form-control">
|
||||||
@foreach($locations as $location)
|
@foreach($locations as $location)
|
||||||
<option value="{{ $location->id }}" {{ (old('location', $node->location) === $location->id) ? 'checked' : '' }}>{{ $location->long }} ({{ $location->short }})</option>
|
<option value="{{ $location->id }}" {{ (old('location_id', $node->location) === $location->id) ? 'selected' : '' }}>{{ $location->long }} ({{ $location->short }})</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
@ -309,7 +309,7 @@
|
||||||
<div class="input-group-btn">
|
<div class="input-group-btn">
|
||||||
<button type="button" class="btn btn-sm btn-primary dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
|
<button type="button" class="btn btn-sm btn-primary dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
|
||||||
<ul class="dropdown-menu dropdown-menu-right">
|
<ul class="dropdown-menu dropdown-menu-right">
|
||||||
@foreach($allocation_ips as $allocation)
|
@foreach($node->allocations->unique('ip')->values()->all() as $allocation)
|
||||||
<li data-action="alloc_dropdown_val" data-value="{{ $allocation->ip }}"><a href="#">{{ $allocation->ip }}</a></li>
|
<li data-action="alloc_dropdown_val" data-value="{{ $allocation->ip }}"><a href="#">{{ $allocation->ip }}</a></li>
|
||||||
@endforeach
|
@endforeach
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -355,7 +355,7 @@
|
||||||
<td></td>
|
<td></td>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach($allocations as $allocation)
|
@foreach($node->allocations as $allocation)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="col-sm-3 align-middle">{{ $allocation->ip }}</td>
|
<td class="col-sm-3 align-middle">{{ $allocation->ip }}</td>
|
||||||
<td class="col-sm-3 align-middle">
|
<td class="col-sm-3 align-middle">
|
||||||
|
@ -376,7 +376,7 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="col-md-12 text-center">
|
<div class="col-md-12 text-center">
|
||||||
{{ $allocations->appends(['tab' => 'tab_allocation'])->links() }}
|
{{ $node->allocations->appends(['tab' => 'tab_allocation'])->render() }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -402,11 +402,11 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach($servers as $server)
|
@foreach($node->servers as $server)
|
||||||
<tr data-server="{{ $server->uuid }}">
|
<tr data-server="{{ $server->uuid }}">
|
||||||
<td><a href="/admin/servers/view/{{ $server->id }}">{{ $server->name }}</a></td>
|
<td><a href="/admin/servers/view/{{ $server->id }}">{{ $server->name }}</a></td>
|
||||||
<td><a href="/admin/users/view/{{ $server->owner }}"><code>{{ $server->a_ownerEmail }}</a></a></td>
|
<td><a href="/admin/users/view/{{ $server->owner_id }}"><code>{{ $server->user->email }}</a></a></td>
|
||||||
<td>{{ $server->a_serviceName }}</td>
|
<td>{{ $server->service->name }}</td>
|
||||||
<td class="text-center"><span data-action="memory">--</span> / {{ $server->memory === 0 ? '∞' : $server->memory }} MB</td>
|
<td class="text-center"><span data-action="memory">--</span> / {{ $server->memory === 0 ? '∞' : $server->memory }} MB</td>
|
||||||
<td class="text-center">{{ $server->disk }} MB</td>
|
<td class="text-center">{{ $server->disk }} MB</td>
|
||||||
<td class="text-center"><span data-action="cpu" data-cpumax="{{ $server->cpu }}">--</span> %</td>
|
<td class="text-center"><span data-action="cpu" data-cpumax="{{ $server->cpu }}">--</span> %</td>
|
||||||
|
@ -415,13 +415,10 @@
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12 text-center">{!! $servers->appends(['tab' => 'tab_servers'])->render() !!}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@if(count($servers) === 0)
|
@if(count($node->servers) === 0)
|
||||||
<div class="tab-pane" id="tab_delete">
|
<div class="tab-pane" id="tab_delete">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"></div>
|
<div class="panel-heading"></div>
|
||||||
|
@ -459,7 +456,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<select class="form-control" name="ip">
|
<select class="form-control" name="ip">
|
||||||
@foreach($allocation_ips as $allocation)
|
@foreach($node->allocations->unique('ip')->values()->all() as $allocation)
|
||||||
<option value="{{ $allocation->ip }}">{{ $allocation->ip }}</option>
|
<option value="{{ $allocation->ip }}">{{ $allocation->ip }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
<h3>All Servers</h3><hr />
|
<h3>All Servers</h3><hr />
|
||||||
<form method="GET" style="margin-bottom:20px;">
|
<form method="GET" style="margin-bottom:20px;">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="text" name="filter" class="form-control" value="{{ urldecode(Input::get('filter')) }}" placeholder="search term" />
|
<input type="text" name="filter" class="form-control" value="{{ urldecode(request()->filter) }}" placeholder="search term" />
|
||||||
<div class="input-group-btn">
|
<div class="input-group-btn">
|
||||||
<button type="submit" class="btn btn-sm btn-primary">Filter Servers</button>
|
<button type="submit" class="btn btn-sm btn-primary">Filter Servers</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -64,8 +64,8 @@
|
||||||
<span class="label label-danger">Pending Deletion</span>
|
<span class="label label-danger">Pending Deletion</span>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td><a href="/admin/users/view/{{ $server->owner }}">{{ $server->a_ownerEmail }}</a></td>
|
<td><a href="/admin/users/view/{{ $server->user->id }}">{{ $server->user->email }}</a></td>
|
||||||
<td><a href="/admin/nodes/view/{{ $server->node }}">{{ $server->a_nodeName }}</a></td>
|
<td><a href="/admin/nodes/view/{{ $server->node->id }}">{{ $server->node->name }}</a></td>
|
||||||
<td class="hidden-xs"><code>{{ $server->username }}</code></td>
|
<td class="hidden-xs"><code>{{ $server->username }}</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
<div class="form-group col-md-6">
|
<div class="form-group col-md-6">
|
||||||
<label for="location" class="control-label">Server Location</label>
|
<label for="location" class="control-label">Server Location</label>
|
||||||
<div>
|
<div>
|
||||||
<select name="location" id="getLocation" class="form-control">
|
<select name="location_id" id="getLocation" class="form-control">
|
||||||
<option disabled selected> -- Select a Location</option>
|
<option disabled selected> -- Select a Location</option>
|
||||||
@foreach($locations as $location)
|
@foreach($locations as $location)
|
||||||
<option value="{{ $location->id }}">{{ $location->long }} ({{ $location->short }})</option>
|
<option value="{{ $location->id }}">{{ $location->long }} ({{ $location->short }})</option>
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
<div class="form-group col-md-6 hidden" id="allocationNode">
|
<div class="form-group col-md-6 hidden" id="allocationNode">
|
||||||
<label for="node" class="control-label">Server Node</label>
|
<label for="node" class="control-label">Server Node</label>
|
||||||
<div>
|
<div>
|
||||||
<select name="node" id="getNode" class="form-control">
|
<select name="node_id" id="getNode" class="form-control">
|
||||||
<option disabled selected> -- Select a Node</option>
|
<option disabled selected> -- Select a Node</option>
|
||||||
</select>
|
</select>
|
||||||
<p class="text-muted"><small>The node which this server will be deployed to.</small></p>
|
<p class="text-muted"><small>The node which this server will be deployed to.</small></p>
|
||||||
|
@ -181,9 +181,9 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="ajax_loading_box" style="display:none;"><i class="fa fa-refresh fa-spin ajax_loading_position"></i></div>
|
<div class="ajax_loading_box" style="display:none;"><i class="fa fa-refresh fa-spin ajax_loading_position"></i></div>
|
||||||
<div class="form-group col-md-12">
|
<div class="form-group col-md-12">
|
||||||
<label for="service" class="control-label">Service Type</label>
|
<label for="service_id" class="control-label">Service Type</label>
|
||||||
<div>
|
<div>
|
||||||
<select name="service" id="getService" class="form-control">
|
<select name="service_id" id="getService" class="form-control">
|
||||||
<option disabled selected> -- Select a Service</option>
|
<option disabled selected> -- Select a Service</option>
|
||||||
@foreach($services as $service)
|
@foreach($services as $service)
|
||||||
<option value="{{ $service->id }}">{{ $service->name }}</option>
|
<option value="{{ $service->id }}">{{ $service->name }}</option>
|
||||||
|
@ -193,18 +193,18 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-12 hidden">
|
<div class="form-group col-md-12 hidden">
|
||||||
<label for="option" class="control-label">Service Option</label>
|
<label for="option_id" class="control-label">Service Option</label>
|
||||||
<div>
|
<div>
|
||||||
<select name="option" id="getOption" class="form-control">
|
<select name="option_id" id="getOption" class="form-control">
|
||||||
<option disabled selected> -- Select a Service Option</option>
|
<option disabled selected> -- Select a Service Option</option>
|
||||||
</select>
|
</select>
|
||||||
<p class="text-muted"><small>Select the type of service that this server will be running.</small></p>
|
<p class="text-muted"><small>Select the type of service that this server will be running.</small></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-12 hidden">
|
<div class="form-group col-md-12 hidden">
|
||||||
<label for="option" class="control-label">Service Pack</label>
|
<label for="pack_id" class="control-label">Service Pack</label>
|
||||||
<div>
|
<div>
|
||||||
<select name="pack" id="getPack" class="form-control">
|
<select name="pack_id" id="getPack" class="form-control">
|
||||||
<option disabled selected> -- Select a Service Pack</option>
|
<option disabled selected> -- Select a Service Pack</option>
|
||||||
</select>
|
</select>
|
||||||
<p class="text-muted"><small>Select the service pack that should be used for this server. This option can be changed later.</small></p>
|
<p class="text-muted"><small>Select the service pack that should be used for this server. This option can be changed later.</small></p>
|
||||||
|
@ -230,7 +230,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="well" id="serviceOptions" style="display:none;">
|
<div class="well" id="ServiceOption" style="display:none;">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="form-group col-md-12">
|
<div class="form-group col-md-12">
|
||||||
<h3 class="nopad">Service Setup & Options</h3>
|
<h3 class="nopad">Service Setup & Options</h3>
|
||||||
|
@ -248,7 +248,7 @@
|
||||||
<div class="alert alert-info">Some service options have additional environment variables that you can define for a given instance. They will show up below when you select a service option. If none show up, chances are that none were defined, and there is nothing to worry about.</div>
|
<div class="alert alert-info">Some service options have additional environment variables that you can define for a given instance. They will show up below when you select a service option. If none show up, chances are that none were defined, and there is nothing to worry about.</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" id="serverVariables"></div>
|
<div class="row" id="ServerVariable"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="well">
|
<div class="well">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -399,7 +399,7 @@ $(document).ready(function () {
|
||||||
|
|
||||||
currentService = $('#getService').val();
|
currentService = $('#getService').val();
|
||||||
handleLoader('#load_services', true);
|
handleLoader('#load_services', true);
|
||||||
$('#serviceOptions').slideUp();
|
$('#ServiceOption').slideUp();
|
||||||
$('#getOption').html('<option disabled selected> -- Select a Service Option</option>');
|
$('#getOption').html('<option disabled selected> -- Select a Service Option</option>');
|
||||||
$('#getPack').html('<option disabled selected> -- Select a Service Pack</option>');
|
$('#getPack').html('<option disabled selected> -- Select a Service Pack</option>');
|
||||||
|
|
||||||
|
@ -430,8 +430,8 @@ $(document).ready(function () {
|
||||||
$('#getOption').on('change', function (event) {
|
$('#getOption').on('change', function (event) {
|
||||||
|
|
||||||
handleLoader('#load_services', true);
|
handleLoader('#load_services', true);
|
||||||
handleLoader('#serviceOptions', true);
|
handleLoader('#ServiceOption', true);
|
||||||
$('#serverVariables').html('');
|
$('#ServerVariable').html('');
|
||||||
$('input[name="custom_image_name"]').val($(this).find(':selected').data('image'));
|
$('input[name="custom_image_name"]').val($(this).find(':selected').data('image'));
|
||||||
$('#getPack').html('<option disabled selected> -- Select a Service Pack</option>');
|
$('#getPack').html('<option disabled selected> -- Select a Service Pack</option>');
|
||||||
|
|
||||||
|
@ -466,14 +466,14 @@ $(document).ready(function () {
|
||||||
</div>\
|
</div>\
|
||||||
</div>\
|
</div>\
|
||||||
';
|
';
|
||||||
$('#serverVariables').append(dataAppend);
|
$('#ServerVariable').append(dataAppend);
|
||||||
});
|
});
|
||||||
$('#serviceOptions').slideDown();
|
$('#ServiceOption').slideDown();
|
||||||
}).fail(function (jqXHR) {
|
}).fail(function (jqXHR) {
|
||||||
console.error(jqXHR);
|
console.error(jqXHR);
|
||||||
}).always(function () {
|
}).always(function () {
|
||||||
handleLoader('#load_services');
|
handleLoader('#load_services');
|
||||||
handleLoader('#serviceOptions');
|
handleLoader('#ServiceOption');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -89,19 +89,19 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Owner</td>
|
<td>Owner</td>
|
||||||
<td><a href="{{ route('admin.users.view', $server->owner) }}">{{ $server->a_ownerEmail }}</a></td>
|
<td><a href="{{ route('admin.users.view', $server->owner_id) }}">{{ $server->user->email }}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Location</td>
|
<td>Location</td>
|
||||||
<td><a href="{{ route('admin.locations') }}">{{ $node->a_locationName }}</a></td>
|
<td><a href="{{ route('admin.locations') }}">{{ $server->node->location->short }}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Node</td>
|
<td>Node</td>
|
||||||
<td><a href="{{ route('admin.nodes.view', $server->node) }}">{{ $node->name }}</a></td>
|
<td><a href="{{ route('admin.nodes.view', $server->node_id) }}">{{ $server->node->name }}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Service</td>
|
<td>Service</td>
|
||||||
<td>{{ $server->a_serviceName }} :: {{ $server->a_servceOptionName }}</td>
|
<td>{{ $server->option->service->name }} :: {{ $server->option->name }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Name</td>
|
<td>Name</td>
|
||||||
|
@ -129,13 +129,13 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Default Connection</td>
|
<td>Default Connection</td>
|
||||||
<td><code>{{ $server->ip }}:{{ $server->port }}</code></td>
|
<td><code>{{ $server->allocation->ip }}:{{ $server->allocation->port }}</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Connection Alias</td>
|
<td>Connection Alias</td>
|
||||||
<td>
|
<td>
|
||||||
@if(!is_null($server->ip_alias))
|
@if($server->allocation->alias !== $server->allocation->ip)
|
||||||
<code>{{ $server->ip_alias }}:{{ $server->port }}</code>
|
<code>{{ $server->allocation->alias }}:{{ $server->allocation->port }}</code>
|
||||||
@else
|
@else
|
||||||
<span class="label label-default">No Alias Assigned</span>
|
<span class="label label-default">No Alias Assigned</span>
|
||||||
@endif
|
@endif
|
||||||
|
@ -170,7 +170,7 @@
|
||||||
<div class="form-group {{ $errors->has('owner') ? 'has-error' : '' }}">
|
<div class="form-group {{ $errors->has('owner') ? 'has-error' : '' }}">
|
||||||
<label for="name" class="control-label">Server Owner</label>
|
<label for="name" class="control-label">Server Owner</label>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" name="owner" value="{{ old('owner', $server->a_ownerEmail) }}" class="form-control" />
|
<input type="text" name="owner" value="{{ old('owner', $server->user->email) }}" class="form-control" />
|
||||||
<p class="text-muted"><small>You can change the owner of this server by changing this field to an email matching another use on this system. If you do this a new daemon security token will be generated automatically.</small></p>
|
<p class="text-muted"><small>You can change the owner of this server by changing this field to an email matching another use on this system. If you do this a new daemon security token will be generated automatically.</small></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -278,9 +278,15 @@
|
||||||
@foreach ($assigned as $assignment)
|
@foreach ($assigned as $assignment)
|
||||||
<div class="input-group" style="margin:5px auto;">
|
<div class="input-group" style="margin:5px auto;">
|
||||||
<span class="input-group-addon">
|
<span class="input-group-addon">
|
||||||
<input type="radio" @if($assignment->ip == $server->ip && $assignment->port == $server->port) checked="checked" @endif name="default" value="{{ $assignment->ip }}:{{ $assignment->port }}"/>
|
<input type="radio"
|
||||||
|
@if($assignment->id === $server->allocation_id) checked="checked" @endif
|
||||||
|
name="default" value="{{ $assignment->ip }}:{{ $assignment->port }}"/>
|
||||||
</span>
|
</span>
|
||||||
<input type="text" class="form-control" value="@if(!is_null($assignment->ip_alias)){{ $assignment->ip_alias }}@else{{ $assignment->ip }}@endif:{{ $assignment->port }} @if(!is_null($assignment->ip_alias))(alias of {{ $assignment->ip }})@endif" readonly />
|
<input type="text" class="form-control" value="{{ $assignment->alias }}:{{ $assignment->port }}"
|
||||||
|
@if($assignment->has_alias)
|
||||||
|
data-toggle="tooltip" data-placement="left" title="{{ $assignment->ip }}:{{ $assignment->port }}"
|
||||||
|
@endif
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
|
@ -291,7 +297,7 @@
|
||||||
<div>
|
<div>
|
||||||
<select name="add_additional[]" class="form-control" multiple>
|
<select name="add_additional[]" class="form-control" multiple>
|
||||||
@foreach ($unassigned as $assignment)
|
@foreach ($unassigned as $assignment)
|
||||||
<option value="{{ $assignment->ip }}:{{ $assignment->port }}">@if(!is_null($assignment->ip_alias)){{ $assignment->ip_alias }}@else{{ $assignment->ip }}@endif:{{ $assignment->port }} @if(!is_null($assignment->ip_alias))(alias of {{ $assignment->ip }})@endif</option>
|
<option value="{{ $assignment->ip }}:{{ $assignment->port }}">{{ $assignment->alias }}:{{ $assignment->port }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
@ -304,7 +310,7 @@
|
||||||
<div>
|
<div>
|
||||||
<select name="remove_additional[]" class="form-control" multiple>
|
<select name="remove_additional[]" class="form-control" multiple>
|
||||||
@foreach ($assigned as $assignment)
|
@foreach ($assigned as $assignment)
|
||||||
<option value="{{ $assignment->ip }}:{{ $assignment->port }}" @if($server->allocation === $assignment->id)disabled @endif>@if(!is_null($assignment->ip_alias)){{ $assignment->ip_alias }}@else{{ $assignment->ip }}@endif:{{ $assignment->port }} @if(!is_null($assignment->ip_alias))(alias of {{ $assignment->ip }})@endif</option>
|
<option value="{{ $assignment->ip }}:{{ $assignment->port }}" @if($server->allocation_id === $assignment->id)disabled @endif>{{ $assignment->alias }}:{{ $assignment->port }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
@ -333,7 +339,7 @@
|
||||||
<div class="alert alert-info">Changing any of the values below will require a restart for them to take effect.</div>
|
<div class="alert alert-info">Changing any of the values below will require a restart for them to take effect.</div>
|
||||||
<label class="control-label">Server Startup Command</label>
|
<label class="control-label">Server Startup Command</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-addon">{{ $server->a_serviceExecutable }}</span>
|
<span class="input-group-addon">{{ $server->option->display_executable }}</span>
|
||||||
<input type="text" class="form-control" name="startup" value="{{ old('startup', $server->startup) }}" />
|
<input type="text" class="form-control" name="startup" value="{{ old('startup', $server->startup) }}" />
|
||||||
</div>
|
</div>
|
||||||
<p class="text-muted"><small>The following data replacers are avaliable for the startup command: <code>@{{SERVER_MEMORY}}</code>, <code>@{{SERVER_IP}}</code>, and <code>@{{SERVER_PORT}}</code>. They will be replaced with the allocated memory, server ip, and server port respectively.</small></p>
|
<p class="text-muted"><small>The following data replacers are avaliable for the startup command: <code>@{{SERVER_MEMORY}}</code>, <code>@{{SERVER_IP}}</code>, and <code>@{{SERVER_PORT}}</code>. They will be replaced with the allocated memory, server ip, and server port respectively.</small></p>
|
||||||
|
@ -343,18 +349,18 @@
|
||||||
<div class="panel-heading" style="border-top: 1px solid #ddd;"></div>
|
<div class="panel-heading" style="border-top: 1px solid #ddd;"></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@foreach($startup as $item)
|
@foreach($server->option->variables as $variable)
|
||||||
<div class="form-group col-md-6">
|
<div class="form-group col-md-6">
|
||||||
<label class="control-label">
|
<label class="control-label">
|
||||||
@if($item->required === 1)<span class="label label-primary">Required</span> @endif
|
@if($variable->required)<span class="label label-primary">Required</span> @endif
|
||||||
@if($item->user_viewable === 0)<span data-toggle="tooltip" data-placement="top" title="Not Visible to Users" class="label label-danger"><i class="fa fa-eye-slash"></i></span> @endif
|
@if(! $variable->user_viewable)<span data-toggle="tooltip" data-placement="top" title="Not Visible to Users" class="label label-danger"><i class="fa fa-eye-slash"></i></span> @endif
|
||||||
@if($item->user_editable === 0)<span data-toggle="tooltip" data-placement="top" title="Not Editable by Users" class="label label-danger"><i class="fa fa-edit"></i></span> @endif
|
@if(! $variable->user_editable)<span data-toggle="tooltip" data-placement="top" title="Not Editable by Users" class="label label-danger"><i class="fa fa-edit"></i></span> @endif
|
||||||
{{ $item->name }}
|
{{ $variable->name }}
|
||||||
</label>
|
</label>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" name="{{ $item->env_variable }}" class="form-control" value="{{ old($item->env_variable, $item->a_serverValue) }}" data-action="matchRegex" data-regex="{{ $item->regex }}" />
|
<input type="text" name="{{ $variable->env_variable }}" class="form-control" value="{{ old($variable->env_variable, (! $variable->server_value) ? $variable->default_value : $variable->server_value) }}" data-action="matchRegex" data-regex="{{ $variable->regex }}" />
|
||||||
</div>
|
</div>
|
||||||
<p class="text-muted"><small>{!! $item->description !!}<br />Regex: <code>{{ $item->regex }}</code><br />Access as: <code>{{{{$item->env_variable}}}}</code></small></p>
|
<p class="text-muted"><small>{!! $variable->description !!}<br />Regex: <code>{{ $variable->regex }}</code><br />Access as: <code>{{{{ $variable->env_variable }}}}</code></small></p>
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
|
@ -398,7 +404,7 @@
|
||||||
<label class="control-label">Database Server:</label>
|
<label class="control-label">Database Server:</label>
|
||||||
<select name="db_server" class="form-control">
|
<select name="db_server" class="form-control">
|
||||||
@foreach($db_servers as $dbs)
|
@foreach($db_servers as $dbs)
|
||||||
<option value="{{ $dbs->id }}" @if($dbs->linked_node === $server->node)selected="selected"@endif>{{ $dbs->name }} ({{ $dbs->host }}:{{ $dbs->port }})</option>
|
<option value="{{ $dbs->id }}" @if($dbs->linked_node === $server->node_id)selected="selected"@endif>{{ $dbs->name }} ({{ $dbs->host }}:{{ $dbs->port }})</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
@ -412,7 +418,7 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@if(count($databases) > 0)
|
@if(count($server->databases) > 0)
|
||||||
<div class="panel-heading" style="border-top: 1px solid #ddd;"></div>
|
<div class="panel-heading" style="border-top: 1px solid #ddd;"></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<table class="table table-bordered table-hover">
|
<table class="table table-bordered table-hover">
|
||||||
|
@ -426,12 +432,12 @@
|
||||||
</th>
|
</th>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach($databases as $database)
|
@foreach($server->databases as $database)
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ $database->database }}</td>
|
<td>{{ $database->database }}</td>
|
||||||
<td>{{ $database->username }} ({{ $database->remote }})</td>
|
<td>{{ $database->username }} ({{ $database->remote }})</td>
|
||||||
<td><code>{{ Crypt::decrypt($database->password) }}</code> <a href="#" data-action="reset-database-password" data-id="{{ $database->id }}"><i class="fa fa-refresh pull-right"></i></a></td>
|
<td><code>{{ Crypt::decrypt($database->password) }}</code> <a href="#" data-action="reset-database-password" data-id="{{ $database->id }}"><i class="fa fa-refresh pull-right"></i></a></td>
|
||||||
<td><code>{{ $database->a_host }}:{{ $database->a_port }}</code></td>
|
<td><code>{{ $database->host->host }}:{{ $database->host->port }}</code></td>
|
||||||
<td class="text-center"><a href="#delete" data-action="delete_database" data-database="{{ $database->id }}" class="text-danger"><i class="fa fa-trash-o"></i></a></td>
|
<td class="text-center"><a href="#delete" data-action="delete_database" data-database="{{ $database->id }}" class="text-danger"><i class="fa fa-trash-o"></i></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
@ -568,7 +574,7 @@ $(document).ready(function () {
|
||||||
'X-Access-Token': '{{ $server->daemonSecret }}',
|
'X-Access-Token': '{{ $server->daemonSecret }}',
|
||||||
'X-Access-Server': '{{ $server->uuid }}'
|
'X-Access-Server': '{{ $server->uuid }}'
|
||||||
},
|
},
|
||||||
url: '{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}/server',
|
url: '{{ $server->node->scheme }}://{{ $server->node->fqdn }}:{{ $server->node->daemonListen }}/server',
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
}).done(function (data) {
|
}).done(function (data) {
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{{ route('admin.services.service', $service->id) }}">{{ $service->name }}</a></td>
|
<td><a href="{{ route('admin.services.service', $service->id) }}">{{ $service->name }}</a></td>
|
||||||
<td>{!! $service->description !!}</td>
|
<td>{!! $service->description !!}</td>
|
||||||
<td class="text-center">{{ $service->c_servers }}</td>
|
<td class="text-center">{{ $service->servers_count }}</td>
|
||||||
<td class="text-center align-middle"><a href="{{ route('admin.services.service.config', $service->id) }}"><button class="btn btn-xxs btn-primary"><i class="fa fa-wrench"></i> Configure</button></a></td>
|
<td class="text-center align-middle"><a href="{{ route('admin.services.service.config', $service->id) }}"><button class="btn btn-xxs btn-primary"><i class="fa fa-wrench"></i> Configure</button></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
|
@ -28,12 +28,12 @@
|
||||||
<ul class="breadcrumb">
|
<ul class="breadcrumb">
|
||||||
<li><a href="/admin">Admin Control</a></li>
|
<li><a href="/admin">Admin Control</a></li>
|
||||||
<li><a href="/admin/services">Services</a></li>
|
<li><a href="/admin/services">Services</a></li>
|
||||||
<li><a href="{{ route('admin.services.service', $service->id) }}">{{ $service->name }}</a></li>
|
<li><a href="{{ route('admin.services.service', $option->service->id) }}">{{ $option->service->name }}</a></li>
|
||||||
<li><a href="{{ route('admin.services.option', [$service->id, $option->id]) }}">{{ $option->name }}</a></li>
|
<li><a href="{{ route('admin.services.option', [$option->service->id, $option->id]) }}">{{ $option->name }}</a></li>
|
||||||
<li class="active">New Variable</li>
|
<li class="active">New Variable</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3>New Option Variable</h3><hr />
|
<h3>New Option Variable</h3><hr />
|
||||||
<form action="{{ route('admin.services.option.variable.new', [$service->id, $option->id]) }}" method="POST">
|
<form action="{{ route('admin.services.option.variable.new', [$option->service->id, $option->id]) }}" method="POST">
|
||||||
<div class="well">
|
<div class="well">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12 form-group">
|
<div class="col-md-12 form-group">
|
||||||
|
|
|
@ -28,12 +28,12 @@
|
||||||
<ul class="breadcrumb">
|
<ul class="breadcrumb">
|
||||||
<li><a href="/admin">Admin Control</a></li>
|
<li><a href="/admin">Admin Control</a></li>
|
||||||
<li><a href="/admin/services">Services</a></li>
|
<li><a href="/admin/services">Services</a></li>
|
||||||
<li><a href="{{ route('admin.services.service', $service->id) }}">{{ $service->name }}</a></li>
|
<li><a href="{{ route('admin.services.service', $option->service->id) }}">{{ $option->service->name }}</a></li>
|
||||||
<li class="active">{{ $option->name }}</li>
|
<li class="active">{{ $option->name }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="alert alert-warning"><strong>Warning!</strong> This page contains advanced settings that the panel and daemon use to control servers. Modifying information on this page is not recommended unless you are absolutely sure of what you are doing.</div>
|
<div class="alert alert-warning"><strong>Warning!</strong> This page contains advanced settings that the panel and daemon use to control servers. Modifying information on this page is not recommended unless you are absolutely sure of what you are doing.</div>
|
||||||
<h3>Settings</h3><hr />
|
<h3>Settings</h3><hr />
|
||||||
<form action="{{ route('admin.services.option', [$service->id, $option->id]) }}" method="POST">
|
<form action="{{ route('admin.services.option', [$option->service->id, $option->id]) }}" method="POST">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6 form-group">
|
<div class="col-md-6 form-group">
|
||||||
<label class="control-label">Name:</label>
|
<label class="control-label">Name:</label>
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
<div class="col-md-12 form-group">
|
<div class="col-md-12 form-group">
|
||||||
<label class="control-label">Default Startup Command:</label>
|
<label class="control-label">Default Startup Command:</label>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" name="startup" value="{{ old('startup', $option->startup) }}" class="form-control" />
|
<input type="text" name="startup" value="{{ old('startup', $option->startup) }}" placeholder="{{ $option->service->startup }}" class="form-control" />
|
||||||
<p class="text-muted"><small>To use the default startup of the parent service simply leave this field blank.</small></p>
|
<p class="text-muted"><small>To use the default startup of the parent service simply leave this field blank.</small></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -88,9 +88,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<h3>Variables <small><a href="{{ route('admin.services.option.variable.new', [$service->id, $option->id]) }}"><i class="fa fa-plus"></i></a></small></h3><hr />
|
<h3>Variables <small><a href="{{ route('admin.services.option.variable.new', [$option->service->id, $option->id]) }}"><i class="fa fa-plus"></i></a></small></h3><hr />
|
||||||
@foreach($variables as $variable)
|
@foreach($option->variables as $variable)
|
||||||
<form action="{{ route('admin.services.option.variable', [$service->id, $option->id, $variable->id]) }}" method="POST">
|
<form action="{{ route('admin.services.option.variable', [$option->service->id, $option->id, $variable->id]) }}" method="POST">
|
||||||
<div class="well">
|
<div class="well">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6 form-group">
|
<div class="col-md-6 form-group">
|
||||||
|
@ -158,7 +158,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
{!! csrf_field() !!}
|
{!! csrf_field() !!}
|
||||||
<a href="{{ route('admin.services.option.variable.delete', [$service->id, $option->id, $variable->id]) }}"><button type="button" class="btn btn-sm btn-danger pull-right"><i class="fa fa-times"></i></button></a>
|
<a href="{{ route('admin.services.option.variable.delete', [$option->service->id, $option->id, $variable->id]) }}"><button type="button" class="btn btn-sm btn-danger pull-right"><i class="fa fa-times"></i></button></a>
|
||||||
<input type="submit" class="btn btn-sm btn-success" value="Update Variable" />
|
<input type="submit" class="btn btn-sm btn-success" value="Update Variable" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -175,16 +175,19 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach ($servers as $server)
|
@foreach ($option->servers as $server)
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{{ route('admin.servers.view', $server->id) }}">{{ $server->name }}</a></td>
|
<td><a href="{{ route('admin.servers.view', $server->id) }}">{{ $server->name }}</a></td>
|
||||||
<td><a href="{{ route('admin.users.view', $server->owner) }}">{{ $server->a_ownerEmail }}</a></td>
|
<td><a href="{{ route('admin.users.view', $server->owner_id) }}">{{ $server->user->email }}</a></td>
|
||||||
<td>{{ $server->updated_at }}</td>
|
<td>{{ $server->updated_at }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<form action="{{ route('admin.services.option', [$service->id, $option->id]) }}" method="POST">
|
<div class="text-center">
|
||||||
|
{!! $option->servers->render() !!}
|
||||||
|
</div>
|
||||||
|
<form action="{{ route('admin.services.option', [$option->service->id, $option->id]) }}" method="POST">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div class="alert alert-danger">
|
<div class="alert alert-danger">
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
<li><a href="/admin">Admin Control</a></li>
|
<li><a href="/admin">Admin Control</a></li>
|
||||||
<li><a href="/admin/services">Services</a></li>
|
<li><a href="/admin/services">Services</a></li>
|
||||||
<li><a href="{{ route('admin.services.packs') }}">Packs</a></li>
|
<li><a href="{{ route('admin.services.packs') }}">Packs</a></li>
|
||||||
<li><a href="{{ route('admin.services.packs.service', $service->id) }}">{{ $service->name }}</a></li>
|
<li><a href="{{ route('admin.services.packs.service', $option->service->id) }}">{{ $option->service->name }}</a></li>
|
||||||
<li class="active">{{ $option->name }}</li>
|
<li class="active">{{ $option->name }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3 class="nopad">Service Packs</h3><hr />
|
<h3 class="nopad">Service Packs</h3><hr />
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach ($packs as $pack)
|
@foreach ($option->packs as $pack)
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{{ route('admin.services.packs.edit', $pack->id) }}">{{ $pack->name }}</a></td>
|
<td><a href="{{ route('admin.services.packs.edit', $pack->id) }}">{{ $pack->name }}</a></td>
|
||||||
<td><code>{{ $pack->version }}</code></td>
|
<td><code>{{ $pack->version }}</code></td>
|
||||||
|
|
|
@ -40,10 +40,10 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach ($options as $option)
|
@foreach ($service->options as $option)
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{{ route('admin.services.packs.option', $option->id) }}">{{ $option->name }}</a></td>
|
<td><a href="{{ route('admin.services.packs.option', $option->id) }}">{{ $option->name }}</a></td>
|
||||||
<td>{{ $option->p_count }}</td>
|
<td>{{ $option->packs->count() }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
<li><a href="/admin">Admin Control</a></li>
|
<li><a href="/admin">Admin Control</a></li>
|
||||||
<li><a href="/admin/services">Services</a></li>
|
<li><a href="/admin/services">Services</a></li>
|
||||||
<li><a href="{{ route('admin.services.packs') }}">Packs</a></li>
|
<li><a href="{{ route('admin.services.packs') }}">Packs</a></li>
|
||||||
<li><a href="{{ route('admin.services.packs.service', $service->id) }}">{{ $service->name }}</a></li>
|
<li><a href="{{ route('admin.services.packs.service', $pack->option->service->id) }}">{{ $pack->option->service->name }}</a></li>
|
||||||
<li><a href="{{ route('admin.services.packs.option', $option->id) }}">{{ $option->name }}</a></li>
|
<li><a href="{{ route('admin.services.packs.option', $pack->option->id) }}">{{ $pack->option->name }}</a></li>
|
||||||
<li class="active">{{ $pack->name }} ({{ $pack->version }})</li>
|
<li class="active">{{ $pack->name }} ({{ $pack->version }})</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3 class="nopad">Manage Service Pack</h3><hr />
|
<h3 class="nopad">Manage Service Pack</h3><hr />
|
||||||
|
@ -62,10 +62,10 @@
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label class="control-label">Associated Service Option:</label>
|
<label class="control-label">Associated Service Option:</label>
|
||||||
<select name="option" class="form-control">
|
<select name="option" class="form-control">
|
||||||
@foreach($services as $service => $options)
|
@foreach($services as $service)
|
||||||
<option disabled>{{ $service }}</option>
|
<option disabled>{{ $service->name }}</option>
|
||||||
@foreach($options as $option)
|
@foreach($service->options as $option)
|
||||||
<option value="{{ $option['id'] }}" @if($pack->option === (int) $option['id'])selected="selected"@endif> -- {{ $option['name'] }}</option>
|
<option value="{{ $option->id }}" @if($pack->option_id === $option->id)selected="selected"@endif> -- {{ $option->name }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -59,10 +59,10 @@
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label class="control-label">Associated Service Option:</label>
|
<label class="control-label">Associated Service Option:</label>
|
||||||
<select name="option" class="form-control">
|
<select name="option" class="form-control">
|
||||||
@foreach($services as $service => $options)
|
@foreach($services as $service)
|
||||||
<option disabled>{{ $service }}</option>
|
<option disabled>{{ $service->name }}</option>
|
||||||
@foreach($options as $option)
|
@foreach($service->options as $option)
|
||||||
<option value="{{ $option['id'] }}" @if((int) $packFor === (int) $option['id'])selected="selected"@endif> -- {{ $option['name'] }}</option>
|
<option value="{{ $option->id }}" @if((int) request()->option === $option->id)selected="selected"@endif> -- {{ $option->name }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<label class="control-label">Associated Service Option:</label>
|
<label class="control-label">Associated Service Option:</label>
|
||||||
<select name="option" class="form-control">
|
<select name="option" class="form-control">
|
||||||
@foreach($services as $service => $options)
|
@foreach($services as $service)
|
||||||
<option disabled>{{ $service }}</option>
|
<option disabled>{{ $service->name }}</option>
|
||||||
@foreach($options as $option)
|
@foreach($service->options as $option)
|
||||||
<option value="{{ $option['id'] }}" @if((int) $for === (int) $option['id'])selected="selected"@endif> -- {{ $option['name'] }}</option>
|
<option value="{{ $option->id }}" @if((int) request()->option === $option->id)selected="selected"@endif> -- {{ $option->name }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -41,12 +41,12 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach($options as $option)
|
@foreach($service->options as $option)
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{{ route('admin.services.option', [ $service->id, $option->id]) }}">{{ $option->name }}</a></td>
|
<td><a href="{{ route('admin.services.option', [ $service->id, $option->id]) }}">{{ $option->name }}</a></td>
|
||||||
<td>{!! $option->description !!}</td>
|
<td>{!! $option->description !!}</td>
|
||||||
<td><code>{{ $option->tag }}</code></td>
|
<td><code>{{ $option->tag }}</code></td>
|
||||||
<td class="text-center">{{ $option->c_servers }}</td>
|
<td class="text-center">{{ $option->servers->count() }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="email" class="control-label">{{ trans('strings.email') }}</label>
|
<label for="email" class="control-label">Email</label>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" name="email" value="{{ $user->email }}" class="form-control">
|
<input type="text" name="email" value="{{ $user->email }}" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
{!! csrf_field() !!}
|
{!! csrf_field() !!}
|
||||||
<input type="submit" value="{{ trans('base.account.update_user') }}" class="btn btn-primary btn-sm">
|
<input type="submit" value="Update User" class="btn btn-primary btn-sm">
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
@ -72,7 +72,7 @@
|
||||||
<div class="well" style="padding-bottom: 0;">
|
<div class="well" style="padding-bottom: 0;">
|
||||||
<div class="alert alert-success" style="display:none;margin-bottom:10px;" id="gen_pass"></div>
|
<div class="alert alert-success" style="display:none;margin-bottom:10px;" id="gen_pass"></div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="password" class="control-label">{{ trans('strings.password') }}</label>
|
<label for="password" class="control-label">Password</label>
|
||||||
<div>
|
<div>
|
||||||
<input type="password" id="password" name="password" class="form-control">
|
<input type="password" id="password" name="password" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="well" style="padding-bottom: 0;">
|
<div class="well" style="padding-bottom: 0;">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="root_admin" class="control-label">{{ trans('strings.root_administrator') }}</label>
|
<label for="root_admin" class="control-label">Administrator</label>
|
||||||
<div>
|
<div>
|
||||||
<select name="root_admin" class="form-control">
|
<select name="root_admin" class="form-control">
|
||||||
<option value="0">{{ trans('strings.no') }}</option>
|
<option value="0">{{ trans('strings.no') }}</option>
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<h3>Associated Servers</h3><hr>
|
<h3>Associated Servers</h3><hr>
|
||||||
@if($servers)
|
@if($user->servers)
|
||||||
<table class="table table-striped table-bordered table-hover">
|
<table class="table table-striped table-bordered table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -112,12 +112,12 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach($servers as $server)
|
@foreach($user->servers as $server)
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="/server/{{ $server->uuidShort }}/"><i class="fa fa-tachometer"></i></a></td>
|
<td><a href="/server/{{ $server->uuidShort }}/"><i class="fa fa-tachometer"></i></a></td>
|
||||||
<td><code>{{ $server->uuidShort }}</code></td>
|
<td><code>{{ $server->uuidShort }}</code></td>
|
||||||
<td><a href="/admin/servers/view/{{ $server->id }}">{{ $server->name }}</a></td>
|
<td><a href="/admin/servers/view/{{ $server->id }}">{{ $server->name }}</a></td>
|
||||||
<td>{{ $server->nodeName }}</td>
|
<td>{{ $server->node->name }}</td>
|
||||||
<td><code>{{ $server->username }}</code></td>
|
<td><code>{{ $server->username }}</code></td>
|
||||||
<td class="centered">@if($server->suspended === 0)<span class="label muted muted-hover label-success">Active</span>@else<span class="label label-warning">Suspended</span>@endif</td>
|
<td class="centered">@if($server->suspended === 0)<span class="label muted muted-hover label-success">Active</span>@else<span class="label label-warning">Suspended</span>@endif</td>
|
||||||
</td>
|
</td>
|
||||||
|
@ -127,7 +127,7 @@
|
||||||
@else
|
@else
|
||||||
<div class="alert alert-info">There are no servers associated with this account.</div>
|
<div class="alert alert-info">There are no servers associated with this account.</div>
|
||||||
@endif
|
@endif
|
||||||
<a href="/admin/servers/new?email={{ $user->email }}"><button type="button" class="btn btn-success btn-sm">{{ trans('server.index.add_new') }}</button></a>
|
<a href="/admin/servers/new?email={{ $user->email }}"><button type="button" class="btn btn-success btn-sm">Add New Server</button></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
Loading…
Reference in a new issue