Added startup management, cleaned up code.
Refactored entire startup repository code block to be more efficient and cleaner. Also includes modifications to front-end to make it match backend name and design.
This commit is contained in:
parent
d51ae5ec23
commit
349b36d38a
8 changed files with 252 additions and 146 deletions
|
@ -475,27 +475,34 @@ class ServersController extends Controller
|
|||
return redirect()->route('admin.servers.view.delete', $id);
|
||||
}
|
||||
|
||||
// //
|
||||
// public function postUpdateServerStartup(Request $request, $id)
|
||||
// {
|
||||
// try {
|
||||
// $server = new ServerRepository;
|
||||
// $server->updateStartup($id, $request->except([
|
||||
// '_token',
|
||||
// ]), true);
|
||||
// Alert::success('Server startup variables were successfully updated.')->flash();
|
||||
// } catch (\Pterodactyl\Exceptions\DisplayException $e) {
|
||||
// Alert::danger($e->getMessage())->flash();
|
||||
// } catch (\Exception $e) {
|
||||
// Log::error($e);
|
||||
// Alert::danger('An unhandled exception occured while attemping to update startup variables for this server. Please try again.')->flash();
|
||||
// } finally {
|
||||
// return redirect()->route('admin.servers.view', [
|
||||
// 'id' => $id,
|
||||
// 'tab' => 'tab_startup',
|
||||
// ])->withInput();
|
||||
// }
|
||||
// }
|
||||
/**
|
||||
* Update the startup command as well as variables.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Response\RedirectResponse
|
||||
*/
|
||||
public function saveStartup(Request $request, $id)
|
||||
{
|
||||
$repo = new ServerRepository;
|
||||
|
||||
try {
|
||||
$repo->updateStartup($id, $request->except('_token'), true);
|
||||
|
||||
Alert::success('Startup variables were successfully modified and assigned for this server.')->flash();
|
||||
} catch(DisplayException $ex) {
|
||||
Alert::danger($ex->getMessage())->flash();
|
||||
} catch (TransferException $ex) {
|
||||
Log::warning($ex);
|
||||
Alert::danger('A TransferException occurred while attempting to update the startup for this server, please ensure the daemon is running. This error has been logged.')->flash();
|
||||
} catch (\Exception $ex) {
|
||||
Log::error($ex);
|
||||
Alert::danger('An unhandled exception occured while attemping to update startup variables for this server. This error has been logged.')->flash();
|
||||
}
|
||||
|
||||
return redirect()->route('admin.servers.view.startup', $id);
|
||||
}
|
||||
|
||||
//
|
||||
// public function postDatabase(Request $request, $id)
|
||||
// {
|
||||
|
|
|
@ -309,9 +309,7 @@ class ServerController extends Controller
|
|||
|
||||
try {
|
||||
$repo = new ServerRepository;
|
||||
$repo->updateStartup($server->id, $request->except([
|
||||
'_token',
|
||||
]));
|
||||
$repo->updateStartup($server->id, $request->except('_token'));
|
||||
Alert::success('Server startup variables were successfully updated.')->flash();
|
||||
} catch (DisplayException $ex) {
|
||||
Alert::danger($ex->getMessage())->flash();
|
||||
|
|
|
@ -174,6 +174,10 @@ class AdminRoutes
|
|||
'uses' => 'Admin\ServersController@viewStartup',
|
||||
]);
|
||||
|
||||
$router->post('/view/{id}/startup', [
|
||||
'uses' => 'Admin\ServersController@saveStartup',
|
||||
]);
|
||||
|
||||
$router->get('/view/{id}/database', [
|
||||
'as' => 'admin.servers.view.database',
|
||||
'uses' => 'Admin\ServersController@viewDatabase',
|
||||
|
|
|
@ -617,109 +617,75 @@ class ServerRepository
|
|||
{
|
||||
$server = Models\Server::with('variables', 'option.variables')->findOrFail($id);
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
// Check the startup
|
||||
DB::transaction(function () use ($admin, $data, $server) {
|
||||
if (isset($data['startup']) && $admin) {
|
||||
$server->startup = $data['startup'];
|
||||
$server->save();
|
||||
}
|
||||
|
||||
// Check those Variables
|
||||
$server->option->variables->transform(function ($item, $key) use ($server) {
|
||||
$displayValue = $server->variables->where('variable_id', $item->id)->pluck('variable_value')->first();
|
||||
$item->server_value = (! is_null($displayValue)) ? $displayValue : $item->default_value;
|
||||
|
||||
return $item;
|
||||
});
|
||||
|
||||
$variableList = [];
|
||||
if ($server->option->variables) {
|
||||
foreach ($server->option->variables as &$variable) {
|
||||
// Move on if the new data wasn't even sent
|
||||
if (! isset($data[$variable->env_variable])) {
|
||||
$variableList[] = [
|
||||
'id' => $variable->id,
|
||||
'env' => $variable->env_variable,
|
||||
'val' => $variable->server_value,
|
||||
];
|
||||
foreach($server->option->variables as &$variable) {
|
||||
$set = isset($data['env_' . $variable->id]);
|
||||
|
||||
// Variable is required but was not passed into the function.
|
||||
if ($variable->required && ! $set) {
|
||||
throw new DisplayException('A required variable (' . $variable->env_variable . ') was not passed in the request.');
|
||||
}
|
||||
|
||||
// If user is not an admin and are trying to edit a non-editable field
|
||||
// or an invisible field just silently skip the variable.
|
||||
if (! $admin && (! $variable->user_editable || ! $variable->user_viewable)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Update Empty but skip validation
|
||||
if (empty($data[$variable->env_variable])) {
|
||||
$variableList[] = [
|
||||
'id' => $variable->id,
|
||||
'env' => $variable->env_variable,
|
||||
'val' => null,
|
||||
];
|
||||
continue;
|
||||
}
|
||||
|
||||
// Is the variable required?
|
||||
// @TODO: is this even logical to perform this check?
|
||||
if (isset($data[$variable->env_variable]) && empty($data[$variable->env_variable])) {
|
||||
if ($variable->required) {
|
||||
throw new DisplayException('A required service option variable field (' . $variable->env_variable . ') was included in this request but was left blank.');
|
||||
// Confirm value is valid when compared aganist regex.
|
||||
// @TODO: switch to Laravel validation rules.
|
||||
if ($set && ! is_null($variable->regex)) {
|
||||
if (! preg_match($variable->regex, $data['env_' . $variable->id])) {
|
||||
throw new DisplayException('The value passed for a variable (' . $variable->env_variable . ') could not be matched aganist the regex for that field (' . $variable->regex . ').');
|
||||
}
|
||||
}
|
||||
|
||||
// Variable hidden and/or not user editable
|
||||
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.');
|
||||
}
|
||||
|
||||
// Check aganist Regex Pattern
|
||||
if (! is_null($variable->regex) && ! preg_match($variable->regex, $data[$variable->env_variable])) {
|
||||
throw new DisplayException('Failed to validate service option variable field (' . $variable->env_variable . ') aganist regex (' . $variable->regex . ').');
|
||||
}
|
||||
|
||||
$variableList[] = [
|
||||
'id' => $variable->id,
|
||||
'env' => $variable->env_variable,
|
||||
'val' => $data[$variable->env_variable],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Add Variables
|
||||
$environmentVariables = [
|
||||
'STARTUP' => $server->startup,
|
||||
];
|
||||
foreach ($variableList as $item) {
|
||||
$environmentVariables[$item['env']] = $item['val'];
|
||||
|
||||
// Update model or make a new record if it doesn't exist.
|
||||
$model = Models\ServerVariable::firstOrNew([
|
||||
'variable_id' => $item['id'],
|
||||
$svar = Models\ServerVariable::firstOrNew([
|
||||
'server_id' => $server->id,
|
||||
'variable_id' => $variable->id,
|
||||
]);
|
||||
$model->variable_value = $item['val'];
|
||||
$model->save();
|
||||
|
||||
// Set the value; if one was not passed set it to the default value
|
||||
if ($set) {
|
||||
$svar->variable_value = $data['env_' . $variable->id];
|
||||
|
||||
// Not passed, check if this record exists if so keep value, otherwise set default
|
||||
} else {
|
||||
$svar->variable_value = ($svar->exists) ? $svar->variable_value : $variable->default_value;
|
||||
}
|
||||
|
||||
$svar->save();
|
||||
}
|
||||
}
|
||||
|
||||
// Reload Variables
|
||||
$server->load('variables');
|
||||
$environment = $server->option->variables->map(function ($item, $key) use ($server) {
|
||||
$display = $server->variables->where('variable_id', $item->id)->pluck('variable_value')->first();
|
||||
|
||||
return [
|
||||
'variable' => $item->env_variable,
|
||||
'value' => (! is_null($display)) ? $display : $item->default_value,
|
||||
];
|
||||
});
|
||||
|
||||
$server->node->guzzleClient([
|
||||
'X-Access-Server' => $server->uuid,
|
||||
'X-Access-Token' => $server->node->daemonSecret,
|
||||
])->request('PATCH', '/server', [
|
||||
'json' => [
|
||||
'build' => [
|
||||
'env|overwrite' => $environmentVariables,
|
||||
'env|overwrite' => $environment->pluck('value', 'variable')->merge(['STARTUP' => $server->startup]),
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
DB::commit();
|
||||
|
||||
return true;
|
||||
} catch (TransferException $ex) {
|
||||
DB::rollBack();
|
||||
throw new DisplayException('An error occured while attempting to update the server configuration.', $ex);
|
||||
} catch (\Exception $ex) {
|
||||
DB::rollBack();
|
||||
throw $ex;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function queueDeletion($id, $force = false)
|
||||
|
|
|
@ -233,6 +233,8 @@ return [
|
|||
'command' => 'Startup Command',
|
||||
'edit_params' => 'Edit Parameters',
|
||||
'update' => 'Update Startup Parameters',
|
||||
'startup_var' => 'Startup Command Variable',
|
||||
'startup_regex' => 'Verification Regex',
|
||||
],
|
||||
'sftp' => [
|
||||
'header' => 'SFTP Configuration',
|
||||
|
|
|
@ -63,4 +63,6 @@ return [
|
|||
'2fa' => '2FA',
|
||||
'logout' => 'Logout',
|
||||
'admin_cp' => 'Admin Control Panel',
|
||||
'optional' => 'Optional',
|
||||
'read_only' => 'Read Only',
|
||||
];
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
{{-- Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com> --}}
|
||||
|
||||
{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}}
|
||||
{{-- of this software and associated documentation files (the "Software"), to deal --}}
|
||||
{{-- in the Software without restriction, including without limitation the rights --}}
|
||||
{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}}
|
||||
{{-- copies of the Software, and to permit persons to whom the Software is --}}
|
||||
{{-- furnished to do so, subject to the following conditions: --}}
|
||||
|
||||
{{-- The above copyright notice and this permission notice shall be included in all --}}
|
||||
{{-- copies or substantial portions of the Software. --}}
|
||||
|
||||
{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}}
|
||||
{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}}
|
||||
{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}}
|
||||
{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}}
|
||||
{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}}
|
||||
{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}}
|
||||
{{-- SOFTWARE. --}}
|
||||
@extends('layouts.admin')
|
||||
|
||||
@section('title')
|
||||
Server — {{ $server->name }}: Startup
|
||||
@endsection
|
||||
|
||||
@section('content-header')
|
||||
<h1>{{ $server->name }}<small>Control startup command as well as variables.</small></h1>
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
||||
<li><a href="{{ route('admin.servers') }}">Servers</a></li>
|
||||
<li><a href="{{ route('admin.servers.view', $server->id) }}">{{ $server->name }}</a></li>
|
||||
<li class="active">Startup</li>
|
||||
</ol>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="nav-tabs-custom nav-tabs-floating">
|
||||
<ul class="nav nav-tabs">
|
||||
<li><a href="{{ route('admin.servers.view', $server->id) }}">About</a></li>
|
||||
@if(! $server->trashed() && $server->installed === 1)
|
||||
<li><a href="{{ route('admin.servers.view.details', $server->id) }}">Details</a></li>
|
||||
<li><a href="{{ route('admin.servers.view.build', $server->id) }}">Build Configuration</a></li>
|
||||
<li class="active"><a href="{{ route('admin.servers.view.startup', $server->id) }}">Startup</a></li>
|
||||
<li><a href="{{ route('admin.servers.view.database', $server->id) }}">Database</a></li>
|
||||
@endif
|
||||
@if(! $server->trashed())
|
||||
<li><a href="{{ route('admin.servers.view.manage', $server->id) }}">Manage</a></li>
|
||||
@endif
|
||||
<li class="tab-danger"><a href="{{ route('admin.servers.view.delete', $server->id) }}">Delete</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<form action="{{ route('admin.servers.view.startup', $server->id) }}" method="POST">
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Startup Command Modification</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<label for="pStartup" class="form-label">Startup Command</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon bg-gray">{{ $server->option->display_executable }}</span>
|
||||
<input id="pStartup" name="startup" class="form-control" type="text" value="{{ old('startup', $server->startup) }}" />
|
||||
</div>
|
||||
<p class="small text-muted">Edit your server's startup command here. The following variables are available by default: <code>@{{SERVER_MEMORY}}</code>, <code>@{{SERVER_IP}}</code>, and <code>@{{SERVER_PORT}}</code>.</p>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
{!! csrf_field() !!}
|
||||
<button type="submit" class="btn btn-primary btn-sm pull-right">Save Modifications</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@foreach($server->option->variables as $variable)
|
||||
<div class="col-xs-12 col-md-4 col-sm-6">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ $variable->name }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<input data-action="match-regex" data-regex="{{ $variable->regex }}" name="env_{{ $variable->id }}" class="form-control" type="text" value="{{ old('env_' . $variable->id, $variable->server_value) }}" />
|
||||
<p class="no-margin small text-muted">{{ $variable->description }}</p>
|
||||
<p class="no-margin">
|
||||
@if($variable->required)<span class="label label-danger">Required</span>@else<span class="label label-default">Optional</span>@endif
|
||||
@if($variable->user_viewable)<span class="label label-success">Visible</span>@else<span class="label label-primary">Hidden</span>@endif
|
||||
@if($variable->user_editable)<span class="label label-success">Editable</span>@else<span class="label label-primary">Locked</span>@endif
|
||||
</p>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<p class="no-margin text-muted small"><strong>Startup Command Variable:</strong> <code>{{ $variable->env_variable }}</code></p>
|
||||
<p class="no-margin text-muted small"><strong>Verification Regex:</strong> <code>{{ $variable->regex }}</code></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
|
||||
@section('footer-scripts')
|
||||
@parent
|
||||
<script>
|
||||
$('input[data-action="match-regex"]').on('keyup', function (event) {
|
||||
if (! $(this).data('regex')) return;
|
||||
|
||||
var input = $(this).val();
|
||||
var regex = new RegExp($(this).data('regex').replace(/^\/|\/$/g, ''));
|
||||
|
||||
$(this).parent().parent().removeClass('has-success has-error').addClass((! regex.test(input)) ? 'has-error' : 'has-success');
|
||||
});
|
||||
</script>
|
||||
@endsection
|
|
@ -35,7 +35,8 @@
|
|||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<form action="{{ route('server.settings.startup', $server->uuidShort) }}" method="POST">
|
||||
<div class="col-xs-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">@lang('server.config.startup.command')</h3>
|
||||
|
@ -46,53 +47,64 @@
|
|||
<input type="text" class="form-control" readonly="readonly" value="{{ $processedStartup }}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">@lang('server.config.startup.edit_params')</h3>
|
||||
</div>
|
||||
@can('edit-startup', $server)
|
||||
<form action="{{ route('server.settings.startup', $server->uuidShort) }}" method="POST">
|
||||
<div class="box-body">
|
||||
@foreach($variables as $item)
|
||||
<div class="form-group">
|
||||
<label class="control-label">
|
||||
@if($item->required === 1)<span class="label label-danger">@lang('strings.required')</span> @endif
|
||||
{{ $item->name }}
|
||||
</label>
|
||||
<div>
|
||||
<input type="text"
|
||||
@if($item->user_editable === 1)
|
||||
name="{{ $item->env_variable }}"
|
||||
@else
|
||||
readonly="readonly"
|
||||
@endif
|
||||
class="form-control" value="{{ old($item->env_variable, $item->a_serverValue) }}" data-action="matchRegex" data-regex="{{ $item->regex }}" />
|
||||
</div>
|
||||
<p class="text-muted"><small>{!! $item->description !!}</small></p>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
{!! csrf_field() !!}
|
||||
<input type="submit" class="btn btn-primary btn-sm" value="@lang('server.config.startup.update')" />
|
||||
</div>
|
||||
</form>
|
||||
@else
|
||||
<div class="box-body">
|
||||
<div class="callout callout-warning callout-nomargin">
|
||||
<p>@lang('auth.not_authorized')</p>
|
||||
</div>
|
||||
<input type="submit" class="btn btn-primary btn-sm pull-right" value="@lang('server.config.startup.update')" />
|
||||
</div>
|
||||
@endcan
|
||||
</div>
|
||||
</div>
|
||||
@can('edit-startup', $server)
|
||||
@foreach($variables as $variable)
|
||||
<div class="col-xs-12 col-md-4 col-sm-6">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ $variable->name }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<input data-action="match-regex" data-regex="{{ $variable->regex }}"
|
||||
@if($variable->user_editable)
|
||||
name="env_{{ $variable->id }}"
|
||||
@else
|
||||
readonly
|
||||
@endif
|
||||
class="form-control" type="text" value="{{ old('env_' . $variable->id, $variable->server_value) }}" />
|
||||
<p class="small text-muted">{{ $variable->description }}</p>
|
||||
<p class="no-margin">
|
||||
@if($variable->required && $variable->user_editable)
|
||||
<span class="label label-danger">@lang('strings.required')</span>
|
||||
@elseif(! $variable->required && $variable->user_editable)
|
||||
<span class="label label-default">@lang('strings.optional')</span>
|
||||
@endif
|
||||
@if(! $variable->user_editable)
|
||||
<span class="label label-warning">@lang('strings.read_only')</span>
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<p class="no-margin text-muted small"><strong>@lang('server.config.startup.startup_var'):</strong> <code>{{ $variable->env_variable }}</code></p>
|
||||
<p class="no-margin text-muted small"><strong>@lang('server.config.startup.startup_regex'):</strong> <code>{{ $variable->regex }}</code></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
@endcan
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('footer-scripts')
|
||||
@parent
|
||||
{!! Theme::js('js/frontend/server.socket.js') !!}
|
||||
<script>
|
||||
$('input[data-action="match-regex"]').on('keyup', function (event) {
|
||||
if (! $(this).data('regex')) return;
|
||||
|
||||
var input = $(this).val();
|
||||
var regex = new RegExp($(this).data('regex').replace(/^\/|\/$/g, ''));
|
||||
|
||||
$(this).parent().parent().removeClass('has-success has-error').addClass((! regex.test(input)) ? 'has-error' : 'has-success');
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
|
Loading…
Reference in a new issue