From cd49324d46207bf1aeefdf57ddd8f27b6ca56a61 Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sun, 23 Oct 2022 02:02:58 -0400 Subject: [PATCH] Replace allocation repository --- .../AllocationRepositoryInterface.php | 19 ---- .../Admin/Nodes/NodeViewController.php | 2 - .../Controllers/Admin/NodesController.php | 21 ++-- .../Servers/ServerTransferController.php | 17 ++- .../Controllers/Admin/ServersController.php | 2 - app/Providers/RepositoryServiceProvider.php | 3 - .../Eloquent/AllocationRepository.php | 100 ------------------ .../Allocations/AllocationDeletionService.php | 10 +- .../Allocations/AssignmentService.php | 6 +- .../Deployment/AllocationSelectionService.php | 79 ++++++++++++-- 10 files changed, 95 insertions(+), 164 deletions(-) delete mode 100644 app/Contracts/Repository/AllocationRepositoryInterface.php delete mode 100644 app/Repositories/Eloquent/AllocationRepository.php diff --git a/app/Contracts/Repository/AllocationRepositoryInterface.php b/app/Contracts/Repository/AllocationRepositoryInterface.php deleted file mode 100644 index 810880327..000000000 --- a/app/Contracts/Repository/AllocationRepositoryInterface.php +++ /dev/null @@ -1,19 +0,0 @@ -allocationRepository->deleteWhere([ - ['node_id', '=', $node], - ['server_id', '=', null], - ['ip', '=', $request->input('ip')], - ]); + /** @var Node $node */ + $node = Node::query()->findOrFail($node); + $node->allocations() + ->where('ip', $request->input('ip')) + ->whereNull('server_id') + ->delete(); $this->alert->success(trans('admin/node.notices.unallocated_deleted', ['ip' => $request->input('ip')])) ->flash(); @@ -140,14 +139,12 @@ class NodesController extends Controller /** * Sets an alias for a specific allocation on a node. * - * @throws \Pterodactyl\Exceptions\Model\DataValidationException - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ public function allocationSetAlias(AllocationAliasFormRequest $request): \Symfony\Component\HttpFoundation\Response { - $this->allocationRepository->update($request->input('allocation_id'), [ - 'ip_alias' => (empty($request->input('alias'))) ? null : $request->input('alias'), - ]); + $allocation = Allocation::query()->findOrFail($request->input('allocation_id')); + $alias = (empty($request->input('alias'))) ? null : $request->input('alias'); + $allocation->update(['ip_alias' => $alias]); return response('', 204); } diff --git a/app/Http/Controllers/Admin/Servers/ServerTransferController.php b/app/Http/Controllers/Admin/Servers/ServerTransferController.php index cdb2bb557..50c6a038e 100644 --- a/app/Http/Controllers/Admin/Servers/ServerTransferController.php +++ b/app/Http/Controllers/Admin/Servers/ServerTransferController.php @@ -3,15 +3,16 @@ namespace Pterodactyl\Http\Controllers\Admin\Servers; use Illuminate\Http\Request; +use Pterodactyl\Models\Node; use Pterodactyl\Models\Server; -use Prologue\Alerts\AlertsMessageBag; +use Pterodactyl\Models\Allocation; use Illuminate\Http\RedirectResponse; +use Prologue\Alerts\AlertsMessageBag; use Pterodactyl\Models\ServerTransfer; use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Services\Servers\TransferService; use Pterodactyl\Repositories\Eloquent\NodeRepository; use Pterodactyl\Repositories\Wings\DaemonConfigurationRepository; -use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface; class ServerTransferController extends Controller { @@ -20,7 +21,6 @@ class ServerTransferController extends Controller */ public function __construct( private AlertsMessageBag $alert, - private AllocationRepositoryInterface $allocationRepository, private NodeRepository $nodeRepository, private TransferService $transferService, private DaemonConfigurationRepository $daemonConfigurationRepository @@ -87,7 +87,12 @@ class ServerTransferController extends Controller $allocations = $additional_allocations; $allocations[] = $allocation_id; - $unassigned = $this->allocationRepository->getUnassignedAllocationIds($node_id); + /** @var Node $node */ + $node = Node::query()->findOrFail($node_id); + $unassigned = $node->allocations() + ->whereNull('server_id') + ->pluck('id') + ->toArray(); $updateIds = []; foreach ($allocations as $allocation) { @@ -99,7 +104,9 @@ class ServerTransferController extends Controller } if (!empty($updateIds)) { - $this->allocationRepository->updateWhereIn('id', $updateIds, ['server_id' => $server->id]); + Allocation::query() + ->whereIn('id', $updateIds) + ->update(['server_id' => $server->id]); } } } diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index 3d2c55ac4..baaee7dbe 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -30,7 +30,6 @@ use Pterodactyl\Services\Databases\DatabaseManagementService; use Illuminate\Contracts\Config\Repository as ConfigRepository; use Pterodactyl\Contracts\Repository\ServerRepositoryInterface; use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface; -use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface; use Pterodactyl\Services\Servers\ServerConfigurationStructureService; use Pterodactyl\Http\Requests\Admin\Servers\Databases\StoreServerDatabaseRequest; @@ -41,7 +40,6 @@ class ServersController extends Controller */ public function __construct( protected AlertsMessageBag $alert, - protected AllocationRepositoryInterface $allocationRepository, protected BuildModificationService $buildModificationService, protected ConfigRepository $config, protected DaemonServerRepository $daemonServerRepository, diff --git a/app/Providers/RepositoryServiceProvider.php b/app/Providers/RepositoryServiceProvider.php index 8a0434f52..4aee18a18 100644 --- a/app/Providers/RepositoryServiceProvider.php +++ b/app/Providers/RepositoryServiceProvider.php @@ -16,7 +16,6 @@ use Pterodactyl\Repositories\Eloquent\DatabaseRepository; use Pterodactyl\Repositories\Eloquent\LocationRepository; use Pterodactyl\Repositories\Eloquent\ScheduleRepository; use Pterodactyl\Repositories\Eloquent\SettingsRepository; -use Pterodactyl\Repositories\Eloquent\AllocationRepository; use Pterodactyl\Contracts\Repository\EggRepositoryInterface; use Pterodactyl\Repositories\Eloquent\EggVariableRepository; use Pterodactyl\Contracts\Repository\NestRepositoryInterface; @@ -33,7 +32,6 @@ use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface; use Pterodactyl\Contracts\Repository\LocationRepositoryInterface; use Pterodactyl\Contracts\Repository\ScheduleRepositoryInterface; use Pterodactyl\Contracts\Repository\SettingsRepositoryInterface; -use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface; use Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface; use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface; use Pterodactyl\Contracts\Repository\ServerVariableRepositoryInterface; @@ -46,7 +44,6 @@ class RepositoryServiceProvider extends ServiceProvider public function register() { // Eloquent Repositories - $this->app->bind(AllocationRepositoryInterface::class, AllocationRepository::class); $this->app->bind(ApiKeyRepositoryInterface::class, ApiKeyRepository::class); $this->app->bind(DatabaseRepositoryInterface::class, DatabaseRepository::class); $this->app->bind(DatabaseHostRepositoryInterface::class, DatabaseHostRepository::class); diff --git a/app/Repositories/Eloquent/AllocationRepository.php b/app/Repositories/Eloquent/AllocationRepository.php deleted file mode 100644 index 6eb8b6d1e..000000000 --- a/app/Repositories/Eloquent/AllocationRepository.php +++ /dev/null @@ -1,100 +0,0 @@ -select('id') - ->whereNull('server_id') - ->where('node_id', $node) - ->get() - ->pluck('id') - ->toArray(); - } - - /** - * Return a concatenated result set of node ips that already have at least one - * server assigned to that IP. This allows for filtering out sets for - * dedicated allocation IPs. - * - * If an array of nodes is passed the results will be limited to allocations - * in those nodes. - */ - protected function getDiscardableDedicatedAllocations(array $nodes = []): array - { - $query = Allocation::query()->selectRaw('CONCAT_WS("-", node_id, ip) as result'); - - if (!empty($nodes)) { - $query->whereIn('node_id', $nodes); - } - - return $query->whereNotNull('server_id') - ->groupByRaw('CONCAT(node_id, ip)') - ->get() - ->pluck('result') - ->toArray(); - } - - /** - * Return a single allocation from those meeting the requirements. - */ - public function getRandomAllocation(array $nodes, array $ports, bool $dedicated = false): ?Allocation - { - $query = Allocation::query()->whereNull('server_id'); - - if (!empty($nodes)) { - $query->whereIn('node_id', $nodes); - } - - if (!empty($ports)) { - $query->where(function (Builder $inner) use ($ports) { - $whereIn = []; - foreach ($ports as $port) { - if (is_array($port)) { - $inner->orWhereBetween('port', $port); - continue; - } - - $whereIn[] = $port; - } - - if (!empty($whereIn)) { - $inner->orWhereIn('port', $whereIn); - } - }); - } - - // If this allocation should not be shared with any other servers get - // the data and modify the query as necessary, - if ($dedicated) { - $discard = $this->getDiscardableDedicatedAllocations($nodes); - - if (!empty($discard)) { - $query->whereNotIn( - $this->getBuilder()->raw('CONCAT_WS("-", node_id, ip)'), - $discard - ); - } - } - - return $query->inRandomOrder()->first(); - } -} diff --git a/app/Services/Allocations/AllocationDeletionService.php b/app/Services/Allocations/AllocationDeletionService.php index 8ea677245..818e8171d 100644 --- a/app/Services/Allocations/AllocationDeletionService.php +++ b/app/Services/Allocations/AllocationDeletionService.php @@ -3,18 +3,10 @@ namespace Pterodactyl\Services\Allocations; use Pterodactyl\Models\Allocation; -use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface; use Pterodactyl\Exceptions\Service\Allocation\ServerUsingAllocationException; class AllocationDeletionService { - /** - * AllocationDeletionService constructor. - */ - public function __construct(private AllocationRepositoryInterface $repository) - { - } - /** * Delete an allocation from the database only if it does not have a server * that is actively attached to it. @@ -27,6 +19,6 @@ class AllocationDeletionService throw new ServerUsingAllocationException(trans('exceptions.allocations.server_using')); } - return $this->repository->delete($allocation->id); + return $allocation->delete(); } } diff --git a/app/Services/Allocations/AssignmentService.php b/app/Services/Allocations/AssignmentService.php index ec79d18f1..5c4b10a40 100644 --- a/app/Services/Allocations/AssignmentService.php +++ b/app/Services/Allocations/AssignmentService.php @@ -4,10 +4,10 @@ namespace Pterodactyl\Services\Allocations; use Exception; use IPTools\Network; +use Pterodactyl\Models\Allocation; use Pterodactyl\Models\Node; use Illuminate\Database\ConnectionInterface; use Pterodactyl\Exceptions\DisplayException; -use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface; use Pterodactyl\Exceptions\Service\Allocation\CidrOutOfRangeException; use Pterodactyl\Exceptions\Service\Allocation\PortOutOfRangeException; use Pterodactyl\Exceptions\Service\Allocation\InvalidPortMappingException; @@ -25,7 +25,7 @@ class AssignmentService /** * AssignmentService constructor. */ - public function __construct(protected AllocationRepositoryInterface $repository, protected ConnectionInterface $connection) + public function __construct(protected ConnectionInterface $connection) { } @@ -101,7 +101,7 @@ class AssignmentService ]; } - $this->repository->insertIgnore($insertData); + Allocation::query()->insertOrIgnore($insertData); } } diff --git a/app/Services/Deployment/AllocationSelectionService.php b/app/Services/Deployment/AllocationSelectionService.php index ae334edd2..6465f3b28 100644 --- a/app/Services/Deployment/AllocationSelectionService.php +++ b/app/Services/Deployment/AllocationSelectionService.php @@ -2,10 +2,10 @@ namespace Pterodactyl\Services\Deployment; +use Illuminate\Database\Eloquent\Builder; use Pterodactyl\Models\Allocation; use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Services\Allocations\AssignmentService; -use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface; use Pterodactyl\Exceptions\Service\Deployment\NoViableAllocationException; class AllocationSelectionService @@ -16,13 +16,6 @@ class AllocationSelectionService protected array $ports = []; - /** - * AllocationSelectionService constructor. - */ - public function __construct(private AllocationRepositoryInterface $repository) - { - } - /** * Toggle if the selected allocation should be the only allocation belonging * to the given IP address. If true an allocation will not be selected if an IP @@ -84,7 +77,7 @@ class AllocationSelectionService */ public function handle(): Allocation { - $allocation = $this->repository->getRandomAllocation($this->nodes, $this->ports, $this->dedicated); + $allocation = $this->getRandomAllocation($this->nodes, $this->ports, $this->dedicated); if (is_null($allocation)) { throw new NoViableAllocationException(trans('exceptions.deployment.no_viable_allocations')); @@ -92,4 +85,72 @@ class AllocationSelectionService return $allocation; } + + /** + * Return a single allocation from those meeting the requirements. + */ + private function getRandomAllocation(array $nodes = [], array $ports = [], bool $dedicated = false): ?Allocation + { + $query = Allocation::query()->whereNull('server_id'); + + if (!empty($nodes)) { + $query->whereIn('node_id', $nodes); + } + + if (!empty($ports)) { + $query->where(function (Builder $inner) use ($ports) { + $whereIn = []; + foreach ($ports as $port) { + if (is_array($port)) { + $inner->orWhereBetween('port', $port); + continue; + } + + $whereIn[] = $port; + } + + if (!empty($whereIn)) { + $inner->orWhereIn('port', $whereIn); + } + }); + } + + // If this allocation should not be shared with any other servers get + // the data and modify the query as necessary, + if ($dedicated) { + $discard = $this->getDiscardableDedicatedAllocations($nodes); + + if (!empty($discard)) { + $query->whereNotIn( + $this->getBuilder()->raw('CONCAT_WS("-", node_id, ip)'), + $discard + ); + } + } + + return $query->inRandomOrder()->first(); + } + + /** + * Return a concatenated result set of node ips that already have at least one + * server assigned to that IP. This allows for filtering out sets for + * dedicated allocation IPs. + * + * If an array of nodes is passed the results will be limited to allocations + * in those nodes. + */ + private function getDiscardableDedicatedAllocations(array $nodes = []): array + { + $query = Allocation::query()->selectRaw('CONCAT_WS("-", node_id, ip) as result'); + + if (!empty($nodes)) { + $query->whereIn('node_id', $nodes); + } + + return $query->whereNotNull('server_id') + ->groupByRaw('CONCAT(node_id, ip)') + ->get() + ->pluck('result') + ->toArray(); + } }