From e980877bbce20a88a54beccbf9f9f9d92607dc8d Mon Sep 17 00:00:00 2001 From: notCharles Date: Wed, 29 May 2024 18:28:21 -0400 Subject: [PATCH 01/11] Fix Node Creation Add missing defaults --- app/Filament/Resources/NodeResource/Pages/CreateNode.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Filament/Resources/NodeResource/Pages/CreateNode.php b/app/Filament/Resources/NodeResource/Pages/CreateNode.php index 899e7b3ab..775fe5e9f 100644 --- a/app/Filament/Resources/NodeResource/Pages/CreateNode.php +++ b/app/Filament/Resources/NodeResource/Pages/CreateNode.php @@ -329,6 +329,7 @@ class CreateNode extends CreateRecord true => 'primary', false => 'warning', ]) + ->default(0) ->columnSpan(2), Forms\Components\TextInput::make('cpu') ->dehydratedWhenHidden() @@ -346,6 +347,7 @@ class CreateNode extends CreateRecord ->hintIconTooltip('The % allowable to go over the set limit.') ->columnSpan(2) ->numeric() + ->default(0) ->minValue(-1) ->maxValue(100) ->suffix('%'), From b6e46f758d03f11c7ce944ccafd877d065ced164 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Thu, 30 May 2024 00:41:44 +0200 Subject: [PATCH 02/11] Remove hashids (#282) and close #269 --- .env.example | 3 - .github/workflows/ci.yaml | 2 - .../Environment/AppSettingsCommand.php | 5 -- .../Schedule/ProcessRunnableCommand.php | 2 +- app/Contracts/Extensions/HashidsInterface.php | 15 ---- app/Extensions/Hashids.php | 22 ------ app/Models/Allocation.php | 9 --- app/Models/Database.php | 22 ------ app/Models/Schedule.php | 11 --- app/Models/Subuser.php | 8 -- app/Models/Task.php | 11 --- app/Providers/HashidsServiceProvider.php | 26 ------- app/Providers/RouteServiceProvider.php | 6 -- .../Api/Client/DatabaseTransformer.php | 13 +--- bootstrap/providers.php | 1 - composer.json | 1 - composer.lock | 73 +------------------ config/hashids.php | 15 ---- lang/en/command/messages.php | 2 +- .../Database/DatabaseAuthorizationTest.php | 14 ++-- 20 files changed, 11 insertions(+), 250 deletions(-) delete mode 100644 app/Contracts/Extensions/HashidsInterface.php delete mode 100644 app/Extensions/Hashids.php delete mode 100644 app/Providers/HashidsServiceProvider.php delete mode 100644 config/hashids.php diff --git a/.env.example b/.env.example index eab42b85a..c91d26013 100644 --- a/.env.example +++ b/.env.example @@ -17,9 +17,6 @@ CACHE_STORE=file QUEUE_CONNECTION=database SESSION_DRIVER=file -HASHIDS_SALT= -HASHIDS_LENGTH=8 - MAIL_MAILER=log MAIL_HOST=smtp.example.com MAIL_PORT=25 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index bcc56c1a7..998654549 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -34,7 +34,6 @@ jobs: MAIL_MAILER: array SESSION_DRIVER: array QUEUE_CONNECTION: sync - HASHIDS_SALT: alittlebitofsalt1234 DB_CONNECTION: mysql DB_HOST: 127.0.0.1 DB_DATABASE: testing @@ -97,7 +96,6 @@ jobs: MAIL_MAILER: array SESSION_DRIVER: array QUEUE_CONNECTION: sync - HASHIDS_SALT: alittlebitofsalt1234 DB_CONNECTION: sqlite DB_DATABASE: testing.sqlite steps: diff --git a/app/Console/Commands/Environment/AppSettingsCommand.php b/app/Console/Commands/Environment/AppSettingsCommand.php index 8a01437fa..ff75057a3 100644 --- a/app/Console/Commands/Environment/AppSettingsCommand.php +++ b/app/Console/Commands/Environment/AppSettingsCommand.php @@ -32,7 +32,6 @@ class AppSettingsCommand extends Command protected $description = 'Configure basic environment settings for the Panel.'; protected $signature = 'p:environment:setup - {--new-salt : Whether or not to generate a new salt for Hashids.} {--url= : The URL that this Panel is running on.} {--cache= : The cache driver backend to use.} {--session= : The session driver backend to use.} @@ -61,10 +60,6 @@ class AppSettingsCommand extends Command { $this->variables['APP_TIMEZONE'] = 'UTC'; - if (empty(config('hashids.salt')) || $this->option('new-salt')) { - $this->variables['HASHIDS_SALT'] = str_random(20); - } - $this->output->comment(__('commands.appsettings.comment.url')); $this->variables['APP_URL'] = $this->option('url') ?? $this->ask( 'Application URL', diff --git a/app/Console/Commands/Schedule/ProcessRunnableCommand.php b/app/Console/Commands/Schedule/ProcessRunnableCommand.php index 343328cc8..687752a2d 100644 --- a/app/Console/Commands/Schedule/ProcessRunnableCommand.php +++ b/app/Console/Commands/Schedule/ProcessRunnableCommand.php @@ -62,7 +62,7 @@ class ProcessRunnableCommand extends Command $this->line(trans('command/messages.schedule.output_line', [ 'schedule' => $schedule->name, - 'hash' => $schedule->hashid, + 'id' => $schedule->id, ])); } catch (\Throwable|\Exception $exception) { logger()->error($exception, ['schedule_id' => $schedule->id]); diff --git a/app/Contracts/Extensions/HashidsInterface.php b/app/Contracts/Extensions/HashidsInterface.php deleted file mode 100644 index 4f02d0bea..000000000 --- a/app/Contracts/Extensions/HashidsInterface.php +++ /dev/null @@ -1,15 +0,0 @@ -decode($encoded); - if (!is_array($result)) { - return $default; - } - - return array_first($result, null, $default); - } -} diff --git a/app/Models/Allocation.php b/app/Models/Allocation.php index 6a7d45db7..33bc7f16d 100644 --- a/app/Models/Allocation.php +++ b/app/Models/Allocation.php @@ -22,7 +22,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; * @property bool $has_alias * @property \App\Models\Server|null $server * @property \App\Models\Node $node - * @property string $hashid * * @method static \Database\Factories\AllocationFactory factory(...$parameters) * @method static \Illuminate\Database\Eloquent\Builder|Allocation newModelQuery() @@ -88,14 +87,6 @@ class Allocation extends Model return $this->getKeyName(); } - /** - * Return a hashid encoded string to represent the ID of the allocation. - */ - public function getHashidAttribute(): string - { - return app()->make('hashids')->encode($this->id); - } - /** * Accessor to automatically provide the IP alias if defined. */ diff --git a/app/Models/Database.php b/app/Models/Database.php index 6d4fde2f9..99e9a27f8 100644 --- a/app/Models/Database.php +++ b/app/Models/Database.php @@ -2,9 +2,7 @@ namespace App\Models; -use Illuminate\Container\Container; use Illuminate\Database\Eloquent\Relations\BelongsTo; -use App\Contracts\Extensions\HashidsInterface; use Illuminate\Support\Facades\DB; /** @@ -72,26 +70,6 @@ class Database extends Model return $this->getKeyName(); } - /** - * Resolves the database using the ID by checking if the value provided is a HashID - * string value, or just the ID to the database itself. - * - * @param mixed $value - * @param string|null $field - * - * @throws \Illuminate\Contracts\Container\BindingResolutionException - */ - public function resolveRouteBinding($value, $field = null): ?\Illuminate\Database\Eloquent\Model - { - if (is_scalar($value) && ($field ?? $this->getRouteKeyName()) === 'id') { - $value = ctype_digit((string) $value) - ? $value - : Container::getInstance()->make(HashidsInterface::class)->decodeFirst($value); - } - - return $this->where($field ?? $this->getRouteKeyName(), $value)->firstOrFail(); - } - /** * Gets the host database server associated with a database. */ diff --git a/app/Models/Schedule.php b/app/Models/Schedule.php index 8fb3f4167..7042d25a4 100644 --- a/app/Models/Schedule.php +++ b/app/Models/Schedule.php @@ -4,10 +4,8 @@ namespace App\Models; use Cron\CronExpression; use Carbon\CarbonImmutable; -use Illuminate\Container\Container; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\BelongsTo; -use App\Contracts\Extensions\HashidsInterface; /** * @property int $id @@ -25,7 +23,6 @@ use App\Contracts\Extensions\HashidsInterface; * @property \Carbon\Carbon|null $next_run_at * @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $updated_at - * @property string $hashid * @property \App\Models\Server $server * @property \App\Models\Task[]|\Illuminate\Support\Collection $tasks */ @@ -124,14 +121,6 @@ class Schedule extends Model ); } - /** - * Return a hashid encoded string to represent the ID of the schedule. - */ - public function getHashidAttribute(): string - { - return Container::getInstance()->make(HashidsInterface::class)->encode($this->id); - } - /** * Return tasks belonging to a schedule. */ diff --git a/app/Models/Subuser.php b/app/Models/Subuser.php index 0c1f4d382..566c8a741 100644 --- a/app/Models/Subuser.php +++ b/app/Models/Subuser.php @@ -52,14 +52,6 @@ class Subuser extends Model ]; } - /** - * Return a hashid encoded string to represent the ID of the subuser. - */ - public function getHashidAttribute(): string - { - return app()->make('hashids')->encode($this->id); - } - /** * Gets the server associated with a subuser. */ diff --git a/app/Models/Task.php b/app/Models/Task.php index 591bfcfbb..6545ab5f5 100644 --- a/app/Models/Task.php +++ b/app/Models/Task.php @@ -2,10 +2,8 @@ namespace App\Models; -use Illuminate\Container\Container; use Illuminate\Database\Eloquent\Relations\HasOneThrough; use Illuminate\Database\Eloquent\Relations\BelongsTo; -use App\Contracts\Extensions\HashidsInterface; /** * @property int $id @@ -18,7 +16,6 @@ use App\Contracts\Extensions\HashidsInterface; * @property bool $continue_on_failure * @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $updated_at - * @property string $hashid * @property \App\Models\Schedule $schedule * @property \App\Models\Server $server */ @@ -96,14 +93,6 @@ class Task extends Model return $this->getKeyName(); } - /** - * Return a hashid encoded string to represent the ID of the task. - */ - public function getHashidAttribute(): string - { - return Container::getInstance()->make(HashidsInterface::class)->encode($this->id); - } - /** * Return the schedule that a task belongs to. */ diff --git a/app/Providers/HashidsServiceProvider.php b/app/Providers/HashidsServiceProvider.php deleted file mode 100644 index 4639bfaed..000000000 --- a/app/Providers/HashidsServiceProvider.php +++ /dev/null @@ -1,26 +0,0 @@ -app->singleton(HashidsInterface::class, function () { - return new Hashids( - config('hashids.salt', ''), - config('hashids.length', 0), - config('hashids.alphabet', 'abcdefghijkmlnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890') - ); - }); - - $this->app->alias(HashidsInterface::class, 'hashids'); - } -} diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 449a083c5..432ededc0 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -3,7 +3,6 @@ namespace App\Providers; use Illuminate\Http\Request; -use App\Models\Database; use Illuminate\Foundation\Http\Middleware\TrimStrings; use Illuminate\Support\Facades\Route; use Illuminate\Cache\RateLimiting\Limit; @@ -29,11 +28,6 @@ class RouteServiceProvider extends ServiceProvider return preg_match(self::FILE_PATH_REGEX, $request->getPathInfo()) === 1; }); - // This is needed to make use of the "resolveRouteBinding" functionality in the - // model. Without it you'll never trigger that logic flow thus resulting in a 404 - // error because we request databases with a HashID, and not with a normal ID. - Route::model('database', Database::class); - $this->routes(function () { Route::middleware('web')->group(function () { Route::middleware(['auth.session', RequireTwoFactorAuthentication::class]) diff --git a/app/Transformers/Api/Client/DatabaseTransformer.php b/app/Transformers/Api/Client/DatabaseTransformer.php index 2739ac7ec..71bbb9aba 100644 --- a/app/Transformers/Api/Client/DatabaseTransformer.php +++ b/app/Transformers/Api/Client/DatabaseTransformer.php @@ -6,22 +6,11 @@ use App\Models\Database; use League\Fractal\Resource\Item; use App\Models\Permission; use League\Fractal\Resource\NullResource; -use App\Contracts\Extensions\HashidsInterface; class DatabaseTransformer extends BaseClientTransformer { protected array $availableIncludes = ['password']; - private HashidsInterface $hashids; - - /** - * Handle dependency injection. - */ - public function handle(HashidsInterface $hashids) - { - $this->hashids = $hashids; - } - public function getResourceName(): string { return Database::RESOURCE_NAME; @@ -32,7 +21,7 @@ class DatabaseTransformer extends BaseClientTransformer $model->loadMissing('host'); return [ - 'id' => $this->hashids->encode($model->id), + 'id' => $model->id, 'host' => [ 'address' => $model->getRelation('host')->host, 'port' => $model->getRelation('host')->port, diff --git a/bootstrap/providers.php b/bootstrap/providers.php index 04b20a98c..80be25c8e 100644 --- a/bootstrap/providers.php +++ b/bootstrap/providers.php @@ -6,7 +6,6 @@ return [ App\Providers\BackupsServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\Filament\AdminPanelProvider::class, - App\Providers\HashidsServiceProvider::class, App\Providers\RouteServiceProvider::class, App\Providers\ViewComposerServiceProvider::class, ]; diff --git a/composer.json b/composer.json index 29ef59290..8de5cefc6 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,6 @@ "doctrine/dbal": "~3.6.0", "filament/filament": "^3.2", "guzzlehttp/guzzle": "^7.8.1", - "hashids/hashids": "~5.0.0", "laracasts/utilities": "~3.2.2", "laravel/framework": "^11.7", "laravel/helpers": "^1.7", diff --git a/composer.lock b/composer.lock index 7a8205f17..df5e09434 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "dc1c1e5ee766f2e31e84c50670fa0c98", + "content-hash": "e5ad978f95a98d7b1af728ade36c5f0d", "packages": [ { "name": "abdelhamiderrahmouni/filament-monaco-editor", @@ -2613,75 +2613,6 @@ ], "time": "2023-12-03T19:50:20+00:00" }, - { - "name": "hashids/hashids", - "version": "5.0.2", - "source": { - "type": "git", - "url": "https://github.com/vinkla/hashids.git", - "reference": "197171016b77ddf14e259e186559152eb3f8cf33" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/vinkla/hashids/zipball/197171016b77ddf14e259e186559152eb3f8cf33", - "reference": "197171016b77ddf14e259e186559152eb3f8cf33", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": "^8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "suggest": { - "ext-bcmath": "Required to use BC Math arbitrary precision mathematics (*).", - "ext-gmp": "Required to use GNU multiple precision mathematics (*)." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "psr-4": { - "Hashids\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ivan Akimov", - "email": "ivan@barreleye.com" - }, - { - "name": "Vincent Klaiber", - "email": "hello@doubledip.se" - } - ], - "description": "Generate short, unique, non-sequential ids (like YouTube and Bitly) from numbers", - "homepage": "https://hashids.org/php", - "keywords": [ - "bitly", - "decode", - "encode", - "hash", - "hashid", - "hashids", - "ids", - "obfuscate", - "youtube" - ], - "support": { - "issues": "https://github.com/vinkla/hashids/issues", - "source": "https://github.com/vinkla/hashids/tree/5.0.2" - }, - "time": "2023-02-23T15:00:54+00:00" - }, { "name": "kirschbaum-development/eloquent-power-joins", "version": "3.5.6", @@ -13061,5 +12992,5 @@ "ext-zip": "*" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/config/hashids.php b/config/hashids.php deleted file mode 100644 index 199de1a32..000000000 --- a/config/hashids.php +++ /dev/null @@ -1,15 +0,0 @@ - env('HASHIDS_SALT'), - 'length' => env('HASHIDS_LENGTH', 8), - 'alphabet' => env('HASHIDS_ALPHABET', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'), -]; diff --git a/lang/en/command/messages.php b/lang/en/command/messages.php index 4e640b3fa..50adf0fa3 100644 --- a/lang/en/command/messages.php +++ b/lang/en/command/messages.php @@ -23,7 +23,7 @@ return [ '2fa_disabled' => '2-Factor authentication has been disabled for :email.', ], 'schedule' => [ - 'output_line' => 'Dispatching job for first task in `:schedule` (:hash).', + 'output_line' => 'Dispatching job for first task in `:schedule` (:id).', ], 'maintenance' => [ 'deleting_service_backup' => 'Deleting service backup file :file.', diff --git a/tests/Integration/Api/Client/Server/Database/DatabaseAuthorizationTest.php b/tests/Integration/Api/Client/Server/Database/DatabaseAuthorizationTest.php index 0b3b88cd9..b95778104 100644 --- a/tests/Integration/Api/Client/Server/Database/DatabaseAuthorizationTest.php +++ b/tests/Integration/Api/Client/Server/Database/DatabaseAuthorizationTest.php @@ -5,7 +5,6 @@ namespace App\Tests\Integration\Api\Client\Server\Database; use App\Models\Subuser; use App\Models\Database; use App\Models\DatabaseHost; -use App\Contracts\Extensions\HashidsInterface; use App\Services\Databases\DatabasePasswordService; use App\Services\Databases\DatabaseManagementService; use App\Tests\Integration\Api\Client\ClientApiIntegrationTestCase; @@ -39,23 +38,22 @@ class DatabaseAuthorizationTest extends ClientApiIntegrationTestCase ->expects($method === 'POST' ? 'handle' : 'delete') ->andReturn($method === 'POST' ? 'foo' : null); - $hashids = $this->app->make(HashidsInterface::class); // This is the only valid call for this test, accessing the database for the same // server that the API user is the owner of. - $this->actingAs($user)->json($method, $this->link($server1, '/databases/' . $hashids->encode($database1->id) . $endpoint)) + $this->actingAs($user)->json($method, $this->link($server1, '/databases/' . $database1->id . $endpoint)) ->assertStatus($method === 'DELETE' ? 204 : 200); // This request fails because the database is valid for that server but the user // making the request is not authorized to perform that action. - $this->actingAs($user)->json($method, $this->link($server2, '/databases/' . $hashids->encode($database2->id) . $endpoint))->assertForbidden(); + $this->actingAs($user)->json($method, $this->link($server2, '/databases/' . $database2->id . $endpoint))->assertForbidden(); // Both of these should report a 404 error due to the database being linked to // servers that are not the same as the server in the request, or are assigned // to a server for which the user making the request has no access to. - $this->actingAs($user)->json($method, $this->link($server1, '/databases/' . $hashids->encode($database2->id) . $endpoint))->assertNotFound(); - $this->actingAs($user)->json($method, $this->link($server1, '/databases/' . $hashids->encode($database3->id) . $endpoint))->assertNotFound(); - $this->actingAs($user)->json($method, $this->link($server2, '/databases/' . $hashids->encode($database3->id) . $endpoint))->assertNotFound(); - $this->actingAs($user)->json($method, $this->link($server3, '/databases/' . $hashids->encode($database3->id) . $endpoint))->assertNotFound(); + $this->actingAs($user)->json($method, $this->link($server1, '/databases/' . $database2->id . $endpoint))->assertNotFound(); + $this->actingAs($user)->json($method, $this->link($server1, '/databases/' . $database3->id . $endpoint))->assertNotFound(); + $this->actingAs($user)->json($method, $this->link($server2, '/databases/' . $database3->id . $endpoint))->assertNotFound(); + $this->actingAs($user)->json($method, $this->link($server3, '/databases/' . $database3->id . $endpoint))->assertNotFound(); } public static function methodDataProvider(): array From 5760e72b8f9af4ea6d812a39c4dac8bc31267826 Mon Sep 17 00:00:00 2001 From: Senna <62171904+Poseidon281@users.noreply.github.com> Date: Thu, 30 May 2024 00:51:45 +0200 Subject: [PATCH 03/11] Added 2 badges (#296) --- readme.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/readme.md b/readme.md index 192c2c3dd..b737a25aa 100644 --- a/readme.md +++ b/readme.md @@ -2,6 +2,10 @@ # Pelican Panel +![Total Downloads](https://img.shields.io/github/downloads/pelican-dev/panel/total?style=flat&label=Total%20Downloads&labelColor=rgba(0%2C%2070%2C%20114%2C%201)&color=rgba(255%2C%20255%2C%20255%2C%201)) +![Latest Release](https://img.shields.io/github/v/release/pelican-dev/panel?style=flat&label=Latest%20Release&labelColor=rgba(0%2C%2070%2C%20114%2C%201)&color=rgba(255%2C%20255%2C%20255%2C%201)) + + Pelican Panel is an open-source, web-based application designed for easy management of game servers. It offers a user-friendly interface for deploying, configuring, and managing servers, with features like real-time resource monitoring, Docker container isolation, and extensive customization options. Ideal for both individual gamers and hosting companies, it simplifies server administration without requiring deep technical knowledge. From 7674ee0e2b91aa6c7037264a64860aee03ee2621 Mon Sep 17 00:00:00 2001 From: Exotical Date: Thu, 30 May 2024 00:54:07 +0200 Subject: [PATCH 04/11] Make deploy.locations optional in the api (#295) --- .../Requests/Api/Application/Servers/StoreServerRequest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/Http/Requests/Api/Application/Servers/StoreServerRequest.php b/app/Http/Requests/Api/Application/Servers/StoreServerRequest.php index fd735edf0..263b7c540 100644 --- a/app/Http/Requests/Api/Application/Servers/StoreServerRequest.php +++ b/app/Http/Requests/Api/Application/Servers/StoreServerRequest.php @@ -56,11 +56,10 @@ class StoreServerRequest extends ApplicationApiRequest // Automatic deployment rules 'deploy' => 'sometimes|required|array', 'deploy.locations' => 'array', - 'deploy.locations.*' => 'integer|min:1', + 'deploy.locations.*' => 'required_with:deploy.locations,integer|min:1', 'deploy.dedicated_ip' => 'required_with:deploy,boolean', 'deploy.port_range' => 'array', 'deploy.port_range.*' => 'string', - 'start_on_completion' => 'sometimes|boolean', ]; } From f6325c07c4dddc8d133c0283f2a3e3cc86072d6e Mon Sep 17 00:00:00 2001 From: Boy132 Date: Thu, 30 May 2024 00:57:30 +0200 Subject: [PATCH 05/11] Fix overallocation `-1` and close #268 (#283) --- .../Nodes/NodeDeploymentController.php | 2 +- app/Models/Node.php | 29 ++++++++++++++----- .../Deployment/FindViableNodesService.php | 8 ++--- .../Servers/ServerCreationService.php | 2 +- .../Servers/TransferServerService.php | 4 ++- 5 files changed, 29 insertions(+), 16 deletions(-) diff --git a/app/Http/Controllers/Api/Application/Nodes/NodeDeploymentController.php b/app/Http/Controllers/Api/Application/Nodes/NodeDeploymentController.php index f00c8d667..7a16fab01 100644 --- a/app/Http/Controllers/Api/Application/Nodes/NodeDeploymentController.php +++ b/app/Http/Controllers/Api/Application/Nodes/NodeDeploymentController.php @@ -24,8 +24,8 @@ class NodeDeploymentController extends ApplicationApiController $data = $request->validated(); $nodes = $this->viableNodesService->handle( - $data['disk'] ?? 0, $data['memory'] ?? 0, + $data['disk'] ?? 0, $data['cpu'] ?? 0, $data['tags'] ?? $data['location_ids'] ?? [], ); diff --git a/app/Models/Node.php b/app/Models/Node.php index c693c5b0d..8f1c42bdb 100644 --- a/app/Models/Node.php +++ b/app/Models/Node.php @@ -63,10 +63,6 @@ class Node extends Model */ protected $hidden = ['daemon_token_id', 'daemon_token']; - public int $sum_memory; - public int $sum_disk; - public int $sum_cpu; - /** * Fields that are mass assignable. */ @@ -250,11 +246,28 @@ class Node extends Model */ public function isViable(int $memory, int $disk, int $cpu): bool { - $memoryLimit = $this->memory * (1 + ($this->memory_overallocate / 100)); - $diskLimit = $this->disk * (1 + ($this->disk_overallocate / 100)); - $cpuLimit = $this->cpu * (1 + ($this->cpu_overallocate / 100)); + if ($this->memory_overallocate >= 0) { + $memoryLimit = $this->memory * (1 + ($this->memory_overallocate / 100)); + if ($this->servers_sum_memory + $memory > $memoryLimit) { + return false; + } + } - return ($this->sum_memory + $memory) <= $memoryLimit && ($this->sum_disk + $disk) <= $diskLimit && ($this->sum_cpu + $cpu) <= $cpuLimit; + if ($this->disk_overallocate >= 0) { + $diskLimit = $this->disk * (1 + ($this->disk_overallocate / 100)); + if ($this->servers_sum_disk + $disk > $diskLimit) { + return false; + } + } + + if ($this->cpu_overallocate >= 0) { + $cpuLimit = $this->cpu * (1 + ($this->cpu_overallocate / 100)); + if ($this->servers_sum_cpu + $cpu > $cpuLimit) { + return false; + } + } + + return true; } public static function getForServerCreation() diff --git a/app/Services/Deployment/FindViableNodesService.php b/app/Services/Deployment/FindViableNodesService.php index 9a51d1c6f..4cffc71d2 100644 --- a/app/Services/Deployment/FindViableNodesService.php +++ b/app/Services/Deployment/FindViableNodesService.php @@ -17,19 +17,17 @@ class FindViableNodesService * are tossed out, as are any nodes marked as non-public, meaning automatic * deployments should not be done against them. */ - public function handle(int $disk = 0, int $memory = 0, int $cpu = 0, $tags = []): Collection + public function handle(int $memory = 0, int $disk = 0, int $cpu = 0, $tags = []): Collection { $nodes = Node::query() - ->withSum('servers', 'disk') ->withSum('servers', 'memory') + ->withSum('servers', 'disk') ->withSum('servers', 'cpu') ->where('public', true) ->get(); return $nodes ->filter(fn (Node $node) => !$tags || collect($node->tags)->intersect($tags)) - ->filter(fn (Node $node) => $node->servers_sum_disk + $disk <= $node->disk * (1 + $node->disk_overallocate / 100)) - ->filter(fn (Node $node) => $node->servers_sum_memory + $memory <= $node->memory * (1 + $node->memory_overallocate / 100)) - ->filter(fn (Node $node) => $node->servers_sum_cpu + $cpu <= $node->cpu * (1 + $node->cpu_overallocate / 100)); + ->filter(fn (Node $node) => $node->isViable($memory, $disk, $cpu)); } } diff --git a/app/Services/Servers/ServerCreationService.php b/app/Services/Servers/ServerCreationService.php index 8953b1325..57d8ad086 100644 --- a/app/Services/Servers/ServerCreationService.php +++ b/app/Services/Servers/ServerCreationService.php @@ -109,8 +109,8 @@ class ServerCreationService { /** @var Collection<\App\Models\Node> $nodes */ $nodes = $this->findViableNodesService->handle( - Arr::get($data, 'disk', 0), Arr::get($data, 'memory', 0), + Arr::get($data, 'disk', 0), Arr::get($data, 'cpu', 0), Arr::get($data, 'tags', []), ); diff --git a/app/Services/Servers/TransferServerService.php b/app/Services/Servers/TransferServerService.php index 2cc34db70..72bac7dda 100644 --- a/app/Services/Servers/TransferServerService.php +++ b/app/Services/Servers/TransferServerService.php @@ -58,7 +58,9 @@ class TransferServerService // Check if the node is viable for the transfer. $node = Node::query() ->select(['nodes.id', 'nodes.fqdn', 'nodes.scheme', 'nodes.daemon_token', 'nodes.daemon_listen', 'nodes.memory', 'nodes.disk', 'nodes.cpu', 'nodes.memory_overallocate', 'nodes.disk_overallocate', 'nodes.cpu_overallocate']) - ->selectRaw('IFNULL(SUM(servers.memory), 0) as sum_memory, IFNULL(SUM(servers.disk), 0) as sum_disk, IFNULL(SUM(servers.cpu), 0) as sum_cpu') + ->withSum('servers', 'disk') + ->withSum('servers', 'memory') + ->withSum('servers', 'cpu') ->leftJoin('servers', 'servers.node_id', '=', 'nodes.id') ->where('nodes.id', $node_id) ->first(); From 8ecabef6b581a244d2ba9aa840eaded9ccf9f7bf Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Wed, 29 May 2024 19:24:02 -0400 Subject: [PATCH 06/11] Add customization --- app/Providers/Filament/AdminPanelProvider.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index 575fa500b..60339c744 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -35,11 +35,13 @@ class AdminPanelProvider extends PanelProvider ->default() ->id('admin') ->path('admin') - ->topNavigation(config('panel.filament.top-navigation', false)) + ->topNavigation(config('panel.filament.top-navigation', true)) ->login() ->homeUrl('/') - ->favicon('/pelican.ico') - ->brandName('Pelican') + ->favicon(config('app.favicon', '/pelican.ico')) + ->brandName(config('app.name', 'Pelican')) + ->brandLogo(config('app.logo')) + ->brandLogoHeight('2rem') ->profile(EditProfile::class, false) ->colors([ 'danger' => Color::Red, From aa82c6dd047fdc2d15ce354f17270eef4fb24828 Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Fri, 31 May 2024 01:20:25 -0400 Subject: [PATCH 07/11] Update this --- app/Exceptions/DisplayException.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Exceptions/DisplayException.php b/app/Exceptions/DisplayException.php index 9c7927a43..6c44c356c 100644 --- a/app/Exceptions/DisplayException.php +++ b/app/Exceptions/DisplayException.php @@ -48,7 +48,7 @@ class DisplayException extends PanelException implements HttpExceptionInterface */ public function render(Request $request) { - if (str($request->url())->contains('livewire')) { + if ($request->is('livewire/update')) { Notification::make() ->title(static::class) ->body($this->getMessage()) From 97ac0fe54b5dffa9c84acddf97c79e316c25b0c3 Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 31 May 2024 01:41:21 -0400 Subject: [PATCH 08/11] Add Reset Daemon Key Button (#298) closes #292 --- .../Resources/NodeResource/Pages/EditNode.php | 14 ++++++++++++++ app/Services/Nodes/NodeUpdateService.php | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/app/Filament/Resources/NodeResource/Pages/EditNode.php b/app/Filament/Resources/NodeResource/Pages/EditNode.php index a5126f694..ca0ac657f 100644 --- a/app/Filament/Resources/NodeResource/Pages/EditNode.php +++ b/app/Filament/Resources/NodeResource/Pages/EditNode.php @@ -6,9 +6,11 @@ use App\Filament\Resources\NodeResource; use App\Filament\Resources\NodeResource\Widgets\NodeMemoryChart; use App\Filament\Resources\NodeResource\Widgets\NodeStorageChart; use App\Models\Node; +use App\Services\Nodes\NodeUpdateService; use Filament\Actions; use Filament\Forms; use Filament\Forms\Components\Tabs; +use Filament\Notifications\Notification; use Filament\Resources\Pages\EditRecord; use Illuminate\Support\HtmlString; use Webbingbrasil\FilamentCopyActions\Forms\Actions\CopyAction; @@ -374,6 +376,18 @@ class EditNode extends EditRecord ->rows(19) ->hintAction(CopyAction::make()) ->columnSpanFull(), + Forms\Components\Actions::make([ + Forms\Components\Actions\Action::make('resetKey') + ->label('Reset Daemon Token') + ->color('danger') + ->requiresConfirmation() + ->modalHeading('Reset Daemon Token?') + ->modalDescription('Resetting the daemon token will void any request coming from the old token. This token is used for all sensitive operations on the daemon including server creation and deletion. We suggest changing this token regularly for security.') + ->action(fn (NodeUpdateService $nodeUpdateService, Node $node) => $nodeUpdateService->handle($node, [], true) + && Notification::make()->success()->title('Daemon Key Reset')->send() + && $this->fillForm() + ), + ]), ]), ]), ]); diff --git a/app/Services/Nodes/NodeUpdateService.php b/app/Services/Nodes/NodeUpdateService.php index 76d1aadbd..c76353d33 100644 --- a/app/Services/Nodes/NodeUpdateService.php +++ b/app/Services/Nodes/NodeUpdateService.php @@ -34,8 +34,8 @@ class NodeUpdateService [$updated, $exception] = $this->connection->transaction(function () use ($data, $node) { /** @var \App\Models\Node $updated */ - $updated = $node->replicate()->forceFill($data)->save(); - + $updated = $node->replicate(); + $updated->forceFill($data)->save(); try { // If we're changing the FQDN for the node, use the newly provided FQDN for the connection // address. This should alleviate issues where the node gets pointed to a "valid" FQDN that From 065f3f246803fbfa8517559f82c35d43cb426679 Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Fri, 31 May 2024 15:18:04 -0400 Subject: [PATCH 09/11] Activity log fix #257 --- app/Transformers/Api/Client/ActivityLogTransformer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Transformers/Api/Client/ActivityLogTransformer.php b/app/Transformers/Api/Client/ActivityLogTransformer.php index af666beb6..d02f95988 100644 --- a/app/Transformers/Api/Client/ActivityLogTransformer.php +++ b/app/Transformers/Api/Client/ActivityLogTransformer.php @@ -55,7 +55,7 @@ class ActivityLogTransformer extends BaseClientTransformer $properties = $model->properties ->mapWithKeys(function ($value, $key) use ($model) { - if ($key === 'ip' && !$model->actor->is($this->request->user())) { + if ($key === 'ip' && $model->actor && !$model->actor->is($this->request->user())) { return [$key => '[hidden]']; } From 264d3498a663f87abc7ea7ab3a675d8e2ac5cdf5 Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Fri, 31 May 2024 15:44:21 -0400 Subject: [PATCH 10/11] Allow mailgun to work #257 --- composer.json | 3 +- composer.lock | 186 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 181 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 8de5cefc6..407c79890 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,8 @@ "s1lentium/iptools": "~1.2.0", "spatie/laravel-fractal": "^6.2", "spatie/laravel-query-builder": "^5.8.1", - "symfony/mailgun-mailer": "^7.0.7", + "symfony/http-client": "^7.1", + "symfony/mailgun-mailer": "^7.1", "symfony/postmark-mailer": "^7.0.7", "symfony/yaml": "^7.0.7", "webbingbrasil/filament-copyactions": "^3.0.1", diff --git a/composer.lock b/composer.lock index df5e09434..d92e3bd6f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e5ad978f95a98d7b1af728ade36c5f0d", + "content-hash": "328bdd29cb83793ec0a99b2210941740", "packages": [ { "name": "abdelhamiderrahmouni/filament-monaco-editor", @@ -7653,6 +7653,178 @@ ], "time": "2024-04-18T09:29:19+00:00" }, + { + "name": "symfony/http-client", + "version": "v7.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "2266f9813ed7d8c84e04627edead7b7fd249d6e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/2266f9813ed7d8c84e04627edead7b7fd249d6e9", + "reference": "2266f9813ed7d8c84e04627edead7b7fd249d6e9", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "^3.4.1", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.4" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4|^2.0", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v7.1.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-05-13T15:35:37+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "20414d96f391677bf80078aa55baece78b82647d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", + "reference": "20414d96f391677bf80078aa55baece78b82647d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" + }, { "name": "symfony/http-foundation", "version": "v7.0.7", @@ -7925,16 +8097,16 @@ }, { "name": "symfony/mailgun-mailer", - "version": "v7.0.7", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/mailgun-mailer.git", - "reference": "e9bb8fdbdd79334a8a88bdd233204315abd992c5" + "reference": "aa5afbe846bbc8bde6afe2602f0427834b872f55" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/e9bb8fdbdd79334a8a88bdd233204315abd992c5", - "reference": "e9bb8fdbdd79334a8a88bdd233204315abd992c5", + "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/aa5afbe846bbc8bde6afe2602f0427834b872f55", + "reference": "aa5afbe846bbc8bde6afe2602f0427834b872f55", "shasum": "" }, "require": { @@ -7974,7 +8146,7 @@ "description": "Symfony Mailgun Mailer Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailgun-mailer/tree/v7.0.7" + "source": "https://github.com/symfony/mailgun-mailer/tree/v7.1.0" }, "funding": [ { @@ -7990,7 +8162,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:29:19+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/mime", From 8eb2c23420dd093ae6a6774f4559481821150351 Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Fri, 31 May 2024 16:03:12 -0400 Subject: [PATCH 11/11] Fix creating new node --- app/Filament/Resources/NodeResource/Pages/CreateNode.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Filament/Resources/NodeResource/Pages/CreateNode.php b/app/Filament/Resources/NodeResource/Pages/CreateNode.php index 775fe5e9f..1d506083e 100644 --- a/app/Filament/Resources/NodeResource/Pages/CreateNode.php +++ b/app/Filament/Resources/NodeResource/Pages/CreateNode.php @@ -329,7 +329,6 @@ class CreateNode extends CreateRecord true => 'primary', false => 'warning', ]) - ->default(0) ->columnSpan(2), Forms\Components\TextInput::make('cpu') ->dehydratedWhenHidden() @@ -338,6 +337,7 @@ class CreateNode extends CreateRecord ->suffix('%') ->columnSpan(2) ->numeric() + ->default(0) ->minValue(0), Forms\Components\TextInput::make('cpu_overallocate') ->dehydratedWhenHidden()