[L6] Move all of the template files into the new correct location
This commit is contained in:
parent
1c5b9dbb87
commit
c97461d602
83 changed files with 0 additions and 0 deletions
112
resources/views/admin/nodes/index.blade.php
Normal file
112
resources/views/admin/nodes/index.blade.php
Normal file
|
@ -0,0 +1,112 @@
|
|||
{{-- Pterodactyl - Panel --}}
|
||||
{{-- Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com> --}}
|
||||
|
||||
{{-- This software is licensed under the terms of the MIT license. --}}
|
||||
{{-- https://opensource.org/licenses/MIT --}}
|
||||
@extends('layouts.admin')
|
||||
|
||||
@section('title')
|
||||
List Nodes
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
@parent
|
||||
{!! Theme::css('vendor/fontawesome/animation.min.css') !!}
|
||||
@endsection
|
||||
|
||||
@section('content-header')
|
||||
<h1>Nodes<small>All nodes available on the system.</small></h1>
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
||||
<li class="active">Nodes</li>
|
||||
</ol>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Node List</h3>
|
||||
<div class="box-tools">
|
||||
<form action="{{ route('admin.nodes') }}" method="GET">
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" name="query" class="form-control pull-right" style="width:30%;" value="{{ request()->input('query') }}" placeholder="Search Nodes">
|
||||
<div class="input-group-btn">
|
||||
<button type="submit" class="btn btn-default"><i class="fa fa-search"></i></button>
|
||||
<a href="{{ route('admin.nodes.new') }}"><button type="button" class="btn btn-sm btn-primary" style="border-radius: 0 3px 3px 0;margin-left:-1px;">Create New</button></a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Name</th>
|
||||
<th>Location</th>
|
||||
<th>Memory</th>
|
||||
<th>Disk</th>
|
||||
<th class="text-center">Servers</th>
|
||||
<th class="text-center">SSL</th>
|
||||
<th class="text-center">Public</th>
|
||||
</tr>
|
||||
@foreach ($nodes as $node)
|
||||
<tr>
|
||||
<td class="text-center text-muted left-icon" data-action="ping" data-secret="{{ $node->daemonSecret }}" data-location="{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}/v1"><i class="fa fa-fw fa-refresh fa-spin"></i></td>
|
||||
<td>{!! $node->maintenance_mode ? '<span class="label label-warning"><i class="fa fa-wrench"></i></span> ' : '' !!}<a href="{{ route('admin.nodes.view', $node->id) }}">{{ $node->name }}</a></td>
|
||||
<td>{{ $node->location->short }}</td>
|
||||
<td>{{ $node->memory }} MB</td>
|
||||
<td>{{ $node->disk }} MB</td>
|
||||
<td class="text-center">{{ $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"><i class="fa fa-{{ ($node->public) ? 'eye' : 'eye-slash' }}"></i></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@if($nodes->hasPages())
|
||||
<div class="box-footer with-border">
|
||||
<div class="col-md-12 text-center">{!! $nodes->appends(['query' => Request::input('query')])->render() !!}</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('footer-scripts')
|
||||
@parent
|
||||
<script>
|
||||
(function pingNodes() {
|
||||
$('td[data-action="ping"]').each(function(i, element) {
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: $(element).data('location'),
|
||||
headers: {
|
||||
'X-Access-Token': $(element).data('secret'),
|
||||
},
|
||||
timeout: 5000
|
||||
}).done(function (data) {
|
||||
$(element).find('i').tooltip({
|
||||
title: 'v' + data.version,
|
||||
});
|
||||
$(element).removeClass('text-muted').find('i').removeClass().addClass('fa fa-fw fa-heartbeat faa-pulse animated').css('color', '#50af51');
|
||||
}).fail(function (error) {
|
||||
var errorText = 'Error connecting to node! Check browser console for details.';
|
||||
try {
|
||||
errorText = error.responseJSON.errors[0].detail || errorText;
|
||||
} catch (ex) {}
|
||||
|
||||
$(element).removeClass('text-muted').find('i').removeClass().addClass('fa fa-fw fa-heart-o').css('color', '#d9534f');
|
||||
$(element).find('i').tooltip({ title: errorText });
|
||||
});
|
||||
}).promise().done(function () {
|
||||
setTimeout(pingNodes, 10000);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
@endsection
|
180
resources/views/admin/nodes/new.blade.php
Normal file
180
resources/views/admin/nodes/new.blade.php
Normal file
|
@ -0,0 +1,180 @@
|
|||
{{-- Pterodactyl - Panel --}}
|
||||
{{-- Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com> --}}
|
||||
|
||||
{{-- This software is licensed under the terms of the MIT license. --}}
|
||||
{{-- https://opensource.org/licenses/MIT --}}
|
||||
@extends('layouts.admin')
|
||||
|
||||
@section('title')
|
||||
Nodes → New
|
||||
@endsection
|
||||
|
||||
@section('content-header')
|
||||
<h1>New Node<small>Create a new local or remote node for servers to be installed to.</small></h1>
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
||||
<li><a href="{{ route('admin.nodes') }}">Nodes</a></li>
|
||||
<li class="active">New</li>
|
||||
</ol>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<form action="{{ route('admin.nodes.new') }}" method="POST">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Basic Details</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label for="pName" class="form-label">Name</label>
|
||||
<input type="text" name="name" id="pName" class="form-control" value="{{ old('name') }}"/>
|
||||
<p class="text-muted small">Character limits: <code>a-zA-Z0-9_.-</code> and <code>[Space]</code> (min 1, max 100 characters).</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pDescription" class="form-label">Description</label>
|
||||
<textarea name="description" id="pDescription" rows="4" class="form-control">{{ old('description') }}</textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pLocationId" class="form-label">Location</label>
|
||||
<select name="location_id" id="pLocationId">
|
||||
@foreach($locations as $location)
|
||||
<option value="{{ $location->id }}" {{ $location->id != old('location_id') ?: 'selected' }}>{{ $location->short }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Node Visibility</label>
|
||||
<div>
|
||||
<div class="radio radio-success radio-inline">
|
||||
|
||||
<input type="radio" id="pPublicTrue" value="1" name="public" checked>
|
||||
<label for="pPublicTrue"> Public </label>
|
||||
</div>
|
||||
<div class="radio radio-danger radio-inline">
|
||||
<input type="radio" id="pPublicFalse" value="0" name="public">
|
||||
<label for="pPublicFalse"> Private </label>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-muted small">By setting a node to <code>private</code> you will be denying the ability to auto-deploy to this node.
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pFQDN" class="form-label">FQDN</label>
|
||||
<input type="text" name="fqdn" id="pFQDN" class="form-control" value="{{ old('fqdn') }}"/>
|
||||
<p class="text-muted small">Please enter domain name (e.g <code>node.example.com</code>) to be used for connecting to the daemon. An IP address may be used <em>only</em> if you are not using SSL for this node.</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Communicate Over SSL</label>
|
||||
<div>
|
||||
<div class="radio radio-success radio-inline">
|
||||
<input type="radio" id="pSSLTrue" value="https" name="scheme" checked>
|
||||
<label for="pSSLTrue"> Use SSL Connection</label>
|
||||
</div>
|
||||
<div class="radio radio-danger radio-inline">
|
||||
<input type="radio" id="pSSLFalse" value="http" name="scheme" @if(request()->isSecure()) disabled @endif>
|
||||
<label for="pSSLFalse"> Use HTTP Connection</label>
|
||||
</div>
|
||||
</div>
|
||||
@if(request()->isSecure())
|
||||
<p class="text-danger small">Your Panel is currently configured to use a secure connection. In order for browsers to connect to your node it <strong>must</strong> use a SSL connection.</p>
|
||||
@else
|
||||
<p class="text-muted small">In most cases you should select to use a SSL connection. If using an IP Address or you do not wish to use SSL at all, select a HTTP connection.</p>
|
||||
@endif
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Behind Proxy</label>
|
||||
<div>
|
||||
<div class="radio radio-success radio-inline">
|
||||
<input type="radio" id="pProxyFalse" value="0" name="behind_proxy" checked>
|
||||
<label for="pProxyFalse"> Not Behind Proxy </label>
|
||||
</div>
|
||||
<div class="radio radio-info radio-inline">
|
||||
<input type="radio" id="pProxyTrue" value="1" name="behind_proxy">
|
||||
<label for="pProxyTrue"> Behind Proxy </label>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-muted small">If you are running the daemon behind a proxy such as Cloudflare, select this to have the daemon skip looking for certificates on boot.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Configuration</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="form-group col-xs-12">
|
||||
<label for="pDaemonBase" class="form-label">Daemon Server File Directory</label>
|
||||
<input type="text" name="daemonBase" id="pDaemonBase" class="form-control" value="/srv/daemon-data" />
|
||||
<p class="text-muted small">Enter the directory where server files should be stored. <strong>If you use OVH you should check your partition scheme. You may need to use <code>/home/daemon-data</code> to have enough space.</strong></p>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label for="pMemory" class="form-label">Total Memory</label>
|
||||
<div class="input-group">
|
||||
<input type="text" name="memory" data-multiplicator="true" class="form-control" id="pMemory" value="{{ old('memory') }}"/>
|
||||
<span class="input-group-addon">MB</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label for="pMemoryOverallocate" class="form-label">Memory Over-Allocation</label>
|
||||
<div class="input-group">
|
||||
<input type="text" name="memory_overallocate" class="form-control" id="pMemoryOverallocate" value="{{ old('memory_overallocate') }}"/>
|
||||
<span class="input-group-addon">%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<p class="text-muted small">Enter the total amount of memory available for new servers. If you would like to allow overallocation of memory enter the percentage that you want to allow. To disable checking for overallocation enter <code>-1</code> into the field. Entering <code>0</code> will prevent creating new servers if it would put the node over the limit.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<label for="pDisk" class="form-label">Total Disk Space</label>
|
||||
<div class="input-group">
|
||||
<input type="text" name="disk" data-multiplicator="true" class="form-control" id="pDisk" value="{{ old('disk') }}"/>
|
||||
<span class="input-group-addon">MB</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label for="pDiskOverallocate" class="form-label">Disk Over-Allocation</label>
|
||||
<div class="input-group">
|
||||
<input type="text" name="disk_overallocate" class="form-control" id="pDiskOverallocate" value="{{ old('disk_overallocate') }}"/>
|
||||
<span class="input-group-addon">%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<p class="text-muted small">Enter the total amount of disk space available for new servers. If you would like to allow overallocation of disk space enter the percentage that you want to allow. To disable checking for overallocation enter <code>-1</code> into the field. Entering <code>0</code> will prevent creating new servers if it would put the node over the limit.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<label for="pDaemonListen" class="form-label">Daemon Port</label>
|
||||
<input type="text" name="daemonListen" class="form-control" id="pDaemonListen" value="8080" />
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label for="pDaemonSFTP" class="form-label">Daemon SFTP Port</label>
|
||||
<input type="text" name="daemonSFTP" class="form-control" id="pDaemonSFTP" value="2022" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<p class="text-muted small">The daemon runs its own SFTP management container and does not use the SSHd process on the main physical server. <Strong>Do not use the same port that you have assigned for your physical server's SSH process.</strong> If you will be running the daemon behind CloudFlare® you should set the daemon port to <code>8443</code> to allow websocket proxying over SSL.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
{!! csrf_field() !!}
|
||||
<button type="submit" class="btn btn-success pull-right">Create Node</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
|
||||
@section('footer-scripts')
|
||||
@parent
|
||||
<script>
|
||||
$('#pLocationId').select2();
|
||||
</script>
|
||||
@endsection
|
365
resources/views/admin/nodes/view/allocation.blade.php
Normal file
365
resources/views/admin/nodes/view/allocation.blade.php
Normal file
|
@ -0,0 +1,365 @@
|
|||
{{-- Pterodactyl - Panel --}}
|
||||
{{-- Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com> --}}
|
||||
|
||||
{{-- This software is licensed under the terms of the MIT license. --}}
|
||||
{{-- https://opensource.org/licenses/MIT --}}
|
||||
@extends('layouts.admin')
|
||||
|
||||
@section('title')
|
||||
{{ $node->name }}: Allocations
|
||||
@endsection
|
||||
|
||||
@section('content-header')
|
||||
<h1>{{ $node->name }}<small>Control allocations available for servers on this node.</small></h1>
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
||||
<li><a href="{{ route('admin.nodes') }}">Nodes</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view', $node->id) }}">{{ $node->name }}</a></li>
|
||||
<li class="active">Allocations</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.nodes.view', $node->id) }}">About</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view.settings', $node->id) }}">Settings</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view.configuration', $node->id) }}">Configuration</a></li>
|
||||
<li class="active"><a href="{{ route('admin.nodes.view.allocation', $node->id) }}">Allocation</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view.servers', $node->id) }}">Servers</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Existing Allocations</h3>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding" style="overflow-x: visible">
|
||||
<table class="table table-hover" style="margin-bottom:0;">
|
||||
<tr>
|
||||
<th>
|
||||
<input type="checkbox" class="select-all-files hidden-xs" data-action="selectAll">
|
||||
</th>
|
||||
<th>IP Address <i class="fa fa-fw fa-minus-square" style="font-weight:normal;color:#d9534f;cursor:pointer;" data-toggle="modal" data-target="#allocationModal"></i></th>
|
||||
<th>IP Alias</th>
|
||||
<th>Port</th>
|
||||
<th>Assigned To</th>
|
||||
<th>
|
||||
<div class="btn-group hidden-xs">
|
||||
<button type="button" id="mass_actions" class="btn btn-sm btn-default dropdown-toggle disabled"
|
||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">@lang('server.allocations.mass_actions') <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-massactions">
|
||||
<li><a href="#" id="selective-deletion" data-action="selective-deletion">@lang('server.allocations.delete') <i class="fa fa-fw fa-trash-o"></i></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
@foreach($node->allocations as $allocation)
|
||||
<tr>
|
||||
<td class="middle min-size" data-identifier="type">
|
||||
@if(is_null($allocation->server_id))
|
||||
<input type="checkbox" class="select-file hidden-xs" data-action="addSelection">
|
||||
@else
|
||||
<input disabled="disabled" type="checkbox" class="select-file hidden-xs" data-action="addSelection">
|
||||
@endif
|
||||
</td>
|
||||
<td class="col-sm-3 middle" data-identifier="ip">{{ $allocation->ip }}</td>
|
||||
<td class="col-sm-3 middle">
|
||||
<input class="form-control input-sm" type="text" value="{{ $allocation->ip_alias }}" data-action="set-alias" data-id="{{ $allocation->id }}" placeholder="none" />
|
||||
<span class="input-loader"><i class="fa fa-refresh fa-spin fa-fw"></i></span>
|
||||
</td>
|
||||
<td class="col-sm-2 middle" data-identifier="port">{{ $allocation->port }}</td>
|
||||
<td class="col-sm-3 middle">
|
||||
@if(! is_null($allocation->server))
|
||||
<a href="{{ route('admin.servers.view', $allocation->server_id) }}">{{ $allocation->server->name }}</a>
|
||||
@endif
|
||||
</td>
|
||||
<td class="col-sm-1 middle">
|
||||
@if(is_null($allocation->server_id))
|
||||
<button data-action="deallocate" data-id="{{ $allocation->id }}" class="btn btn-sm btn-danger"><i class="fa fa-trash-o"></i></button>
|
||||
@else
|
||||
<button class="btn btn-sm disabled"><i class="fa fa-trash-o"></i></button>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
</div>
|
||||
@if($node->allocations->hasPages())
|
||||
<div class="box-footer text-center">
|
||||
{{ $node->allocations->render() }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<form action="{{ route('admin.nodes.view.allocation', $node->id) }}" method="POST">
|
||||
<div class="box box-success">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Assign New Allocations</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label for="pAllocationIP" class="control-label">IP Address</label>
|
||||
<div>
|
||||
<select class="form-control" name="allocation_ip" id="pAllocationIP" multiple>
|
||||
@foreach($allocations as $allocation)
|
||||
<option value="{{ $allocation->ip }}">{{ $allocation->ip }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<p class="text-muted small">Enter an IP address to assign ports to here.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pAllocationIP" class="control-label">IP Alias</label>
|
||||
<div>
|
||||
<input type="text" id="pAllocationAlias" class="form-control" name="allocation_alias" placeholder="alias" />
|
||||
<p class="text-muted small">If you would like to assign a default alias to these allocations enter it here.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pAllocationPorts" class="control-label">Ports</label>
|
||||
<div>
|
||||
<select class="form-control" name="allocation_ports[]" id="pAllocationPorts" multiple></select>
|
||||
<p class="text-muted small">Enter individual ports or port ranges here separated by commas or spaces.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
{!! csrf_field() !!}
|
||||
<button type="submit" class="btn btn-success btn-sm pull-right">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="allocationModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">Delete Allocations for IP Block</h4>
|
||||
</div>
|
||||
<form action="{{ route('admin.nodes.view.allocation.removeBlock', $node->id) }}" method="POST">
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<select class="form-control" name="ip">
|
||||
@foreach($allocations as $allocation)
|
||||
<option value="{{ $allocation->ip }}">{{ $allocation->ip }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
{{{ csrf_field() }}}
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
<button type="submit" class="btn btn-danger">Delete Allocations</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('footer-scripts')
|
||||
@parent
|
||||
<script>
|
||||
$('[data-action="addSelection"]').on('click', function () {
|
||||
updateMassActions();
|
||||
});
|
||||
|
||||
$('[data-action="selectAll"]').on('click', function () {
|
||||
$('input.select-file').not(':disabled').prop('checked', function (i, val) {
|
||||
return !val;
|
||||
});
|
||||
|
||||
updateMassActions();
|
||||
});
|
||||
|
||||
$('[data-action="selective-deletion"]').on('mousedown', function () {
|
||||
deleteSelected();
|
||||
});
|
||||
|
||||
$('#pAllocationIP').select2({
|
||||
tags: true,
|
||||
maximumSelectionLength: 1,
|
||||
selectOnClose: true,
|
||||
tokenSeparators: [',', ' '],
|
||||
});
|
||||
|
||||
$('#pAllocationPorts').select2({
|
||||
tags: true,
|
||||
selectOnClose: true,
|
||||
tokenSeparators: [',', ' '],
|
||||
});
|
||||
|
||||
$('button[data-action="deallocate"]').click(function (event) {
|
||||
event.preventDefault();
|
||||
var element = $(this);
|
||||
var allocation = $(this).data('id');
|
||||
swal({
|
||||
title: '',
|
||||
text: 'Are you sure you want to delete this allocation?',
|
||||
type: 'warning',
|
||||
showCancelButton: true,
|
||||
allowOutsideClick: true,
|
||||
closeOnConfirm: false,
|
||||
confirmButtonText: 'Delete',
|
||||
confirmButtonColor: '#d9534f',
|
||||
showLoaderOnConfirm: true
|
||||
}, function () {
|
||||
$.ajax({
|
||||
method: 'DELETE',
|
||||
url: Router.route('admin.nodes.view.allocation.removeSingle', { node: Pterodactyl.node.id, allocation: allocation }),
|
||||
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
||||
}).done(function (data) {
|
||||
element.parent().parent().addClass('warning').delay(100).fadeOut();
|
||||
swal({ type: 'success', title: 'Port Deleted!' });
|
||||
}).fail(function (jqXHR) {
|
||||
console.error(jqXHR);
|
||||
swal({
|
||||
title: 'Whoops!',
|
||||
text: jqXHR.responseJSON.error,
|
||||
type: 'error'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var typingTimer;
|
||||
$('input[data-action="set-alias"]').keyup(function () {
|
||||
clearTimeout(typingTimer);
|
||||
$(this).parent().removeClass('has-error has-success');
|
||||
typingTimer = setTimeout(sendAlias, 250, $(this));
|
||||
});
|
||||
|
||||
var fadeTimers = [];
|
||||
function sendAlias(element) {
|
||||
element.parent().find('.input-loader').show();
|
||||
clearTimeout(fadeTimers[element.data('id')]);
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: Router.route('admin.nodes.view.allocation.setAlias', { id: Pterodactyl.node.id }),
|
||||
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
||||
data: {
|
||||
alias: element.val(),
|
||||
allocation_id: element.data('id'),
|
||||
}
|
||||
}).done(function () {
|
||||
element.parent().addClass('has-success');
|
||||
}).fail(function (jqXHR) {
|
||||
console.error(jqXHR);
|
||||
element.parent().addClass('has-error');
|
||||
}).always(function () {
|
||||
element.parent().find('.input-loader').hide();
|
||||
fadeTimers[element.data('id')] = setTimeout(clearHighlight, 2500, element);
|
||||
});
|
||||
}
|
||||
|
||||
function clearHighlight(element) {
|
||||
element.parent().removeClass('has-error has-success');
|
||||
}
|
||||
|
||||
function updateMassActions() {
|
||||
if ($('input.select-file:checked').length > 0) {
|
||||
$('#mass_actions').removeClass('disabled');
|
||||
} else {
|
||||
$('#mass_actions').addClass('disabled');
|
||||
}
|
||||
}
|
||||
|
||||
function deleteSelected() {
|
||||
var selectedIds = [];
|
||||
var selectedItems = [];
|
||||
var selectedItemsElements = [];
|
||||
|
||||
$('input.select-file:checked').each(function () {
|
||||
var $parent = $($(this).closest('tr'));
|
||||
var id = $parent.find('[data-action="deallocate"]').data('id');
|
||||
var $ip = $parent.find('td[data-identifier="ip"]');
|
||||
var $port = $parent.find('td[data-identifier="port"]');
|
||||
var block = `${$ip.text()}:${$port.text()}`;
|
||||
|
||||
selectedIds.push({
|
||||
id: id
|
||||
});
|
||||
selectedItems.push(block);
|
||||
selectedItemsElements.push($parent);
|
||||
});
|
||||
|
||||
if (selectedItems.length !== 0) {
|
||||
var formattedItems = "";
|
||||
var i = 0;
|
||||
$.each(selectedItems, function (key, value) {
|
||||
formattedItems += ("<code>" + value + "</code>, ");
|
||||
i++;
|
||||
return i < 5;
|
||||
});
|
||||
|
||||
formattedItems = formattedItems.slice(0, -2);
|
||||
if (selectedItems.length > 5) {
|
||||
formattedItems += ', and ' + (selectedItems.length - 5) + ' other(s)';
|
||||
}
|
||||
|
||||
swal({
|
||||
type: 'warning',
|
||||
title: '',
|
||||
text: 'Are you sure you want to delete the following allocations: ' + formattedItems + '?',
|
||||
html: true,
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
closeOnConfirm: false,
|
||||
showLoaderOnConfirm: true
|
||||
}, function () {
|
||||
$.ajax({
|
||||
method: 'DELETE',
|
||||
url: Router.route('admin.nodes.view.allocation.removeMultiple', {
|
||||
node: Pterodactyl.node.id
|
||||
}),
|
||||
headers: {'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')},
|
||||
data: JSON.stringify({
|
||||
allocations: selectedIds
|
||||
}),
|
||||
contentType: 'application/json',
|
||||
processData: false
|
||||
}).done(function () {
|
||||
$('#file_listing input:checked').each(function () {
|
||||
$(this).prop('checked', false);
|
||||
});
|
||||
|
||||
$.each(selectedItemsElements, function () {
|
||||
$(this).addClass('warning').delay(200).fadeOut();
|
||||
});
|
||||
|
||||
swal({
|
||||
type: 'success',
|
||||
title: 'Allocations Deleted'
|
||||
});
|
||||
}).fail(function (jqXHR) {
|
||||
console.error(jqXHR);
|
||||
swal({
|
||||
type: 'error',
|
||||
title: 'Whoops!',
|
||||
html: true,
|
||||
text: 'An error occurred while attempting to delete these allocations. Please try again.',
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
swal({
|
||||
type: 'warning',
|
||||
title: '',
|
||||
text: 'Please select allocation(s) to delete.',
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@endsection
|
87
resources/views/admin/nodes/view/configuration.blade.php
Normal file
87
resources/views/admin/nodes/view/configuration.blade.php
Normal file
|
@ -0,0 +1,87 @@
|
|||
{{-- Pterodactyl - Panel --}}
|
||||
{{-- Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com> --}}
|
||||
|
||||
{{-- This software is licensed under the terms of the MIT license. --}}
|
||||
{{-- https://opensource.org/licenses/MIT --}}
|
||||
@extends('layouts.admin')
|
||||
|
||||
@section('title')
|
||||
{{ $node->name }}: Configuration
|
||||
@endsection
|
||||
|
||||
@section('content-header')
|
||||
<h1>{{ $node->name }}<small>Your daemon configuration file.</small></h1>
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
||||
<li><a href="{{ route('admin.nodes') }}">Nodes</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view', $node->id) }}">{{ $node->name }}</a></li>
|
||||
<li class="active">Configuration</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.nodes.view', $node->id) }}">About</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view.settings', $node->id) }}">Settings</a></li>
|
||||
<li class="active"><a href="{{ route('admin.nodes.view.configuration', $node->id) }}">Configuration</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view.allocation', $node->id) }}">Allocation</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view.servers', $node->id) }}">Servers</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Configuration File</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<pre class="no-margin">{{ $node->getConfigurationAsJson(true) }}</pre>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<p class="no-margin">This file should be placed in your daemon's <code>config</code> directory in a file called <code>core.json</code>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div class="box box-success">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Auto-Deploy</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p class="text-muted small">To simplify the configuration of nodes it is possible to fetch the config from the panel. A token is required for this process. The button below will generate a token and provide you with the commands necessary for automatic configuration of the node. <em>Tokens are only valid for 5 minutes.</em></p>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="button" id="configTokenBtn" class="btn btn-sm btn-default" style="width:100%;">Generate Token</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('footer-scripts')
|
||||
@parent
|
||||
<script>
|
||||
$('#configTokenBtn').on('click', function (event) {
|
||||
$.getJSON('{{ route('admin.nodes.view.configuration.token', $node->id) }}').done(function (data) {
|
||||
swal({
|
||||
type: 'success',
|
||||
title: 'Token created.',
|
||||
text: 'Your token will expire <strong>in 5 minutes.</strong><br /><br />' +
|
||||
'<p>To auto-configure your node run the following command:<br /><small><pre>npm run configure -- --panel-url {{ config('app.url') }} --token ' + data.token + '</pre></small></p>',
|
||||
html: true
|
||||
})
|
||||
}).fail(function () {
|
||||
swal({
|
||||
title: 'Error',
|
||||
text: 'Something went wrong creating your token.',
|
||||
type: 'error'
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endsection
|
172
resources/views/admin/nodes/view/index.blade.php
Normal file
172
resources/views/admin/nodes/view/index.blade.php
Normal file
|
@ -0,0 +1,172 @@
|
|||
{{-- Pterodactyl - Panel --}}
|
||||
{{-- Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com> --}}
|
||||
|
||||
{{-- This software is licensed under the terms of the MIT license. --}}
|
||||
{{-- https://opensource.org/licenses/MIT --}}
|
||||
@extends('layouts.admin')
|
||||
|
||||
@section('title')
|
||||
{{ $node->name }}
|
||||
@endsection
|
||||
|
||||
@section('content-header')
|
||||
<h1>{{ $node->name }}<small>A quick overview of your node.</small></h1>
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
||||
<li><a href="{{ route('admin.nodes') }}">Nodes</a></li>
|
||||
<li class="active">{{ $node->name }}</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 class="active"><a href="{{ route('admin.nodes.view', $node->id) }}">About</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view.settings', $node->id) }}">Settings</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view.configuration', $node->id) }}">Configuration</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view.allocation', $node->id) }}">Allocation</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view.servers', $node->id) }}">Servers</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Information</h3>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover">
|
||||
<tr>
|
||||
<td>Daemon Version</td>
|
||||
<td><code data-attr="info-version"><i class="fa fa-refresh fa-fw fa-spin"></i></code> (Latest: <code>{{ $version->getDaemon() }}</code>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>System Information</td>
|
||||
<td data-attr="info-system"><i class="fa fa-refresh fa-fw fa-spin"></i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Total CPU Cores</td>
|
||||
<td data-attr="info-cpus"><i class="fa fa-refresh fa-fw fa-spin"></i></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if ($node->description)
|
||||
<div class="col-xs-12">
|
||||
<div class="box box-default">
|
||||
<div class="box-header with-border">
|
||||
Description
|
||||
</div>
|
||||
<div class="box-body table-responsive">
|
||||
<pre>{{ $node->description }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<div class="col-xs-12">
|
||||
<div class="box box-danger">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Delete Node</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p class="no-margin">Deleting a node is a irreversible action and will immediately remove this node from the panel. There must be no servers associated with this node in order to continue.</p>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<form action="{{ route('admin.nodes.view.delete', $node->id) }}" method="POST">
|
||||
{!! csrf_field() !!}
|
||||
{!! method_field('DELETE') !!}
|
||||
<button type="submit" class="btn btn-danger btn-sm pull-right" {{ ($node->servers_count < 1) ?: 'disabled' }}>Yes, Delete This Node</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">At-a-Glance</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
@if($node->maintenance_mode)
|
||||
<div class="col-sm-12">
|
||||
<div class="info-box bg-grey">
|
||||
<span class="info-box-icon"><i class="ion ion-wrench"></i></span>
|
||||
<div class="info-box-content" style="padding: 23px 10px 0;">
|
||||
<span class="info-box-text">This node is under</span>
|
||||
<span class="info-box-number">Maintenance</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<div class="col-sm-12">
|
||||
<div class="info-box bg-{{ $stats['disk']['css'] }}">
|
||||
<span class="info-box-icon"><i class="ion ion-ios-folder-outline"></i></span>
|
||||
<div class="info-box-content" style="padding: 15px 10px 0;">
|
||||
<span class="info-box-text">Disk Space Allocated</span>
|
||||
<span class="info-box-number">{{ $stats['disk']['value'] }} / {{ $stats['disk']['max'] }} Mb</span>
|
||||
<div class="progress">
|
||||
<div class="progress-bar" style="width: {{ $stats['disk']['percent'] }}%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<div class="info-box bg-{{ $stats['memory']['css'] }}">
|
||||
<span class="info-box-icon"><i class="ion ion-ios-barcode-outline"></i></span>
|
||||
<div class="info-box-content" style="padding: 15px 10px 0;">
|
||||
<span class="info-box-text">Memory Allocated</span>
|
||||
<span class="info-box-number">{{ $stats['memory']['value'] }} / {{ $stats['memory']['max'] }} Mb</span>
|
||||
<div class="progress">
|
||||
<div class="progress-bar" style="width: {{ $stats['memory']['percent'] }}%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<div class="info-box bg-gray">
|
||||
<span class="info-box-icon"><i class="ion ion-social-buffer-outline"></i></span>
|
||||
<div class="info-box-content" style="padding: 23px 10px 0;">
|
||||
<span class="info-box-text">Total Servers</span>
|
||||
<span class="info-box-number">{{ $node->servers_count }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('footer-scripts')
|
||||
@parent
|
||||
<script>
|
||||
(function getInformation() {
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: '{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}/v1',
|
||||
timeout: 5000,
|
||||
headers: {
|
||||
'X-Access-Token': '{{ $node->daemonSecret }}'
|
||||
},
|
||||
}).done(function (data) {
|
||||
$('[data-attr="info-version"]').html(data.version);
|
||||
$('[data-attr="info-system"]').html(data.system.type + '(' + data.system.arch + ') <code>' + data.system.release + '</code>');
|
||||
$('[data-attr="info-cpus"]').html(data.system.cpus);
|
||||
}).fail(function (jqXHR) {
|
||||
|
||||
}).always(function() {
|
||||
setTimeout(getInformation, 10000);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
@endsection
|
81
resources/views/admin/nodes/view/servers.blade.php
Normal file
81
resources/views/admin/nodes/view/servers.blade.php
Normal file
|
@ -0,0 +1,81 @@
|
|||
{{-- Pterodactyl - Panel --}}
|
||||
{{-- Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com> --}}
|
||||
|
||||
{{-- This software is licensed under the terms of the MIT license. --}}
|
||||
{{-- https://opensource.org/licenses/MIT --}}
|
||||
@extends('layouts.admin')
|
||||
|
||||
@section('title')
|
||||
{{ $node->name }}: Servers
|
||||
@endsection
|
||||
|
||||
@section('content-header')
|
||||
<h1>{{ $node->name }}<small>All servers currently assigned to this node.</small></h1>
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
||||
<li><a href="{{ route('admin.nodes') }}">Nodes</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view', $node->id) }}">{{ $node->name }}</a></li>
|
||||
<li class="active">Servers</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.nodes.view', $node->id) }}">About</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view.settings', $node->id) }}">Settings</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view.configuration', $node->id) }}">Configuration</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view.allocation', $node->id) }}">Allocation</a></li>
|
||||
<li class="active"><a href="{{ route('admin.nodes.view.servers', $node->id) }}">Servers</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Process Manager</h3>
|
||||
</div>
|
||||
<div class="box-body table-responsive no-padding">
|
||||
<table class="table table-hover">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Server Name</th>
|
||||
<th>Owner</th>
|
||||
<th>Service</th>
|
||||
<th class="text-center">Memory</th>
|
||||
<th class="text-center">Disk</th>
|
||||
<th class="text-center">CPU</th>
|
||||
<th class="text-center">Status</th>
|
||||
</tr>
|
||||
@foreach($servers as $server)
|
||||
<tr data-server="{{ $server->uuid }}">
|
||||
<td><code>{{ $server->uuidShort }}</code></td>
|
||||
<td><a href="{{ route('admin.servers.view', $server->id) }}">{{ $server->name }}</a></td>
|
||||
<td><a href="{{ route('admin.users.view', $server->owner_id) }}">{{ $server->user->username }}</a></td>
|
||||
<td>{{ $server->nest->name }} ({{ $server->egg->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="disk">--</span> / {{ $server->disk === 0 ? '∞' : $server->disk }} MB </td>
|
||||
<td class="text-center"><span data-action="cpu" data-cpumax="{{ $server->cpu }}">--</span> %</td>
|
||||
<td class="text-center" data-action="status">--</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
@if($servers->hasPages())
|
||||
<div class="box-footer with-border">
|
||||
<div class="col-md-12 text-center">{!! $servers->render() !!}</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('footer-scripts')
|
||||
@parent
|
||||
{!! Theme::js('js/admin/node/view-servers.js') !!}
|
||||
@endsection
|
245
resources/views/admin/nodes/view/settings.blade.php
Normal file
245
resources/views/admin/nodes/view/settings.blade.php
Normal file
|
@ -0,0 +1,245 @@
|
|||
{{-- Pterodactyl - Panel --}}
|
||||
{{-- Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com> --}}
|
||||
|
||||
{{-- This software is licensed under the terms of the MIT license. --}}
|
||||
{{-- https://opensource.org/licenses/MIT --}}
|
||||
@extends('layouts.admin')
|
||||
|
||||
@section('title')
|
||||
{{ $node->name }}: Settings
|
||||
@endsection
|
||||
|
||||
@section('content-header')
|
||||
<h1>{{ $node->name }}<small>Configure your node settings.</small></h1>
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
||||
<li><a href="{{ route('admin.nodes') }}">Nodes</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view', $node->id) }}">{{ $node->name }}</a></li>
|
||||
<li class="active">Settings</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.nodes.view', $node->id) }}">About</a></li>
|
||||
<li class="active"><a href="{{ route('admin.nodes.view.settings', $node->id) }}">Settings</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view.configuration', $node->id) }}">Configuration</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view.allocation', $node->id) }}">Allocation</a></li>
|
||||
<li><a href="{{ route('admin.nodes.view.servers', $node->id) }}">Servers</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<form action="{{ route('admin.nodes.view.settings', $node->id) }}" method="POST">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Settings</h3>
|
||||
</div>
|
||||
<div class="box-body row">
|
||||
<div class="form-group col-xs-12">
|
||||
<label for="name" class="control-label">Node Name</label>
|
||||
<div>
|
||||
<input type="text" autocomplete="off" name="name" class="form-control" value="{{ old('name', $node->name) }}" />
|
||||
<p class="text-muted"><small>Character limits: <code>a-zA-Z0-9_.-</code> and <code>[Space]</code> (min 1, max 100 characters).</small></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-xs-12">
|
||||
<label for="description" class="control-label">Description</label>
|
||||
<div>
|
||||
<textarea name="description" id="description" rows="4" class="form-control">{{ $node->description }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-xs-12">
|
||||
<label for="name" class="control-label">Location</label>
|
||||
<div>
|
||||
<select name="location_id" class="form-control">
|
||||
@foreach($locations as $location)
|
||||
<option value="{{ $location->id }}" {{ (old('location_id', $node->location_id) === $location->id) ? 'selected' : '' }}>{{ $location->long }} ({{ $location->short }})</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-xs-12">
|
||||
<label for="public" class="control-label">Allow Automatic Allocation <sup><a data-toggle="tooltip" data-placement="top" title="Allow automatic allocation to this Node?">?</a></sup></label>
|
||||
<div>
|
||||
<input type="radio" name="public" value="1" {{ (old('public', $node->public)) ? 'checked' : '' }} id="public_1" checked> <label for="public_1" style="padding-left:5px;">Yes</label><br />
|
||||
<input type="radio" name="public" value="0" {{ (old('public', $node->public)) ? '' : 'checked' }} id="public_0"> <label for="public_0" style="padding-left:5px;">No</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-xs-12">
|
||||
<label for="fqdn" class="control-label">Fully Qualified Domain Name</label>
|
||||
<div>
|
||||
<input type="text" autocomplete="off" name="fqdn" class="form-control" value="{{ old('fqdn', $node->fqdn) }}" />
|
||||
</div>
|
||||
<p class="text-muted"><small>Please enter domain name (e.g <code>node.example.com</code>) to be used for connecting to the daemon. An IP address may only be used if you are not using SSL for this node.
|
||||
<a tabindex="0" data-toggle="popover" data-trigger="focus" title="Why do I need a FQDN?" data-content="In order to secure communications between your server and this node we use SSL. We cannot generate a SSL certificate for IP Addresses, and as such you will need to provide a FQDN.">Why?</a>
|
||||
</small></p>
|
||||
</div>
|
||||
<div class="form-group col-xs-12">
|
||||
<label class="form-label"><span class="label label-warning"><i class="fa fa-power-off"></i></span> Communicate Over SSL</label>
|
||||
<div>
|
||||
<div class="radio radio-success radio-inline">
|
||||
<input type="radio" id="pSSLTrue" value="https" name="scheme" {{ (old('scheme', $node->scheme) === 'https') ? 'checked' : '' }}>
|
||||
<label for="pSSLTrue"> Use SSL Connection</label>
|
||||
</div>
|
||||
<div class="radio radio-danger radio-inline">
|
||||
<input type="radio" id="pSSLFalse" value="http" name="scheme" {{ (old('scheme', $node->scheme) !== 'https') ? 'checked' : '' }}>
|
||||
<label for="pSSLFalse"> Use HTTP Connection</label>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-muted small">In most cases you should select to use a SSL connection. If using an IP Address or you do not wish to use SSL at all, select a HTTP connection.</p>
|
||||
</div>
|
||||
<div class="form-group col-xs-12">
|
||||
<label class="form-label"><span class="label label-warning"><i class="fa fa-power-off"></i></span> Behind Proxy</label>
|
||||
<div>
|
||||
<div class="radio radio-success radio-inline">
|
||||
<input type="radio" id="pProxyFalse" value="0" name="behind_proxy" {{ (old('behind_proxy', $node->behind_proxy) == false) ? 'checked' : '' }}>
|
||||
<label for="pProxyFalse"> Not Behind Proxy </label>
|
||||
</div>
|
||||
<div class="radio radio-info radio-inline">
|
||||
<input type="radio" id="pProxyTrue" value="1" name="behind_proxy" {{ (old('behind_proxy', $node->behind_proxy) == true) ? 'checked' : '' }}>
|
||||
<label for="pProxyTrue"> Behind Proxy </label>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-muted small">If you are running the daemon behind a proxy such as Cloudflare, select this to have the daemon skip looking for certificates on boot.</p>
|
||||
</div>
|
||||
<div class="form-group col-xs-12">
|
||||
<label class="form-label"><span class="label label-warning"><i class="fa fa-wrench"></i></span> Maintenance Mode</label>
|
||||
<div>
|
||||
<div class="radio radio-success radio-inline">
|
||||
<input type="radio" id="pMaintenanceFalse" value="0" name="maintenance_mode" {{ (old('behind_proxy', $node->maintenance_mode) == false) ? 'checked' : '' }}>
|
||||
<label for="pMaintenanceFalse"> Disabled</label>
|
||||
</div>
|
||||
<div class="radio radio-warning radio-inline">
|
||||
<input type="radio" id="pMaintenanceTrue" value="1" name="maintenance_mode" {{ (old('behind_proxy', $node->maintenance_mode) == true) ? 'checked' : '' }}>
|
||||
<label for="pMaintenanceTrue"> Enabled</label>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-muted small">If the node is marked as 'Under Maintenance' users won't be able to access servers that are on this node.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Allocation Limits</h3>
|
||||
</div>
|
||||
<div class="box-body row">
|
||||
<div class="col-xs-12">
|
||||
<div class="row">
|
||||
<div class="form-group col-xs-6">
|
||||
<label for="memory" class="control-label">Total Memory</label>
|
||||
<div class="input-group">
|
||||
<input type="text" name="memory" class="form-control" data-multiplicator="true" value="{{ old('memory', $node->memory) }}"/>
|
||||
<span class="input-group-addon">MB</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-xs-6">
|
||||
<label for="memory_overallocate" class="control-label">Overallocate</label>
|
||||
<div class="input-group">
|
||||
<input type="text" name="memory_overallocate" class="form-control" value="{{ old('memory_overallocate', $node->memory_overallocate) }}"/>
|
||||
<span class="input-group-addon">%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-muted small">Enter the total amount of memory available on this node for allocation to servers. You may also provide a percentage that can allow allocation of more than the defined memory.</p>
|
||||
</div>
|
||||
<div class="col-xs-12">
|
||||
<div class="row">
|
||||
<div class="form-group col-xs-6">
|
||||
<label for="disk" class="control-label">Disk Space</label>
|
||||
<div class="input-group">
|
||||
<input type="text" name="disk" class="form-control" data-multiplicator="true" value="{{ old('disk', $node->disk) }}"/>
|
||||
<span class="input-group-addon">MB</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-xs-6">
|
||||
<label for="disk_overallocate" class="control-label">Overallocate</label>
|
||||
<div class="input-group">
|
||||
<input type="text" name="disk_overallocate" class="form-control" value="{{ old('disk_overallocate', $node->disk_overallocate) }}"/>
|
||||
<span class="input-group-addon">%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-muted small">Enter the total amount of disk space available on this node for server allocation. You may also provide a percentage that will determine the amount of disk space over the set limit to allow.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">General Configuration</h3>
|
||||
</div>
|
||||
<div class="box-body row">
|
||||
<div class="form-group col-xs-12">
|
||||
<label for="disk_overallocate" class="control-label">Maximum Web Upload Filesize</label>
|
||||
<div class="input-group">
|
||||
<input type="text" name="upload_size" class="form-control" value="{{ old('upload_size', $node->upload_size) }}"/>
|
||||
<span class="input-group-addon">MB</span>
|
||||
</div>
|
||||
<p class="text-muted"><small>Enter the maximum size of files that can be uploaded through the web-based file manager.</small></p>
|
||||
</div>
|
||||
<div class="col-xs-12">
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<label for="daemonListen" class="control-label"><span class="label label-warning"><i class="fa fa-power-off"></i></span> Daemon Port</label>
|
||||
<div>
|
||||
<input type="text" name="daemonListen" class="form-control" value="{{ old('daemonListen', $node->daemonListen) }}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label for="daemonSFTP" class="control-label"><span class="label label-warning"><i class="fa fa-power-off"></i></span> Daemon SFTP Port</label>
|
||||
<div>
|
||||
<input type="text" name="daemonSFTP" class="form-control" value="{{ old('daemonSFTP', $node->daemonSFTP) }}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<p class="text-muted"><small>The daemon runs its own SFTP management container and does not use the SSHd process on the main physical server. <Strong>Do not use the same port that you have assigned for your physical server's SSH process.</strong></small></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Save Settings</h3>
|
||||
</div>
|
||||
<div class="box-body row">
|
||||
<div class="form-group col-sm-6">
|
||||
<div>
|
||||
<input type="checkbox" name="reset_secret" id="reset_secret" /> <label for="reset_secret" class="control-label">Reset Daemon Master Key</label>
|
||||
</div>
|
||||
<p class="text-muted"><small>Resetting the daemon master key will void any request coming from the old key. This key is used for all sensitive operations on the daemon including server creation and deletion. We suggest changing this key regularly for security.</small></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
{!! method_field('PATCH') !!}
|
||||
{!! csrf_field() !!}
|
||||
<button type="submit" class="btn btn-primary pull-right">Save Changes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
|
||||
@section('footer-scripts')
|
||||
@parent
|
||||
<script>
|
||||
$('[data-toggle="popover"]').popover({
|
||||
placement: 'auto'
|
||||
});
|
||||
$('select[name="location_id"]').select2();
|
||||
</script>
|
||||
@endsection
|
Reference in a new issue