diff --git a/.env.example b/.env.example index 004bfa4e4..ba98b1c75 100644 --- a/.env.example +++ b/.env.example @@ -4,6 +4,7 @@ APP_KEY=SomeRandomString3232RandomString APP_THEME=default APP_TIMEZONE=UTC APP_CLEAR_TASKLOG=720 +APP_DELETE_MINUTES=10 CONSOLE_PUSH_FREQ=250 CONSOLE_PUSH_COUNT=10 @@ -15,7 +16,6 @@ DB_PASSWORD=secret CACHE_DRIVER=file SESSION_DRIVER=database -QUEUE_DRIVER=database MAIL_DRIVER=smtp MAIL_HOST=mailtrap.io @@ -28,3 +28,12 @@ MAIL_FROM=you@example.com API_PREFIX=api API_VERSION=v1 API_DEBUG=false + +QUEUE_DRIVER=database +QUEUE_HIGH=high +QUEUE_STANDARD=standard +QUEUE_LOW=low + +SQS_KEY=aws-public +SQS_SECRET=aws-secret +SQS_QUEUE_PREFIX=aws-queue-prefix diff --git a/app/Console/Commands/RunTasks.php b/app/Console/Commands/RunTasks.php index 92daef203..3047dc54e 100644 --- a/app/Console/Commands/RunTasks.php +++ b/app/Console/Commands/RunTasks.php @@ -74,7 +74,7 @@ class RunTasks extends Command foreach ($tasks as &$task) { $bar->advance(); - $this->dispatch(new SendScheduledTask(Models\Server::findOrFail($task->server), $task)); + $this->dispatch((new SendScheduledTask(Models\Server::findOrFail($task->server), $task))->onQueue(env('QUEUE_LOW', 'low'))); } $bar->finish(); diff --git a/app/Events/ServerDeleted.php b/app/Events/ServerDeleted.php new file mode 100644 index 000000000..4451b01bc --- /dev/null +++ b/app/Events/ServerDeleted.php @@ -0,0 +1,44 @@ + + * + * 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: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * 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. + */ +namespace Pterodactyl\Events; + +use Illuminate\Queue\SerializesModels; + +class ServerDeleted +{ + use SerializesModels; + + public $server; + + /** + * Create a new event instance. + * + * @return void + */ + public function __construct($id) + { + $this->server = $id; + } + +} diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index 05cbe134d..8f0b184c6 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -51,7 +51,7 @@ class ServersController extends Controller public function getIndex(Request $request) { - $query = Models\Server::select( + $query = Models\Server::withTrashed()->select( 'servers.*', 'nodes.name as a_nodeName', 'users.email as a_ownerEmail', @@ -84,7 +84,7 @@ class ServersController extends Controller $servers = $query->paginate(20); } catch (\Exception $ex) { Alert::warning('There was an error with the search parameters provided.'); - $servers = Models\Server::select( + $servers = Models\Server::withTrashed()->select( 'servers.*', 'nodes.name as a_nodeName', 'users.email as a_ownerEmail', @@ -112,7 +112,7 @@ class ServersController extends Controller public function getView(Request $request, $id) { - $server = Models\Server::select( + $server = Models\Server::withTrashed()->select( 'servers.*', 'nodes.name as a_nodeName', 'users.email as a_ownerEmail', @@ -394,7 +394,7 @@ class ServersController extends Controller try { $server = new ServerRepository; $server->deleteServer($id, $force); - Alert::success('Server was successfully deleted from the panel and the daemon.')->flash(); + Alert::success('Server has been marked for deletion on the system.')->flash(); return redirect()->route('admin.servers'); } catch (DisplayException $ex) { Alert::danger($ex->getMessage())->flash(); @@ -510,4 +510,31 @@ class ServersController extends Controller } } + public function postQueuedDeletionHandler(Request $request, $id) + { + try { + $repo = new ServerRepository; + if (!is_null($request->input('cancel'))) { + $repo->cancelDeletion($id); + Alert::success('Server deletion has been cancelled. This server will remain suspended until you unsuspend it.')->flash(); + return redirect()->route('admin.servers.view', $id); + } else if(!is_null($request->input('delete'))) { + $repo->deleteNow($id); + Alert::success('Server was successfully deleted from the system.')->flash(); + return redirect()->route('admin.servers'); + } else if(!is_null($request->input('force_delete'))) { + $repo->deleteNow($id, true); + Alert::success('Server was successfully force deleted from the system.')->flash(); + return redirect()->route('admin.servers'); + } + } catch (DisplayException $ex) { + Alert::danger($ex->getMessage())->flash(); + return redirect()->route('admin.servers.view', $id); + } catch (\Exception $ex) { + Log::error($ex); + Alert::danger('An unhandled error occured while attempting to perform this action.')->flash(); + return redirect()->route('admin.servers.view', $id); + } + } + } diff --git a/app/Http/Routes/AdminRoutes.php b/app/Http/Routes/AdminRoutes.php index f8df15274..bfc07b725 100644 --- a/app/Http/Routes/AdminRoutes.php +++ b/app/Http/Routes/AdminRoutes.php @@ -210,6 +210,11 @@ class AdminRoutes { 'uses' => 'Admin\ServersController@deleteServer' ]); + $router->post('/view/{id}/queuedDeletion', [ + 'uses' => 'Admin\ServersController@postQueuedDeletionHandler', + 'as' => 'admin.servers.post.queuedDeletion' + ]); + }); // Node Routes diff --git a/app/Jobs/DeleteServer.php b/app/Jobs/DeleteServer.php new file mode 100644 index 000000000..78e1e1f48 --- /dev/null +++ b/app/Jobs/DeleteServer.php @@ -0,0 +1,67 @@ + + * + * 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: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * 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. + */ +namespace Pterodactyl\Jobs; + +use DB; + +use Illuminate\Bus\Queueable; +use Illuminate\Queue\SerializesModels; +use Illuminate\Queue\InteractsWithQueue; +use Illuminate\Contracts\Queue\ShouldQueue; + +use Pterodactyl\Models; +use Pterodactyl\Repositories\ServerRepository; + +class DeleteServer extends Job implements ShouldQueue +{ + use InteractsWithQueue, SerializesModels; + + /** + * Id of server to be deleted. + * @var object + */ + protected $id; + + /** + * Create a new job instance. + * + * @param integer $server + * @return void + */ + public function __construct($id) + { + $this->id = $id; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + $repo = new ServerRepository; + $repo->deleteNow($this->id); + } +} diff --git a/app/Jobs/SuspendServer.php b/app/Jobs/SuspendServer.php new file mode 100644 index 000000000..912f8a0a9 --- /dev/null +++ b/app/Jobs/SuspendServer.php @@ -0,0 +1,65 @@ + + * + * 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: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * 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. + */ +namespace Pterodactyl\Jobs; + +use Debugbar; +use Illuminate\Bus\Queueable; +use Illuminate\Queue\SerializesModels; +use Illuminate\Queue\InteractsWithQueue; +use Illuminate\Contracts\Queue\ShouldQueue; + +use Pterodactyl\Repositories\ServerRepository; + +class SuspendServer extends Job implements ShouldQueue +{ + use InteractsWithQueue, SerializesModels; + + /** + * ID of associated server model. + * @var object + */ + protected $id; + + /** + * Create a new job instance. + * + * @param integer $id + * @return void + */ + public function __construct($id) + { + $this->id = $id; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + $repo = new ServerRepository; + $repo->suspend($this->id, true); + } +} diff --git a/app/Listeners/DeleteServerListener.php b/app/Listeners/DeleteServerListener.php new file mode 100644 index 000000000..6a7833504 --- /dev/null +++ b/app/Listeners/DeleteServerListener.php @@ -0,0 +1,64 @@ + + * + * 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: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * 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. + */ +namespace Pterodactyl\Listeners; + +use Carbon; + +use Pterodactyl\Events\ServerDeleted; +use Illuminate\Foundation\Bus\DispatchesJobs; + +use Pterodactyl\Jobs\SuspendServer; +use Pterodactyl\Jobs\DeleteServer; + +class DeleteServerListener +{ + + use DispatchesJobs; + + /** + * Create the event listener. + * + * @return void + */ + public function __construct() + { + // + } + + /** + * Handle the event. + * + * @param DeleteServerEvent $event + * @return void + */ + public function handle(ServerDeleted $event) + { + $this->dispatch((new SuspendServer($event->server))->onQueue(env('QUEUE_HIGH', 'high'))); + $this->dispatch( + (new DeleteServer($event->server)) + ->delay(Carbon::now()->addMinutes(env('APP_DELETE_MINUTES', 10))) + ->onQueue(env('QUEUE_STANDARD', 'standard')) + ); + } +} diff --git a/app/Models/Server.php b/app/Models/Server.php index d9c2f958a..9948c7a10 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -26,12 +26,15 @@ namespace Pterodactyl\Models; use Auth; use Pterodactyl\Models\Subuser; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\SoftDeletes; use Pterodactyl\Exceptions\DisplayException; class Server extends Model { + use SoftDeletes; + /** * The table associated with the model. * @@ -44,17 +47,21 @@ class Server extends Model * * @var array */ - protected $hidden = [ - 'daemonSecret', - 'sftp_password' - ]; + protected $hidden = ['daemonSecret', 'sftp_password']; + + /** + * The attributes that should be mutated to dates. + * + * @var array + */ + protected $dates = ['deleted_at']; /** * Fields that are not mass assignable. * * @var array */ - protected $guarded = ['id', 'installed', 'created_at', 'updated_at']; + protected $guarded = ['id', 'installed', 'created_at', 'updated_at', 'deleted_at']; /** * Cast values to correct type. @@ -92,6 +99,7 @@ class Server extends Model */ public function __construct() { + parent::__construct(); self::$user = Auth::user(); } @@ -181,10 +189,6 @@ class Server extends Model $result = $query->first(); - if (!$result) { - throw new DisplayException('No server was found belonging to this user.'); - } - if(!is_null($result)) { $result->daemonSecret = self::getUserDaemonSecret($result); } diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index d706f31ce..7ec0d48ae 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -13,8 +13,8 @@ class EventServiceProvider extends ServiceProvider * @var array */ protected $listen = [ - 'Pterodactyl\Events\SomeEvent' => [ - 'Pterodactyl\Listeners\EventListener', + 'Pterodactyl\Events\ServerDeleted' => [ + 'Pterodactyl\Listeners\DeleteServerListener', ], ]; diff --git a/app/Repositories/ServerRepository.php b/app/Repositories/ServerRepository.php index 979554800..47b1a4a97 100644 --- a/app/Repositories/ServerRepository.php +++ b/app/Repositories/ServerRepository.php @@ -33,6 +33,7 @@ use Pterodactyl\Models; use Pterodactyl\Services\UuidService; use Pterodactyl\Services\DeploymentService; use Pterodactyl\Notifications\ServerCreated; +use Pterodactyl\Events\ServerDeleted; use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\AccountNotFoundException; @@ -767,11 +768,37 @@ class ServerRepository public function deleteServer($id, $force) { $server = Models\Server::findOrFail($id); - $node = Models\Node::findOrFail($server->node); DB::beginTransaction(); try { - // Delete Allocations + if ($force === 'force' || $force === true) { + $server->installed = 3; + $server->save(); + } + + $server->delete(); + DB::commit(); + + event(new ServerDeleted($server->id)); + } catch (\Exception $ex) { + DB::rollBack(); + throw $ex; + } + } + + public function deleteNow($id, $force = false) { + $server = Models\Server::withTrashed()->findOrFail($id); + $node = Models\Node::findOrFail($server->node); + + // Handle server being restored previously or + // an accidental queue. + if (!$server->trashed()) { + return; + } + + DB::beginTransaction(); + try { + // Unassign Allocations Models\Allocation::where('assigned_to', $server->id)->update([ 'assigned_to' => null ]); @@ -779,20 +806,23 @@ class ServerRepository // Remove Variables Models\ServerVariables::where('server_id', $server->id)->delete(); + // Remove Permissions (Foreign Key requires before Subusers) + Models\Permission::where('server_id', $server->id)->delete(); + // Remove SubUsers Models\Subuser::where('server_id', $server->id)->delete(); - // Remove Permissions - Models\Permission::where('server_id', $server->id)->delete(); - // Remove Downloads Models\Download::where('server', $server->uuid)->delete(); + // Clear Tasks + Models\Task::where('server', $server->id)->delete(); + // Delete Databases - $databases = Models\Database::select('id')->where('server_id', $server->id)->get(); + // This is the one un-recoverable point where + // transactions will not save us. $repository = new DatabaseRepository; - foreach($databases as &$database) { - // Use the repository to drop the database, we don't need to delete here because it is now gone. + foreach(Models\Database::select('id')->where('server_id', $server->id)->get() as &$database) { $repository->drop($database->id); } @@ -804,17 +834,16 @@ class ServerRepository ] ]); - $server->delete(); + $server->forceDelete(); DB::commit(); - return true; } catch (\GuzzleHttp\Exception\TransferException $ex) { - if ($force === 'force') { - $server->delete(); + // Set installed is set to 3 when force deleting. + if ($server->installed === 3 || $force) { + $server->forceDelete(); DB::commit(); - return true; } else { DB::rollBack(); - throw new DisplayException('An error occured while attempting to delete the server on the daemon.', $ex); + throw $ex; } } catch (\Exception $ex) { DB::rollBack(); @@ -822,6 +851,15 @@ class ServerRepository } } + public function cancelDeletion($id) + { + $server = Models\Server::withTrashed()->findOrFail($id); + $server->restore(); + + $server->installed = 1; + $server->save(); + } + public function toggleInstall($id) { $server = Models\Server::findOrFail($id); @@ -837,9 +875,9 @@ class ServerRepository * @param integer $id * @return boolean */ - public function suspend($id) + public function suspend($id, $deleted = false) { - $server = Models\Server::findOrFail($id); + $server = ($deleted) ? Models\Server::withTrashed()->findOrFail($id) : Models\Server::findOrFail($id); $node = Models\Node::findOrFail($server->node); DB::beginTransaction(); diff --git a/composer.json b/composer.json index bdb40a090..3569e3d1b 100644 --- a/composer.json +++ b/composer.json @@ -8,28 +8,25 @@ "email": "dane@daneeveritt.com", "homepage": "https://github.com/DaneEveritt", "role": "Lead Developer" - }, - { - "name": "Dylan Seidt", - "email": "dylan.seidt@gmail.com", - "role": "Developer" } ], "require": { "php": ">=5.6.4", - "laravel/framework": "5.3.6", - "barryvdh/laravel-debugbar": "^2.2.3", - "doctrine/dbal": "^2.5.4", - "guzzlehttp/guzzle": "^6.2.1", - "pragmarx/google2fa": "^1.0.1", - "webpatser/laravel-uuid": "^2.0", - "prologue/alerts": "^0.4.0", - "s1lentium/iptools": "^1.1.0", - "edvinaskrucas/settings": "^2.0", - "igaster/laravel-theme": "^1.1.3", - "nesbot/carbon": "^1.21", - "mtdowling/cron-expression": "^1.1", - "dingo/api": "1.0.0-beta6" + "laravel/framework": "5.3.21", + "barryvdh/laravel-debugbar": "2.2.3", + "doctrine/dbal": "2.5.5", + "guzzlehttp/guzzle": "6.2.2", + "pragmarx/google2fa": "1.0.1", + "webpatser/laravel-uuid": "2.0.1", + "prologue/alerts": "0.4.0", + "s1lentium/iptools": "1.1.0", + "edvinaskrucas/settings": "2.0.0", + "igaster/laravel-theme": "1.1.3", + "nesbot/carbon": "1.21.0", + "mtdowling/cron-expression": "1.1.0", + "dingo/api": "1.0.0-beta6", + "aws/aws-sdk-php": "3.19.20", + "predis/predis": "1.1.1" }, "require-dev": { "fzaninotto/faker": "~1.4", diff --git a/config/queue.php b/config/queue.php index 0d80b7c51..4ed92ba94 100644 --- a/config/queue.php +++ b/config/queue.php @@ -38,38 +38,23 @@ return [ 'database' => [ 'driver' => 'database', 'table' => 'jobs', - 'queue' => 'default', + 'queue' => env('QUEUE_STANDARD'), 'retry_after' => 60, ], - 'beanstalkd' => [ - 'driver' => 'beanstalkd', - 'host' => 'localhost', - 'queue' => 'default', - 'retry_after' => 60, - ], - 'sqs' => [ 'driver' => 'sqs', - 'key' => 'your-public-key', - 'secret' => 'your-secret-key', - 'queue' => 'your-queue-url', - 'region' => 'us-east-1', - ], - - 'iron' => [ - 'driver' => 'iron', - 'host' => 'mq-aws-us-east-1.iron.io', - 'token' => 'your-token', - 'project' => 'your-project-id', - 'queue' => 'your-queue-name', - 'encrypt' => true, + 'key' => env('SQS_KEY'), + 'secret' => env('SQS_SECRET'), + 'prefix' => env('SQS_QUEUE_PREFIX'), + 'queue' => env('QUEUE_STANDARD'), + 'region' => env('SQS_REGION', 'us-east-1'), ], 'redis' => [ 'driver' => 'redis', 'connection' => 'default', - 'queue' => 'default', + 'queue' => env('QUEUE_STANDARD'), 'retry_after' => 60, ], diff --git a/database/migrations/2016_10_23_193810_add_foreign_keys_servers.php b/database/migrations/2016_10_23_193810_add_foreign_keys_servers.php new file mode 100644 index 000000000..59bc0ac39 --- /dev/null +++ b/database/migrations/2016_10_23_193810_add_foreign_keys_servers.php @@ -0,0 +1,65 @@ +foreign('node')->references('id')->on('nodes'); + $table->foreign('owner')->references('id')->on('users'); + $table->foreign('allocation')->references('id')->on('allocations'); + $table->foreign('service')->references('id')->on('services'); + $table->foreign('option')->references('id')->on('service_options'); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('servers', function (Blueprint $table) { + $table->dropForeign('servers_node_foreign'); + $table->dropForeign('servers_owner_foreign'); + $table->dropForeign('servers_allocation_foreign'); + $table->dropForeign('servers_service_foreign'); + $table->dropForeign('servers_option_foreign'); + + $table->dropIndex('servers_node_foreign'); + $table->dropIndex('servers_owner_foreign'); + $table->dropIndex('servers_allocation_foreign'); + $table->dropIndex('servers_service_foreign'); + $table->dropIndex('servers_option_foreign'); + + $table->dropColumn('deleted_at'); + }); + + DB::statement('ALTER TABLE servers + MODIFY COLUMN node MEDIUMINT(8) UNSIGNED NOT NULL, + MODIFY COLUMN owner MEDIUMINT(8) UNSIGNED NOT NULL, + MODIFY COLUMN allocation MEDIUMINT(8) UNSIGNED NOT NULL, + MODIFY COLUMN service MEDIUMINT(8) UNSIGNED NOT NULL, + MODIFY COLUMN servers.option MEDIUMINT(8) UNSIGNED NOT NULL + '); + } +} diff --git a/database/migrations/2016_10_23_201624_add_foreign_allocations.php b/database/migrations/2016_10_23_201624_add_foreign_allocations.php new file mode 100644 index 000000000..6b73df2d6 --- /dev/null +++ b/database/migrations/2016_10_23_201624_add_foreign_allocations.php @@ -0,0 +1,47 @@ +foreign('assigned_to')->references('id')->on('servers'); + $table->foreign('node')->references('id')->on('nodes'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('allocations', function (Blueprint $table) { + $table->dropForeign('allocations_assigned_to_foreign'); + $table->dropForeign('allocations_node_foreign'); + + $table->dropIndex('allocations_assigned_to_foreign'); + $table->dropIndex('allocations_node_foreign'); + }); + + DB::statement('ALTER TABLE allocations + MODIFY COLUMN assigned_to MEDIUMINT(8) UNSIGNED NULL, + MODIFY COLUMN node MEDIUMINT(8) UNSIGNED NOT NULL + '); + } +} diff --git a/database/migrations/2016_10_23_202222_add_foreign_api_keys.php b/database/migrations/2016_10_23_202222_add_foreign_api_keys.php new file mode 100644 index 000000000..67dcd3ce3 --- /dev/null +++ b/database/migrations/2016_10_23_202222_add_foreign_api_keys.php @@ -0,0 +1,33 @@ +foreign('user')->references('id')->on('users'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('api_keys', function (Blueprint $table) { + $table->dropForeign('api_keys_user_foreign'); + $table->dropIndex('api_keys_user_foreign'); + }); + } +} diff --git a/database/migrations/2016_10_23_202703_add_foreign_api_permissions.php b/database/migrations/2016_10_23_202703_add_foreign_api_permissions.php new file mode 100644 index 000000000..58bf1a5a5 --- /dev/null +++ b/database/migrations/2016_10_23_202703_add_foreign_api_permissions.php @@ -0,0 +1,37 @@ +foreign('key_id')->references('id')->on('api_keys'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('api_permissions', function (Blueprint $table) { + $table->dropForeign('api_permissions_key_id_foreign'); + $table->dropIndex('api_permissions_key_id_foreign'); + }); + + DB::statement('ALTER TABLE api_permissions MODIFY key_id MEDIUMINT(8) UNSIGNED NOT NULL'); + } +} diff --git a/database/migrations/2016_10_23_202953_add_foreign_database_servers.php b/database/migrations/2016_10_23_202953_add_foreign_database_servers.php new file mode 100644 index 000000000..b6f012dff --- /dev/null +++ b/database/migrations/2016_10_23_202953_add_foreign_database_servers.php @@ -0,0 +1,33 @@ +foreign('linked_node')->references('id')->on('nodes'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('database_servers', function (Blueprint $table) { + $table->dropForeign('database_servers_linked_node_foreign'); + $table->dropIndex('database_servers_linked_node_foreign'); + }); + } +} diff --git a/database/migrations/2016_10_23_203105_add_foreign_databases.php b/database/migrations/2016_10_23_203105_add_foreign_databases.php new file mode 100644 index 000000000..2d6b6e9a2 --- /dev/null +++ b/database/migrations/2016_10_23_203105_add_foreign_databases.php @@ -0,0 +1,37 @@ +foreign('server_id')->references('id')->on('servers'); + $table->foreign('db_server')->references('id')->on('database_servers'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('databases', function (Blueprint $table) { + $table->dropForeign('databases_server_id_foreign'); + $table->dropForeign('databases_db_server_foreign'); + + $table->dropIndex('databases_server_id_foreign'); + $table->dropIndex('databases_db_server_foreign'); + }); + } +} diff --git a/database/migrations/2016_10_23_203335_add_foreign_nodes.php b/database/migrations/2016_10_23_203335_add_foreign_nodes.php new file mode 100644 index 000000000..8fa516c00 --- /dev/null +++ b/database/migrations/2016_10_23_203335_add_foreign_nodes.php @@ -0,0 +1,37 @@ +foreign('location')->references('id')->on('locations'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('nodes', function (Blueprint $table) { + $table->dropForeign('nodes_location_foreign'); + $table->dropIndex('nodes_location_foreign'); + }); + + DB::statement('ALTER TABLE nodes MODIFY location MEDIUMINT(10) UNSIGNED NOT NULL'); + } +} diff --git a/database/migrations/2016_10_23_203522_add_foreign_permissions.php b/database/migrations/2016_10_23_203522_add_foreign_permissions.php new file mode 100644 index 000000000..8de3f3b8f --- /dev/null +++ b/database/migrations/2016_10_23_203522_add_foreign_permissions.php @@ -0,0 +1,38 @@ +foreign('user_id')->references('id')->on('users'); + $table->foreign('server_id')->references('id')->on('servers'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('permissions', function (Blueprint $table) { + $table->dropForeign('permissions_user_id_foreign'); + $table->dropForeign('permissions_server_id_foreign'); + + $table->dropIndex('permissions_user_id_foreign'); + $table->dropIndex('permissions_server_id_foreign'); + }); + } + +} diff --git a/database/migrations/2016_10_23_203857_add_foreign_server_variables.php b/database/migrations/2016_10_23_203857_add_foreign_server_variables.php new file mode 100644 index 000000000..116434161 --- /dev/null +++ b/database/migrations/2016_10_23_203857_add_foreign_server_variables.php @@ -0,0 +1,48 @@ +foreign('server_id')->references('id')->on('servers'); + $table->foreign('variable_id')->references('id')->on('service_variables'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('server_variables', function (Blueprint $table) { + $table->dropForeign('server_variables_server_id_foreign'); + $table->dropForeign('server_variables_variable_id_foreign'); + + $table->dropIndex('server_variables_server_id_foreign'); + $table->dropIndex('server_variables_variable_id_foreign'); + }); + + DB::statement('ALTER TABLE allocations + MODIFY COLUMN server_id MEDIUMINT(8) UNSIGNED NULL, + MODIFY COLUMN variable_id MEDIUMINT(8) UNSIGNED NOT NULL + '); + } + +} diff --git a/database/migrations/2016_10_23_204157_add_foreign_service_options.php b/database/migrations/2016_10_23_204157_add_foreign_service_options.php new file mode 100644 index 000000000..0baad0c36 --- /dev/null +++ b/database/migrations/2016_10_23_204157_add_foreign_service_options.php @@ -0,0 +1,37 @@ +foreign('parent_service')->references('id')->on('services'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('service_options', function (Blueprint $table) { + $table->dropForeign('service_options_parent_service_foreign'); + $table->dropIndex('service_options_parent_service_foreign'); + }); + + DB::statement('ALTER TABLE service_options MODIFY parent_service MEDIUMINT(8) UNSIGNED NOT NULL'); + } +} diff --git a/database/migrations/2016_10_23_204321_add_foreign_service_variables.php b/database/migrations/2016_10_23_204321_add_foreign_service_variables.php new file mode 100644 index 000000000..4f7f43ae2 --- /dev/null +++ b/database/migrations/2016_10_23_204321_add_foreign_service_variables.php @@ -0,0 +1,37 @@ +foreign('option_id')->references('id')->on('service_options'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('service_variables', function (Blueprint $table) { + $table->dropForeign('service_variables_option_id_foreign'); + $table->dropIndex('service_variables_option_id_foreign'); + }); + + DB::statement('ALTER TABLE service_variables MODIFY option_id MEDIUMINT(8) UNSIGNED NOT NULL'); + } + } diff --git a/database/migrations/2016_10_23_204454_add_foreign_subusers.php b/database/migrations/2016_10_23_204454_add_foreign_subusers.php new file mode 100644 index 000000000..2f4045669 --- /dev/null +++ b/database/migrations/2016_10_23_204454_add_foreign_subusers.php @@ -0,0 +1,37 @@ +foreign('user_id')->references('id')->on('users'); + $table->foreign('server_id')->references('id')->on('servers'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('subusers', function (Blueprint $table) { + $table->dropForeign('subusers_user_id_foreign'); + $table->dropForeign('subusers_server_id_foreign'); + + $table->dropIndex('subusers_user_id_foreign'); + $table->dropIndex('subusers_server_id_foreign'); + }); + } +} diff --git a/database/migrations/2016_10_23_204610_add_foreign_tasks.php b/database/migrations/2016_10_23_204610_add_foreign_tasks.php new file mode 100644 index 000000000..77b736201 --- /dev/null +++ b/database/migrations/2016_10_23_204610_add_foreign_tasks.php @@ -0,0 +1,36 @@ +foreign('server')->references('id')->on('servers'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('tasks', function (Blueprint $table) { + $table->dropForeign('tasks_server_foreign'); + $table->dropForeign('tasks_server_foreign'); + + $table->dropIndex('tasks_server_foreign'); + $table->dropIndex('tasks_server_foreign'); + }); + } +} diff --git a/resources/views/admin/servers/index.blade.php b/resources/views/admin/servers/index.blade.php index d49d7a585..67a913037 100644 --- a/resources/views/admin/servers/index.blade.php +++ b/resources/views/admin/servers/index.blade.php @@ -49,8 +49,21 @@
@foreach ($servers as $server) -{{ $server->username }}