From 37769dfc9ebb8f93ac530a46ab10feceb86a9e7b Mon Sep 17 00:00:00 2001 From: notCharles Date: Sat, 4 Jan 2025 19:12:41 -0500 Subject: [PATCH 01/12] Fix 500 on duplicate ports This should also address N+1 issues from the last PR --- .../AllocationsRelationManager.php | 53 +++++++++++++++---- .../ServerResource/Pages/CreateServer.php | 42 +++++++++++++-- .../AllocationsRelationManager.php | 51 +++++++++++++++--- 3 files changed, 124 insertions(+), 22 deletions(-) diff --git a/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php b/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php index ba7ee06b01..bd8d3748e9 100644 --- a/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php +++ b/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php @@ -9,7 +9,9 @@ use Filament\Forms\Components\TagsInput; use Filament\Forms\Components\TextInput; use Filament\Forms\Form; +use Filament\Forms\Get; use Filament\Forms\Set; +use Filament\Notifications\Notification; use Filament\Resources\RelationManagers\RelationManager; use Filament\Tables; use Filament\Tables\Actions\BulkActionGroup; @@ -97,18 +99,32 @@ public function table(Table $table): Table ->label('Ports') ->inlineLabel() ->live() - ->afterStateUpdated(function ($state, Set $set) { + ->afterStateUpdated(function ($state, Set $set, Get $get) { $ports = collect(); $update = false; + $existingPorts = Allocation::query() + ->where('ip', $get('allocation_ip')) + ->pluck('port') + ->toArray(); + foreach ($state as $portEntry) { if (!str_contains($portEntry, '-')) { if (is_numeric($portEntry)) { - $ports->push((int) $portEntry); - - continue; + $portEntry = (int) $portEntry; + if (in_array($portEntry, $existingPorts)) { + Notification::make() + ->title('Port Already Exists') + ->danger() + ->body('Port ' . $portEntry . ' already exists.') + ->send(); + } else { + $ports->push($portEntry); + + continue; + } } - // Do not add non numerical ports + // Do not add non-numerical ports $update = true; continue; @@ -122,8 +138,29 @@ public function table(Table $table): Table $start = max((int) $start, 0); $end = min((int) $end, 2 ** 16 - 1); - foreach (range($start, $end) as $i) { - $ports->push($i); + $range = $start <= $end ? range($start, $end) : range($end, $start); + + if (count($range) > 1001) { + Notification::make() + ->title('Port Range Too High') + ->danger() + ->body('Port range ' . $portEntry . ' is too high. Please keep it under 1000.') + ->send(); + break; + } + + foreach ($range as $i) { + if ($i > 1024 && $i <= 65535) { + if (in_array($i, $existingPorts)) { + Notification::make() + ->title('Port Already Exists') + ->danger() + ->body('Port ' . $i . ' already exists for ' . $get('allocation_ip')) + ->send(); + } else { + $ports->push($i); + } + } } } @@ -139,8 +176,6 @@ public function table(Table $table): Table $ports = $sortedPorts; } - $ports = $ports->filter(fn ($port) => $port > 1024 && $port < 65535)->values(); - if ($update) { $set('allocation_ports', $ports->all()); } diff --git a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php index 745e45aa76..3c6cbb5c1d 100644 --- a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php +++ b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php @@ -226,15 +226,29 @@ public function form(Form $form): Form ->label('Ports') ->inlineLabel() ->live() - ->afterStateUpdated(function ($state, Set $set) { + ->afterStateUpdated(function ($state, Set $set, Get $get) { $ports = collect(); $update = false; + $existingPorts = Allocation::query() + ->where('ip', $get('allocation_ip')) + ->pluck('port') + ->toArray(); + foreach ($state as $portEntry) { if (!str_contains($portEntry, '-')) { if (is_numeric($portEntry)) { - $ports->push((int) $portEntry); - - continue; + $portEntry = (int) $portEntry; + if (in_array($portEntry, $existingPorts)) { + Notification::make() + ->title('Port Already Exists') + ->danger() + ->body('Port ' . $portEntry . ' already exists.') + ->send(); + } else { + $ports->push($portEntry); + + continue; + } } // Do not add non-numerical ports @@ -252,9 +266,27 @@ public function form(Form $form): Form $start = max((int) $start, 0); $end = min((int) $end, 2 ** 16 - 1); $range = $start <= $end ? range($start, $end) : range($end, $start); + + if (count($range) > 1001) { + Notification::make() + ->title('Port Range Too High') + ->danger() + ->body('Port range ' . $portEntry . ' is too high. Please keep it under 1000.') + ->send(); + break; + } + foreach ($range as $i) { if ($i > 1024 && $i <= 65535) { - $ports->push($i); + if (in_array($i, $existingPorts)) { + Notification::make() + ->title('Port Already Exists') + ->danger() + ->body('Port ' . $i . ' already exists for ' . $get('allocation_ip')) + ->send(); + } else { + $ports->push($i); + } } } } diff --git a/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php b/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php index f0fca624a5..af5188a625 100644 --- a/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php +++ b/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php @@ -9,7 +9,9 @@ use Filament\Forms\Components\TagsInput; use Filament\Forms\Components\TextInput; use Filament\Forms\Form; +use Filament\Forms\Get; use Filament\Forms\Set; +use Filament\Notifications\Notification; use Filament\Resources\RelationManagers\RelationManager; use Filament\Tables; use Filament\Tables\Actions\Action; @@ -95,18 +97,32 @@ public function table(Table $table): Table ->label('Ports') ->inlineLabel() ->live() - ->afterStateUpdated(function ($state, Set $set) { + ->afterStateUpdated(function ($state, Set $set, Get $get) { $ports = collect(); $update = false; + $existingPorts = Allocation::query() + ->where('ip', $get('allocation_ip')) + ->pluck('port') + ->toArray(); + foreach ($state as $portEntry) { if (!str_contains($portEntry, '-')) { if (is_numeric($portEntry)) { - $ports->push((int) $portEntry); + $portEntry = (int) $portEntry; + if (in_array($portEntry, $existingPorts)) { + Notification::make() + ->title('Port Already Exists') + ->danger() + ->body('Port ' . $portEntry . ' already exists.') + ->send(); + } else { + $ports->push($portEntry); - continue; + continue; + } } - // Do not add non numerical ports + // Do not add non-numerical ports $update = true; continue; @@ -120,8 +136,29 @@ public function table(Table $table): Table $start = max((int) $start, 0); $end = min((int) $end, 2 ** 16 - 1); - foreach (range($start, $end) as $i) { - $ports->push($i); + $range = $start <= $end ? range($start, $end) : range($end, $start); + + if (count($range) > 1001) { + Notification::make() + ->title('Port Range Too High') + ->danger() + ->body('Port range ' . $portEntry . ' is too high. Please keep it under 1000.') + ->send(); + break; + } + + foreach ($range as $i) { + if ($i > 1024 && $i <= 65535) { + if (in_array($i, $existingPorts)) { + Notification::make() + ->title('Port Already Exists') + ->danger() + ->body('Port ' . $i . ' already exists for ' . $get('allocation_ip')) + ->send(); + } else { + $ports->push($i); + } + } } } @@ -137,8 +174,6 @@ public function table(Table $table): Table $ports = $sortedPorts; } - $ports = $ports->filter(fn ($port) => $port > 1024 && $port < 65535)->values(); - if ($update) { $set('allocation_ports', $ports->all()); } From 0b3b77cedcaa954bd6d44850f9cdda6e459a30b6 Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sat, 4 Jan 2025 21:01:54 -0500 Subject: [PATCH 02/12] Combine into one method --- .../AllocationsRelationManager.php | 84 +------ .../ServerResource/Pages/CreateServer.php | 238 ++++++++++-------- .../AllocationsRelationManager.php | 82 +----- 3 files changed, 139 insertions(+), 265 deletions(-) diff --git a/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php b/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php index bd8d3748e9..eb8c8eece7 100644 --- a/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php +++ b/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php @@ -2,6 +2,7 @@ namespace App\Filament\Admin\Resources\NodeResource\RelationManagers; +use App\Filament\Admin\Resources\ServerResource\Pages\CreateServer; use App\Models\Allocation; use App\Models\Node; use App\Services\Allocations\AssignmentService; @@ -82,6 +83,7 @@ public function table(Table $table): Table ->inlineLabel() ->ipv4() ->helperText("Usually your machine's public IP unless you are port forwarding.") + ->live() ->required(), TextInput::make('allocation_alias') ->label('Alias') @@ -99,85 +101,13 @@ public function table(Table $table): Table ->label('Ports') ->inlineLabel() ->live() + ->disabled(fn (Get $get) => empty($get('allocation_ip'))) ->afterStateUpdated(function ($state, Set $set, Get $get) { - $ports = collect(); - $update = false; - $existingPorts = Allocation::query() - ->where('ip', $get('allocation_ip')) - ->pluck('port') - ->toArray(); - - foreach ($state as $portEntry) { - if (!str_contains($portEntry, '-')) { - if (is_numeric($portEntry)) { - $portEntry = (int) $portEntry; - if (in_array($portEntry, $existingPorts)) { - Notification::make() - ->title('Port Already Exists') - ->danger() - ->body('Port ' . $portEntry . ' already exists.') - ->send(); - } else { - $ports->push($portEntry); - - continue; - } - } - - // Do not add non-numerical ports - $update = true; - - continue; - } - - $update = true; - [$start, $end] = explode('-', $portEntry); - if (!is_numeric($start) || !is_numeric($end)) { - continue; - } - - $start = max((int) $start, 0); - $end = min((int) $end, 2 ** 16 - 1); - $range = $start <= $end ? range($start, $end) : range($end, $start); - - if (count($range) > 1001) { - Notification::make() - ->title('Port Range Too High') - ->danger() - ->body('Port range ' . $portEntry . ' is too high. Please keep it under 1000.') - ->send(); - break; - } - - foreach ($range as $i) { - if ($i > 1024 && $i <= 65535) { - if (in_array($i, $existingPorts)) { - Notification::make() - ->title('Port Already Exists') - ->danger() - ->body('Port ' . $i . ' already exists for ' . $get('allocation_ip')) - ->send(); - } else { - $ports->push($i); - } - } - } - } - - $uniquePorts = $ports->unique()->values(); - if ($ports->count() > $uniquePorts->count()) { - $update = true; - $ports = $uniquePorts; - } - - $sortedPorts = $ports->sort()->values(); - if ($sortedPorts->all() !== $ports->all()) { - $update = true; - $ports = $sortedPorts; - } + $node = $this->getOwnerRecord(); + $ports = CreateServer::retrieveValidPorts($node, $state, $get('allocation_ip')); - if ($update) { - $set('allocation_ports', $ports->all()); + if ($ports !== null) { + $set('allocation_ports', $ports); } }) ->splitKeys(['Tab', ' ', ',']) diff --git a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php index 3c6cbb5c1d..793ae0152e 100644 --- a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php +++ b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php @@ -198,118 +198,52 @@ public function form(Form $form): Form ->where('node_id', $get('node_id')) ->whereNull('server_id'), ) - ->createOptionForm(fn (Get $get) => [ - Select::make('allocation_ip') - ->options(collect(Node::find($get('node_id'))?->ipAddresses())->mapWithKeys(fn (string $ip) => [$ip => $ip])) - ->label('IP Address') - ->inlineLabel() - ->ipv4() - ->helperText("Usually your machine's public IP unless you are port forwarding.") - ->required(), - TextInput::make('allocation_alias') - ->label('Alias') - ->inlineLabel() - ->default(null) - ->datalist([ - $get('name'), - Egg::find($get('egg_id'))?->name, - ]) - ->helperText('Optional display name to help you remember what these are.') - ->required(false), - TagsInput::make('allocation_ports') - ->placeholder('Examples: 27015, 27017-27019') - ->helperText(new HtmlString(' - These are the ports that users can connect to this Server through. -
- You would have to port forward these on your home network. - ')) - ->label('Ports') - ->inlineLabel() - ->live() - ->afterStateUpdated(function ($state, Set $set, Get $get) { - $ports = collect(); - $update = false; - $existingPorts = Allocation::query() - ->where('ip', $get('allocation_ip')) - ->pluck('port') - ->toArray(); - - foreach ($state as $portEntry) { - if (!str_contains($portEntry, '-')) { - if (is_numeric($portEntry)) { - $portEntry = (int) $portEntry; - if (in_array($portEntry, $existingPorts)) { - Notification::make() - ->title('Port Already Exists') - ->danger() - ->body('Port ' . $portEntry . ' already exists.') - ->send(); - } else { - $ports->push($portEntry); - - continue; - } - } - - // Do not add non-numerical ports - $update = true; - - continue; - } - - $update = true; - [$start, $end] = explode('-', $portEntry); - if (!is_numeric($start) || !is_numeric($end)) { - continue; - } - - $start = max((int) $start, 0); - $end = min((int) $end, 2 ** 16 - 1); - $range = $start <= $end ? range($start, $end) : range($end, $start); - - if (count($range) > 1001) { - Notification::make() - ->title('Port Range Too High') - ->danger() - ->body('Port range ' . $portEntry . ' is too high. Please keep it under 1000.') - ->send(); - break; - } - - foreach ($range as $i) { - if ($i > 1024 && $i <= 65535) { - if (in_array($i, $existingPorts)) { - Notification::make() - ->title('Port Already Exists') - ->danger() - ->body('Port ' . $i . ' already exists for ' . $get('allocation_ip')) - ->send(); - } else { - $ports->push($i); - } - } + ->createOptionForm(function (Get $get) { + $getPage = $get; + + return [ + Select::make('allocation_ip') + ->options(collect(Node::find($get('node_id'))?->ipAddresses())->mapWithKeys(fn(string $ip) => [$ip => $ip])) + ->label('IP Address') + ->inlineLabel() + ->ipv4() + ->helperText("Usually your machine's public IP unless you are port forwarding.") + ->live() + ->required(), + TextInput::make('allocation_alias') + ->label('Alias') + ->inlineLabel() + ->default(null) + ->datalist([ + $get('name'), + Egg::find($get('egg_id'))?->name, + ]) + ->helperText('Optional display name to help you remember what these are.') + ->required(false), + TagsInput::make('allocation_ports') + ->placeholder('Examples: 27015, 27017-27019') + ->helperText(new HtmlString(' + These are the ports that users can connect to this Server through. +
+ You would have to port forward these on your home network. + ')) + ->label('Ports') + ->inlineLabel() + ->live() + ->disabled(fn (Get $get) => empty($get('allocation_ip'))) + ->afterStateUpdated(function ($state, Set $set, Get $get) use ($getPage) { + $node = Node::find($getPage('node_id')); + $ip = $get('allocation_ip'); + + $ports = self::retrieveValidPorts($node, $state, $ip); + if ($ports !== null) { + $set('allocation_ports', $ports); } - } - - $uniquePorts = $ports->unique()->values(); - if ($ports->count() > $uniquePorts->count()) { - $update = true; - $ports = $uniquePorts; - } - - $sortedPorts = $ports->sort()->values(); - if ($sortedPorts->all() !== $ports->all()) { - $update = true; - $ports = $sortedPorts; - } - - if ($update) { - $set('allocation_ports', $ports->all()); - } - }) - ->splitKeys(['Tab', ' ', ',']) - ->required(), - ]) + }) + ->splitKeys(['Tab', ' ', ',']) + ->required(), + ]; + }) ->createOptionUsing(function (array $data, Get $get, AssignmentService $assignmentService): int { return collect( $assignmentService->handle(Node::find($get('node_id')), $data) @@ -954,4 +888,86 @@ private function getSelectOptionsFromRules(Get $get): array ->mapWithKeys(fn ($value) => [$value => $value]) ->all(); } + + public static function retrieveValidPorts(Node $node, array $portEntries, string $ip, $maxPorts = 1000): ?array + { + $ports = collect(); + $update = false; + + $existingPorts = $node + ->allocations() + ->where('ip', $ip) + ->pluck('port') + ->all(); + + foreach ($portEntries as $portEntry) { + if (!str_contains($portEntry, '-')) { + if (is_numeric($portEntry)) { + $portEntry = (int) $portEntry; + if (!in_array($portEntry, $existingPorts)) { + $ports->push($portEntry); + + continue; + } + } + + // Do not add non-numerical ports + $update = true; + + continue; + } + + $update = true; + [$start, $end] = explode('-', $portEntry); + if (!is_numeric($start) || !is_numeric($end)) { + continue; + } + + $start = max((int) $start, 0); + $end = min((int) $end, 2 ** 16 - 1); + $range = $start <= $end ? range($start, $end) : range($end, $start); + + if (count($range) > $maxPorts) { + Notification::make() + ->title('Too many ports at one time!') + ->danger() + ->body("The current limit is $maxPorts number of ports at one time.") + ->send(); + + break; + } + + foreach ($range as $i) { + // Invalid port number + if ($i <= AssignmentService::PORT_FLOOR || $i > AssignmentService::PORT_CEIL) { + continue; + } + + // Already exists + if (in_array($i, $existingPorts)) { + continue; + } + + $ports->push($i); + } + } + + $uniquePorts = $ports->unique()->values(); + if ($ports->count() > $uniquePorts->count()) { + $update = true; + $ports = $uniquePorts; + } + + $sortedPorts = $ports->sort()->values(); + if ($sortedPorts->all() !== $ports->all()) { + $update = true; + $ports = $sortedPorts; + } + + if ($update) { + return $ports->all(); + } + + return null; + } } diff --git a/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php b/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php index af5188a625..475d7947d4 100644 --- a/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php +++ b/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php @@ -2,6 +2,7 @@ namespace App\Filament\Admin\Resources\ServerResource\RelationManagers; +use App\Filament\Admin\Resources\ServerResource\Pages\CreateServer; use App\Models\Allocation; use App\Models\Server; use App\Services\Allocations\AssignmentService; @@ -98,84 +99,11 @@ public function table(Table $table): Table ->inlineLabel() ->live() ->afterStateUpdated(function ($state, Set $set, Get $get) { - $ports = collect(); - $update = false; - $existingPorts = Allocation::query() - ->where('ip', $get('allocation_ip')) - ->pluck('port') - ->toArray(); + $server = $this->getOwnerRecord(); + $ports = CreateServer::retrieveValidPorts($server->node, $state, $get('allocation_ip')); - foreach ($state as $portEntry) { - if (!str_contains($portEntry, '-')) { - if (is_numeric($portEntry)) { - $portEntry = (int) $portEntry; - if (in_array($portEntry, $existingPorts)) { - Notification::make() - ->title('Port Already Exists') - ->danger() - ->body('Port ' . $portEntry . ' already exists.') - ->send(); - } else { - $ports->push($portEntry); - - continue; - } - } - - // Do not add non-numerical ports - $update = true; - - continue; - } - - $update = true; - [$start, $end] = explode('-', $portEntry); - if (!is_numeric($start) || !is_numeric($end)) { - continue; - } - - $start = max((int) $start, 0); - $end = min((int) $end, 2 ** 16 - 1); - $range = $start <= $end ? range($start, $end) : range($end, $start); - - if (count($range) > 1001) { - Notification::make() - ->title('Port Range Too High') - ->danger() - ->body('Port range ' . $portEntry . ' is too high. Please keep it under 1000.') - ->send(); - break; - } - - foreach ($range as $i) { - if ($i > 1024 && $i <= 65535) { - if (in_array($i, $existingPorts)) { - Notification::make() - ->title('Port Already Exists') - ->danger() - ->body('Port ' . $i . ' already exists for ' . $get('allocation_ip')) - ->send(); - } else { - $ports->push($i); - } - } - } - } - - $uniquePorts = $ports->unique()->values(); - if ($ports->count() > $uniquePorts->count()) { - $update = true; - $ports = $uniquePorts; - } - - $sortedPorts = $ports->sort()->values(); - if ($sortedPorts->all() !== $ports->all()) { - $update = true; - $ports = $sortedPorts; - } - - if ($update) { - $set('allocation_ports', $ports->all()); + if ($ports !== null) { + $set('allocation_ports', $ports); } }) ->splitKeys(['Tab', ' ', ',']) From 7dfd71251f0fee87e890784be6f8ea94f2159250 Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sat, 4 Jan 2025 21:02:26 -0500 Subject: [PATCH 03/12] Pint --- .../RelationManagers/AllocationsRelationManager.php | 1 - .../Admin/Resources/ServerResource/Pages/CreateServer.php | 2 +- .../RelationManagers/AllocationsRelationManager.php | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php b/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php index eb8c8eece7..419991713f 100644 --- a/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php +++ b/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php @@ -12,7 +12,6 @@ use Filament\Forms\Form; use Filament\Forms\Get; use Filament\Forms\Set; -use Filament\Notifications\Notification; use Filament\Resources\RelationManagers\RelationManager; use Filament\Tables; use Filament\Tables\Actions\BulkActionGroup; diff --git a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php index 793ae0152e..efc5892c5f 100644 --- a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php +++ b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php @@ -203,7 +203,7 @@ public function form(Form $form): Form return [ Select::make('allocation_ip') - ->options(collect(Node::find($get('node_id'))?->ipAddresses())->mapWithKeys(fn(string $ip) => [$ip => $ip])) + ->options(collect(Node::find($get('node_id'))?->ipAddresses())->mapWithKeys(fn (string $ip) => [$ip => $ip])) ->label('IP Address') ->inlineLabel() ->ipv4() diff --git a/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php b/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php index 475d7947d4..698ed9a6da 100644 --- a/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php +++ b/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php @@ -12,7 +12,6 @@ use Filament\Forms\Form; use Filament\Forms\Get; use Filament\Forms\Set; -use Filament\Notifications\Notification; use Filament\Resources\RelationManagers\RelationManager; use Filament\Tables; use Filament\Tables\Actions\Action; From 1c0584234c9b3065454175a7b502669d812d96ed Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sat, 4 Jan 2025 21:05:23 -0500 Subject: [PATCH 04/12] Add missing type --- .../Admin/Resources/ServerResource/Pages/CreateServer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php index efc5892c5f..042af597ee 100644 --- a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php +++ b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php @@ -889,7 +889,7 @@ private function getSelectOptionsFromRules(Get $get): array ->all(); } - public static function retrieveValidPorts(Node $node, array $portEntries, string $ip, $maxPorts = 1000): ?array + public static function retrieveValidPorts(Node $node, array $portEntries, string $ip, int $maxPorts = 1000): ?array { $ports = collect(); $update = false; From 9e62fad7be91c5fcae42665ce0c8d99718624815 Mon Sep 17 00:00:00 2001 From: notCharles Date: Sat, 4 Jan 2025 21:14:25 -0500 Subject: [PATCH 05/12] Add 0.0.0.0 --- app/Models/Node.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Models/Node.php b/app/Models/Node.php index 011abb2527..d6383be27e 100644 --- a/app/Models/Node.php +++ b/app/Models/Node.php @@ -387,6 +387,7 @@ public function ipAddresses(): array // pass } + $ips->push('0.0.0.0'); // Only IPV4 $ips = $ips->filter(fn (string $ip) => filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false); From 5ddf095d612c4420c682fede925e5e0f71f3eace Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sat, 4 Jan 2025 21:21:56 -0500 Subject: [PATCH 06/12] Add notifications to help the user --- .../ServerResource/Pages/CreateServer.php | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php index 042af597ee..034098fe60 100644 --- a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php +++ b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php @@ -889,8 +889,12 @@ private function getSelectOptionsFromRules(Get $get): array ->all(); } - public static function retrieveValidPorts(Node $node, array $portEntries, string $ip, int $maxPorts = 1000): ?array + public static function retrieveValidPorts(Node $node, array $portEntries, string $ip): ?array { + $portRangeLimit = AssignmentService::PORT_RANGE_LIMIT; + $portFloor = AssignmentService::PORT_FLOOR; + $portCeil = AssignmentService::PORT_CEIL; + $ports = collect(); $update = false; @@ -914,12 +918,24 @@ public static function retrieveValidPorts(Node $node, array $portEntries, string // Do not add non-numerical ports $update = true; + Notification::make() + ->title("Invalid Port") + ->danger() + ->body("Your port must be a number!") + ->send(); + continue; } $update = true; [$start, $end] = explode('-', $portEntry); if (!is_numeric($start) || !is_numeric($end)) { + Notification::make() + ->title("Invalid Port Range") + ->danger() + ->body("Your port range are not valid integers: $portEntry") + ->send(); + continue; } @@ -927,24 +943,44 @@ public static function retrieveValidPorts(Node $node, array $portEntries, string $end = min((int) $end, 2 ** 16 - 1); $range = $start <= $end ? range($start, $end) : range($end, $start); - if (count($range) > $maxPorts) { + if (count($range) > $portRangeLimit) { Notification::make() ->title('Too many ports at one time!') ->danger() - ->body("The current limit is $maxPorts number of ports at one time.") + ->body("The current limit is $portRangeLimit number of ports at one time.") ->send(); break; } + if (empty($range)) { + Notification::make() + ->title('Invalid Port Range') + ->danger() + ->body("The current limit is $portRangeLimit number of ports at one time.") + ->send(); + } + foreach ($range as $i) { // Invalid port number - if ($i <= AssignmentService::PORT_FLOOR || $i > AssignmentService::PORT_CEIL) { + if ($i <= $portFloor || $i > $portCeil) { + Notification::make() + ->title('Port not in valid range') + ->danger() + ->body("$i is not in the valid port range between $portFloor-$portCeil") + ->send(); + continue; } // Already exists if (in_array($i, $existingPorts)) { + Notification::make() + ->title('Port already in use') + ->danger() + ->body("$i is already with an allocation") + ->send(); + continue; } From 12459a21fdb53dd0c647e8e462749678aecf9aea Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sat, 4 Jan 2025 21:22:08 -0500 Subject: [PATCH 07/12] Pint --- .../Admin/Resources/ServerResource/Pages/CreateServer.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php index 034098fe60..97b1fe51e2 100644 --- a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php +++ b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php @@ -919,9 +919,9 @@ public static function retrieveValidPorts(Node $node, array $portEntries, string $update = true; Notification::make() - ->title("Invalid Port") + ->title('Invalid Port') ->danger() - ->body("Your port must be a number!") + ->body('Your port must be a number!') ->send(); continue; @@ -931,7 +931,7 @@ public static function retrieveValidPorts(Node $node, array $portEntries, string [$start, $end] = explode('-', $portEntry); if (!is_numeric($start) || !is_numeric($end)) { Notification::make() - ->title("Invalid Port Range") + ->title('Invalid Port Range') ->danger() ->body("Your port range are not valid integers: $portEntry") ->send(); From 034ab22ba8de1891cc34e72340d0f1e21bd2409a Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sat, 4 Jan 2025 21:25:26 -0500 Subject: [PATCH 08/12] Too verbose --- .../Admin/Resources/ServerResource/Pages/CreateServer.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php index 97b1fe51e2..0dffb863f2 100644 --- a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php +++ b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php @@ -918,12 +918,6 @@ public static function retrieveValidPorts(Node $node, array $portEntries, string // Do not add non-numerical ports $update = true; - Notification::make() - ->title('Invalid Port') - ->danger() - ->body('Your port must be a number!') - ->send(); - continue; } From 3c4886b003a200bdbb6b20489d4f6a29d292c36b Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sat, 4 Jan 2025 21:27:58 -0500 Subject: [PATCH 09/12] Show notification here --- .../Admin/Resources/ServerResource/Pages/CreateServer.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php index 0dffb863f2..a85269e8b1 100644 --- a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php +++ b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php @@ -912,6 +912,12 @@ public static function retrieveValidPorts(Node $node, array $portEntries, string $ports->push($portEntry); continue; + } else { + Notification::make() + ->title('Port already in use') + ->danger() + ->body("$portEntry is already with an allocation") + ->send(); } } From abc67c195119929b877ce9a86f248699c5c0063d Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sat, 4 Jan 2025 22:01:08 -0500 Subject: [PATCH 10/12] Simplify code --- .../AllocationsRelationManager.php | 11 +--- .../ServerResource/Pages/CreateServer.php | 58 +++---------------- .../AllocationsRelationManager.php | 11 +--- app/Models/Node.php | 1 + 4 files changed, 16 insertions(+), 65 deletions(-) diff --git a/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php b/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php index 419991713f..070ded68e8 100644 --- a/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php +++ b/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php @@ -101,14 +101,9 @@ public function table(Table $table): Table ->inlineLabel() ->live() ->disabled(fn (Get $get) => empty($get('allocation_ip'))) - ->afterStateUpdated(function ($state, Set $set, Get $get) { - $node = $this->getOwnerRecord(); - $ports = CreateServer::retrieveValidPorts($node, $state, $get('allocation_ip')); - - if ($ports !== null) { - $set('allocation_ports', $ports); - } - }) + ->afterStateUpdated(fn ($state, Set $set, Get $get) => $set('allocation_ports', + CreateServer::retrieveValidPorts($this->getOwnerRecord(), $state, $get('allocation_ip'))) + ) ->splitKeys(['Tab', ' ', ',']) ->required(), ]) diff --git a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php index a85269e8b1..df986f919d 100644 --- a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php +++ b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php @@ -231,15 +231,9 @@ public function form(Form $form): Form ->inlineLabel() ->live() ->disabled(fn (Get $get) => empty($get('allocation_ip'))) - ->afterStateUpdated(function ($state, Set $set, Get $get) use ($getPage) { - $node = Node::find($getPage('node_id')); - $ip = $get('allocation_ip'); - - $ports = self::retrieveValidPorts($node, $state, $ip); - if ($ports !== null) { - $set('allocation_ports', $ports); - } - }) + ->afterStateUpdated(fn ($state, Set $set, Get $get) => $set('allocation_ports', + CreateServer::retrieveValidPorts(Node::find($getPage('node_id')), $state, $get('allocation_ip'))) + ) ->splitKeys(['Tab', ' ', ',']) ->required(), ]; @@ -889,14 +883,13 @@ private function getSelectOptionsFromRules(Get $get): array ->all(); } - public static function retrieveValidPorts(Node $node, array $portEntries, string $ip): ?array + public static function retrieveValidPorts(Node $node, array $portEntries, string $ip): array { $portRangeLimit = AssignmentService::PORT_RANGE_LIMIT; $portFloor = AssignmentService::PORT_FLOOR; $portCeil = AssignmentService::PORT_CEIL; $ports = collect(); - $update = false; $existingPorts = $node ->allocations() @@ -905,30 +898,11 @@ public static function retrieveValidPorts(Node $node, array $portEntries, string ->all(); foreach ($portEntries as $portEntry) { - if (!str_contains($portEntry, '-')) { - if (is_numeric($portEntry)) { - $portEntry = (int) $portEntry; - if (!in_array($portEntry, $existingPorts)) { - $ports->push($portEntry); - - continue; - } else { - Notification::make() - ->title('Port already in use') - ->danger() - ->body("$portEntry is already with an allocation") - ->send(); - } - } - - // Do not add non-numerical ports - $update = true; - - continue; + $start = $end = $portEntry; + if (str_contains($portEntry, '-')) { + [$start, $end] = explode('-', $portEntry); } - $update = true; - [$start, $end] = explode('-', $portEntry); if (!is_numeric($start) || !is_numeric($end)) { Notification::make() ->title('Invalid Port Range') @@ -950,15 +924,7 @@ public static function retrieveValidPorts(Node $node, array $portEntries, string ->body("The current limit is $portRangeLimit number of ports at one time.") ->send(); - break; - } - - if (empty($range)) { - Notification::make() - ->title('Invalid Port Range') - ->danger() - ->body("The current limit is $portRangeLimit number of ports at one time.") - ->send(); + continue; } foreach ($range as $i) { @@ -990,20 +956,14 @@ public static function retrieveValidPorts(Node $node, array $portEntries, string $uniquePorts = $ports->unique()->values(); if ($ports->count() > $uniquePorts->count()) { - $update = true; $ports = $uniquePorts; } $sortedPorts = $ports->sort()->values(); if ($sortedPorts->all() !== $ports->all()) { - $update = true; $ports = $sortedPorts; } - if ($update) { - return $ports->all(); - } - - return null; + return $ports->all(); } } diff --git a/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php b/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php index 698ed9a6da..67fba86799 100644 --- a/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php +++ b/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php @@ -97,14 +97,9 @@ public function table(Table $table): Table ->label('Ports') ->inlineLabel() ->live() - ->afterStateUpdated(function ($state, Set $set, Get $get) { - $server = $this->getOwnerRecord(); - $ports = CreateServer::retrieveValidPorts($server->node, $state, $get('allocation_ip')); - - if ($ports !== null) { - $set('allocation_ports', $ports); - } - }) + ->afterStateUpdated(fn ($state, Set $set, Get $get) => $set('allocation_ports', + CreateServer::retrieveValidPorts($this->getOwnerRecord()->node, $state, $get('allocation_ip'))) + ) ->splitKeys(['Tab', ' ', ',']) ->required(), ]) diff --git a/app/Models/Node.php b/app/Models/Node.php index d6383be27e..72e2b26121 100644 --- a/app/Models/Node.php +++ b/app/Models/Node.php @@ -388,6 +388,7 @@ public function ipAddresses(): array } $ips->push('0.0.0.0'); + // Only IPV4 $ips = $ips->filter(fn (string $ip) => filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false); From 708d2b008bb0a2b38d72ec466edbd1799bb1dcc0 Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sat, 4 Jan 2025 22:26:53 -0500 Subject: [PATCH 11/12] Reset the ports if the ip changes --- .../RelationManagers/AllocationsRelationManager.php | 1 + .../Admin/Resources/ServerResource/Pages/CreateServer.php | 3 ++- .../RelationManagers/AllocationsRelationManager.php | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php b/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php index 070ded68e8..7273ddbe0a 100644 --- a/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php +++ b/app/Filament/Admin/Resources/NodeResource/RelationManagers/AllocationsRelationManager.php @@ -82,6 +82,7 @@ public function table(Table $table): Table ->inlineLabel() ->ipv4() ->helperText("Usually your machine's public IP unless you are port forwarding.") + ->afterStateUpdated(fn (Set $set) => $set('allocation_ports', [])) ->live() ->required(), TextInput::make('allocation_alias') diff --git a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php index df986f919d..05c6c8ebf6 100644 --- a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php +++ b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php @@ -205,9 +205,10 @@ public function form(Form $form): Form Select::make('allocation_ip') ->options(collect(Node::find($get('node_id'))?->ipAddresses())->mapWithKeys(fn (string $ip) => [$ip => $ip])) ->label('IP Address') + ->helperText("Usually your machine's public IP unless you are port forwarding.") + ->afterStateUpdated(fn (Set $set) => $set('allocation_ports', [])) ->inlineLabel() ->ipv4() - ->helperText("Usually your machine's public IP unless you are port forwarding.") ->live() ->required(), TextInput::make('allocation_alias') diff --git a/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php b/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php index 67fba86799..43a2ed2ab0 100644 --- a/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php +++ b/app/Filament/Admin/Resources/ServerResource/RelationManagers/AllocationsRelationManager.php @@ -80,6 +80,7 @@ public function table(Table $table): Table ->inlineLabel() ->ipv4() ->helperText("Usually your machine's public IP unless you are port forwarding.") + ->afterStateUpdated(fn (Set $set) => $set('allocation_ports', [])) ->required(), TextInput::make('allocation_alias') ->label('Alias') From 4006bb8172a3b6a16389f8d876b89ccf049b013c Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sat, 4 Jan 2025 22:27:03 -0500 Subject: [PATCH 12/12] =?UTF-8?q?Don=E2=80=99t=20limit=20these=20anymore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Admin/Resources/ServerResource/Pages/CreateServer.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php index 05c6c8ebf6..caca65cce0 100644 --- a/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php +++ b/app/Filament/Admin/Resources/ServerResource/Pages/CreateServer.php @@ -914,8 +914,8 @@ public static function retrieveValidPorts(Node $node, array $portEntries, string continue; } - $start = max((int) $start, 0); - $end = min((int) $end, 2 ** 16 - 1); + $start = (int) $start; + $end = (int) $end; $range = $start <= $end ? range($start, $end) : range($end, $start); if (count($range) > $portRangeLimit) {