Fix up node autodeployment
This commit is contained in:
parent
fc31d6347e
commit
fda88940f7
6 changed files with 119 additions and 20 deletions
88
app/Http/Controllers/Admin/NodeAutoDeployController.php
Normal file
88
app/Http/Controllers/Admin/NodeAutoDeployController.php
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Pterodactyl\Models\Node;
|
||||||
|
use Pterodactyl\Models\ApiKey;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Pterodactyl\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Contracts\Encryption\Encrypter;
|
||||||
|
use Pterodactyl\Services\Api\KeyCreationService;
|
||||||
|
use Pterodactyl\Repositories\Eloquent\ApiKeyRepository;
|
||||||
|
|
||||||
|
class NodeAutoDeployController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Services\Api\KeyCreationService
|
||||||
|
*/
|
||||||
|
private $keyCreationService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Repositories\Eloquent\ApiKeyRepository
|
||||||
|
*/
|
||||||
|
private $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Contracts\Encryption\Encrypter
|
||||||
|
*/
|
||||||
|
private $encrypter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NodeAutoDeployController constructor.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Repositories\Eloquent\ApiKeyRepository $repository
|
||||||
|
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
|
||||||
|
* @param \Pterodactyl\Services\Api\KeyCreationService $keyCreationService
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
ApiKeyRepository $repository,
|
||||||
|
Encrypter $encrypter,
|
||||||
|
KeyCreationService $keyCreationService
|
||||||
|
) {
|
||||||
|
$this->keyCreationService = $keyCreationService;
|
||||||
|
$this->repository = $repository;
|
||||||
|
$this->encrypter = $encrypter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a new API key for the logged in user with only permission to read
|
||||||
|
* nodes, and returns that as the deployment key for a node.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \Pterodactyl\Models\Node $node
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*
|
||||||
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
|
*/
|
||||||
|
public function __invoke(Request $request, Node $node)
|
||||||
|
{
|
||||||
|
/** @var \Pterodactyl\Models\ApiKey|null $key */
|
||||||
|
$key = $this->repository->getApplicationKeys($request->user())
|
||||||
|
->filter(function (ApiKey $key) {
|
||||||
|
foreach ($key->getAttributes() as $permission => $value) {
|
||||||
|
if ($permission === 'r_nodes' && $value === 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
->first();
|
||||||
|
|
||||||
|
// We couldn't find a key that exists for this user with only permission for
|
||||||
|
// reading nodes. Go ahead and create it now.
|
||||||
|
if (! $key) {
|
||||||
|
$key = $this->keyCreationService->setKeyType(ApiKey::TYPE_APPLICATION)->handle([
|
||||||
|
'user_id' => $request->user()->id,
|
||||||
|
'memo' => 'Automatically generated node deployment key.',
|
||||||
|
'allowed_ips' => [],
|
||||||
|
], ['r_nodes' => 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return JsonResponse::create([
|
||||||
|
'node' => $node->id,
|
||||||
|
'token' => $key->identifier . $this->encrypter->decrypt($key->token),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\Admin;
|
namespace Pterodactyl\Http\Controllers\Admin;
|
||||||
|
|
||||||
use Cake\Chronos\Chronos;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Pterodactyl\Models\Node;
|
use Pterodactyl\Models\Node;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
|
@ -300,18 +299,4 @@ class NodesController extends Controller
|
||||||
|
|
||||||
return redirect()->route('admin.nodes');
|
return redirect()->route('admin.nodes');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the configuration token to auto-deploy a node.
|
|
||||||
*
|
|
||||||
* @param \Pterodactyl\Models\Node $node
|
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*/
|
|
||||||
public function setToken(Node $node)
|
|
||||||
{
|
|
||||||
$token = bin2hex(random_bytes(16));
|
|
||||||
$this->cache->put('Node:Configuration:' . $token, $node->id, Chronos::now()->addMinutes(5));
|
|
||||||
|
|
||||||
return response()->json(['token' => $token]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Controllers\Api\Application\Nodes;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\Node;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\Nodes\GetNodeRequest;
|
||||||
|
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
|
|
||||||
|
class NodeConfigurationController extends ApplicationApiController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns the configuration information for a node. This allows for automated deployments
|
||||||
|
* to remote machines so long as an API key is provided to the machine to make the request
|
||||||
|
* with, and the node is known.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Http\Requests\Api\Application\Nodes\GetNodeRequest $request
|
||||||
|
* @param \Pterodactyl\Models\Node $node
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function __invoke(GetNodeRequest $request, Node $node)
|
||||||
|
{
|
||||||
|
return JsonResponse::create($node->getConfiguration());
|
||||||
|
}
|
||||||
|
}
|
|
@ -71,8 +71,7 @@
|
||||||
swal({
|
swal({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
title: 'Token created.',
|
title: 'Token created.',
|
||||||
text: 'Your token will expire <strong>in 5 minutes.</strong><br /><br />' +
|
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>',
|
||||||
'<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
|
html: true
|
||||||
})
|
})
|
||||||
}).fail(function () {
|
}).fail(function () {
|
||||||
|
|
|
@ -151,7 +151,7 @@ Route::group(['prefix' => 'nodes'], function () {
|
||||||
Route::get('/view/{node}/allocation', 'Nodes\NodeViewController@allocations')->name('admin.nodes.view.allocation');
|
Route::get('/view/{node}/allocation', 'Nodes\NodeViewController@allocations')->name('admin.nodes.view.allocation');
|
||||||
Route::get('/view/{node}/servers', 'Nodes\NodeViewController@servers')->name('admin.nodes.view.servers');
|
Route::get('/view/{node}/servers', 'Nodes\NodeViewController@servers')->name('admin.nodes.view.servers');
|
||||||
Route::get('/view/{node}/system-information', 'Nodes\SystemInformationController');
|
Route::get('/view/{node}/system-information', 'Nodes\SystemInformationController');
|
||||||
Route::get('/view/{node}/settings/token', 'NodesController@setToken')->name('admin.nodes.view.configuration.token');
|
Route::get('/view/{node}/settings/token', 'NodeAutoDeployController')->name('admin.nodes.view.configuration.token');
|
||||||
|
|
||||||
Route::post('/new', 'NodesController@store');
|
Route::post('/new', 'NodesController@store');
|
||||||
Route::post('/view/{node}/allocation', 'NodesController@createAllocation');
|
Route::post('/view/{node}/allocation', 'NodesController@createAllocation');
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| User Controller Routes
|
| User Controller Routes
|
||||||
|
@ -8,6 +10,7 @@
|
||||||
| Endpoint: /api/application/users
|
| Endpoint: /api/application/users
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Route::group(['prefix' => '/users'], function () {
|
Route::group(['prefix' => '/users'], function () {
|
||||||
Route::get('/', 'Users\UserController@index')->name('api.application.users');
|
Route::get('/', 'Users\UserController@index')->name('api.application.users');
|
||||||
Route::get('/{user}', 'Users\UserController@view')->name('api.application.users.view');
|
Route::get('/{user}', 'Users\UserController@view')->name('api.application.users.view');
|
||||||
|
@ -30,6 +33,7 @@ Route::group(['prefix' => '/users'], function () {
|
||||||
Route::group(['prefix' => '/nodes'], function () {
|
Route::group(['prefix' => '/nodes'], function () {
|
||||||
Route::get('/', 'Nodes\NodeController@index')->name('api.application.nodes');
|
Route::get('/', 'Nodes\NodeController@index')->name('api.application.nodes');
|
||||||
Route::get('/{node}', 'Nodes\NodeController@view')->name('api.application.nodes.view');
|
Route::get('/{node}', 'Nodes\NodeController@view')->name('api.application.nodes.view');
|
||||||
|
Route::get('/{node}/configuration', 'Nodes\NodeConfigurationController');
|
||||||
|
|
||||||
Route::post('/', 'Nodes\NodeController@store');
|
Route::post('/', 'Nodes\NodeController@store');
|
||||||
Route::patch('/{node}', 'Nodes\NodeController@update');
|
Route::patch('/{node}', 'Nodes\NodeController@update');
|
||||||
|
@ -38,9 +42,7 @@ Route::group(['prefix' => '/nodes'], function () {
|
||||||
|
|
||||||
Route::group(['prefix' => '/{node}/allocations'], function () {
|
Route::group(['prefix' => '/{node}/allocations'], function () {
|
||||||
Route::get('/', 'Nodes\AllocationController@index')->name('api.application.allocations');
|
Route::get('/', 'Nodes\AllocationController@index')->name('api.application.allocations');
|
||||||
|
|
||||||
Route::post('/', 'Nodes\AllocationController@store');
|
Route::post('/', 'Nodes\AllocationController@store');
|
||||||
|
|
||||||
Route::delete('/{allocation}', 'Nodes\AllocationController@delete')->name('api.application.allocations.view');
|
Route::delete('/{allocation}', 'Nodes\AllocationController@delete')->name('api.application.allocations.view');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue