117 lines
4.0 KiB
PHP
117 lines
4.0 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Network Metrics Controller — client API
|
|
*
|
|
* @author Ball Studios <https://git.balls.studio>
|
|
* @license MIT
|
|
*/
|
|
|
|
namespace Pterodactyl\Addons\AdvancedAdmin\Http\Controllers\Client;
|
|
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Routing\Controller;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Pterodactyl\Models\Server;
|
|
|
|
class NetworkMetricsController extends Controller
|
|
{
|
|
/** GET /api/client/servers/{server}/addons/network/live */
|
|
public function live(Request $request, Server $server): JsonResponse
|
|
{
|
|
$this->requireAccess($request, $server);
|
|
|
|
// Latest raw metric (most recent 30 seconds)
|
|
$latest = DB::table('addon_network_metrics')
|
|
->where('server_id', $server->id)
|
|
->where('resolution', 'raw')
|
|
->where('recorded_at', '>=', now()->subSeconds(30))
|
|
->orderByDesc('recorded_at')
|
|
->select('rx_bytes', 'tx_bytes', 'recorded_at')
|
|
->first();
|
|
|
|
return response()->json(['data' => $latest]);
|
|
}
|
|
|
|
/** GET /api/client/servers/{server}/addons/network/history */
|
|
public function history(Request $request, Server $server): JsonResponse
|
|
{
|
|
$this->requireAccess($request, $server);
|
|
|
|
$resolution = $request->get('resolution', '5m');
|
|
abort_unless(in_array($resolution, ['raw', '5m', '1h', '1d'], true), 422, 'Invalid resolution.');
|
|
|
|
$hours = match ($resolution) {
|
|
'raw' => 1,
|
|
'5m' => 24,
|
|
'1h' => 168,
|
|
'1d' => 8760,
|
|
};
|
|
|
|
$metrics = DB::table('addon_network_metrics')
|
|
->where('server_id', $server->id)
|
|
->where('resolution', $resolution)
|
|
->where('recorded_at', '>=', now()->subHours($hours))
|
|
->orderBy('recorded_at')
|
|
->select('rx_bytes', 'tx_bytes', 'recorded_at')
|
|
->get();
|
|
|
|
return response()->json(['data' => $metrics]);
|
|
}
|
|
|
|
/** GET /api/client/servers/{server}/addons/network/ports */
|
|
public function ports(Request $request, Server $server): JsonResponse
|
|
{
|
|
$this->requireAccess($request, $server);
|
|
|
|
if (!config('advanced-admin.network.iptables_enabled')) {
|
|
return response()->json(['data' => [], 'unavailable' => true, 'reason' => 'iptables collection not enabled']);
|
|
}
|
|
|
|
$ports = DB::table('addon_network_port_metrics')
|
|
->where('server_id', $server->id)
|
|
->where('resolution', '5m')
|
|
->where('recorded_at', '>=', now()->subHour())
|
|
->groupBy('port', 'protocol')
|
|
->select('port', 'protocol', DB::raw('SUM(rx_bytes) as rx_bytes'), DB::raw('SUM(tx_bytes) as tx_bytes'))
|
|
->orderByDesc('rx_bytes')
|
|
->limit(50)
|
|
->get();
|
|
|
|
return response()->json(['data' => $ports]);
|
|
}
|
|
|
|
/** GET /api/client/servers/{server}/addons/network/flows */
|
|
public function flows(Request $request, Server $server): JsonResponse
|
|
{
|
|
$this->requireAccess($request, $server);
|
|
|
|
$flows = DB::table('addon_network_flows')
|
|
->where(function ($q) use ($server) {
|
|
$q->where('src_server_id', $server->id)
|
|
->orWhere('dst_server_id', $server->id);
|
|
})
|
|
->where('recorded_at', '>=', now()->subHours(24))
|
|
->select('src_server_id', 'dst_server_id', DB::raw('SUM(bytes) as bytes'), DB::raw('SUM(packets) as packets'))
|
|
->groupBy('src_server_id', 'dst_server_id')
|
|
->orderByDesc('bytes')
|
|
->limit(50)
|
|
->get();
|
|
|
|
return response()->json(['data' => $flows]);
|
|
}
|
|
|
|
private function requireAccess(Request $request, Server $server): void
|
|
{
|
|
$user = $request->user();
|
|
abort_unless($user, 401);
|
|
$isOwner = $server->owner_id === $user->id;
|
|
$isAdmin = $user->root_admin;
|
|
if (!$isOwner && !$isAdmin) {
|
|
$subuser = $server->subusers()->where('user_id', $user->id)->first();
|
|
abort_unless($subuser, 403);
|
|
}
|
|
}
|
|
}
|