2016-01-05 04:59:45 +00:00
< ? php
2016-01-20 00:10:39 +00:00
/**
2016-01-20 21:05:16 +00:00
* Pterodactyl - Panel
2017-01-24 22:57:08 +00:00
* Copyright ( c ) 2015 - 2017 Dane Everitt < dane @ daneeveritt . com >.
2016-01-20 00:10:39 +00:00
*
2016-01-20 20:56:40 +00:00
* 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 :
2016-01-20 00:10:39 +00:00
*
2016-01-20 20:56:40 +00:00
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software .
2016-01-20 00:10:39 +00:00
*
2016-01-20 20:56:40 +00:00
* 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 .
2016-01-20 00:10:39 +00:00
*/
2016-12-07 22:46:38 +00:00
2016-01-05 04:59:45 +00:00
namespace Pterodactyl\Http\Controllers\Admin ;
use DB ;
2016-12-07 22:46:38 +00:00
use Log ;
use Alert ;
2017-01-08 14:21:02 +00:00
use Carbon ;
2016-09-30 21:12:36 +00:00
use Validator ;
2016-01-05 04:59:45 +00:00
use Pterodactyl\Models ;
2016-12-07 22:46:38 +00:00
use Illuminate\Http\Request ;
2016-09-07 20:12:06 +00:00
use Pterodactyl\Exceptions\DisplayException ;
2016-01-05 04:59:45 +00:00
use Pterodactyl\Http\Controllers\Controller ;
2016-12-07 22:46:38 +00:00
use Pterodactyl\Repositories\NodeRepository ;
use Pterodactyl\Exceptions\DisplayValidationException ;
2016-01-05 04:59:45 +00:00
class NodesController extends Controller
{
/**
2016-12-07 22:46:38 +00:00
* Controller Constructor .
2016-01-05 04:59:45 +00:00
*/
public function __construct ()
{
//
}
2016-02-06 04:41:16 +00:00
public function getScript ( Request $request , $id )
{
2017-02-03 21:50:28 +00:00
return response () -> view ( 'admin.nodes.remote.deploy' , [
'node' => Models\Node :: findOrFail ( $id ),
]) -> header ( 'Content-Type' , 'text/plain' );
2016-02-06 04:41:16 +00:00
}
2016-01-05 04:59:45 +00:00
public function getIndex ( Request $request )
{
return view ( 'admin.nodes.index' , [
2017-02-03 21:50:28 +00:00
'nodes' => Models\Node :: with ( 'location' ) -> withCount ( 'servers' ) -> paginate ( 20 ),
2016-01-05 04:59:45 +00:00
]);
}
public function getNew ( Request $request )
{
2016-12-07 22:46:38 +00:00
if ( ! Models\Location :: all () -> count ()) {
2016-09-30 20:05:39 +00:00
Alert :: warning ( 'You must add a location before you can add a new node.' ) -> flash ();
2016-12-07 22:46:38 +00:00
2016-09-30 20:05:39 +00:00
return redirect () -> route ( 'admin.locations' );
}
2016-01-05 04:59:45 +00:00
return view ( 'admin.nodes.new' , [
2016-12-07 22:46:38 +00:00
'locations' => Models\Location :: all (),
2016-01-05 04:59:45 +00:00
]);
}
public function postNew ( Request $request )
{
try {
2017-02-03 21:50:28 +00:00
$repo = new NodeRepository ;
$node = $repo -> create ( $request -> only ([
'name' ,
'location' ,
'public' ,
'fqdn' ,
'scheme' ,
'memory' ,
'memory_overallocate' ,
'disk' ,
'disk_overallocate' ,
'daemonBase' ,
'daemonSFTP' ,
'daemonListen' ,
2016-01-05 04:59:45 +00:00
]));
2017-02-03 21:50:28 +00:00
Alert :: success ( 'Successfully created new node that can be configured automatically on your remote machine by visiting the configuration tab. <strong>Before you can add any servers you need to first assign some IP addresses and ports.</strong>' ) -> flash ();
2016-12-07 22:46:38 +00:00
2016-01-05 04:59:45 +00:00
return redirect () -> route ( 'admin.nodes.view' , [
2017-02-03 21:50:28 +00:00
'id' => $node -> id ,
2016-12-07 22:46:38 +00:00
'tab' => 'tab_allocation' ,
2016-01-05 04:59:45 +00:00
]);
2016-09-07 20:12:06 +00:00
} catch ( DisplayValidationException $e ) {
2016-01-05 04:59:45 +00:00
return redirect () -> route ( 'admin.nodes.new' ) -> withErrors ( json_decode ( $e -> getMessage ())) -> withInput ();
2016-09-07 20:12:06 +00:00
} catch ( DisplayException $e ) {
2016-01-05 04:59:45 +00:00
Alert :: danger ( $e -> getMessage ()) -> flash ();
} catch ( \Exception $e ) {
Log :: error ( $e );
Alert :: danger ( 'An unhandled exception occured while attempting to add this node. Please try again.' ) -> flash ();
}
2016-12-07 22:46:38 +00:00
2016-01-05 04:59:45 +00:00
return redirect () -> route ( 'admin.nodes.new' ) -> withInput ();
}
public function getView ( Request $request , $id )
{
2017-02-03 21:50:28 +00:00
$node = Models\Node :: with (
2017-02-10 22:18:46 +00:00
'servers.user' , 'servers.service' ,
'servers.allocations' , 'location'
2017-02-03 21:50:28 +00:00
) -> findOrFail ( $id );
$node -> setRelation ( 'allocations' , $node -> allocations () -> paginate ( 40 ));
2016-09-30 01:34:20 +00:00
2016-01-05 04:59:45 +00:00
return view ( 'admin.nodes.view' , [
2016-01-05 05:52:20 +00:00
'node' => $node ,
2017-02-03 00:46:46 +00:00
'stats' => Models\Server :: select ( DB :: raw ( 'SUM(memory) as memory, SUM(disk) as disk' )) -> where ( 'node_id' , $node -> id ) -> first (),
2016-01-05 23:31:25 +00:00
'locations' => Models\Location :: all (),
2016-01-05 04:59:45 +00:00
]);
}
2016-01-05 23:31:25 +00:00
public function postView ( Request $request , $id )
{
try {
$node = new NodeRepository ;
2017-02-03 21:50:28 +00:00
$node -> update ( $id , $request -> only ([
2017-02-10 22:18:46 +00:00
'name' , 'location' , 'public' ,
'fqdn' , 'scheme' , 'memory' ,
'memory_overallocate' , 'disk' ,
'disk_overallocate' , 'upload_size' ,
'daemonBase' , 'daemonSFTP' ,
'daemonListen' , 'reset_secret' ,
2016-01-05 23:31:25 +00:00
]));
Alert :: success ( 'Successfully update this node\'s information. If you changed any daemon settings you will need to restart it now.' ) -> flash ();
2016-12-07 22:46:38 +00:00
2016-01-05 23:31:25 +00:00
return redirect () -> route ( 'admin.nodes.view' , [
'id' => $id ,
2016-12-07 22:46:38 +00:00
'tab' => 'tab_settings' ,
2016-01-05 23:31:25 +00:00
]);
2016-09-07 20:12:06 +00:00
} catch ( DisplayValidationException $e ) {
2016-01-05 23:31:25 +00:00
return redirect () -> route ( 'admin.nodes.view' , $id ) -> withErrors ( json_decode ( $e -> getMessage ())) -> withInput ();
2016-09-07 20:12:06 +00:00
} catch ( DisplayException $e ) {
2016-01-05 23:31:25 +00:00
Alert :: danger ( $e -> getMessage ()) -> flash ();
} catch ( \Exception $e ) {
Log :: error ( $e );
Alert :: danger ( 'An unhandled exception occured while attempting to edit this node. Please try again.' ) -> flash ();
}
2016-12-07 22:46:38 +00:00
2016-01-05 23:31:25 +00:00
return redirect () -> route ( 'admin.nodes.view' , [
'id' => $id ,
2016-12-07 22:46:38 +00:00
'tab' => 'tab_settings' ,
2016-01-05 23:31:25 +00:00
]) -> withInput ();
}
2016-09-30 01:34:20 +00:00
public function deallocateSingle ( Request $request , $node , $allocation )
2016-01-09 01:01:18 +00:00
{
2017-02-16 18:56:28 +00:00
$query = Models\Allocation :: where ( 'node' , $node ) -> whereNull ( 'server_id' ) -> where ( 'id' , $allocation ) -> delete ();
2016-09-30 01:34:20 +00:00
if (( int ) $query === 0 ) {
2016-01-09 01:01:18 +00:00
return response () -> json ([
2016-12-07 22:46:38 +00:00
'error' => 'Unable to find an allocation matching those details to delete.' ,
2016-01-09 01:01:18 +00:00
], 400 );
}
2016-12-07 22:46:38 +00:00
2016-01-09 01:01:18 +00:00
return response ( '' , 204 );
}
2016-09-30 01:34:20 +00:00
public function deallocateBlock ( Request $request , $node )
{
2017-02-16 18:56:28 +00:00
$query = Models\Allocation :: where ( 'node' , $node ) -> whereNull ( 'server_id' ) -> where ( 'ip' , $request -> input ( 'ip' )) -> delete ();
2016-09-30 01:34:20 +00:00
if (( int ) $query === 0 ) {
Alert :: danger ( 'There was an error while attempting to delete allocations on that IP.' ) -> flash ();
2016-12-07 22:46:38 +00:00
2016-09-30 01:34:20 +00:00
return redirect () -> route ( 'admin.nodes.view' , [
'id' => $node ,
2016-12-07 22:46:38 +00:00
'tab' => 'tab_allocations' ,
2016-09-30 01:34:20 +00:00
]);
}
Alert :: success ( 'Deleted all unallocated ports for <code>' . $request -> input ( 'ip' ) . '</code>.' ) -> flash ();
2016-12-07 22:46:38 +00:00
2016-09-30 01:34:20 +00:00
return redirect () -> route ( 'admin.nodes.view' , [
'id' => $node ,
2016-12-07 22:46:38 +00:00
'tab' => 'tab_allocation' ,
2016-09-30 01:34:20 +00:00
]);
}
public function setAlias ( Request $request , $node )
{
2016-12-07 22:46:38 +00:00
if ( ! $request -> input ( 'allocation' )) {
2016-09-30 01:34:20 +00:00
return response ( 'Missing required parameters.' , 422 );
}
try {
$update = Models\Allocation :: findOrFail ( $request -> input ( 'allocation' ));
2016-09-30 20:01:36 +00:00
$update -> ip_alias = ( empty ( $request -> input ( 'alias' ))) ? null : $request -> input ( 'alias' );
2016-09-30 01:34:20 +00:00
$update -> save ();
return response ( '' , 204 );
} catch ( \Exception $ex ) {
throw $ex ;
}
}
2016-01-10 05:38:16 +00:00
public function getAllocationsJson ( Request $request , $id )
{
$allocations = Models\Allocation :: select ( 'ip' ) -> where ( 'node' , $id ) -> groupBy ( 'ip' ) -> get ();
2016-12-07 22:46:38 +00:00
2016-01-10 05:38:16 +00:00
return response () -> json ( $allocations );
}
public function postAllocations ( Request $request , $id )
{
2016-09-30 21:12:36 +00:00
$validator = Validator :: make ( $request -> all (), [
'allocate_ip.*' => 'required|string' ,
2016-12-07 22:46:38 +00:00
'allocate_port.*' => 'required' ,
2016-09-30 21:12:36 +00:00
]);
if ( $validator -> fails ()) {
return redirect () -> route ( 'admin.nodes.view' , [
'id' => $id ,
2016-12-07 22:46:38 +00:00
'tab' => 'tab_allocation' ,
2016-09-30 21:12:36 +00:00
]) -> withErrors ( $validator -> errors ()) -> withInput ();
}
2016-01-10 05:38:16 +00:00
$processedData = [];
2016-12-07 22:46:38 +00:00
foreach ( $request -> input ( 'allocate_ip' ) as $ip ) {
if ( ! array_key_exists ( $ip , $processedData )) {
2016-01-10 05:38:16 +00:00
$processedData [ $ip ] = [];
}
}
2016-12-07 22:46:38 +00:00
foreach ( $request -> input ( 'allocate_port' ) as $portid => $ports ) {
2016-01-10 05:38:16 +00:00
if ( array_key_exists ( $portid , $request -> input ( 'allocate_ip' ))) {
$json = json_decode ( $ports );
2016-12-07 22:46:38 +00:00
if ( json_last_error () === 0 && ! empty ( $json )) {
foreach ( $json as & $parsed ) {
2016-01-10 05:38:16 +00:00
array_push ( $processedData [ $request -> input ( 'allocate_ip' )[ $portid ]], $parsed -> value );
}
}
}
}
try {
$node = new NodeRepository ;
$node -> addAllocations ( $id , $processedData );
Alert :: success ( 'Successfully added new allocations to this node.' ) -> flash ();
2016-09-07 20:12:06 +00:00
} catch ( DisplayException $e ) {
2016-01-10 05:38:16 +00:00
Alert :: danger ( $e -> getMessage ()) -> flash ();
} catch ( \Exception $e ) {
Log :: error ( $e );
Alert :: danger ( 'An unhandled exception occured while attempting to add allocations this node. Please try again.' ) -> flash ();
} finally {
return redirect () -> route ( 'admin.nodes.view' , [
'id' => $id ,
2016-12-07 22:46:38 +00:00
'tab' => 'tab_allocation' ,
2016-01-10 05:38:16 +00:00
]);
}
}
2016-01-10 21:59:19 +00:00
public function deleteNode ( Request $request , $id )
{
2016-11-26 21:29:13 +00:00
try {
$repo = new NodeRepository ;
$repo -> delete ( $id );
Alert :: success ( 'Successfully deleted the requested node from the panel.' ) -> flash ();
2016-12-07 22:46:38 +00:00
2016-11-26 21:29:13 +00:00
return redirect () -> route ( 'admin.nodes' );
} catch ( DisplayException $e ) {
Alert :: danger ( $e -> getMessage ()) -> flash ();
} catch ( \Exception $e ) {
Log :: error ( $e );
Alert :: danger ( 'An unhandled exception occured while attempting to delete this node. Please try again.' ) -> flash ();
2016-01-10 21:59:19 +00:00
}
2016-11-26 21:29:13 +00:00
return redirect () -> route ( 'admin.nodes.view' , [
'id' => $id ,
2016-12-07 22:46:38 +00:00
'tab' => 'tab_delete' ,
2016-11-26 21:29:13 +00:00
]);
2016-01-10 21:59:19 +00:00
}
2017-01-07 17:10:11 +00:00
2017-01-07 17:39:41 +00:00
public function getConfigurationToken ( Request $request , $id )
{
2017-01-07 17:10:11 +00:00
// Check if Node exists. Will lead to 404 if not.
Models\Node :: findOrFail ( $id );
// Create a token
$token = new Models\NodeConfigurationToken ();
$token -> node = $id ;
$token -> token = str_random ( 32 );
$token -> expires_at = Carbon :: now () -> addMinutes ( 5 ); // Expire in 5 Minutes
$token -> save ();
2017-01-07 17:39:41 +00:00
$token_response = [
2017-01-07 17:10:11 +00:00
'token' => $token -> token ,
2017-01-07 17:39:41 +00:00
'expires_at' => $token -> expires_at -> toDateTimeString (),
];
2017-01-07 17:10:11 +00:00
2017-01-08 14:21:02 +00:00
return response () -> json ( $token_response , 200 );
2017-01-07 17:10:11 +00:00
}
2016-01-05 04:59:45 +00:00
}