Replace allocation repository
This commit is contained in:
parent
860b2d890b
commit
cd49324d46
10 changed files with 95 additions and 164 deletions
|
@ -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;
|
|
||||||
}
|
|
|
@ -14,7 +14,6 @@ use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||||
use Pterodactyl\Traits\Controllers\JavascriptInjection;
|
use Pterodactyl\Traits\Controllers\JavascriptInjection;
|
||||||
use Pterodactyl\Services\Helpers\SoftwareVersionService;
|
use Pterodactyl\Services\Helpers\SoftwareVersionService;
|
||||||
use Pterodactyl\Repositories\Eloquent\LocationRepository;
|
use Pterodactyl\Repositories\Eloquent\LocationRepository;
|
||||||
use Pterodactyl\Repositories\Eloquent\AllocationRepository;
|
|
||||||
|
|
||||||
class NodeViewController extends Controller
|
class NodeViewController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -24,7 +23,6 @@ class NodeViewController extends Controller
|
||||||
* NodeViewController constructor.
|
* NodeViewController constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private AllocationRepository $allocationRepository,
|
|
||||||
private LocationRepository $locationRepository,
|
private LocationRepository $locationRepository,
|
||||||
private NodeRepository $repository,
|
private NodeRepository $repository,
|
||||||
private ServerRepository $serverRepository,
|
private ServerRepository $serverRepository,
|
||||||
|
|
|
@ -23,7 +23,6 @@ use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
||||||
use Pterodactyl\Http\Requests\Admin\Node\AllocationFormRequest;
|
use Pterodactyl\Http\Requests\Admin\Node\AllocationFormRequest;
|
||||||
use Pterodactyl\Services\Allocations\AllocationDeletionService;
|
use Pterodactyl\Services\Allocations\AllocationDeletionService;
|
||||||
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
|
||||||
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
|
|
||||||
use Pterodactyl\Http\Requests\Admin\Node\AllocationAliasFormRequest;
|
use Pterodactyl\Http\Requests\Admin\Node\AllocationAliasFormRequest;
|
||||||
|
|
||||||
class NodesController extends Controller
|
class NodesController extends Controller
|
||||||
|
@ -34,7 +33,6 @@ class NodesController extends Controller
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected AlertsMessageBag $alert,
|
protected AlertsMessageBag $alert,
|
||||||
protected AllocationDeletionService $allocationDeletionService,
|
protected AllocationDeletionService $allocationDeletionService,
|
||||||
protected AllocationRepositoryInterface $allocationRepository,
|
|
||||||
protected AssignmentService $assignmentService,
|
protected AssignmentService $assignmentService,
|
||||||
protected CacheRepository $cache,
|
protected CacheRepository $cache,
|
||||||
protected NodeCreationService $creationService,
|
protected NodeCreationService $creationService,
|
||||||
|
@ -125,11 +123,12 @@ class NodesController extends Controller
|
||||||
*/
|
*/
|
||||||
public function allocationRemoveBlock(Request $request, int $node): RedirectResponse
|
public function allocationRemoveBlock(Request $request, int $node): RedirectResponse
|
||||||
{
|
{
|
||||||
$this->allocationRepository->deleteWhere([
|
/** @var Node $node */
|
||||||
['node_id', '=', $node],
|
$node = Node::query()->findOrFail($node);
|
||||||
['server_id', '=', null],
|
$node->allocations()
|
||||||
['ip', '=', $request->input('ip')],
|
->where('ip', $request->input('ip'))
|
||||||
]);
|
->whereNull('server_id')
|
||||||
|
->delete();
|
||||||
|
|
||||||
$this->alert->success(trans('admin/node.notices.unallocated_deleted', ['ip' => $request->input('ip')]))
|
$this->alert->success(trans('admin/node.notices.unallocated_deleted', ['ip' => $request->input('ip')]))
|
||||||
->flash();
|
->flash();
|
||||||
|
@ -140,14 +139,12 @@ class NodesController extends Controller
|
||||||
/**
|
/**
|
||||||
* Sets an alias for a specific allocation on a node.
|
* 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
|
public function allocationSetAlias(AllocationAliasFormRequest $request): \Symfony\Component\HttpFoundation\Response
|
||||||
{
|
{
|
||||||
$this->allocationRepository->update($request->input('allocation_id'), [
|
$allocation = Allocation::query()->findOrFail($request->input('allocation_id'));
|
||||||
'ip_alias' => (empty($request->input('alias'))) ? null : $request->input('alias'),
|
$alias = (empty($request->input('alias'))) ? null : $request->input('alias');
|
||||||
]);
|
$allocation->update(['ip_alias' => $alias]);
|
||||||
|
|
||||||
return response('', 204);
|
return response('', 204);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,16 @@
|
||||||
namespace Pterodactyl\Http\Controllers\Admin\Servers;
|
namespace Pterodactyl\Http\Controllers\Admin\Servers;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Pterodactyl\Models\Node;
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Prologue\Alerts\AlertsMessageBag;
|
use Pterodactyl\Models\Allocation;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
|
use Prologue\Alerts\AlertsMessageBag;
|
||||||
use Pterodactyl\Models\ServerTransfer;
|
use Pterodactyl\Models\ServerTransfer;
|
||||||
use Pterodactyl\Http\Controllers\Controller;
|
use Pterodactyl\Http\Controllers\Controller;
|
||||||
use Pterodactyl\Services\Servers\TransferService;
|
use Pterodactyl\Services\Servers\TransferService;
|
||||||
use Pterodactyl\Repositories\Eloquent\NodeRepository;
|
use Pterodactyl\Repositories\Eloquent\NodeRepository;
|
||||||
use Pterodactyl\Repositories\Wings\DaemonConfigurationRepository;
|
use Pterodactyl\Repositories\Wings\DaemonConfigurationRepository;
|
||||||
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
|
|
||||||
|
|
||||||
class ServerTransferController extends Controller
|
class ServerTransferController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -20,7 +21,6 @@ class ServerTransferController extends Controller
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private AlertsMessageBag $alert,
|
private AlertsMessageBag $alert,
|
||||||
private AllocationRepositoryInterface $allocationRepository,
|
|
||||||
private NodeRepository $nodeRepository,
|
private NodeRepository $nodeRepository,
|
||||||
private TransferService $transferService,
|
private TransferService $transferService,
|
||||||
private DaemonConfigurationRepository $daemonConfigurationRepository
|
private DaemonConfigurationRepository $daemonConfigurationRepository
|
||||||
|
@ -87,7 +87,12 @@ class ServerTransferController extends Controller
|
||||||
$allocations = $additional_allocations;
|
$allocations = $additional_allocations;
|
||||||
$allocations[] = $allocation_id;
|
$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 = [];
|
$updateIds = [];
|
||||||
foreach ($allocations as $allocation) {
|
foreach ($allocations as $allocation) {
|
||||||
|
@ -99,7 +104,9 @@ class ServerTransferController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($updateIds)) {
|
if (!empty($updateIds)) {
|
||||||
$this->allocationRepository->updateWhereIn('id', $updateIds, ['server_id' => $server->id]);
|
Allocation::query()
|
||||||
|
->whereIn('id', $updateIds)
|
||||||
|
->update(['server_id' => $server->id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ use Pterodactyl\Services\Databases\DatabaseManagementService;
|
||||||
use Illuminate\Contracts\Config\Repository as ConfigRepository;
|
use Illuminate\Contracts\Config\Repository as ConfigRepository;
|
||||||
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
||||||
use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface;
|
||||||
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
|
|
||||||
use Pterodactyl\Services\Servers\ServerConfigurationStructureService;
|
use Pterodactyl\Services\Servers\ServerConfigurationStructureService;
|
||||||
use Pterodactyl\Http\Requests\Admin\Servers\Databases\StoreServerDatabaseRequest;
|
use Pterodactyl\Http\Requests\Admin\Servers\Databases\StoreServerDatabaseRequest;
|
||||||
|
|
||||||
|
@ -41,7 +40,6 @@ class ServersController extends Controller
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected AlertsMessageBag $alert,
|
protected AlertsMessageBag $alert,
|
||||||
protected AllocationRepositoryInterface $allocationRepository,
|
|
||||||
protected BuildModificationService $buildModificationService,
|
protected BuildModificationService $buildModificationService,
|
||||||
protected ConfigRepository $config,
|
protected ConfigRepository $config,
|
||||||
protected DaemonServerRepository $daemonServerRepository,
|
protected DaemonServerRepository $daemonServerRepository,
|
||||||
|
|
|
@ -16,7 +16,6 @@ use Pterodactyl\Repositories\Eloquent\DatabaseRepository;
|
||||||
use Pterodactyl\Repositories\Eloquent\LocationRepository;
|
use Pterodactyl\Repositories\Eloquent\LocationRepository;
|
||||||
use Pterodactyl\Repositories\Eloquent\ScheduleRepository;
|
use Pterodactyl\Repositories\Eloquent\ScheduleRepository;
|
||||||
use Pterodactyl\Repositories\Eloquent\SettingsRepository;
|
use Pterodactyl\Repositories\Eloquent\SettingsRepository;
|
||||||
use Pterodactyl\Repositories\Eloquent\AllocationRepository;
|
|
||||||
use Pterodactyl\Contracts\Repository\EggRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\EggRepositoryInterface;
|
||||||
use Pterodactyl\Repositories\Eloquent\EggVariableRepository;
|
use Pterodactyl\Repositories\Eloquent\EggVariableRepository;
|
||||||
use Pterodactyl\Contracts\Repository\NestRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\NestRepositoryInterface;
|
||||||
|
@ -33,7 +32,6 @@ use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface;
|
||||||
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
|
||||||
use Pterodactyl\Contracts\Repository\ScheduleRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\ScheduleRepositoryInterface;
|
||||||
use Pterodactyl\Contracts\Repository\SettingsRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\SettingsRepositoryInterface;
|
||||||
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
|
|
||||||
use Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface;
|
||||||
use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface;
|
||||||
use Pterodactyl\Contracts\Repository\ServerVariableRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\ServerVariableRepositoryInterface;
|
||||||
|
@ -46,7 +44,6 @@ class RepositoryServiceProvider extends ServiceProvider
|
||||||
public function register()
|
public function register()
|
||||||
{
|
{
|
||||||
// Eloquent Repositories
|
// Eloquent Repositories
|
||||||
$this->app->bind(AllocationRepositoryInterface::class, AllocationRepository::class);
|
|
||||||
$this->app->bind(ApiKeyRepositoryInterface::class, ApiKeyRepository::class);
|
$this->app->bind(ApiKeyRepositoryInterface::class, ApiKeyRepository::class);
|
||||||
$this->app->bind(DatabaseRepositoryInterface::class, DatabaseRepository::class);
|
$this->app->bind(DatabaseRepositoryInterface::class, DatabaseRepository::class);
|
||||||
$this->app->bind(DatabaseHostRepositoryInterface::class, DatabaseHostRepository::class);
|
$this->app->bind(DatabaseHostRepositoryInterface::class, DatabaseHostRepository::class);
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,18 +3,10 @@
|
||||||
namespace Pterodactyl\Services\Allocations;
|
namespace Pterodactyl\Services\Allocations;
|
||||||
|
|
||||||
use Pterodactyl\Models\Allocation;
|
use Pterodactyl\Models\Allocation;
|
||||||
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
|
|
||||||
use Pterodactyl\Exceptions\Service\Allocation\ServerUsingAllocationException;
|
use Pterodactyl\Exceptions\Service\Allocation\ServerUsingAllocationException;
|
||||||
|
|
||||||
class AllocationDeletionService
|
class AllocationDeletionService
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* AllocationDeletionService constructor.
|
|
||||||
*/
|
|
||||||
public function __construct(private AllocationRepositoryInterface $repository)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete an allocation from the database only if it does not have a server
|
* Delete an allocation from the database only if it does not have a server
|
||||||
* that is actively attached to it.
|
* that is actively attached to it.
|
||||||
|
@ -27,6 +19,6 @@ class AllocationDeletionService
|
||||||
throw new ServerUsingAllocationException(trans('exceptions.allocations.server_using'));
|
throw new ServerUsingAllocationException(trans('exceptions.allocations.server_using'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->repository->delete($allocation->id);
|
return $allocation->delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,10 @@ namespace Pterodactyl\Services\Allocations;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use IPTools\Network;
|
use IPTools\Network;
|
||||||
|
use Pterodactyl\Models\Allocation;
|
||||||
use Pterodactyl\Models\Node;
|
use Pterodactyl\Models\Node;
|
||||||
use Illuminate\Database\ConnectionInterface;
|
use Illuminate\Database\ConnectionInterface;
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
|
|
||||||
use Pterodactyl\Exceptions\Service\Allocation\CidrOutOfRangeException;
|
use Pterodactyl\Exceptions\Service\Allocation\CidrOutOfRangeException;
|
||||||
use Pterodactyl\Exceptions\Service\Allocation\PortOutOfRangeException;
|
use Pterodactyl\Exceptions\Service\Allocation\PortOutOfRangeException;
|
||||||
use Pterodactyl\Exceptions\Service\Allocation\InvalidPortMappingException;
|
use Pterodactyl\Exceptions\Service\Allocation\InvalidPortMappingException;
|
||||||
|
@ -25,7 +25,7 @@ class AssignmentService
|
||||||
/**
|
/**
|
||||||
* AssignmentService constructor.
|
* 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Services\Deployment;
|
namespace Pterodactyl\Services\Deployment;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Pterodactyl\Models\Allocation;
|
use Pterodactyl\Models\Allocation;
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
use Pterodactyl\Services\Allocations\AssignmentService;
|
use Pterodactyl\Services\Allocations\AssignmentService;
|
||||||
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
|
|
||||||
use Pterodactyl\Exceptions\Service\Deployment\NoViableAllocationException;
|
use Pterodactyl\Exceptions\Service\Deployment\NoViableAllocationException;
|
||||||
|
|
||||||
class AllocationSelectionService
|
class AllocationSelectionService
|
||||||
|
@ -16,13 +16,6 @@ class AllocationSelectionService
|
||||||
|
|
||||||
protected array $ports = [];
|
protected array $ports = [];
|
||||||
|
|
||||||
/**
|
|
||||||
* AllocationSelectionService constructor.
|
|
||||||
*/
|
|
||||||
public function __construct(private AllocationRepositoryInterface $repository)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle if the selected allocation should be the only allocation belonging
|
* 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
|
* 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
|
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)) {
|
if (is_null($allocation)) {
|
||||||
throw new NoViableAllocationException(trans('exceptions.deployment.no_viable_allocations'));
|
throw new NoViableAllocationException(trans('exceptions.deployment.no_viable_allocations'));
|
||||||
|
@ -92,4 +85,72 @@ class AllocationSelectionService
|
||||||
|
|
||||||
return $allocation;
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue