diff --git a/app/Http/Controllers/Api/Admin/VCenter/VCenterController.php b/app/Http/Controllers/Api/Admin/VCenter/VCenterController.php index 0a867ed..a460fb3 100644 --- a/app/Http/Controllers/Api/Admin/VCenter/VCenterController.php +++ b/app/Http/Controllers/Api/Admin/VCenter/VCenterController.php @@ -80,12 +80,7 @@ class VCenterController extends Controller return response()->json([ 'error' => false, - 'data' => preg_replace( - '#^wss://[^/]+#', - 'wss://' . self::CONSOLE_HOST, - $ticket['data'] - ), - 'host' => $vcenter->host, + 'data' => 'wss://' . self::CONSOLE_HOST . '/ticket/' . $ticket['data']['ticket'] . '?host=' . $ticket['data']['host'], 'vmware-api-session-id' => $serviceVCenter->token, ])->cookie('vmware-api-session-id', $serviceVCenter->token, 60, '/', null, false, false); } diff --git a/app/Http/Controllers/Api/Admin/VPS/VPSController.php b/app/Http/Controllers/Api/Admin/VPS/VPSController.php index 7fa50e2..6e29e7a 100644 --- a/app/Http/Controllers/Api/Admin/VPS/VPSController.php +++ b/app/Http/Controllers/Api/Admin/VPS/VPSController.php @@ -273,10 +273,7 @@ class VPSController extends Controller return response()->json([ 'error' => false, - 'data' => [ - 'ticket' => $ticket['data'], - 'host' => $vcenter->host - ] + 'data' => $ticket['data'], ]); } } diff --git a/app/Http/Controllers/Api/Client/Service/ServiceController.php b/app/Http/Controllers/Api/Client/Service/ServiceController.php index 60dea42..c3296ca 100644 --- a/app/Http/Controllers/Api/Client/Service/ServiceController.php +++ b/app/Http/Controllers/Api/Client/Service/ServiceController.php @@ -158,8 +158,6 @@ class ServiceController extends Controller return response()->json(['error' => true, 'message' => $consoleTicket['data']]); } - $ticket = basename(parse_url((string) $consoleTicket['data'], PHP_URL_PATH)); - $this->activityLogger->log( event: 'console_access', logName: 'VM', @@ -170,7 +168,8 @@ class ServiceController extends Controller return response()->json([ 'error' => false, - 'message' => $ticket, + 'message' => $consoleTicket['data']['ticket'], + 'host' => $consoleTicket['data']['host'], ]); } diff --git a/app/Http/Services/vCenter/Client.php b/app/Http/Services/vCenter/Client.php index 9551ba5..fc287a9 100644 --- a/app/Http/Services/vCenter/Client.php +++ b/app/Http/Services/vCenter/Client.php @@ -16,7 +16,10 @@ class Client public function loginServer(Vcenter $vcenterModel): bool|string { - $this->apiUri = 'console.tgs.com.vn'; + // console.tgs.com.vn (HAProxy) only proxies WMKS console websockets + // to ESXi hosts by ?host= — the vCenter management API must be + // called directly against the vCenter's own host. + $this->apiUri = $vcenterModel->host; $this->username = $vcenterModel->user; $this->password = SignRSA::DecryptFunc($vcenterModel->password); diff --git a/app/Http/Services/vCenter/PowerManagementService.php b/app/Http/Services/vCenter/PowerManagementService.php index 356c72c..a961bff 100644 --- a/app/Http/Services/vCenter/PowerManagementService.php +++ b/app/Http/Services/vCenter/PowerManagementService.php @@ -158,9 +158,28 @@ class PowerManagementService "type" => "WEBMKS" ])->json(); if (!isset($response['error_type'])) { + // vCenter returns "wss:///ticket/" — the esxi + // host is only reachable through HAProxy's ?host= routing + // (see config('vmware.console_nodes')), so split it out here. + $esxiHost = parse_url((string) $response['ticket'], PHP_URL_HOST); + $ticketId = basename(parse_url((string) $response['ticket'], PHP_URL_PATH)); + // Array access, not config('vmware.console_nodes.'.$esxiHost) — + // IPs contain dots, which collide with Laravel's dot notation. + $consoleHost = config('vmware.console_nodes')[$esxiHost] ?? null; + + if (!$consoleHost) { + return [ + 'error' => true, + 'data' => "Không tìm thấy console node cho ESXi host: $esxiHost", + ]; + } + return [ 'error' => false, - 'data' => $response['ticket'] + 'data' => [ + 'ticket' => $ticketId, + 'host' => $consoleHost, + ], ]; } return [ diff --git a/config/vmware.php b/config/vmware.php index 988bc7e..58cbc44 100644 --- a/config/vmware.php +++ b/config/vmware.php @@ -1,5 +1,23 @@ env('WMKS_HOST', '10.10.10.120'), + // HAProxy (console.tgs.com.vn) routes WMKS console websockets to the + // ESXi host that owns the ticket via the `?host=` query param — see + // ha-proxy.md. This maps each ESXi IP to the domain HAProxy matches on. + 'console_nodes' => [ + '10.10.10.125' => 'consolenode125.tgs.com.vn', + '10.10.10.121' => 'consolenode121.tgs.com.vn', + '192.168.99.90' => 'consoleviettel90.tgs.com.vn', + '192.168.99.91' => 'consoleviettel91.tgs.com.vn', + '103.42.57.35' => 'consolenode35.tgs.com.vn', + '103.42.57.36' => 'consolenode36.tgs.com.vn', + '103.42.57.37' => 'consolenode37.tgs.com.vn', + '10.10.10.126' => 'consolenode126.tgs.com.vn', + '10.10.10.127' => 'consolenode127.tgs.com.vn', + '10.10.10.128' => 'consolenode128.tgs.com.vn', + '10.10.10.129' => 'consolenode129.tgs.com.vn', + '10.10.10.130' => 'consolenode130.tgs.com.vn', + '10.10.10.101' => 'consolenode101.tgs.com.vn', + '10.10.10.120' => 'consolenode120.tgs.com.vn', + ], ]; \ No newline at end of file diff --git a/routes/api.php b/routes/api.php index 8806ed3..777e481 100644 --- a/routes/api.php +++ b/routes/api.php @@ -734,7 +734,6 @@ Route::prefix('v1') ->json([ 'error' => false, 'data' => $ConsoleTicket['data'], - 'host' => $vcenter->host, 'vmware-api-session-id' => $serviceVCenter->token, ]) ->cookie('vmware-api-session-id', $serviceVCenter->token, 60, '/', null, false, false);