fix: use port range on free allocation lookup (#1882)

Co-authored-by: MartinOscar <40749467+rmartinoscar@users.noreply.github.com>
Co-authored-by: Boy132 <Boy132@users.noreply.github.com>
This commit is contained in:
PalmarHealer 2025-11-17 10:56:48 +01:00 committed by GitHub
parent 886836c60a
commit 5e25ea4a43
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 12 additions and 8 deletions

View File

@ -40,6 +40,12 @@ class FindAssignableAllocationService
// Attempt to find a given available allocation for a server. If one cannot be found // Attempt to find a given available allocation for a server. If one cannot be found
// we will fall back to attempting to create a new allocation that can be used for the // we will fall back to attempting to create a new allocation that can be used for the
// server. // server.
$start = config('panel.client_features.allocations.range_start', null);
$end = config('panel.client_features.allocations.range_end', null);
Assert::integerish($start);
Assert::integerish($end);
// //
// Note: We use withoutGlobalScopes() to bypass Filament's tenant scoping when called // Note: We use withoutGlobalScopes() to bypass Filament's tenant scoping when called
// from the Server panel context, which would otherwise filter allocations to only // from the Server panel context, which would otherwise filter allocations to only
@ -50,11 +56,12 @@ class FindAssignableAllocationService
->when($server->allocation, function ($query) use ($server) { ->when($server->allocation, function ($query) use ($server) {
$query->where('ip', $server->allocation->ip); $query->where('ip', $server->allocation->ip);
}) })
->whereBetween('port', [$start, $end])
->whereNull('server_id') ->whereNull('server_id')
->inRandomOrder() ->inRandomOrder()
->first(); ->first();
$allocation = $allocation ?? $this->createNewAllocation($server); $allocation ??= $this->createNewAllocation($server, $start, $end);
$allocation->update(['server_id' => $server->id]); $allocation->update(['server_id' => $server->id]);
@ -72,18 +79,12 @@ class FindAssignableAllocationService
* @throws PortOutOfRangeException * @throws PortOutOfRangeException
* @throws TooManyPortsInRangeException * @throws TooManyPortsInRangeException
*/ */
protected function createNewAllocation(Server $server): Allocation protected function createNewAllocation(Server $server, ?int $start, ?int $end): Allocation
{ {
$start = config('panel.client_features.allocations.range_start', null);
$end = config('panel.client_features.allocations.range_end', null);
if (!$start || !$end) { if (!$start || !$end) {
throw new NoAutoAllocationSpaceAvailableException(); throw new NoAutoAllocationSpaceAvailableException();
} }
Assert::integerish($start);
Assert::integerish($end);
// Get all the currently allocated ports for the node so that we can figure out // Get all the currently allocated ports for the node so that we can figure out
// which port might be available. // which port might be available.
// Use withoutGlobalScopes() to bypass tenant filtering. // Use withoutGlobalScopes() to bypass tenant filtering.

View File

@ -29,10 +29,13 @@ class FindAssignableAllocationServiceTest extends IntegrationTestCase
public function test_existing_allocation_is_preferred(): void public function test_existing_allocation_is_preferred(): void
{ {
$server = $this->createServerModel(); $server = $this->createServerModel();
config()->set('panel.client_features.allocations.range_start', 5000);
config()->set('panel.client_features.allocations.range_end', 5005);
$created = Allocation::factory()->create([ $created = Allocation::factory()->create([
'node_id' => $server->node_id, 'node_id' => $server->node_id,
'ip' => $server->allocation->ip, 'ip' => $server->allocation->ip,
'port' => 5005,
]); ]);
$response = $this->getService()->handle($server); $response = $this->getService()->handle($server);