From aeb7590a6d7528c62c853a0b1ed67ea810bcf3ea Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Sun, 23 Oct 2022 22:17:24 -0400 Subject: [PATCH] Replace node repository --- .../Repository/NodeRepositoryInterface.php | 38 ----- .../Admin/Nodes/NodeViewController.php | 42 +++++- .../Controllers/Admin/NodesController.php | 2 - .../Admin/Servers/CreateServerController.php | 4 +- .../Servers/ServerTransferController.php | 11 +- .../Admin/Servers/ServerViewController.php | 9 +- .../Api/Daemon/DaemonAuthenticate.php | 25 ++-- app/Models/Node.php | 22 +++ app/Providers/RepositoryServiceProvider.php | 3 - app/Repositories/Eloquent/NodeRepository.php | 138 +----------------- .../Locations/LocationDeletionService.php | 23 +-- app/Services/Nodes/NodeCreationService.php | 9 +- app/Services/Nodes/NodeDeletionService.php | 19 +-- app/Services/Nodes/NodeUpdateService.php | 6 +- 14 files changed, 101 insertions(+), 250 deletions(-) delete mode 100644 app/Contracts/Repository/NodeRepositoryInterface.php diff --git a/app/Contracts/Repository/NodeRepositoryInterface.php b/app/Contracts/Repository/NodeRepositoryInterface.php deleted file mode 100644 index 87d5b4de5..000000000 --- a/app/Contracts/Repository/NodeRepositoryInterface.php +++ /dev/null @@ -1,38 +0,0 @@ -repository->loadLocationAndServerCount($node); + $node->load('location')->loadCount('servers'); + + $stats = Node::query() + ->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('node_id', '=', $node->id) + ->first(); + + $usageStats = Collection::make(['disk' => $stats->sum_disk, 'memory' => $stats->sum_memory]) + ->mapWithKeys(function ($value, $key) use ($node) { + $maxUsage = $node->{$key}; + if ($node->{$key . '_overallocate'} > 0) { + $maxUsage = $node->{$key} * (1 + ($node->{$key . '_overallocate'} / 100)); + } + + $percent = ($value / $maxUsage) * 100; + + return [ + $key => [ + 'value' => number_format($value), + 'max' => number_format($maxUsage), + 'percent' => $percent, + 'css' => ($percent <= self::THRESHOLD_PERCENTAGE_LOW) ? 'green' : (($percent > self::THRESHOLD_PERCENTAGE_MEDIUM) ? 'red' : 'yellow'), + ], + ]; + }) + ->toArray(); return $this->view->make('admin.nodes.view.index', [ 'node' => $node, - 'stats' => $this->repository->getUsageStats($node), + 'stats' => $usageStats, 'version' => $this->versionService, ]); } @@ -71,7 +95,15 @@ class NodeViewController extends Controller */ public function allocations(Request $request, Node $node): View { - $node = $this->repository->loadNodeAllocations($node); + $node->setRelation( + 'allocations', + $node->allocations() + ->orderByRaw('server_id IS NOT NULL DESC, server_id IS NULL') + ->orderByRaw('INET_ATON(ip) ASC') + ->orderBy('port') + ->with('server:id,name') + ->paginate(50) + ); $this->plainInject(['node' => Collection::wrap($node)->only(['id'])]); diff --git a/app/Http/Controllers/Admin/NodesController.php b/app/Http/Controllers/Admin/NodesController.php index 573a1d9f8..ae22a8f69 100644 --- a/app/Http/Controllers/Admin/NodesController.php +++ b/app/Http/Controllers/Admin/NodesController.php @@ -18,7 +18,6 @@ use Pterodactyl\Services\Nodes\NodeDeletionService; use Pterodactyl\Services\Allocations\AssignmentService; use Pterodactyl\Services\Helpers\SoftwareVersionService; use Pterodactyl\Http\Requests\Admin\Node\NodeFormRequest; -use Pterodactyl\Contracts\Repository\NodeRepositoryInterface; use Pterodactyl\Contracts\Repository\ServerRepositoryInterface; use Pterodactyl\Http\Requests\Admin\Node\AllocationFormRequest; use Pterodactyl\Services\Allocations\AllocationDeletionService; @@ -40,7 +39,6 @@ class NodesController extends Controller protected NodeCreationService $creationService, protected NodeDeletionService $deletionService, protected LocationRepositoryInterface $locationRepository, - protected NodeRepositoryInterface $repository, protected ServerRepositoryInterface $serverRepository, protected NodeUpdateService $updateService, protected SoftwareVersionService $versionService, diff --git a/app/Http/Controllers/Admin/Servers/CreateServerController.php b/app/Http/Controllers/Admin/Servers/CreateServerController.php index c7a1653ad..253b448c3 100644 --- a/app/Http/Controllers/Admin/Servers/CreateServerController.php +++ b/app/Http/Controllers/Admin/Servers/CreateServerController.php @@ -11,7 +11,6 @@ use Prologue\Alerts\AlertsMessageBag; use Illuminate\View\Factory as ViewFactory; use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Repositories\Eloquent\NestRepository; -use Pterodactyl\Repositories\Eloquent\NodeRepository; use Pterodactyl\Http\Requests\Admin\ServerFormRequest; use Pterodactyl\Services\Servers\ServerCreationService; @@ -23,7 +22,6 @@ class CreateServerController extends Controller public function __construct( private AlertsMessageBag $alert, private NestRepository $nestRepository, - private NodeRepository $nodeRepository, private ServerCreationService $creationService, private ViewFactory $view ) { @@ -46,7 +44,7 @@ class CreateServerController extends Controller $nests = $this->nestRepository->getWithEggs(); JavaScript::put([ - 'nodeData' => $this->nodeRepository->getNodesForServerCreation(), + 'nodeData' => Node::getForServerCreation(), 'nests' => $nests->map(function ($item) { return array_merge($item->toArray(), [ 'eggs' => $item->eggs->keyBy('id')->toArray(), diff --git a/app/Http/Controllers/Admin/Servers/ServerTransferController.php b/app/Http/Controllers/Admin/Servers/ServerTransferController.php index cdb2bb557..51a8cff47 100644 --- a/app/Http/Controllers/Admin/Servers/ServerTransferController.php +++ b/app/Http/Controllers/Admin/Servers/ServerTransferController.php @@ -3,13 +3,13 @@ namespace Pterodactyl\Http\Controllers\Admin\Servers; use Illuminate\Http\Request; +use Pterodactyl\Models\Node; use Pterodactyl\Models\Server; use Prologue\Alerts\AlertsMessageBag; use Illuminate\Http\RedirectResponse; 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; @@ -21,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 ) { @@ -45,7 +44,13 @@ class ServerTransferController extends Controller $additional_allocations = array_map('intval', $validatedData['allocation_additional'] ?? []); // Check if the node is viable for the transfer. - $node = $this->nodeRepository->getNodeWithResourceUsage($node_id); + $node = Node::query() + ->select(['nodes.id', 'nodes.fqdn', 'nodes.scheme', 'nodes.daemon_token', 'nodes.daemonListen', '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') + ->leftJoin('servers', 'servers.node_id', '=', 'nodes.id') + ->where('nodes.id', $node_id) + ->first(); + if ($node->isViable($server->memory, $server->disk)) { // Check if the selected daemon is online. $this->daemonConfigurationRepository->setNode($node)->getSystemInformation(); diff --git a/app/Http/Controllers/Admin/Servers/ServerViewController.php b/app/Http/Controllers/Admin/Servers/ServerViewController.php index 7cf64a2f5..78429b7e2 100644 --- a/app/Http/Controllers/Admin/Servers/ServerViewController.php +++ b/app/Http/Controllers/Admin/Servers/ServerViewController.php @@ -6,13 +6,13 @@ use JavaScript; use Illuminate\View\View; use Illuminate\Http\Request; use Pterodactyl\Models\Nest; +use Pterodactyl\Models\Node; use Pterodactyl\Models\Server; use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Services\Servers\EnvironmentService; use Illuminate\Contracts\View\Factory as ViewFactory; use Pterodactyl\Repositories\Eloquent\NestRepository; -use Pterodactyl\Repositories\Eloquent\NodeRepository; use Pterodactyl\Repositories\Eloquent\MountRepository; use Pterodactyl\Repositories\Eloquent\ServerRepository; use Pterodactyl\Traits\Controllers\JavascriptInjection; @@ -31,7 +31,6 @@ class ServerViewController extends Controller private LocationRepository $locationRepository, private MountRepository $mountRepository, private NestRepository $nestRepository, - private NodeRepository $nodeRepository, private ServerRepository $repository, private EnvironmentService $environmentService, private ViewFactory $view @@ -128,14 +127,14 @@ class ServerViewController extends Controller } // Check if the panel doesn't have at least 2 nodes configured. - $nodes = $this->nodeRepository->all(); + $nodeCount = Node::query()->count(); $canTransfer = false; - if (count($nodes) >= 2) { + if ($nodeCount >= 2) { $canTransfer = true; } JavaScript::put([ - 'nodeData' => $this->nodeRepository->getNodesForServerCreation(), + 'nodeData' => Node::getForServerCreation(), ]); return $this->view->make('admin.servers.view.manage', [ diff --git a/app/Http/Middleware/Api/Daemon/DaemonAuthenticate.php b/app/Http/Middleware/Api/Daemon/DaemonAuthenticate.php index cea8bc5ed..56b484333 100644 --- a/app/Http/Middleware/Api/Daemon/DaemonAuthenticate.php +++ b/app/Http/Middleware/Api/Daemon/DaemonAuthenticate.php @@ -4,10 +4,9 @@ namespace Pterodactyl\Http\Middleware\Api\Daemon; use Closure; use Illuminate\Http\Request; +use Pterodactyl\Models\Node; use Illuminate\Contracts\Encryption\Encrypter; -use Pterodactyl\Repositories\Eloquent\NodeRepository; use Symfony\Component\HttpKernel\Exception\HttpException; -use Pterodactyl\Exceptions\Repository\RecordNotFoundException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; @@ -23,14 +22,14 @@ class DaemonAuthenticate /** * DaemonAuthenticate constructor. */ - public function __construct(private Encrypter $encrypter, private NodeRepository $repository) + public function __construct(private Encrypter $encrypter) { } /** * Check if a request from the daemon can be properly attributed back to a single node instance. * - * @throws \Symfony\Component\HttpKernel\Exception\HttpException + * @throws HttpException */ public function handle(Request $request, Closure $next): mixed { @@ -43,24 +42,18 @@ class DaemonAuthenticate } $parts = explode('.', $bearer); - // Ensure that all of the correct parts are provided in the header. + // Ensure that all the correct parts are provided in the header. if (count($parts) !== 2 || empty($parts[0]) || empty($parts[1])) { throw new BadRequestHttpException('The Authorization header provided was not in a valid format.'); } - try { - /** @var \Pterodactyl\Models\Node $node */ - $node = $this->repository->findFirstWhere([ - 'daemon_token_id' => $parts[0], - ]); + /** @var Node $node */ + $node = Node::query()->where('daemon_token_id', $parts[0])->firstOrFail(); - if (hash_equals((string) $this->encrypter->decrypt($node->daemon_token), $parts[1])) { - $request->attributes->set('node', $node); + if (hash_equals((string) $this->encrypter->decrypt($node->daemon_token), $parts[1])) { + $request->attributes->set('node', $node); - return $next($request); - } - } catch (RecordNotFoundException $exception) { - // Do nothing, we don't want to expose a node not existing at all. + return $next($request); } throw new AccessDeniedHttpException('You are not authorized to access this resource.'); diff --git a/app/Models/Node.php b/app/Models/Node.php index 37aec760d..ec26a20d8 100644 --- a/app/Models/Node.php +++ b/app/Models/Node.php @@ -225,4 +225,26 @@ class Node extends Model return ($this->sum_memory + $memory) <= $memoryLimit && ($this->sum_disk + $disk) <= $diskLimit; } + + public static function getForServerCreation() + { + return self::with('allocations')->get()->map(function (Node $item) { + $filtered = $item->getRelation('allocations')->where('server_id', null)->map(function ($map) { + return collect($map)->only(['id', 'ip', 'port']); + }); + + $item->ports = $filtered->map(function ($map) { + return [ + 'id' => $map['id'], + 'text' => sprintf('%s:%s', $map['ip'], $map['port']), + ]; + })->values(); + + return [ + 'id' => $item->id, + 'text' => $item->name, + 'allocations' => $item->ports, + ]; + })->values(); + } } diff --git a/app/Providers/RepositoryServiceProvider.php b/app/Providers/RepositoryServiceProvider.php index 8a0434f52..19364aace 100644 --- a/app/Providers/RepositoryServiceProvider.php +++ b/app/Providers/RepositoryServiceProvider.php @@ -5,7 +5,6 @@ namespace Pterodactyl\Providers; use Illuminate\Support\ServiceProvider; use Pterodactyl\Repositories\Eloquent\EggRepository; use Pterodactyl\Repositories\Eloquent\NestRepository; -use Pterodactyl\Repositories\Eloquent\NodeRepository; use Pterodactyl\Repositories\Eloquent\TaskRepository; use Pterodactyl\Repositories\Eloquent\UserRepository; use Pterodactyl\Repositories\Eloquent\ApiKeyRepository; @@ -20,7 +19,6 @@ use Pterodactyl\Repositories\Eloquent\AllocationRepository; use Pterodactyl\Contracts\Repository\EggRepositoryInterface; use Pterodactyl\Repositories\Eloquent\EggVariableRepository; use Pterodactyl\Contracts\Repository\NestRepositoryInterface; -use Pterodactyl\Contracts\Repository\NodeRepositoryInterface; use Pterodactyl\Contracts\Repository\TaskRepositoryInterface; use Pterodactyl\Contracts\Repository\UserRepositoryInterface; use Pterodactyl\Repositories\Eloquent\DatabaseHostRepository; @@ -54,7 +52,6 @@ class RepositoryServiceProvider extends ServiceProvider $this->app->bind(EggVariableRepositoryInterface::class, EggVariableRepository::class); $this->app->bind(LocationRepositoryInterface::class, LocationRepository::class); $this->app->bind(NestRepositoryInterface::class, NestRepository::class); - $this->app->bind(NodeRepositoryInterface::class, NodeRepository::class); $this->app->bind(ScheduleRepositoryInterface::class, ScheduleRepository::class); $this->app->bind(ServerRepositoryInterface::class, ServerRepository::class); $this->app->bind(ServerVariableRepositoryInterface::class, ServerVariableRepository::class); diff --git a/app/Repositories/Eloquent/NodeRepository.php b/app/Repositories/Eloquent/NodeRepository.php index fe019e50a..f8be4b39d 100644 --- a/app/Repositories/Eloquent/NodeRepository.php +++ b/app/Repositories/Eloquent/NodeRepository.php @@ -3,10 +3,8 @@ namespace Pterodactyl\Repositories\Eloquent; use Pterodactyl\Models\Node; -use Illuminate\Support\Collection; -use Pterodactyl\Contracts\Repository\NodeRepositoryInterface; -class NodeRepository extends EloquentRepository implements NodeRepositoryInterface +class NodeRepository { /** * Return the model backing this repository. @@ -15,138 +13,4 @@ class NodeRepository extends EloquentRepository implements NodeRepositoryInterfa { return Node::class; } - - /** - * Return the usage stats for a single node. - */ - public function getUsageStats(Node $node): array - { - $stats = $this->getBuilder() - ->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('node_id', '=', $node->id) - ->first(); - - return Collection::make(['disk' => $stats->sum_disk, 'memory' => $stats->sum_memory]) - ->mapWithKeys(function ($value, $key) use ($node) { - $maxUsage = $node->{$key}; - if ($node->{$key . '_overallocate'} > 0) { - $maxUsage = $node->{$key} * (1 + ($node->{$key . '_overallocate'} / 100)); - } - - $percent = ($value / $maxUsage) * 100; - - return [ - $key => [ - 'value' => number_format($value), - 'max' => number_format($maxUsage), - 'percent' => $percent, - 'css' => ($percent <= self::THRESHOLD_PERCENTAGE_LOW) ? 'green' : (($percent > self::THRESHOLD_PERCENTAGE_MEDIUM) ? 'red' : 'yellow'), - ], - ]; - }) - ->toArray(); - } - - /** - * Return the usage stats for a single node. - */ - public function getUsageStatsRaw(Node $node): array - { - $stats = $this->getBuilder()->select( - $this->getBuilder()->raw('IFNULL(SUM(servers.memory), 0) as sum_memory, IFNULL(SUM(servers.disk), 0) as sum_disk') - )->join('servers', 'servers.node_id', '=', 'nodes.id')->where('node_id', $node->id)->first(); - - return collect(['disk' => $stats->sum_disk, 'memory' => $stats->sum_memory])->mapWithKeys(function ($value, $key) use ($node) { - $maxUsage = $node->{$key}; - if ($node->{$key . '_overallocate'} > 0) { - $maxUsage = $node->{$key} * (1 + ($node->{$key . '_overallocate'} / 100)); - } - - return [ - $key => [ - 'value' => $value, - 'max' => $maxUsage, - ], - ]; - })->toArray(); - } - - /** - * Return a single node with location and server information. - */ - public function loadLocationAndServerCount(Node $node, bool $refresh = false): Node - { - if (!$node->relationLoaded('location') || $refresh) { - $node->load('location'); - } - - // This is quite ugly and can probably be improved down the road. - // And by probably, I mean it should. - if (is_null($node->servers_count) || $refresh) { - $node->load('servers'); - $node->setRelation('servers_count', count($node->getRelation('servers'))); - unset($node->servers); - } - - return $node; - } - - /** - * Attach a paginated set of allocations to a node mode including - * any servers that are also attached to those allocations. - */ - public function loadNodeAllocations(Node $node, bool $refresh = false): Node - { - $node->setRelation( - 'allocations', - $node->allocations() - ->orderByRaw('server_id IS NOT NULL DESC, server_id IS NULL') - ->orderByRaw('INET_ATON(ip) ASC') - ->orderBy('port') - ->with('server:id,name') - ->paginate(50) - ); - - return $node; - } - - /** - * Return a collection of nodes for all locations to use in server creation UI. - */ - public function getNodesForServerCreation(): Collection - { - return $this->getBuilder()->with('allocations')->get()->map(function (Node $item) { - $filtered = $item->getRelation('allocations')->where('server_id', null)->map(function ($map) { - return collect($map)->only(['id', 'ip', 'port']); - }); - - $item->ports = $filtered->map(function ($map) { - return [ - 'id' => $map['id'], - 'text' => sprintf('%s:%s', $map['ip'], $map['port']), - ]; - })->values(); - - return [ - 'id' => $item->id, - 'text' => $item->name, - 'allocations' => $item->ports, - ]; - })->values(); - } - - /** - * Returns a node with the given id with the Node's resource usage. - */ - public function getNodeWithResourceUsage(int $node_id): Node - { - $instance = $this->getBuilder() - ->select(['nodes.id', 'nodes.fqdn', 'nodes.scheme', 'nodes.daemon_token', 'nodes.daemonListen', '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') - ->leftJoin('servers', 'servers.node_id', '=', 'nodes.id') - ->where('nodes.id', $node_id); - - return $instance->first(); - } } diff --git a/app/Services/Locations/LocationDeletionService.php b/app/Services/Locations/LocationDeletionService.php index 5b4b9eba4..0c9974d4c 100644 --- a/app/Services/Locations/LocationDeletionService.php +++ b/app/Services/Locations/LocationDeletionService.php @@ -2,39 +2,26 @@ namespace Pterodactyl\Services\Locations; -use Webmozart\Assert\Assert; use Pterodactyl\Models\Location; -use Pterodactyl\Contracts\Repository\NodeRepositoryInterface; -use Pterodactyl\Contracts\Repository\LocationRepositoryInterface; use Pterodactyl\Exceptions\Service\Location\HasActiveNodesException; class LocationDeletionService { - /** - * LocationDeletionService constructor. - */ - public function __construct( - protected LocationRepositoryInterface $repository, - protected NodeRepositoryInterface $nodeRepository - ) { - } - /** * Delete an existing location. * - * @throws \Pterodactyl\Exceptions\Service\Location\HasActiveNodesException + * @throws HasActiveNodesException */ public function handle(Location|int $location): ?int { - $location = ($location instanceof Location) ? $location->id : $location; + /** @var Location $location */ + $location = ($location instanceof Location) ? $location : Location::query()->findOrFail($location); - Assert::integerish($location, 'First argument passed to handle must be numeric or an instance of ' . Location::class . ', received %s.'); - - $count = $this->nodeRepository->findCountWhere([['location_id', '=', $location]]); + $count = $location->nodes()->count(); if ($count > 0) { throw new HasActiveNodesException(trans('exceptions.locations.has_nodes')); } - return $this->repository->delete($location); + return $location->delete(); } } diff --git a/app/Services/Nodes/NodeCreationService.php b/app/Services/Nodes/NodeCreationService.php index e4946bc20..9c6c8654b 100644 --- a/app/Services/Nodes/NodeCreationService.php +++ b/app/Services/Nodes/NodeCreationService.php @@ -6,21 +6,19 @@ use Ramsey\Uuid\Uuid; use Illuminate\Support\Str; use Pterodactyl\Models\Node; use Illuminate\Contracts\Encryption\Encrypter; -use Pterodactyl\Contracts\Repository\NodeRepositoryInterface; class NodeCreationService { /** * NodeCreationService constructor. */ - public function __construct(private Encrypter $encrypter, protected NodeRepositoryInterface $repository) + public function __construct(private Encrypter $encrypter) { } /** * Create a new node on the panel. * - * @throws \Pterodactyl\Exceptions\Model\DataValidationException */ public function handle(array $data): Node { @@ -28,6 +26,9 @@ class NodeCreationService $data['daemon_token'] = $this->encrypter->encrypt(Str::random(Node::DAEMON_TOKEN_LENGTH)); $data['daemon_token_id'] = Str::random(Node::DAEMON_TOKEN_ID_LENGTH); - return $this->repository->create($data, true, true); + /** @var Node $node */ + $node = Node::query()->create($data); + + return $node; } } diff --git a/app/Services/Nodes/NodeDeletionService.php b/app/Services/Nodes/NodeDeletionService.php index adb9a0628..f90e8058b 100644 --- a/app/Services/Nodes/NodeDeletionService.php +++ b/app/Services/Nodes/NodeDeletionService.php @@ -4,38 +4,33 @@ namespace Pterodactyl\Services\Nodes; use Pterodactyl\Models\Node; use Illuminate\Contracts\Translation\Translator; -use Pterodactyl\Contracts\Repository\NodeRepositoryInterface; use Pterodactyl\Exceptions\Service\HasActiveServersException; -use Pterodactyl\Contracts\Repository\ServerRepositoryInterface; class NodeDeletionService { /** * NodeDeletionService constructor. */ - public function __construct( - protected NodeRepositoryInterface $repository, - protected ServerRepositoryInterface $serverRepository, - protected Translator $translator - ) { + public function __construct(protected Translator $translator) + { } /** * Delete a node from the panel if no servers are attached to it. * - * @throws \Pterodactyl\Exceptions\Service\HasActiveServersException + * @throws HasActiveServersException */ public function handle(int|Node $node): int { - if ($node instanceof Node) { - $node = $node->id; + if (is_int($node)) { + $node = Node::query()->findOrFail($node); } - $servers = $this->serverRepository->setColumns('id')->findCountWhere([['node_id', '=', $node]]); + $servers = $node->servers()->count(); if ($servers > 0) { throw new HasActiveServersException($this->translator->get('exceptions.node.servers_attached')); } - return $this->repository->delete($node); + return $node->delete(); } } diff --git a/app/Services/Nodes/NodeUpdateService.php b/app/Services/Nodes/NodeUpdateService.php index 28733e35a..f473df5a0 100644 --- a/app/Services/Nodes/NodeUpdateService.php +++ b/app/Services/Nodes/NodeUpdateService.php @@ -7,7 +7,6 @@ use Pterodactyl\Models\Node; use Illuminate\Support\Facades\Log; use Illuminate\Database\ConnectionInterface; use Illuminate\Contracts\Encryption\Encrypter; -use Pterodactyl\Repositories\Eloquent\NodeRepository; use Pterodactyl\Repositories\Wings\DaemonConfigurationRepository; use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException; use Pterodactyl\Exceptions\Service\Node\ConfigurationNotPersistedException; @@ -20,8 +19,7 @@ class NodeUpdateService public function __construct( private ConnectionInterface $connection, private DaemonConfigurationRepository $configurationRepository, - private Encrypter $encrypter, - private NodeRepository $repository + private Encrypter $encrypter ) { } @@ -39,7 +37,7 @@ class NodeUpdateService [$updated, $exception] = $this->connection->transaction(function () use ($data, $node) { /** @var \Pterodactyl\Models\Node $updated */ - $updated = $this->repository->withFreshModel()->update($node->id, $data, true, true); + $updated = (clone $node)->update($data); try { // If we're changing the FQDN for the node, use the newly provided FQDN for the connection