Replace allocation repository

This commit is contained in:
Lance Pioch 2022-10-23 02:02:58 -04:00
parent 860b2d890b
commit cd49324d46
10 changed files with 95 additions and 164 deletions

View file

@ -1,19 +0,0 @@
<?php
namespace Pterodactyl\Contracts\Repository;
use Pterodactyl\Models\Allocation;
interface AllocationRepositoryInterface extends RepositoryInterface
{
/**
* Return all the allocations that exist for a node that are not currently
* allocated.
*/
public function getUnassignedAllocationIds(int $node): array;
/**
* Return a single allocation from those meeting the requirements.
*/
public function getRandomAllocation(array $nodes, array $ports, bool $dedicated = false): ?Allocation;
}

View file

@ -14,7 +14,6 @@ use Pterodactyl\Repositories\Eloquent\ServerRepository;
use Pterodactyl\Traits\Controllers\JavascriptInjection;
use Pterodactyl\Services\Helpers\SoftwareVersionService;
use Pterodactyl\Repositories\Eloquent\LocationRepository;
use Pterodactyl\Repositories\Eloquent\AllocationRepository;
class NodeViewController extends Controller
{
@ -24,7 +23,6 @@ class NodeViewController extends Controller
* NodeViewController constructor.
*/
public function __construct(
private AllocationRepository $allocationRepository,
private LocationRepository $locationRepository,
private NodeRepository $repository,
private ServerRepository $serverRepository,

View file

@ -23,7 +23,6 @@ use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
use Pterodactyl\Http\Requests\Admin\Node\AllocationFormRequest;
use Pterodactyl\Services\Allocations\AllocationDeletionService;
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
use Pterodactyl\Http\Requests\Admin\Node\AllocationAliasFormRequest;
class NodesController extends Controller
@ -34,7 +33,6 @@ class NodesController extends Controller
public function __construct(
protected AlertsMessageBag $alert,
protected AllocationDeletionService $allocationDeletionService,
protected AllocationRepositoryInterface $allocationRepository,
protected AssignmentService $assignmentService,
protected CacheRepository $cache,
protected NodeCreationService $creationService,
@ -125,11 +123,12 @@ class NodesController extends Controller
*/
public function allocationRemoveBlock(Request $request, int $node): RedirectResponse
{
$this->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);
}

View file

@ -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]);
}
}
}

View file

@ -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,

View file

@ -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);

View file

@ -1,100 +0,0 @@
<?php
namespace Pterodactyl\Repositories\Eloquent;
use Pterodactyl\Models\Allocation;
use Illuminate\Database\Eloquent\Builder;
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
class AllocationRepository extends EloquentRepository implements AllocationRepositoryInterface
{
/**
* Return the model backing this repository.
*/
public function model(): string
{
return Allocation::class;
}
/**
* Return all the allocations that exist for a node that are not currently
* allocated.
*/
public function getUnassignedAllocationIds(int $node): array
{
return Allocation::query()->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();
}
}

View file

@ -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();
}
}

View file

@ -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);
}
}

View file

@ -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();
}
}