Skip to content

Commit 5be4520

Browse files
authored
Merge pull request pterodactyl#1129 from stanjg/feature/node-maintenance
Added a maintenance mode for nodes
2 parents 357c9e1 + 8aadc62 commit 5be4520

File tree

13 files changed

+224
-6
lines changed

13 files changed

+224
-6
lines changed

app/Http/Kernel.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Pterodactyl\Http;
44

5+
use Pterodactyl\Http\Middleware\MaintenanceMiddleware;
56
use Pterodactyl\Models\ApiKey;
67
use Illuminate\Auth\Middleware\Authorize;
78
use Illuminate\Auth\Middleware\Authenticate;
@@ -108,6 +109,7 @@ class Kernel extends HttpKernel
108109
'can' => Authorize::class,
109110
'bindings' => SubstituteBindings::class,
110111
'recaptcha' => VerifyReCaptcha::class,
112+
'node.maintenance' => MaintenanceMiddleware::class,
111113

112114
// Server specific middleware (used for authenticating access to resources)
113115
//
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace Pterodactyl\Http\Middleware;
4+
5+
use Closure;
6+
use Illuminate\Contracts\Routing\ResponseFactory;
7+
8+
class MaintenanceMiddleware
9+
{
10+
/**
11+
* @var \Illuminate\Contracts\Routing\ResponseFactory
12+
*/
13+
private $response;
14+
15+
/**
16+
* MaintenanceMiddleware constructor.
17+
*
18+
* @param \Illuminate\Contracts\Routing\ResponseFactory $response
19+
*/
20+
public function __construct(ResponseFactory $response)
21+
{
22+
$this->response = $response;
23+
}
24+
25+
/**
26+
* Handle an incoming request.
27+
*
28+
* @param \Illuminate\Http\Request $request
29+
* @param \Closure $next
30+
* @return mixed
31+
*/
32+
public function handle($request, Closure $next)
33+
{
34+
/** @var \Pterodactyl\Models\Server $server */
35+
$server = $request->attributes->get('server');
36+
$node = $server->getRelation('node');
37+
38+
if ($node->maintenance_mode) {
39+
return $this->response->view('errors.maintenance');
40+
}
41+
42+
return $next($request);
43+
}
44+
}

app/Models/Node.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class Node extends Model implements CleansAttributes, ValidableContract
4848
'daemonSFTP' => 'integer',
4949
'behind_proxy' => 'boolean',
5050
'public' => 'boolean',
51+
'maintenance_mode' => 'boolean',
5152
];
5253

5354
/**
@@ -62,7 +63,7 @@ class Node extends Model implements CleansAttributes, ValidableContract
6263
'disk_overallocate', 'upload_size',
6364
'daemonSecret', 'daemonBase',
6465
'daemonSFTP', 'daemonListen',
65-
'description',
66+
'description', 'maintenance_mode',
6667
];
6768

6869
/**
@@ -111,6 +112,7 @@ class Node extends Model implements CleansAttributes, ValidableContract
111112
'daemonBase' => 'regex:/^([\/][\d\w.\-\/]+)$/',
112113
'daemonSFTP' => 'numeric|between:1024,65535',
113114
'daemonListen' => 'numeric|between:1024,65535',
115+
'maintenance_mode' => 'boolean',
114116
];
115117

116118
/**
@@ -126,6 +128,7 @@ class Node extends Model implements CleansAttributes, ValidableContract
126128
'daemonBase' => '/srv/daemon-data',
127129
'daemonSFTP' => 2022,
128130
'daemonListen' => 8080,
131+
'maintenance_mode' => false,
129132
];
130133

131134
/**

app/Providers/RouteServiceProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function map()
3333
->namespace($this->namespace . '\Auth')
3434
->group(base_path('routes/auth.php'));
3535

36-
Route::middleware(['web', 'csrf', 'auth', 'server', 'subuser.auth'])->prefix('/server/{server}')
36+
Route::middleware(['web', 'csrf', 'auth', 'server', 'subuser.auth', 'node.maintenance'])->prefix('/server/{server}')
3737
->namespace($this->namespace . '\Server')
3838
->group(base_path('routes/server.php'));
3939

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
use Illuminate\Support\Facades\Schema;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Database\Migrations\Migration;
6+
7+
class AddMaintenanceToNodes extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::table('nodes', function (Blueprint $table) {
17+
$table->boolean('maintenance_mode')->after('behind_proxy')->default(false);
18+
});
19+
}
20+
21+
/**
22+
* Reverse the migrations.
23+
*
24+
* @return void
25+
*/
26+
public function down()
27+
{
28+
Schema::table('nodes', function (Blueprint $table) {
29+
$table->dropColumn('maintenance_mode');
30+
});
31+
}
32+
}

resources/lang/en/base.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@
2121
'header' => 'Server Suspended',
2222
'desc' => 'This server has been suspended and cannot be accessed.',
2323
],
24+
'maintenance' => [
25+
'header' => 'Node Under Maintenance',
26+
'title' => 'Temporarily Unavailable',
27+
'desc' => 'This node is under maintenance, therefore your server can temporarily not be accessed.',
28+
],
2429
],
2530
'index' => [
2631
'header' => 'Your Servers',

resources/lang/en/strings.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
'tasks' => 'Tasks',
7575
'seconds' => 'Seconds',
7676
'minutes' => 'Minutes',
77+
'under_maintenance' => 'Under Maintenance',
7778
'days' => [
7879
'sun' => 'Sunday',
7980
'mon' => 'Monday',

resources/themes/pterodactyl/admin/nodes/index.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
@foreach ($nodes as $node)
5757
<tr>
5858
<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>
59-
<td><a href="{{ route('admin.nodes.view', $node->id) }}">{{ $node->name }}</a></td>
59+
<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>
6060
<td>{{ $node->location->short }}</td>
6161
<td>{{ $node->memory }} MB</td>
6262
<td>{{ $node->disk }} MB</td>

resources/themes/pterodactyl/admin/nodes/view/index.blade.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,17 @@
9696
</div>
9797
<div class="box-body">
9898
<div class="row">
99+
@if($node->maintenance_mode)
100+
<div class="col-sm-12">
101+
<div class="info-box bg-orange">
102+
<span class="info-box-icon"><i class="ion ion-wrench"></i></span>
103+
<div class="info-box-content" style="padding: 23px 10px 0;">
104+
<span class="info-box-text">This node is under</span>
105+
<span class="info-box-number">Maintenance</span>
106+
</div>
107+
</div>
108+
</div>
109+
@endif
99110
<div class="col-sm-12">
100111
<div class="info-box bg-{{ $stats['disk']['css'] }}">
101112
<span class="info-box-icon"><i class="ion ion-ios-folder-outline"></i></span>

resources/themes/pterodactyl/admin/nodes/view/settings.blade.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,20 @@
108108
</div>
109109
<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>
110110
</div>
111+
<div class="form-group col-xs-12">
112+
<label class="form-label"><span class="label label-warning"><i class="fa fa-wrench"></i></span> Maintenance Mode</label>
113+
<div>
114+
<div class="radio radio-success radio-inline">
115+
<input type="radio" id="pMaintenanceFalse" value="0" name="maintenance_mode" {{ (old('behind_proxy', $node->maintenance_mode) == false) ? 'checked' : '' }}>
116+
<label for="pMaintenanceFalse"> Disabled</label>
117+
</div>
118+
<div class="radio radio-warning radio-inline">
119+
<input type="radio" id="pMaintenanceTrue" value="1" name="maintenance_mode" {{ (old('behind_proxy', $node->maintenance_mode) == true) ? 'checked' : '' }}>
120+
<label for="pMaintenanceTrue"> Enabled</label>
121+
</div>
122+
</div>
123+
<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>
124+
</div>
111125
</div>
112126
</div>
113127
</div>

0 commit comments

Comments
 (0)