Skip to content

Commit fda8894

Browse files
committed
Fix up node autodeployment
1 parent fc31d63 commit fda8894

File tree

6 files changed

+119
-20
lines changed

6 files changed

+119
-20
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
namespace Pterodactyl\Http\Controllers\Admin;
4+
5+
use Illuminate\Http\Request;
6+
use Pterodactyl\Models\Node;
7+
use Pterodactyl\Models\ApiKey;
8+
use Illuminate\Http\JsonResponse;
9+
use Pterodactyl\Http\Controllers\Controller;
10+
use Illuminate\Contracts\Encryption\Encrypter;
11+
use Pterodactyl\Services\Api\KeyCreationService;
12+
use Pterodactyl\Repositories\Eloquent\ApiKeyRepository;
13+
14+
class NodeAutoDeployController extends Controller
15+
{
16+
/**
17+
* @var \Pterodactyl\Services\Api\KeyCreationService
18+
*/
19+
private $keyCreationService;
20+
21+
/**
22+
* @var \Pterodactyl\Repositories\Eloquent\ApiKeyRepository
23+
*/
24+
private $repository;
25+
26+
/**
27+
* @var \Illuminate\Contracts\Encryption\Encrypter
28+
*/
29+
private $encrypter;
30+
31+
/**
32+
* NodeAutoDeployController constructor.
33+
*
34+
* @param \Pterodactyl\Repositories\Eloquent\ApiKeyRepository $repository
35+
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
36+
* @param \Pterodactyl\Services\Api\KeyCreationService $keyCreationService
37+
*/
38+
public function __construct(
39+
ApiKeyRepository $repository,
40+
Encrypter $encrypter,
41+
KeyCreationService $keyCreationService
42+
) {
43+
$this->keyCreationService = $keyCreationService;
44+
$this->repository = $repository;
45+
$this->encrypter = $encrypter;
46+
}
47+
48+
/**
49+
* Generates a new API key for the logged in user with only permission to read
50+
* nodes, and returns that as the deployment key for a node.
51+
*
52+
* @param \Illuminate\Http\Request $request
53+
* @param \Pterodactyl\Models\Node $node
54+
* @return \Illuminate\Http\JsonResponse
55+
*
56+
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
57+
*/
58+
public function __invoke(Request $request, Node $node)
59+
{
60+
/** @var \Pterodactyl\Models\ApiKey|null $key */
61+
$key = $this->repository->getApplicationKeys($request->user())
62+
->filter(function (ApiKey $key) {
63+
foreach ($key->getAttributes() as $permission => $value) {
64+
if ($permission === 'r_nodes' && $value === 1) {
65+
return true;
66+
}
67+
}
68+
69+
return false;
70+
})
71+
->first();
72+
73+
// We couldn't find a key that exists for this user with only permission for
74+
// reading nodes. Go ahead and create it now.
75+
if (! $key) {
76+
$key = $this->keyCreationService->setKeyType(ApiKey::TYPE_APPLICATION)->handle([
77+
'user_id' => $request->user()->id,
78+
'memo' => 'Automatically generated node deployment key.',
79+
'allowed_ips' => [],
80+
], ['r_nodes' => 1]);
81+
}
82+
83+
return JsonResponse::create([
84+
'node' => $node->id,
85+
'token' => $key->identifier . $this->encrypter->decrypt($key->token),
86+
]);
87+
}
88+
}

app/Http/Controllers/Admin/NodesController.php

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
namespace Pterodactyl\Http\Controllers\Admin;
1111

12-
use Cake\Chronos\Chronos;
1312
use Illuminate\Http\Request;
1413
use Pterodactyl\Models\Node;
1514
use Illuminate\Http\Response;
@@ -300,18 +299,4 @@ public function delete($node)
300299

301300
return redirect()->route('admin.nodes');
302301
}
303-
304-
/**
305-
* Returns the configuration token to auto-deploy a node.
306-
*
307-
* @param \Pterodactyl\Models\Node $node
308-
* @return \Illuminate\Http\JsonResponse
309-
*/
310-
public function setToken(Node $node)
311-
{
312-
$token = bin2hex(random_bytes(16));
313-
$this->cache->put('Node:Configuration:' . $token, $node->id, Chronos::now()->addMinutes(5));
314-
315-
return response()->json(['token' => $token]);
316-
}
317302
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Pterodactyl\Http\Controllers\Api\Application\Nodes;
4+
5+
use Pterodactyl\Models\Node;
6+
use Illuminate\Http\JsonResponse;
7+
use Pterodactyl\Http\Requests\Api\Application\Nodes\GetNodeRequest;
8+
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
9+
10+
class NodeConfigurationController extends ApplicationApiController
11+
{
12+
/**
13+
* Returns the configuration information for a node. This allows for automated deployments
14+
* to remote machines so long as an API key is provided to the machine to make the request
15+
* with, and the node is known.
16+
*
17+
* @param \Pterodactyl\Http\Requests\Api\Application\Nodes\GetNodeRequest $request
18+
* @param \Pterodactyl\Models\Node $node
19+
* @return \Illuminate\Http\JsonResponse
20+
*/
21+
public function __invoke(GetNodeRequest $request, Node $node)
22+
{
23+
return JsonResponse::create($node->getConfiguration());
24+
}
25+
}

resources/views/admin/nodes/view/configuration.blade.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,7 @@
7171
swal({
7272
type: 'success',
7373
title: 'Token created.',
74-
text: 'Your token will expire <strong>in 5 minutes.</strong><br /><br />' +
75-
'<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>',
74+
text: '<p>To auto-configure your node run the following command:<br /><small><pre>cd /srv/wings && ./wings configure --panel-url {{ config('app.url') }} --token ' + data.token + ' --node ' + data.node + '{{ config('app.debug') ? ' --allow-insecure' : '' }}</pre></small></p>',
7675
html: true
7776
})
7877
}).fail(function () {

routes/admin.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@
151151
Route::get('/view/{node}/allocation', 'Nodes\NodeViewController@allocations')->name('admin.nodes.view.allocation');
152152
Route::get('/view/{node}/servers', 'Nodes\NodeViewController@servers')->name('admin.nodes.view.servers');
153153
Route::get('/view/{node}/system-information', 'Nodes\SystemInformationController');
154-
Route::get('/view/{node}/settings/token', 'NodesController@setToken')->name('admin.nodes.view.configuration.token');
154+
Route::get('/view/{node}/settings/token', 'NodeAutoDeployController')->name('admin.nodes.view.configuration.token');
155155

156156
Route::post('/new', 'NodesController@store');
157157
Route::post('/view/{node}/allocation', 'NodesController@createAllocation');

routes/api-application.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
use Illuminate\Support\Facades\Route;
4+
35
/*
46
|--------------------------------------------------------------------------
57
| User Controller Routes
@@ -8,6 +10,7 @@
810
| Endpoint: /api/application/users
911
|
1012
*/
13+
1114
Route::group(['prefix' => '/users'], function () {
1215
Route::get('/', 'Users\UserController@index')->name('api.application.users');
1316
Route::get('/{user}', 'Users\UserController@view')->name('api.application.users.view');
@@ -30,6 +33,7 @@
3033
Route::group(['prefix' => '/nodes'], function () {
3134
Route::get('/', 'Nodes\NodeController@index')->name('api.application.nodes');
3235
Route::get('/{node}', 'Nodes\NodeController@view')->name('api.application.nodes.view');
36+
Route::get('/{node}/configuration', 'Nodes\NodeConfigurationController');
3337

3438
Route::post('/', 'Nodes\NodeController@store');
3539
Route::patch('/{node}', 'Nodes\NodeController@update');
@@ -38,9 +42,7 @@
3842

3943
Route::group(['prefix' => '/{node}/allocations'], function () {
4044
Route::get('/', 'Nodes\AllocationController@index')->name('api.application.allocations');
41-
4245
Route::post('/', 'Nodes\AllocationController@store');
43-
4446
Route::delete('/{allocation}', 'Nodes\AllocationController@delete')->name('api.application.allocations.view');
4547
});
4648
});

0 commit comments

Comments
 (0)