2015-12-14 04:22:16 +01:00
< ? php
2016-01-20 01:10:39 +01:00
/**
2016-01-20 22:05:16 +01:00
* Pterodactyl - Panel
2017-01-24 23:57:08 +01:00
* Copyright ( c ) 2015 - 2017 Dane Everitt < dane @ daneeveritt . com >.
2016-01-20 01:10:39 +01:00
*
2016-01-20 21:56:40 +01: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 01:10:39 +01:00
*
2016-01-20 21:56:40 +01:00
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software .
2016-01-20 01:10:39 +01:00
*
2016-01-20 21:56:40 +01: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 01:10:39 +01:00
*/
2016-12-07 23:46:38 +01:00
2015-12-14 04:22:16 +01:00
namespace Pterodactyl\Repositories ;
use DB ;
2016-01-03 00:04:18 +01:00
use Log ;
2016-12-07 23:46:38 +01:00
use Crypt ;
use Validator ;
2015-12-14 04:22:16 +01:00
use Pterodactyl\Models ;
use Pterodactyl\Services\UuidService ;
2017-02-09 23:43:54 +01:00
use GuzzleHttp\Exception\TransferException ;
2016-09-28 03:01:46 +02:00
use Pterodactyl\Services\DeploymentService ;
2015-12-14 04:22:16 +01:00
use Pterodactyl\Exceptions\DisplayException ;
use Pterodactyl\Exceptions\DisplayValidationException ;
class ServerRepository
{
2016-01-19 03:35:37 +01:00
protected $daemonPermissions = [
2016-12-07 23:46:38 +01:00
's:*' ,
2016-01-19 03:35:37 +01:00
];
2015-12-14 04:22:16 +01:00
public function __construct ()
{
//
}
/**
* Generates a SFTP username for a server given a server name .
2016-12-07 23:46:38 +01:00
* format : mumble_67c7a4b0 .
2015-12-14 04:22:16 +01:00
*
* @ param string $name
2017-01-14 04:22:25 +01:00
* @ param string $identifier
2015-12-14 04:22:16 +01:00
* @ return string
*/
2017-01-14 04:22:25 +01:00
protected function generateSFTPUsername ( $name , $identifier = null )
2015-12-14 04:22:16 +01:00
{
2017-01-14 04:22:25 +01:00
if ( is_null ( $identifier ) || ! ctype_alnum ( $identifier )) {
$unique = str_random ( 8 );
} else {
if ( strlen ( $identifier ) < 8 ) {
$unique = $identifier . str_random (( 8 - strlen ( $identifier )));
} else {
$unique = substr ( $identifier , 0 , 8 );
}
}
2015-12-14 04:22:16 +01:00
2017-01-14 04:22:25 +01:00
// Filter the Server Name
$name = trim ( preg_replace ( '/[^\w]+/' , '' , $name ), '_' );
$name = ( strlen ( $name ) < 1 ) ? str_random ( 6 ) : $name ;
return strtolower ( substr ( $name , 0 , 6 ) . '_' . $unique );
2015-12-14 04:22:16 +01:00
}
/**
* Adds a new server to the system .
2016-01-03 00:04:18 +01:00
* @ param array $data An array of data descriptors for creating the server . These should align to the columns in the database .
2016-12-07 23:46:38 +01:00
* @ return int
2015-12-14 04:22:16 +01:00
*/
public function create ( array $data )
{
// Validate Fields
$validator = Validator :: make ( $data , [
2017-02-25 00:19:03 +01:00
'user_id' => 'required|exists:users,id' ,
2016-12-30 21:46:10 +01:00
'name' => 'required|regex:/^([\w .-]{1,200})$/' ,
2016-02-21 07:18:30 +01:00
'memory' => 'required|numeric|min:0' ,
'swap' => 'required|numeric|min:-1' ,
2015-12-14 04:22:16 +01:00
'io' => 'required|numeric|min:10|max:1000' ,
2016-02-21 07:18:30 +01:00
'cpu' => 'required|numeric|min:0' ,
'disk' => 'required|numeric|min:0' ,
2017-02-11 02:26:38 +01:00
'service_id' => 'required|numeric|min:1|exists:services,id' ,
'option_id' => 'required|numeric|min:1|exists:service_options,id' ,
'location_id' => 'required|numeric|min:1|exists:locations,id' ,
'pack_id' => 'sometimes|nullable|numeric|min:0' ,
2016-09-17 00:39:36 +02:00
'startup' => 'string' ,
2016-11-30 17:01:22 +01:00
'auto_deploy' => 'sometimes|boolean' ,
'custom_id' => 'sometimes|required|numeric|unique:servers,id' ,
2015-12-14 04:22:16 +01:00
]);
2017-02-25 00:19:03 +01:00
$validator -> sometimes ( 'node_id' , 'required|numeric|min:1|exists:nodes,id' , function ( $input ) {
2016-12-07 23:46:38 +01:00
return ! ( $input -> auto_deploy );
2016-09-28 03:01:46 +02:00
});
2017-02-25 00:19:03 +01:00
$validator -> sometimes ( 'allocation_id' , 'required|numeric|exists:allocations,id' , function ( $input ) {
return ! ( $input -> auto_deploy );
2016-09-28 03:01:46 +02:00
});
2017-02-25 00:19:03 +01:00
$validator -> sometimes ( 'allocation_additional.*' , 'sometimes|required|numeric|exists:allocations,id' , function ( $input ) {
return ! ( $input -> auto_deploy );
2016-09-28 03:01:46 +02:00
});
2015-12-14 04:22:16 +01:00
// Run validator, throw catchable and displayable exception if it fails.
// Exception includes a JSON result of failed validation rules.
if ( $validator -> fails ()) {
2015-12-15 21:08:41 +01:00
throw new DisplayValidationException ( $validator -> errors ());
2015-12-14 04:22:16 +01:00
}
2017-02-25 00:19:03 +01:00
$user = Models\User :: findOrFail ( $data [ 'user_id' ]);
2015-12-14 04:22:16 +01:00
2016-09-28 03:01:46 +02:00
$autoDeployed = false ;
2017-02-25 00:19:03 +01:00
if ( isset ( $data [ 'auto_deploy' ]) && $data [ 'auto_deploy' ]) {
2016-09-28 03:01:46 +02:00
// This is an auto-deployment situation
// Ignore any other passed node data
2017-02-25 00:19:03 +01:00
unset ( $data [ 'node_id' ], $data [ 'allocation_id' ]);
2016-09-28 03:01:46 +02:00
$autoDeployed = true ;
2017-02-11 02:26:38 +01:00
$node = DeploymentService :: smartRandomNode ( $data [ 'memory' ], $data [ 'disk' ], $data [ 'location_id' ]);
2016-09-28 03:01:46 +02:00
$allocation = DeploymentService :: randomAllocation ( $node -> id );
} else {
2017-02-11 02:26:38 +01:00
$node = Models\Node :: findOrFail ( $data [ 'node_id' ]);
2016-09-28 03:01:46 +02:00
}
2016-09-05 22:21:36 +02:00
2015-12-14 04:22:16 +01:00
// Verify IP & Port are a.) free and b.) assigned to the node.
// We know the node exists because of 'exists:nodes,id' in the validation
2016-12-07 23:46:38 +01:00
if ( ! $autoDeployed ) {
2017-02-25 00:19:03 +01:00
$allocation = Models\Allocation :: where ( 'id' , $data [ 'allocation_id' ]) -> where ( 'node_id' , $data [ 'node_id' ]) -> whereNull ( 'server_id' ) -> first ();
2016-09-05 22:21:36 +02:00
}
2015-12-14 04:22:16 +01:00
// Something failed in the query, either that combo doesn't exist, or it is in use.
2016-12-07 23:46:38 +01:00
if ( ! $allocation ) {
2017-02-25 00:19:03 +01:00
throw new DisplayException ( 'The selected Allocation ID is either already in use, or unavaliable for this node.' );
2015-12-14 04:22:16 +01:00
}
// Validate those Service Option Variables
// We know the service and option exists because of the validation.
// We need to verify that the option exists for the service, and then check for
// any required variable fields. (fields are labeled env_<env_variable>)
2017-02-16 19:56:28 +01:00
$option = Models\ServiceOption :: where ( 'id' , $data [ 'option_id' ]) -> where ( 'service_id' , $data [ 'service_id' ]) -> first ();
2016-12-07 23:46:38 +01:00
if ( ! $option ) {
2015-12-14 04:22:16 +01:00
throw new DisplayException ( 'The requested service option does not exist for the specified service.' );
}
2016-11-27 20:50:10 +01:00
// Validate the Pack
2017-02-25 00:19:03 +01:00
if ( ! isset ( $data [ 'pack_id' ]) || ( int ) $data [ 'pack_id' ] < 1 ) {
2017-02-11 02:26:38 +01:00
$data [ 'pack_id' ] = null ;
2017-02-25 00:19:03 +01:00
} else {
2017-02-16 19:56:28 +01:00
$pack = Models\ServicePack :: where ( 'id' , $data [ 'pack_id' ]) -> where ( 'option_id' , $data [ 'option_id' ]) -> first ();
2016-12-14 22:56:25 +01:00
if ( ! $pack ) {
2016-11-27 20:50:10 +01:00
throw new DisplayException ( 'The requested service pack does not seem to exist for this combination.' );
}
}
2016-01-04 00:10:28 +01:00
// Load up the Service Information
2017-02-05 23:58:17 +01:00
$service = Models\Service :: find ( $option -> service_id );
2016-01-04 00:10:28 +01:00
2015-12-14 04:22:16 +01:00
// Check those Variables
2017-02-12 22:02:23 +01:00
$variables = Models\ServiceVariable :: where ( 'option_id' , $data [ 'option_id' ]) -> get ();
2015-12-15 21:08:41 +01:00
$variableList = [];
2015-12-14 04:22:16 +01:00
if ( $variables ) {
2016-12-07 23:46:38 +01:00
foreach ( $variables as $variable ) {
2015-12-14 04:22:16 +01:00
// Is the variable required?
2016-12-30 22:00:51 +01:00
if ( ! isset ( $data [ 'env_' . $variable -> env_variable ])) {
2017-02-25 00:19:03 +01:00
if ( $variable -> required ) {
2015-12-14 04:22:16 +01:00
throw new DisplayException ( 'A required service option variable field (env_' . $variable -> env_variable . ') was missing from the request.' );
}
2016-12-12 20:30:57 +01:00
$variableList [] = [
2016-01-04 00:10:28 +01:00
'id' => $variable -> id ,
'env' => $variable -> env_variable ,
2016-12-07 23:46:38 +01:00
'val' => $variable -> default_value ,
2016-12-12 20:30:57 +01:00
];
2015-12-14 04:22:16 +01:00
continue ;
}
// Check aganist Regex Pattern
2016-12-07 23:46:38 +01:00
if ( ! is_null ( $variable -> regex ) && ! preg_match ( $variable -> regex , $data [ 'env_' . $variable -> env_variable ])) {
2015-12-14 04:22:16 +01:00
throw new DisplayException ( 'Failed to validate service option variable field (env_' . $variable -> env_variable . ') aganist regex (' . $variable -> regex . ').' );
}
2016-12-12 20:30:57 +01:00
$variableList [] = [
2016-01-04 00:10:28 +01:00
'id' => $variable -> id ,
'env' => $variable -> env_variable ,
2016-12-07 23:46:38 +01:00
'val' => $data [ 'env_' . $variable -> env_variable ],
2016-12-12 20:30:57 +01:00
];
2015-12-14 04:22:16 +01:00
continue ;
2015-12-15 21:08:41 +01:00
}
}
// Check Overallocation
2016-12-07 23:46:38 +01:00
if ( ! $autoDeployed ) {
2016-09-28 03:01:46 +02:00
if ( is_numeric ( $node -> memory_overallocate ) || is_numeric ( $node -> disk_overallocate )) {
2017-02-17 18:08:11 +01:00
$totals = Models\Server :: select ( DB :: raw ( 'SUM(memory) as memory, SUM(disk) as disk' )) -> where ( 'node_id' , $node -> id ) -> first ();
2015-12-15 21:08:41 +01:00
2016-09-28 03:01:46 +02:00
// Check memory limits
if ( is_numeric ( $node -> memory_overallocate )) {
$newMemory = $totals -> memory + $data [ 'memory' ];
$memoryLimit = ( $node -> memory * ( 1 + ( $node -> memory_overallocate / 100 )));
2016-12-07 23:46:38 +01:00
if ( $newMemory > $memoryLimit ) {
2016-09-28 03:01:46 +02:00
throw new DisplayException ( 'The amount of memory allocated to this server would put the node over its allocation limits. This node is allowed ' . ( $node -> memory_overallocate + 100 ) . '% of its assigned ' . $node -> memory . 'Mb of memory (' . $memoryLimit . 'Mb) of which ' . (( $totals -> memory / $node -> memory ) * 100 ) . '% (' . $totals -> memory . 'Mb) is in use already. By allocating this server the node would be at ' . (( $newMemory / $node -> memory ) * 100 ) . '% (' . $newMemory . 'Mb) usage.' );
}
2015-12-15 21:08:41 +01:00
}
2016-09-28 03:01:46 +02:00
// Check Disk Limits
if ( is_numeric ( $node -> disk_overallocate )) {
$newDisk = $totals -> disk + $data [ 'disk' ];
$diskLimit = ( $node -> disk * ( 1 + ( $node -> disk_overallocate / 100 )));
2016-12-07 23:46:38 +01:00
if ( $newDisk > $diskLimit ) {
2016-09-28 03:01:46 +02:00
throw new DisplayException ( 'The amount of disk allocated to this server would put the node over its allocation limits. This node is allowed ' . ( $node -> disk_overallocate + 100 ) . '% of its assigned ' . $node -> disk . 'Mb of disk (' . $diskLimit . 'Mb) of which ' . (( $totals -> disk / $node -> disk ) * 100 ) . '% (' . $totals -> disk . 'Mb) is in use already. By allocating this server the node would be at ' . (( $newDisk / $node -> disk ) * 100 ) . '% (' . $newDisk . 'Mb) usage.' );
}
2015-12-15 21:08:41 +01:00
}
}
}
DB :: beginTransaction ();
2016-02-27 16:30:59 +01:00
try {
$uuid = new UuidService ;
// Add Server to the Database
$server = new Models\Server ;
2016-10-14 21:34:01 +02:00
$genUuid = $uuid -> generate ( 'servers' , 'uuid' );
2016-10-14 21:58:52 +02:00
$genShortUuid = $uuid -> generateShort ( 'servers' , 'uuidShort' , $genUuid );
2016-12-07 23:46:38 +01:00
2016-11-30 17:01:22 +01:00
if ( isset ( $data [ 'custom_id' ])) {
$server -> id = $data [ 'custom_id' ];
}
2016-02-27 16:30:59 +01:00
$server -> fill ([
2016-10-14 21:34:01 +02:00
'uuid' => $genUuid ,
'uuidShort' => $genShortUuid ,
2017-02-11 02:26:38 +01:00
'node_id' => $node -> id ,
2016-02-27 16:30:59 +01:00
'name' => $data [ 'name' ],
2016-09-02 03:21:01 +02:00
'suspended' => 0 ,
2017-02-11 02:26:38 +01:00
'owner_id' => $user -> id ,
2016-02-27 16:30:59 +01:00
'memory' => $data [ 'memory' ],
'swap' => $data [ 'swap' ],
'disk' => $data [ 'disk' ],
'io' => $data [ 'io' ],
'cpu' => $data [ 'cpu' ],
'oom_disabled' => ( isset ( $data [ 'oom_disabled' ])) ? true : false ,
2017-02-16 19:56:28 +01:00
'allocation_id' => $allocation -> id ,
2017-02-11 02:26:38 +01:00
'service_id' => $data [ 'service_id' ],
'option_id' => $data [ 'option_id' ],
'pack_id' => $data [ 'pack_id' ],
2016-02-27 16:30:59 +01:00
'startup' => $data [ 'startup' ],
'daemonSecret' => $uuid -> generate ( 'servers' , 'daemonSecret' ),
2017-02-25 00:19:03 +01:00
'image' => ( isset ( $data [ 'custom_container' ])) ? $data [ 'custom_container' ] : $option -> docker_image ,
2016-10-14 21:34:01 +02:00
'username' => $this -> generateSFTPUsername ( $data [ 'name' ], $genShortUuid ),
2016-12-07 23:46:38 +01:00
'sftp_password' => Crypt :: encrypt ( 'not set' ),
2016-02-27 16:30:59 +01:00
]);
$server -> save ();
2015-12-15 21:08:41 +01:00
2016-02-27 16:30:59 +01:00
// Mark Allocation in Use
2017-02-11 02:26:38 +01:00
$allocation -> server_id = $server -> id ;
2016-02-27 16:30:59 +01:00
$allocation -> save ();
2015-12-15 21:08:41 +01:00
2017-02-25 00:19:03 +01:00
// Add Additional Allocations
if ( isset ( $data [ 'allocation_additional' ]) && is_array ( $data [ 'allocation_additional' ])) {
2017-02-25 00:23:03 +01:00
foreach ( $data [ 'allocation_additional' ] as $allocation ) {
2017-02-25 00:19:03 +01:00
$model = Models\Allocation :: where ( 'id' , $allocation ) -> where ( 'node_id' , $data [ 'node_id' ]) -> whereNull ( 'server_id' ) -> first ();
if ( ! $model ) {
continue ;
}
$model -> server_id = $server -> id ;
$model -> save ();
}
}
2016-02-27 16:30:59 +01:00
// Add Variables
2016-12-12 20:30:57 +01:00
$environmentVariables = [
2016-12-07 23:46:38 +01:00
'STARTUP' => $data [ 'startup' ],
2016-12-12 20:30:57 +01:00
];
2016-12-07 23:46:38 +01:00
foreach ( $variableList as $item ) {
2016-12-12 20:30:57 +01:00
$environmentVariables [ $item [ 'env' ]] = $item [ 'val' ];
2017-02-12 22:03:17 +01:00
Models\ServerVariable :: create ([
2016-02-27 16:30:59 +01:00
'server_id' => $server -> id ,
'variable_id' => $item [ 'id' ],
2016-12-07 23:46:38 +01:00
'variable_value' => $item [ 'val' ],
2016-02-27 16:30:59 +01:00
]);
}
2015-12-15 21:08:41 +01:00
2017-02-25 00:19:03 +01:00
$server -> load ( 'allocation' , 'allocations' );
2017-02-09 23:43:54 +01:00
$node -> guzzleClient ([ 'X-Access-Token' => $node -> daemonSecret ]) -> request ( 'POST' , '/servers' , [
2016-01-04 00:10:28 +01:00
'json' => [
'uuid' => ( string ) $server -> uuid ,
'user' => $server -> username ,
'build' => [
'default' => [
2017-02-25 00:19:03 +01:00
'ip' => $server -> allocation -> ip ,
'port' => $server -> allocation -> port ,
2016-01-04 00:10:28 +01:00
],
2017-02-25 00:19:03 +01:00
'ports' => $server -> allocations -> groupBy ( 'ip' ) -> map ( function ( $item ) {
return $item -> pluck ( 'port' );
}) -> toArray (),
2016-01-04 00:10:28 +01:00
'env' => $environmentVariables ,
'memory' => ( int ) $server -> memory ,
'swap' => ( int ) $server -> swap ,
'io' => ( int ) $server -> io ,
'cpu' => ( int ) $server -> cpu ,
'disk' => ( int ) $server -> disk ,
2017-02-25 00:19:03 +01:00
'image' => ( isset ( $data [ 'custom_container' ])) ? $data [ 'custom_container' ] : $option -> docker_image ,
2016-01-04 00:10:28 +01:00
],
'service' => [
'type' => $service -> file ,
2016-11-27 20:50:10 +01:00
'option' => $option -> tag ,
'pack' => ( isset ( $pack )) ? $pack -> uuid : null ,
2016-01-04 00:10:28 +01:00
],
'keys' => [
2016-11-27 20:50:10 +01:00
( string ) $server -> daemonSecret => $this -> daemonPermissions ,
2016-01-04 00:10:28 +01:00
],
2016-11-27 20:50:10 +01:00
'rebuild' => false ,
2016-12-07 23:46:38 +01:00
],
2016-01-04 00:10:28 +01:00
]);
2015-12-15 21:08:41 +01:00
DB :: commit ();
2016-12-07 23:46:38 +01:00
2017-02-11 02:26:38 +01:00
return $server ;
2017-02-09 23:43:54 +01:00
} catch ( TransferException $ex ) {
2016-01-04 00:10:28 +01:00
DB :: rollBack ();
2016-09-05 22:21:36 +02:00
throw new DisplayException ( 'There was an error while attempting to connect to the daemon to add this server.' , $ex );
2016-01-04 00:10:28 +01:00
} catch ( \Exception $ex ) {
2015-12-15 21:08:41 +01:00
DB :: rollBack ();
2016-01-04 00:10:28 +01:00
throw $ex ;
2015-12-15 21:08:41 +01:00
}
2015-12-14 04:22:16 +01:00
}
2016-01-03 00:04:18 +01:00
/**
2016-12-07 23:46:38 +01:00
* [ updateDetails description ] .
* @ param int $id
2016-01-03 00:04:18 +01:00
* @ param array $data
2016-12-07 23:46:38 +01:00
* @ return bool
2016-01-03 00:04:18 +01:00
*/
public function updateDetails ( $id , array $data )
{
$uuid = new UuidService ;
$resetDaemonKey = false ;
// Validate Fields
$validator = Validator :: make ( $data , [
2017-03-05 01:03:49 +01:00
'owner_id' => 'sometimes|required|integer|exists:users,id' ,
2017-02-25 06:48:12 +01:00
'name' => 'sometimes|required|regex:([\w .-]{1,200})' ,
2017-03-04 05:38:21 +01:00
'reset_token' => 'sometimes|required|accepted' ,
2016-01-03 00:04:18 +01:00
]);
// Run validator, throw catchable and displayable exception if it fails.
// Exception includes a JSON result of failed validation rules.
if ( $validator -> fails ()) {
throw new DisplayValidationException ( $validator -> errors ());
}
DB :: beginTransaction ();
2016-02-27 16:30:59 +01:00
try {
2017-02-09 23:43:54 +01:00
$server = Models\Server :: with ( 'user' ) -> findOrFail ( $id );
2016-02-27 16:30:59 +01:00
// Update daemon secret if it was passed.
2017-03-05 01:03:49 +01:00
if ( isset ( $data [ 'reset_token' ]) || ( isset ( $data [ 'owner_id' ]) && ( int ) $data [ 'owner_id' ] !== $server -> user -> id )) {
2016-02-27 16:30:59 +01:00
$oldDaemonKey = $server -> daemonSecret ;
$server -> daemonSecret = $uuid -> generate ( 'servers' , 'daemonSecret' );
$resetDaemonKey = true ;
}
2016-01-03 00:04:18 +01:00
2016-02-27 16:30:59 +01:00
// Update Server Owner if it was passed.
2017-03-05 01:03:49 +01:00
if ( isset ( $data [ 'owner_id' ]) && ( int ) $data [ 'owner_id' ] !== $server -> user -> id ) {
2017-02-25 06:48:12 +01:00
$server -> owner_id = $data [ 'owner_id' ];
2016-02-27 16:30:59 +01:00
}
2016-01-03 00:04:18 +01:00
2016-02-27 16:30:59 +01:00
// Update Server Name if it was passed.
if ( isset ( $data [ 'name' ])) {
$server -> name = $data [ 'name' ];
}
2016-01-03 00:04:18 +01:00
2016-02-27 16:30:59 +01:00
// Save our changes
$server -> save ();
2016-01-03 00:04:18 +01:00
2016-02-27 16:30:59 +01:00
// Do we need to update? If not, return successful.
2016-12-07 23:46:38 +01:00
if ( ! $resetDaemonKey ) {
2016-02-27 16:30:59 +01:00
DB :: commit ();
2016-12-07 23:46:38 +01:00
2016-02-27 16:30:59 +01:00
return true ;
}
2016-01-03 00:04:18 +01:00
2017-02-09 23:43:54 +01:00
$res = $server -> node -> guzzleClient ([
'X-Access-Server' => $server -> uuid ,
'X-Access-Token' => $server -> node -> daemonSecret ,
]) -> request ( 'PATCH' , '/server' , [
2016-01-03 00:04:18 +01:00
'exceptions' => false ,
'json' => [
'keys' => [
( string ) $oldDaemonKey => [],
2016-12-07 23:46:38 +01:00
( string ) $server -> daemonSecret => $this -> daemonPermissions ,
],
],
2016-01-03 00:04:18 +01:00
]);
if ( $res -> getStatusCode () === 204 ) {
DB :: commit ();
2016-12-07 23:46:38 +01:00
2016-01-03 00:04:18 +01:00
return true ;
} else {
throw new DisplayException ( 'Daemon returned a a non HTTP/204 error code. HTTP/' + $res -> getStatusCode ());
}
} catch ( \Exception $ex ) {
2016-01-03 05:21:22 +01:00
DB :: rollBack ();
2016-01-03 00:04:18 +01:00
Log :: error ( $ex );
throw new DisplayException ( 'An error occured while attempting to update this server\'s information.' );
}
}
2016-09-18 02:14:36 +02:00
/**
2016-12-07 23:46:38 +01:00
* [ updateContainer description ] .
2016-09-18 02:14:36 +02:00
* @ param int $id
* @ param array $data
* @ return bool
*/
public function updateContainer ( $id , array $data )
{
$validator = Validator :: make ( $data , [
2017-02-25 06:48:12 +01:00
'docker_image' => 'required|string' ,
2016-09-18 02:14:36 +02:00
]);
// Run validator, throw catchable and displayable exception if it fails.
// Exception includes a JSON result of failed validation rules.
if ( $validator -> fails ()) {
throw new DisplayValidationException ( $validator -> errors ());
}
DB :: beginTransaction ();
try {
$server = Models\Server :: findOrFail ( $id );
2017-02-25 06:48:12 +01:00
$server -> image = $data [ 'docker_image' ];
2016-09-18 02:14:36 +02:00
$server -> save ();
2017-02-09 23:43:54 +01:00
$server -> node -> guzzleClient ([
'X-Access-Server' => $server -> uuid ,
'X-Access-Token' => $server -> node -> daemonSecret ,
]) -> request ( 'PATCH' , '/server' , [
2016-09-18 02:14:36 +02:00
'json' => [
'build' => [
2016-12-07 23:46:38 +01:00
'image' => $server -> image ,
],
],
2016-09-18 02:14:36 +02:00
]);
DB :: commit ();
2016-12-07 23:46:38 +01:00
2016-09-18 02:14:36 +02:00
return true ;
2017-02-09 23:43:54 +01:00
} catch ( TransferException $ex ) {
2016-09-18 02:14:36 +02:00
DB :: rollBack ();
2017-03-05 01:03:49 +01:00
throw new DisplayException ( 'A TransferException occured while attempting to update the container image. Is the daemon online? This error has been logged.' , $ex );
2016-09-18 02:14:36 +02:00
} catch ( \Exception $ex ) {
DB :: rollBack ();
throw $ex ;
}
}
2016-01-03 05:21:22 +01:00
/**
2016-12-07 23:46:38 +01:00
* [ changeBuild description ] .
* @ param int $id
2016-01-03 05:21:22 +01:00
* @ param array $data
2016-12-07 23:46:38 +01:00
* @ return bool
2016-01-03 05:21:22 +01:00
*/
public function changeBuild ( $id , array $data )
{
$validator = Validator :: make ( $data , [
2017-02-25 06:48:12 +01:00
'allocation_id' => 'sometimes|required|exists:allocations,id' ,
'add_allocations' => 'sometimes|required|array' ,
'remove_allocations' => 'sometimes|required|array' ,
'memory' => 'sometimes|required|integer|min:0' ,
'swap' => 'sometimes|required|integer|min:-1' ,
'io' => 'sometimes|required|integer|min:10|max:1000' ,
'cpu' => 'sometimes|required|integer|min:0' ,
'disk' => 'sometimes|required|integer|min:0' ,
2016-01-03 05:21:22 +01:00
]);
// Run validator, throw catchable and displayable exception if it fails.
// Exception includes a JSON result of failed validation rules.
if ( $validator -> fails ()) {
throw new DisplayValidationException ( $validator -> errors ());
}
DB :: beginTransaction ();
2016-02-27 16:30:59 +01:00
try {
2017-02-09 23:43:54 +01:00
$server = Models\Server :: with ( 'allocation' , 'allocations' ) -> findOrFail ( $id );
2016-09-15 00:36:12 +02:00
$newBuild = [];
2017-02-25 06:48:12 +01:00
$newAllocations = [];
2016-09-15 00:36:12 +02:00
2017-02-25 06:48:12 +01:00
if ( isset ( $data [ 'allocation_id' ])) {
if (( int ) $data [ 'allocation_id' ] !== $server -> allocation_id ) {
$selection = $server -> allocations -> where ( 'id' , $data [ 'allocation_id' ]) -> first ();
2016-12-07 23:46:38 +01:00
if ( ! $selection ) {
2017-02-25 06:48:12 +01:00
throw new DisplayException ( 'The requested default connection is not allocated to this server.' );
2016-02-27 16:30:59 +01:00
}
2016-01-03 05:21:22 +01:00
2017-02-03 00:21:36 +01:00
$server -> allocation_id = $selection -> id ;
2017-02-25 06:48:12 +01:00
$newBuild [ 'default' ] = [ 'ip' => $selection -> ip , 'port' => $selection -> port ];
2016-08-31 22:03:37 +02:00
2017-02-09 23:43:54 +01:00
$server -> load ( 'allocation' );
2016-02-27 16:30:59 +01:00
}
2016-01-03 05:21:22 +01:00
}
2016-09-15 00:36:12 +02:00
$newPorts = false ;
2016-02-27 16:30:59 +01:00
// Remove Assignments
2017-02-25 06:48:12 +01:00
if ( isset ( $data [ 'remove_allocations' ])) {
foreach ( $data [ 'remove_allocations' ] as $allocation ) {
2016-02-27 16:30:59 +01:00
// Can't remove the assigned IP/Port combo
2017-02-25 06:48:12 +01:00
if (( int ) $allocation === $server -> allocation_id ) {
continue ;
2016-02-27 16:30:59 +01:00
}
2016-01-03 05:21:22 +01:00
2016-10-24 01:07:29 +02:00
$newPorts = true ;
2017-02-25 06:48:12 +01:00
Models\Allocation :: where ( 'id' , $allocation ) -> where ( 'server_id' , $server -> id ) -> update ([
2017-02-16 19:56:28 +01:00
'server_id' => null ,
2016-02-27 16:30:59 +01:00
]);
}
2017-02-09 23:43:54 +01:00
$server -> load ( 'allocations' );
2016-01-03 05:21:22 +01:00
}
2016-02-27 16:30:59 +01:00
// Add Assignments
2017-02-25 06:48:12 +01:00
if ( isset ( $data [ 'add_allocations' ])) {
foreach ( $data [ 'add_allocations' ] as $allocation ) {
$model = Models\Allocation :: where ( 'id' , $allocation ) -> whereNull ( 'server_id' ) -> first ();
if ( ! $model ) {
continue ;
2016-02-27 16:30:59 +01:00
}
2016-01-03 05:21:22 +01:00
2016-10-24 01:07:29 +02:00
$newPorts = true ;
2017-02-25 06:48:12 +01:00
$model -> update ([
2017-02-16 19:56:28 +01:00
'server_id' => $server -> id ,
2016-02-27 16:30:59 +01:00
]);
}
2017-02-09 23:43:54 +01:00
$server -> load ( 'allocations' );
2016-01-03 05:21:22 +01:00
}
2017-02-25 06:48:12 +01:00
if ( $newPorts ) {
$newBuild [ 'ports|overwrite' ] = $server -> allocations -> groupBy ( 'ip' ) -> map ( function ( $item ) {
return $item -> pluck ( 'port' );
}) -> toArray ();
2016-09-15 00:36:12 +02:00
}
2016-02-27 16:30:59 +01:00
// @TODO: verify that server can be set to this much memory without
// going over node limits.
2016-10-24 01:07:29 +02:00
if ( isset ( $data [ 'memory' ]) && $server -> memory !== ( int ) $data [ 'memory' ]) {
2016-02-27 16:30:59 +01:00
$server -> memory = $data [ 'memory' ];
2016-10-24 01:07:29 +02:00
$newBuild [ 'memory' ] = ( int ) $server -> memory ;
2016-02-27 16:30:59 +01:00
}
2016-01-03 05:21:22 +01:00
2016-10-24 01:07:29 +02:00
if ( isset ( $data [ 'swap' ]) && $server -> swap !== ( int ) $data [ 'swap' ]) {
2016-02-27 16:30:59 +01:00
$server -> swap = $data [ 'swap' ];
2016-10-24 01:07:29 +02:00
$newBuild [ 'swap' ] = ( int ) $server -> swap ;
2016-02-27 16:30:59 +01:00
}
2016-01-03 05:21:22 +01:00
2016-02-27 16:30:59 +01:00
// @TODO: verify that server can be set to this much disk without
// going over node limits.
2016-10-24 01:07:29 +02:00
if ( isset ( $data [ 'disk' ]) && $server -> disk !== ( int ) $data [ 'disk' ]) {
2016-02-27 16:30:59 +01:00
$server -> disk = $data [ 'disk' ];
2016-10-24 01:07:29 +02:00
$newBuild [ 'disk' ] = ( int ) $server -> disk ;
2016-02-27 16:30:59 +01:00
}
2016-01-03 05:21:22 +01:00
2016-10-24 01:07:29 +02:00
if ( isset ( $data [ 'cpu' ]) && $server -> cpu !== ( int ) $data [ 'cpu' ]) {
2016-02-27 16:30:59 +01:00
$server -> cpu = $data [ 'cpu' ];
2016-10-24 01:07:29 +02:00
$newBuild [ 'cpu' ] = ( int ) $server -> cpu ;
2016-02-27 16:30:59 +01:00
}
2016-01-03 05:21:22 +01:00
2016-10-24 01:07:29 +02:00
if ( isset ( $data [ 'io' ]) && $server -> io !== ( int ) $data [ 'io' ]) {
2016-02-27 16:30:59 +01:00
$server -> io = $data [ 'io' ];
2016-10-24 01:07:29 +02:00
$newBuild [ 'io' ] = ( int ) $server -> io ;
2016-02-27 16:30:59 +01:00
}
2016-01-03 05:21:22 +01:00
2016-08-31 22:09:23 +02:00
// Try save() here so if it fails we haven't contacted the daemon
// This won't be committed unless the HTTP request succeedes anyways
$server -> save ();
2016-12-07 23:46:38 +01:00
if ( ! empty ( $newBuild )) {
2017-02-09 23:43:54 +01:00
$server -> node -> guzzleClient ([
'X-Access-Server' => $server -> uuid ,
'X-Access-Token' => $server -> node -> daemonSecret ,
]) -> request ( 'PATCH' , '/server' , [
2016-10-24 01:07:29 +02:00
'json' => [
2016-12-07 23:46:38 +01:00
'build' => $newBuild ,
],
2016-10-24 01:07:29 +02:00
]);
}
2016-08-31 22:09:23 +02:00
2016-01-03 05:21:22 +01:00
DB :: commit ();
2016-12-07 23:46:38 +01:00
2017-02-25 06:48:12 +01:00
return $server ;
2017-02-09 23:43:54 +01:00
} catch ( TransferException $ex ) {
2016-01-03 05:21:22 +01:00
DB :: rollBack ();
2017-03-05 01:03:49 +01:00
throw new DisplayException ( 'A TransferException occured while attempting to update the server configuration, check that the daemon is online. This error has been logged.' , $ex );
2016-01-23 03:43:56 +01:00
} catch ( \Exception $ex ) {
DB :: rollBack ();
throw $ex ;
2016-01-03 05:21:22 +01:00
}
}
2016-02-13 23:36:03 +01:00
public function updateStartup ( $id , array $data , $admin = false )
2016-01-11 00:57:22 +01:00
{
2017-02-09 23:43:54 +01:00
$server = Models\Server :: with ( 'variables' , 'option.variables' ) -> findOrFail ( $id );
2016-01-11 00:57:22 +01:00
DB :: beginTransaction ();
2016-02-13 23:29:52 +01:00
try {
2016-02-27 16:30:59 +01:00
// Check the startup
2017-02-16 20:23:22 +01:00
if ( isset ( $data [ 'startup' ]) && $admin ) {
2016-02-27 16:30:59 +01:00
$server -> startup = $data [ 'startup' ];
$server -> save ();
}
// Check those Variables
2017-02-09 23:43:54 +01:00
$server -> option -> variables -> transform ( function ( $item , $key ) use ( $server ) {
$displayValue = $server -> variables -> where ( 'variable_id' , $item -> id ) -> pluck ( 'variable_value' ) -> first ();
$item -> server_value = ( ! is_null ( $displayValue )) ? $displayValue : $item -> default_value ;
return $item ;
});
2016-02-13 23:29:52 +01:00
$variableList = [];
2017-02-09 23:43:54 +01:00
if ( $server -> option -> variables ) {
foreach ( $server -> option -> variables as & $variable ) {
2016-02-13 23:29:52 +01:00
// Move on if the new data wasn't even sent
2016-12-07 23:46:38 +01:00
if ( ! isset ( $data [ $variable -> env_variable ])) {
2016-12-12 20:30:57 +01:00
$variableList [] = [
2016-02-13 23:29:52 +01:00
'id' => $variable -> id ,
'env' => $variable -> env_variable ,
2017-02-09 23:43:54 +01:00
'val' => $variable -> server_value ,
2016-12-12 20:30:57 +01:00
];
2016-02-13 23:29:52 +01:00
continue ;
}
// Update Empty but skip validation
if ( empty ( $data [ $variable -> env_variable ])) {
2016-12-12 20:30:57 +01:00
$variableList [] = [
2016-02-13 23:29:52 +01:00
'id' => $variable -> id ,
'env' => $variable -> env_variable ,
2016-12-07 23:46:38 +01:00
'val' => null ,
2016-12-12 20:30:57 +01:00
];
2016-02-13 23:29:52 +01:00
continue ;
}
// Is the variable required?
// @TODO: is this even logical to perform this check?
if ( isset ( $data [ $variable -> env_variable ]) && empty ( $data [ $variable -> env_variable ])) {
2017-02-09 23:43:54 +01:00
if ( $variable -> required ) {
2016-02-13 23:29:52 +01:00
throw new DisplayException ( 'A required service option variable field (' . $variable -> env_variable . ') was included in this request but was left blank.' );
}
}
// Variable hidden and/or not user editable
2017-02-09 23:43:54 +01:00
if (( ! $variable -> user_viewable || ! $variable -> user_editable ) && ! $admin ) {
2016-02-13 23:29:52 +01:00
throw new DisplayException ( 'A service option variable field (' . $variable -> env_variable . ') does not exist or you do not have permission to edit it.' );
}
// Check aganist Regex Pattern
2016-12-07 23:46:38 +01:00
if ( ! is_null ( $variable -> regex ) && ! preg_match ( $variable -> regex , $data [ $variable -> env_variable ])) {
2016-02-13 23:29:52 +01:00
throw new DisplayException ( 'Failed to validate service option variable field (' . $variable -> env_variable . ') aganist regex (' . $variable -> regex . ').' );
}
2016-01-11 00:57:22 +01:00
2016-12-12 20:30:57 +01:00
$variableList [] = [
2016-01-11 00:57:22 +01:00
'id' => $variable -> id ,
'env' => $variable -> env_variable ,
2016-12-07 23:46:38 +01:00
'val' => $data [ $variable -> env_variable ],
2016-12-12 20:30:57 +01:00
];
2016-01-11 00:57:22 +01:00
}
}
2016-02-13 23:29:52 +01:00
// Add Variables
2016-12-12 20:30:57 +01:00
$environmentVariables = [
2016-12-07 23:46:38 +01:00
'STARTUP' => $server -> startup ,
2016-12-12 20:30:57 +01:00
];
2016-12-07 23:46:38 +01:00
foreach ( $variableList as $item ) {
2016-12-12 20:30:57 +01:00
$environmentVariables [ $item [ 'env' ]] = $item [ 'val' ];
2016-01-11 00:57:22 +01:00
2016-02-13 23:29:52 +01:00
// Update model or make a new record if it doesn't exist.
2017-02-12 22:03:17 +01:00
$model = Models\ServerVariable :: firstOrNew ([
2016-02-13 23:29:52 +01:00
'variable_id' => $item [ 'id' ],
2016-12-07 23:46:38 +01:00
'server_id' => $server -> id ,
2016-02-13 23:29:52 +01:00
]);
$model -> variable_value = $item [ 'val' ];
$model -> save ();
}
2016-01-11 00:57:22 +01:00
2017-02-09 23:43:54 +01:00
$server -> node -> guzzleClient ([
'X-Access-Server' => $server -> uuid ,
'X-Access-Token' => $server -> node -> daemonSecret ,
]) -> request ( 'PATCH' , '/server' , [
2016-01-11 00:57:22 +01:00
'json' => [
'build' => [
2016-12-07 23:46:38 +01:00
'env|overwrite' => $environmentVariables ,
],
],
2016-01-11 00:57:22 +01:00
]);
DB :: commit ();
2016-12-07 23:46:38 +01:00
2016-01-11 00:57:22 +01:00
return true ;
2017-02-09 23:43:54 +01:00
} catch ( TransferException $ex ) {
2016-01-11 00:57:22 +01:00
DB :: rollBack ();
2016-08-17 01:20:58 +02:00
throw new DisplayException ( 'An error occured while attempting to update the server configuration.' , $ex );
2016-02-13 23:29:52 +01:00
} catch ( \Exception $ex ) {
2016-01-11 00:57:22 +01:00
DB :: rollBack ();
2016-02-13 23:29:52 +01:00
throw $ex ;
2016-01-11 00:57:22 +01:00
}
}
2017-03-05 01:03:49 +01:00
public function queueDeletion ( $id , $force = false )
2016-01-04 05:16:03 +01:00
{
$server = Models\Server :: findOrFail ( $id );
DB :: beginTransaction ();
2016-02-27 16:30:59 +01:00
try {
2017-03-05 01:03:49 +01:00
if ( $force ) {
2016-10-28 02:05:29 +02:00
$server -> installed = 3 ;
$server -> save ();
}
$server -> delete ();
2017-02-01 02:04:34 +01:00
2017-01-25 01:15:03 +01:00
return DB :: commit ();
2016-10-28 02:05:29 +02:00
} catch ( \Exception $ex ) {
DB :: rollBack ();
throw $ex ;
}
}
2017-03-05 01:03:49 +01:00
public function delete ( $id , $force = false )
2016-12-07 23:46:38 +01:00
{
2017-02-09 23:43:54 +01:00
$server = Models\Server :: withTrashed () -> with ( 'node' ) -> findOrFail ( $id );
2016-10-28 02:05:29 +02:00
// Handle server being restored previously or
// an accidental queue.
2016-12-07 23:46:38 +01:00
if ( ! $server -> trashed ()) {
2016-10-28 02:05:29 +02:00
return ;
}
DB :: beginTransaction ();
try {
// Unassign Allocations
2017-02-11 02:26:38 +01:00
Models\Allocation :: where ( 'server_id' , $server -> id ) -> update ([
'server_id' => null ,
2016-02-27 16:30:59 +01:00
]);
2016-01-04 05:16:03 +01:00
2016-02-27 16:30:59 +01:00
// Remove Variables
2017-02-12 22:03:17 +01:00
Models\ServerVariable :: where ( 'server_id' , $server -> id ) -> delete ();
2016-01-04 05:16:03 +01:00
2016-02-27 16:30:59 +01:00
// Remove SubUsers
2017-02-19 04:57:50 +01:00
foreach ( Models\Subuser :: with ( 'permissions' ) -> where ( 'server_id' , $server -> id ) -> get () as & $subuser ) {
foreach ( $subuser -> permissions as & $permission ) {
2017-02-16 19:26:39 +01:00
$permission -> delete ();
}
$subuser -> delete ();
}
2016-01-04 05:16:03 +01:00
2016-02-27 16:30:59 +01:00
// Remove Downloads
Models\Download :: where ( 'server' , $server -> uuid ) -> delete ();
2016-01-04 05:16:03 +01:00
2016-10-28 02:05:29 +02:00
// Clear Tasks
Models\Task :: where ( 'server' , $server -> id ) -> delete ();
2016-10-24 01:21:57 +02:00
// Delete Databases
2016-10-28 02:05:29 +02:00
// This is the one un-recoverable point where
// transactions will not save us.
2016-10-24 01:21:57 +02:00
$repository = new DatabaseRepository ;
2016-12-07 23:46:38 +01:00
foreach ( Models\Database :: select ( 'id' ) -> where ( 'server_id' , $server -> id ) -> get () as & $database ) {
2016-10-24 01:21:57 +02:00
$repository -> drop ( $database -> id );
}
2017-02-16 19:26:39 +01:00
$server -> node -> guzzleClient ([
2017-02-09 23:43:54 +01:00
'X-Access-Token' => $server -> node -> daemonSecret ,
'X-Access-Server' => $server -> uuid ,
]) -> request ( 'DELETE' , '/servers' );
2016-01-04 05:16:03 +01:00
2016-10-28 02:05:29 +02:00
$server -> forceDelete ();
2016-01-04 05:16:03 +01:00
DB :: commit ();
2017-02-09 23:43:54 +01:00
} catch ( TransferException $ex ) {
2016-10-28 02:05:29 +02:00
// Set installed is set to 3 when force deleting.
if ( $server -> installed === 3 || $force ) {
$server -> forceDelete ();
2016-01-04 05:16:03 +01:00
DB :: commit ();
} else {
DB :: rollBack ();
2016-10-28 02:05:29 +02:00
throw $ex ;
2016-01-04 05:16:03 +01:00
}
} catch ( \Exception $ex ) {
DB :: rollBack ();
throw $ex ;
}
}
2016-10-28 02:05:29 +02:00
public function cancelDeletion ( $id )
{
$server = Models\Server :: withTrashed () -> findOrFail ( $id );
$server -> restore ();
$server -> installed = 1 ;
$server -> save ();
}
2016-01-04 22:09:22 +01:00
public function toggleInstall ( $id )
{
$server = Models\Server :: findOrFail ( $id );
2017-03-05 01:03:49 +01:00
if ( $server -> installed > 1 ) {
throw new DisplayException ( 'This server was marked as having a failed install or being deleted, you cannot override this.' );
2016-01-23 02:39:16 +01:00
}
2017-02-15 22:59:50 +01:00
$server -> installed = ! $server -> installed ;
2016-12-07 23:46:38 +01:00
2016-01-04 22:09:22 +01:00
return $server -> save ();
}
2016-01-16 06:25:21 +01:00
/**
* Suspends a server instance making it unable to be booted or used by a user .
2016-12-07 23:46:38 +01:00
* @ param int $id
* @ return bool
2016-01-16 06:25:21 +01:00
*/
2016-10-28 02:05:29 +02:00
public function suspend ( $id , $deleted = false )
2016-01-16 06:25:21 +01:00
{
2017-02-09 23:43:54 +01:00
$server = Models\Server :: withTrashed () -> with ( 'node' ) -> findOrFail ( $id );
2016-09-02 03:16:38 +02:00
DB :: beginTransaction ();
try {
2016-09-05 22:21:36 +02:00
// Already suspended, no need to make more requests.
2017-02-09 23:43:54 +01:00
if ( $server -> suspended ) {
2016-09-05 22:21:36 +02:00
return true ;
}
2016-09-02 03:16:38 +02:00
$server -> suspended = 1 ;
$server -> save ();
2017-02-09 23:43:54 +01:00
$server -> node -> guzzleClient ([
'X-Access-Token' => $server -> node -> daemonSecret ,
'X-Access-Server' => $server -> uuid ,
]) -> request ( 'POST' , '/server/suspend' );
2016-09-02 03:16:38 +02:00
return DB :: commit ();
2017-02-09 23:43:54 +01:00
} catch ( TransferException $ex ) {
2016-09-02 03:16:38 +02:00
DB :: rollBack ();
2016-09-05 22:21:36 +02:00
throw new DisplayException ( 'An error occured while attempting to contact the remote daemon to suspend this server.' , $ex );
2016-09-02 03:16:38 +02:00
} catch ( \Exception $ex ) {
DB :: rollBack ();
throw $ex ;
}
2016-01-16 06:25:21 +01:00
}
/**
* Unsuspends a server instance .
2016-12-07 23:46:38 +01:00
* @ param int $id
* @ return bool
2016-01-16 06:25:21 +01:00
*/
public function unsuspend ( $id )
{
2017-02-09 23:43:54 +01:00
$server = Models\Server :: with ( 'node' ) -> findOrFail ( $id );
2016-09-02 03:16:38 +02:00
DB :: beginTransaction ();
try {
2016-09-05 22:21:36 +02:00
// Already unsuspended, no need to make more requests.
if ( $server -> suspended === 0 ) {
return true ;
}
2016-09-02 03:16:38 +02:00
$server -> suspended = 0 ;
$server -> save ();
2017-02-09 23:43:54 +01:00
$server -> node -> guzzleClient ([
'X-Access-Token' => $server -> node -> daemonSecret ,
'X-Access-Server' => $server -> uuid ,
]) -> request ( 'POST' , '/server/unsuspend' );
2016-09-02 03:16:38 +02:00
return DB :: commit ();
2017-02-09 23:43:54 +01:00
} catch ( TransferException $ex ) {
2016-09-02 03:16:38 +02:00
DB :: rollBack ();
2016-09-05 22:21:36 +02:00
throw new DisplayException ( 'An error occured while attempting to contact the remote daemon to un-suspend this server.' , $ex );
2016-09-02 03:16:38 +02:00
} catch ( \Exception $ex ) {
DB :: rollBack ();
throw $ex ;
}
2016-01-16 06:25:21 +01:00
}
2016-01-22 05:53:48 +01:00
public function updateSFTPPassword ( $id , $password )
{
2017-02-09 23:43:54 +01:00
$server = Models\Server :: with ( 'node' ) -> findOrFail ( $id );
2016-01-22 05:53:48 +01:00
2017-02-09 23:43:54 +01:00
$validator = Validator :: make ([ 'password' => $password ], [
2016-12-07 23:46:38 +01:00
'password' => 'required|regex:/^((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,})$/' ,
2016-01-22 05:53:48 +01:00
]);
if ( $validator -> fails ()) {
throw new DisplayValidationException ( json_encode ( $validator -> errors ()));
}
2016-09-03 01:26:48 +02:00
DB :: beginTransaction ();
$server -> sftp_password = Crypt :: encrypt ( $password );
2016-01-22 05:53:48 +01:00
try {
2016-09-03 01:26:48 +02:00
$server -> save ();
2017-02-09 23:43:54 +01:00
$server -> node -> guzzleClient ([
'X-Access-Token' => $server -> node -> daemonSecret ,
'X-Access-Server' => $server -> uuid ,
]) -> request ( 'POST' , '/server/password' , [
'json' => [ 'password' => $password ],
2016-01-22 05:53:48 +01:00
]);
2016-09-03 01:26:48 +02:00
DB :: commit ();
2016-12-07 23:46:38 +01:00
2016-01-22 05:53:48 +01:00
return true ;
2017-02-09 23:43:54 +01:00
} catch ( TransferException $ex ) {
2016-09-03 01:26:48 +02:00
DB :: rollBack ();
2016-08-17 01:20:58 +02:00
throw new DisplayException ( 'There was an error while attmping to contact the remote service to change the password.' , $ex );
2016-01-22 05:53:48 +01:00
} catch ( \Exception $ex ) {
2016-09-03 01:26:48 +02:00
DB :: rollBack ();
2016-01-22 05:53:48 +01:00
throw $ex ;
}
}
2015-12-14 04:22:16 +01:00
}