misc_pterodactyl-panel/app/Services/Servers/BuildModificationService.php

180 lines
6.6 KiB
PHP
Raw Normal View History

<?php
namespace Pterodactyl\Services\Servers;
2017-08-05 22:26:30 +00:00
use Pterodactyl\Models\Server;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Database\ConnectionInterface;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
2017-08-05 22:26:30 +00:00
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
2018-01-21 22:02:03 +00:00
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
2017-08-05 22:26:30 +00:00
use Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface as DaemonServerRepositoryInterface;
class BuildModificationService
{
/**
* @var \Pterodactyl\Contracts\Repository\AllocationRepositoryInterface
*/
2018-01-21 22:02:03 +00:00
private $allocationRepository;
/**
* @var \Illuminate\Database\ConnectionInterface
*/
2018-01-21 22:02:03 +00:00
private $connection;
/**
2018-01-21 22:02:03 +00:00
* @var \Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface
*/
2018-01-21 22:02:03 +00:00
private $daemonServerRepository;
/**
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
*/
2018-01-21 22:02:03 +00:00
private $repository;
/**
* BuildModificationService constructor.
*
* @param \Pterodactyl\Contracts\Repository\AllocationRepositoryInterface $allocationRepository
2018-01-21 22:02:03 +00:00
* @param \Illuminate\Database\ConnectionInterface $connection
* @param \Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface $daemonServerRepository
* @param \Pterodactyl\Contracts\Repository\ServerRepositoryInterface $repository
*/
public function __construct(
AllocationRepositoryInterface $allocationRepository,
2018-01-21 22:02:03 +00:00
ConnectionInterface $connection,
DaemonServerRepositoryInterface $daemonServerRepository,
2018-01-21 22:02:03 +00:00
ServerRepositoryInterface $repository
) {
$this->allocationRepository = $allocationRepository;
$this->daemonServerRepository = $daemonServerRepository;
2018-01-21 22:02:03 +00:00
$this->connection = $connection;
$this->repository = $repository;
}
/**
* Change the build details for a specified server.
*
2018-01-21 22:02:03 +00:00
* @param \Pterodactyl\Models\Server $server
* @param array $data
* @return \Pterodactyl\Models\Server
*
* @throws \Pterodactyl\Exceptions\DisplayException
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
2018-01-21 22:02:03 +00:00
public function handle(Server $server, array $data)
{
2018-01-21 22:02:03 +00:00
$build = [];
$this->connection->beginTransaction();
$this->processAllocations($server, $data);
if (isset($data['allocation_id']) && $data['allocation_id'] != $server->allocation_id) {
try {
$allocation = $this->allocationRepository->findFirstWhere([
['id', '=', $data['allocation_id']],
['server_id', '=', $server->id],
]);
} catch (RecordNotFoundException $ex) {
throw new DisplayException(trans('admin/server.exceptions.default_allocation_not_found'));
}
2018-01-21 22:02:03 +00:00
$build['default'] = ['ip' => $allocation->ip, 'port' => $allocation->port];
}
2018-01-21 22:02:03 +00:00
$server = $this->repository->withFreshModel()->update($server->id, [
'memory' => array_get($data, 'memory'),
'swap' => array_get($data, 'swap'),
'io' => array_get($data, 'io'),
'cpu' => array_get($data, 'cpu'),
'disk' => array_get($data, 'disk'),
'allocation_id' => array_get($data, 'allocation_id'),
]);
2018-01-21 22:02:03 +00:00
$allocations = $this->allocationRepository->findWhere([['server_id', '=', $server->id]]);
2018-01-21 22:02:03 +00:00
$build['memory'] = (int) $server->memory;
$build['swap'] = (int) $server->swap;
$build['io'] = (int) $server->io;
$build['cpu'] = (int) $server->cpu;
$build['disk'] = (int) $server->disk;
$build['ports|overwrite'] = $allocations->groupBy('ip')->map(function ($item) {
return $item->pluck('port');
2018-01-21 22:02:03 +00:00
})->toArray();
try {
2018-01-21 22:02:03 +00:00
$this->daemonServerRepository->setServer($server)->update(['build' => $build]);
$this->connection->commit();
} catch (RequestException $exception) {
2018-01-21 22:02:03 +00:00
throw new DaemonConnectionException($exception);
}
2018-01-21 22:02:03 +00:00
return $server;
}
/**
2018-01-21 22:02:03 +00:00
* Process the allocations being assigned in the data and ensure they
* are available for a server.
*
* @param \Pterodactyl\Models\Server $server
* @param array $data
*
* @throws \Pterodactyl\Exceptions\DisplayException
*/
2018-01-21 22:02:03 +00:00
private function processAllocations(Server $server, array &$data)
{
2018-01-21 22:02:03 +00:00
$firstAllocationId = null;
if (! array_key_exists('add_allocations', $data) && ! array_key_exists('remove_allocations', $data)) {
return;
}
2018-01-21 22:02:03 +00:00
// Handle the addition of allocations to this server.
if (array_key_exists('add_allocations', $data) && ! empty($data['add_allocations'])) {
2018-01-21 22:02:03 +00:00
$unassigned = $this->allocationRepository->getUnassignedAllocationIds($server->node_id);
2018-01-21 22:02:03 +00:00
$updateIds = [];
foreach ($data['add_allocations'] as $allocation) {
if (! in_array($allocation, $unassigned)) {
continue;
}
2018-01-21 22:02:03 +00:00
$firstAllocationId = $firstAllocationId ?? $allocation;
$updateIds[] = $allocation;
}
2018-01-21 22:02:03 +00:00
if (! empty($updateIds)) {
$this->allocationRepository->updateWhereIn('id', $updateIds, ['server_id' => $server->id]);
}
}
2018-01-21 22:02:03 +00:00
// Handle removal of allocations from this server.
if (array_key_exists('remove_allocations', $data) && ! empty($data['remove_allocations'])) {
2018-01-21 22:02:03 +00:00
$assigned = $this->allocationRepository->getAssignedAllocationIds($server->id);
2018-01-21 22:02:03 +00:00
$updateIds = [];
foreach ($data['remove_allocations'] as $allocation) {
if (! in_array($allocation, $assigned)) {
continue;
}
if ($allocation == $data['allocation_id']) {
2018-01-21 22:02:03 +00:00
if (is_null($firstAllocationId)) {
throw new DisplayException(trans('admin/server.exceptions.no_new_default_allocation'));
}
2018-01-21 22:02:03 +00:00
$data['allocation_id'] = $firstAllocationId;
}
2018-01-21 22:02:03 +00:00
$updateIds[] = $allocation;
}
2018-01-21 22:02:03 +00:00
if (! empty($updateIds)) {
$this->allocationRepository->updateWhereIn('id', $updateIds, ['server_id' => null]);
}
}
}
}