Implement server creation though the API.

Also implements auto-deployment to specific locations and ports.
This commit is contained in:
Dane Everitt 2018-01-28 17:14:14 -06:00
parent 97ee95b4da
commit 5ed164e13e
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
24 changed files with 927 additions and 223 deletions

View file

@ -4,6 +4,7 @@ namespace Pterodactyl\Repositories\Eloquent;
use Illuminate\Support\Collection;
use Pterodactyl\Models\Allocation;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
@ -94,4 +95,81 @@ class AllocationRepository extends EloquentRepository implements AllocationRepos
return $results->pluck('id')->toArray();
}
/**
* Return a concated 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.
*
* @param array $nodes
* @return array
*/
public function getDiscardableDedicatedAllocations(array $nodes = []): array
{
$instance = $this->getBuilder()->select(
$this->getBuilder()->raw('CONCAT_WS("-", node_id, ip) as result')
);
if (! empty($nodes)) {
$instance->whereIn('node_id', $nodes);
}
$results = $instance->whereNotNull('server_id')
->groupBy($this->getBuilder()->raw('CONCAT(node_id, ip)'))
->get();
return $results->pluck('result')->toArray();
}
/**
* Return a single allocation from those meeting the requirements.
*
* @param array $nodes
* @param array $ports
* @param bool $dedicated
* @return \Pterodactyl\Models\Allocation|null
*/
public function getRandomAllocation(array $nodes, array $ports, bool $dedicated = false)
{
$instance = $this->getBuilder()->whereNull('server_id');
if (! empty($nodes)) {
$instance->whereIn('node_id', $nodes);
}
if (! empty($ports)) {
$instance->where(function (Builder $query) use ($ports) {
$whereIn = [];
foreach ($ports as $port) {
if (is_array($port)) {
$query->orWhereBetween('port', $port);
continue;
}
$whereIn[] = $port;
}
if (! empty($whereIn)) {
$query->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)) {
$instance->whereNotIn(
$this->getBuilder()->raw('CONCAT_WS("-", node_id, ip)'), $discard
);
}
}
return $instance->inRandomOrder()->first();
}
}

View file

@ -2,6 +2,7 @@
namespace Pterodactyl\Repositories\Eloquent;
use Generator;
use Pterodactyl\Models\Node;
use Illuminate\Support\Collection;
use Pterodactyl\Repositories\Concerns\Searchable;
@ -157,4 +158,28 @@ class NodeRepository extends EloquentRepository implements NodeRepositoryInterfa
];
})->values();
}
/**
* Return the IDs of all nodes that exist in the provided locations and have the space
* available to support the additional disk and memory provided.
*
* @param array $locations
* @param int $disk
* @param int $memory
* @return \Generator
*/
public function getNodesWithResourceUse(array $locations, int $disk, int $memory): Generator
{
$instance = $this->getBuilder()
->select(['nodes.id', 'nodes.memory', 'nodes.disk', 'nodes.memory_overallocate', 'nodes.disk_overallocate'])
->selectRaw('IFNULL(SUM(servers.memory), 0) as sum_memory, IFNULL(SUM(servers.disk), 0) as sum_disk')
->join('servers', 'servers.node_id', '=', 'nodes.id')
->where('nodes.public', 1);
if (! empty($locations)) {
$instance->whereIn('nodes.location_id', $locations);
}
return $instance->cursor();
}
}