fix: network page uses globalDaemon type now

This commit is contained in:
Naterfute
2026-01-13 02:32:59 -08:00
parent a60b22d9d5
commit 9d2cacba68
9 changed files with 83 additions and 9 deletions

View File

@@ -0,0 +1,65 @@
<?php
namespace Pterodactyl\Enums\Limits;
use Illuminate\Http\Request;
use Webmozart\Assert\Assert;
use Pterodactyl\Models\Server;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Routing\Middleware\ThrottleRequests;
/**
* A basic resource throttler for individual servers. This is applied in addition
* to existing rate limits and allows the code to slow down speedy users that might
* be creating resources a little too quickly for comfort. This throttle generally
* only applies to creation flows, and not general view/edit/delete flows.
*/
enum ResourceLimit
{
case Allocation;
case Backup;
case Database;
case Schedule;
case Subuser;
case Websocket;
case FilePull;
public function throttleKey(): string
{
return mb_strtolower("api.client:server-resource:{$this->name}");
}
/**
* Returns a middleware that will throttle the specific resource by server. This
* throttle applies to any user making changes to that resource on the specific
* server, it is NOT per-user.
*/
public function middleware(): string
{
return ThrottleRequests::using($this->throttleKey());
}
public function limit(): Limit
{
return match ($this) {
self::Backup => Limit::perMinutes(15, 3),
self::Database => Limit::perMinute(2),
self::FilePull => Limit::perMinutes(10, 5),
self::Subuser => Limit::perMinutes(15, 10),
self::Websocket => Limit::perMinute(5),
default => Limit::perMinute(2),
};
}
public static function boot(): void
{
foreach (self::cases() as $case) {
RateLimiter::for($case->throttleKey(), function (Request $request) use ($case) {
Assert::isInstanceOf($server = $request->route()->parameter('server'), Server::class);
return $case->limit()->by($server->uuid);
});
}
}
}

View File

@@ -19,6 +19,8 @@ use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\StoreBackupRequest;
use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\RestoreBackupRequest;
use Pterodactyl\Enums\Daemon\Adapters;
class BackupsController extends ClientApiController
{
public function __construct(
@@ -44,14 +46,14 @@ class BackupsController extends ClientApiController
$rusticBackupSum = $server->backups()
->where('is_successful', true)
->whereIn('disk', [Backup::ADAPTER_RUSTIC_LOCAL, Backup::ADAPTER_RUSTIC_S3])
->whereIn('disk', Adapters::all_elytra())
->sum('bytes');
$rusticSumMb = round($rusticBackupSum / 1024 / 1024, 2);
$legacyBackupSum = $server->backups()
->where('is_successful', true)
->whereNotIn('disk', [Backup::ADAPTER_RUSTIC_LOCAL, Backup::ADAPTER_RUSTIC_S3])
->whereNotIn('disk', Adapters::all_elytra())
->sum('bytes');
$legacyUsageMb = round($legacyBackupSum / 1024 / 1024, 2);
@@ -101,7 +103,7 @@ class BackupsController extends ClientApiController
'backup_create',
[
'operation' => 'create',
'adapter' => $request->input('adapter', config('backups.default')),
'adapter' => $request->input('adapter', $server->node->backupDisk),
'ignored' => $request->input('ignored', ''),
'name' => $request->input('name'),
],
@@ -407,7 +409,7 @@ class BackupsController extends ClientApiController
[
'operation' => 'delete',
'backup_uuid' => $backup->uuid,
'adapter_type' => $backup->getElytraAdapterType(),
'adapter_type' => $backup->disk,
'snapshot_id' => $backup->snapshot_id,
'checksum' => $backup->checksum,
],

View File

@@ -74,7 +74,7 @@ class BackupController extends ClientApiController
// how best to allow a user to create a backup that is locked without also preventing
// them from just filling up a server with backups that can never be deleted?
if ($request->user()->can(Permission::ACTION_BACKUP_DELETE, $server)) {
$action->setIsLocked((bool) $request->input('is_locked'));
$action->setIsLocked($request->boolean('is_locked'));
}
$backup = $action->handle($server, $request->input('name'));

View File

@@ -4,6 +4,7 @@ namespace Pterodactyl\Providers;
use Illuminate\Http\Request;
use Pterodactyl\Models\Database;
use Pterodactyl\Enums\Limits\ResourceLimit;
use Illuminate\Support\Facades\Route;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
@@ -106,5 +107,6 @@ class RouteServiceProvider extends ServiceProvider
config('http.rate_limit.application')
)->by($key);
});
ResourceLimit::boot();
}
}

View File

@@ -1,9 +1,10 @@
import http from '@/api/http';
import { Allocation } from '@/api/server/getServer';
import { rawDataToServerAllocation } from '@/api/transformers';
import { getGlobalDaemonType } from '@/api/server/getServer';
export default async (uuid: string): Promise<Allocation> => {
const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations`);
const { data } = await http.post(`/api/client/servers/${getGlobalDaemonType()}/${uuid}/network/allocations`);
return rawDataToServerAllocation(data);
};

View File

@@ -1,5 +1,6 @@
import http from '@/api/http';
import { Allocation } from '@/api/server/getServer';
import { getGlobalDaemonType } from '@/api/server/getServer';
export default async (uuid: string, id: number): Promise<Allocation> =>
await http.delete(`/api/client/servers/${uuid}/network/allocations/${id}`);
await http.delete(`/api/client/servers/${getGlobalDaemonType()}/${uuid}/network/allocations/${id}`);

View File

@@ -1,9 +1,10 @@
import http from '@/api/http';
import { Allocation } from '@/api/server/getServer';
import { rawDataToServerAllocation } from '@/api/transformers';
import { getGlobalDaemonType } from '@/api/server/getServer';
export default async (uuid: string, id: number): Promise<Allocation> => {
const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations/${id}/primary`);
const { data } = await http.post(`/api/client/servers/${getGlobalDaemonType()}/${uuid}/network/allocations/${id}/primary`);
return rawDataToServerAllocation(data);
};

View File

@@ -1,9 +1,10 @@
import http from '@/api/http';
import { Allocation } from '@/api/server/getServer';
import { rawDataToServerAllocation } from '@/api/transformers';
import { getGlobalDaemonType } from '@/api/server/getServer';
export default async (uuid: string, id: number, notes: string | null): Promise<Allocation> => {
const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations/${id}`, { notes });
const { data } = await http.post(`/api/client/servers/${getGlobalDaemonType()}/${uuid}/network/allocations/${id}`, { notes });
return rawDataToServerAllocation(data);
};

View File

@@ -25,6 +25,7 @@ export interface AvailabilityResponse {
available: boolean;
message: string;
}
const daemonType = getGlobalDaemonType();
export const getSubdomainInfo = (uuid: string): Promise<SubdomainInfo> => {
return new Promise((resolve, reject) => {