update optimize code

This commit is contained in:
pbao9
2025-07-29 15:48:51 +07:00
parent e8656c5655
commit d80580d1e4
24 changed files with 997 additions and 18755 deletions
@@ -48,8 +48,6 @@ class ServiceController extends Controller
return redirect()->route('service.index')->with('error', 'Bạn không có quyền truy cập dịch vụ này.');
}
// Lấy thông tin VM nếu có - WITH CACHING AND BACKGROUND UPDATE
$vmInfo = null;
if ($invoice->vm_id) {
@@ -234,10 +232,10 @@ class ServiceController extends Controller
/**
* Action để bật/tắt VM (placeholder - chưa implement)
*/
public function toggleVM(Request $request, $invoice_id)
public function toggleVM(Request $request, $invoice_ordernum)
{
try {
$invoice = Invoice::findOrFail($invoice_id);
$invoice = Invoice::where('order_num', $invoice_ordernum)->first();
// Kiểm tra quyền truy cập
if ($invoice->customer_id !== customer()->id) {
@@ -261,7 +259,7 @@ class ServiceController extends Controller
return response()->json($response);
} catch (\Exception $e) {
// Log::error('Error in ServiceController@toggleVM: ' . $e->getMessage());
return response()->json(['error' => true, 'message' => 'Có lỗi xảy ra khi thực hiện thao tác.']);
return response()->json(['error' => true, 'message' => 'Có lỗi xảy ra khi thực hiện thao tác. ' . $e->getMessage()]);
}
}
@@ -433,199 +431,110 @@ class ServiceController extends Controller
/**
* Secure get snapshots using session authentication - NO BEARER TOKEN
*/
/**
* Lấy danh sách snapshot với bảo mật và tối ưu hóa
*/
public function getSnapshots(Request $request, vCenter $serviceVCenter)
{
try {
// Kiểm tra authentication
$user = customer();
if (!$user) {
return response()->json([
'error' => true,
'message' => 'Chưa đăng nhập. Vui lòng đăng nhập để sử dụng tính năng này.',
'debug' => 'User not authenticated via session'
'message' => __('Chưa đăng nhập. Vui lòng đăng nhập để sử dụng tính năng này.')
], 401);
}
// Validation với sanitization
$validator = Validator::make($request->all(), [
'product_id' => 'required|string',
'product_id' => 'required|string|max:255',
]);
if ($validator->fails()) {
return response()->json([
'error' => true,
'message' => 'Dữ liệu không hợp lệ',
'message' => __('Dữ liệu không hợp lệ'),
'errors' => $validator->errors()
], 422);
}
$productId = $request->product_id;
$productId = $this->sanitizeInput($request->product_id);
$userId = $user->id;
Log::info('🔍 Debug - Tìm kiếm VPS để lấy snapshot', [
'product_id' => $productId,
'user_id' => $userId
]);
// Cache key cho snapshot data
$cacheKey = "snapshots_{$userId}_{$productId}";
$cacheDuration = 300; // 5 phút
$product = ModuleVmware::with('ipAddress.host.datacenter.vCenter')
->where('vmware_id', $productId)
->where('customer_id', $userId)
->first();
// Thử lấy từ cache trước
if (Cache::has($cacheKey)) {
$cachedData = Cache::get($cacheKey);
if ($cachedData && !$this->isCacheExpired($cachedData)) {
return response()->json([
'error' => false,
'message' => __('Lấy danh sách snapshot thành công'),
'data' => $cachedData,
'cached' => true
]);
}
}
// Tìm VPS với eager loading tối ưu
$product = $this->findVmwareProduct($productId, $userId);
if (!$product) {
return response()->json([
'error' => true,
'message' => "Không tìm thấy VPS #{$productId} hoặc bạn không có quyền truy cập",
'debug' => 'product not found or unauthorized'
'message' => __('Không tìm thấy VPS hoặc bạn không có quyền truy cập')
], 404);
}
if (!$product->ipAddress) {
// Kiểm tra cấu hình vCenter
$vcenter = $this->validateVcenterConfiguration($product);
if (!$vcenter) {
return response()->json([
'error' => true,
'message' => "VPS #{$productId} không có thông tin IP được cấu hình",
'debug' => 'product->ipAddress is null'
'message' => __('Cấu hình vCenter không hợp lệ')
], 400);
}
if (!$product->ipAddress->host) {
// Lấy snapshot từ vCenter
$snapshots = $this->fetchSnapshotsFromVCenter($serviceVCenter, $product, $vcenter);
if ($snapshots === false) {
return response()->json([
'error' => true,
'message' => "VPS #{$productId} không có thông tin Host được cấu hình",
'debug' => 'product->ipAddress->host is null'
], 400);
}
if (!$product->ipAddress->host->datacenter) {
return response()->json([
'error' => true,
'message' => "VPS #{$productId} không có thông tin Datacenter được cấu hình",
'debug' => 'product->ipAddress->host->datacenter is null'
], 400);
}
if (!$product->ipAddress->host->datacenter->vCenter) {
return response()->json([
'error' => true,
'message' => "VPS #{$productId} không có thông tin vCenter được cấu hình",
'debug' => 'product->ipAddress->host->datacenter->vCenter is null'
], 400);
}
// Get vCenter configuration
$vcenter = $product->ipAddress->host->datacenter->vCenter;
// Login to vCenter
if (!$serviceVCenter->loginServer($vcenter)) {
return response()->json([
'error' => true,
'message' => 'Không thể đăng nhập vào vCenter'
'message' => __('Không thể kết nối đến vCenter')
], 500);
}
Log::info('�� Bắt đầu lấy danh sách snapshot', [
'product_id' => $productId,
'product_name' => $product->name,
'vmware_id' => $product->vmware_id,
'vcenter_host' => $product->ipAddress->host->datacenter->vCenter->host ?? 'null',
'vcenter_user' => $product->ipAddress->host->datacenter->vCenter->user ?? 'null'
]);
// Lấy thông tin bổ sung từ database
$dbSnapshots = $this->getDatabaseSnapshots($userId, $product->id);
// Check if getSnapShot method exists
if (!method_exists($serviceVCenter, 'getSnapShot')) {
Log::error('❌ getSnapShot method không tồn tại trong ServiceVCenter');
return response()->json([
'error' => true,
'message' => 'getSnapShot method không tồn tại'
], 500);
}
// Merge và sanitize data
$processedSnapshots = $this->processSnapshotsData($snapshots, $dbSnapshots);
$result = $serviceVCenter->getSnapShot($product);
Log::info('✅ getSnapShot function đã được gọi');
// Chuẩn bị response data
$responseData = [
'snapshots' => $processedSnapshots,
'total_count' => count($processedSnapshots),
'vm_name' => $this->sanitizeOutput($product->name),
'vm_id' => $product->vmware_id,
'last_updated' => now()->format('Y-m-d H:i:s')
];
Log::info('📸 Kết quả getSnapShot', [
'result' => $result,
'product_id' => $productId
]);
if ($result === "Login_Again") {
if ($serviceVCenter->loginServer($vcenter)) {
$result = $serviceVCenter->getSnapShot($product);
} else {
return response()->json([
'error' => true,
'message' => 'Không thể đăng nhập lại vào vCenter'
], 500);
}
}
if (is_string($result)) {
return response()->json([
'error' => true,
'message' => "Lỗi lấy snapshot: $result"
], 500);
}
if (isset($result['error']) && $result['error']) {
return response()->json([
'error' => true,
'message' => "Lấy snapshot thất bại: " . ($result['message'] ?? 'Unknown error')
], 500);
}
// Get snapshots from database for additional info
$dbSnapshots = ModuleSnapshot::where('customer_id', $user->id)
->where('module_vmware_id', $product->id)
->get()
->keyBy('name');
// Merge vCenter data with database data
$snapshots = [];
if (isset($result['data']) && is_array($result['data'])) {
foreach ($result['data'] as $snapshot) {
$snapshotName = $snapshot['name'] ?? $snapshot['Name'] ?? 'Unknown';
$dbSnapshot = $dbSnapshots->get($snapshotName);
$snapshots[] = [
'name' => $snapshotName,
'description' => $snapshot['description'] ?? $snapshot['Description'] ?? '',
'created' => $snapshot['created'] ?? $snapshot['Created'] ?? '',
'power_state' => $snapshot['power_state'] ?? $snapshot['PowerState'] ?? '',
'size_mb' => $snapshot['size_mb'] ?? $snapshot['SizeMB'] ?? 0,
'size_gb' => $snapshot['size_gb'] ?? $snapshot['SizeGB'] ?? 0,
'vm_name' => $snapshot['vm_name'] ?? $snapshot['VM'] ?? '',
'vm_id' => $snapshot['vm_id'] ?? $snapshot['VMId'] ?? '',
'parent' => $snapshot['parent'] ?? $snapshot['Parent'] ?? '',
'parent_snapshot_id' => $snapshot['parent_snapshot_id'] ?? $snapshot['ParentSnapshotId'] ?? '',
'parent_snapshot' => $snapshot['parent_snapshot'] ?? $snapshot['ParentSnapshot'] ?? '',
'children' => $snapshot['children'] ?? $snapshot['Children'] ?? '',
'is_current' => $snapshot['is_current'] ?? $snapshot['IsCurrent'] ?? false,
'is_replay_supported' => $snapshot['is_replay_supported'] ?? $snapshot['IsReplaySupported'] ?? false,
'snapshot_id' => $snapshot['id'] ?? $snapshot['Id'] ?? '',
'uid' => $snapshot['uid'] ?? $snapshot['Uid'] ?? '',
'in_database' => $dbSnapshot ? true : false,
'db_created_at' => $dbSnapshot ? $dbSnapshot->created_at->format('d/m/Y H:i:s') : null,
'raw_data' => $snapshot
];
}
}
// Cache kết quả
Cache::put($cacheKey, $responseData, $cacheDuration);
return response()->json([
'error' => false,
'message' => 'Lấy danh sách snapshot thành công',
'data' => [
'snapshots' => $snapshots,
'total_count' => count($snapshots),
'vm_name' => $product->name,
'vm_id' => $product->vmware_id,
'cache_info' => [
'cached' => false,
'cache_key' => "snapshots_{$product->id}_{$product->name}"
]
]
'message' => __('Lấy danh sách snapshot thành công'),
'data' => $responseData,
'cached' => false
]);
} catch (\Exception $e) {
Log::error('❌ Lỗi khi lấy danh sách snapshot', [
'product_id' => $request->product_id ?? 'not_provided',
Log::error('Lỗi khi lấy danh sách snapshot', [
'user_id' => $user->id ?? 'guest',
'product_id' => $request->product_id ?? 'not_provided',
'error' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
@@ -633,73 +542,7 @@ class ServiceController extends Controller
return response()->json([
'error' => true,
'message' => 'Lỗi hệ thống khi lấy danh sách snapshot: ' . $e->getMessage()
], 500);
}
}
/**
* Secure start VM using session authentication - NO BEARER TOKEN
*/
public function startVM(Request $request, vCenter $vCenterService)
{
try {
// Use session authentication - NO Bearer token required
$user = customer(); // This uses session
if (!$user) {
return response()->json([
'error' => true,
'message' => 'Chưa đăng nhập. Vui lòng đăng nhập để sử dụng tính năng này.'
], 401);
}
// Implement start VM logic here
return response()->json([
'error' => false,
'message' => 'Chức năng start VM sẽ được thêm vào'
]);
} catch (\Exception $e) {
Log::error('❌ Lỗi trong secure startVM', [
'user_id' => $user->id ?? 'guest',
'error' => $e->getMessage()
]);
return response()->json([
'error' => true,
'message' => 'Lỗi hệ thống: ' . $e->getMessage()
], 500);
}
}
/**
* Secure stop VM using session authentication - NO BEARER TOKEN
*/
public function stopVM(Request $request, vCenter $vCenterService)
{
try {
// Use session authentication - NO Bearer token required
$user = customer(); // This uses session
if (!$user) {
return response()->json([
'error' => true,
'message' => 'Chưa đăng nhập. Vui lòng đăng nhập để sử dụng tính năng này.'
], 401);
}
// Implement stop VM logic here
return response()->json([
'error' => false,
'message' => 'Chức năng stop VM sẽ được thêm vào'
]);
} catch (\Exception $e) {
Log::error('❌ Lỗi trong secure stopVM', [
'user_id' => $user->id ?? 'guest',
'error' => $e->getMessage()
]);
return response()->json([
'error' => true,
'message' => 'Lỗi hệ thống: ' . $e->getMessage()
'message' => __('Có lỗi xảy ra khi lấy danh sách snapshot')
], 500);
}
}
@@ -887,4 +730,345 @@ class ServiceController extends Controller
], 500);
}
}
/**
* Secure start VM using session authentication - NO BEARER TOKEN
*/
public function startVM(Request $request, vCenter $vCenterService)
{
try {
$user = customer();
if (!$user) {
return response()->json([
'error' => true,
'message' => __('Chưa đăng nhập. Vui lòng đăng nhập để sử dụng tính năng này.')
], 401);
}
$validator = \Validator::make($request->all(), [
'product_id' => 'required|string|max:255',
]);
if ($validator->fails()) {
return response()->json([
'error' => true,
'message' => __('Dữ liệu không hợp lệ'),
'errors' => $validator->errors()
], 422);
}
$productId = htmlspecialchars(strip_tags(trim($request->product_id)), ENT_QUOTES, 'UTF-8');
$userId = $user->id;
$product = ModuleVmware::where('vmware_id', $productId)
->where('customer_id', $userId)
->first();
if (!$product) {
return response()->json([
'error' => true,
'message' => __('Không tìm thấy VPS hoặc bạn không có quyền truy cập')
], 404);
}
$result = $vCenterService->StartVirtualMachine($product, $product->vmware_id);
if (is_array($result) && isset($result['error']) && $result['error'] === false) {
// Clear VM info cache after starting VM
\Cache::forget('vm_info_' . $product->vmware_id);
return response()->json([
'error' => false,
'message' => __('Yêu cầu khởi động máy ảo đã được gửi thành công.')
]);
} else {
$msg = is_array($result) && isset($result['data']) ? $result['data'] : __('Không thể khởi động máy ảo');
return response()->json([
'error' => true,
'message' => $msg
], 500);
}
} catch (\Exception $e) {
\Log::error('Lỗi khi khởi động máy ảo', [
'user_id' => $user->id ?? 'guest',
'product_id' => $request->product_id ?? 'not_provided',
'error' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
return response()->json([
'error' => true,
'message' => __('Có lỗi xảy ra khi khởi động máy ảo')
], 500);
}
}
/**
* Secure stop VM using session authentication - NO BEARER TOKEN
*/
public function stopVM(Request $request, vCenter $vCenterService)
{
try {
$user = customer();
if (!$user) {
return response()->json([
'error' => true,
'message' => __('Chưa đăng nhập. Vui lòng đăng nhập để sử dụng tính năng này.')
], 401);
}
$validator = \Validator::make($request->all(), [
'product_id' => 'required|string|max:255',
]);
if ($validator->fails()) {
return response()->json([
'error' => true,
'message' => __('Dữ liệu không hợp lệ'),
'errors' => $validator->errors()
], 422);
}
$productId = htmlspecialchars(strip_tags(trim($request->product_id)), ENT_QUOTES, 'UTF-8');
$userId = $user->id;
$product = ModuleVmware::where('vmware_id', $productId)
->where('customer_id', $userId)
->first();
if (!$product) {
return response()->json([
'error' => true,
'message' => __('Không tìm thấy VPS hoặc bạn không có quyền truy cập')
], 404);
}
$result = $vCenterService->ShutdownGuestVirtualMachine($product, $product->vmware_id);
if (is_array($result) && isset($result['error']) && $result['error'] === false) {
// Clear VM info cache after stopping VM
\Cache::forget('vm_info_' . $product->vmware_id);
return response()->json([
'error' => false,
'message' => __('Yêu cầu tắt máy ảo đã được gửi thành công.')
]);
} else {
$msg = is_array($result) && isset($result['data']) ? $result['data'] : __('Không thể tắt máy ảo');
return response()->json([
'error' => true,
'message' => $msg
], 500);
}
} catch (\Exception $e) {
\Log::error('Lỗi khi tắt máy ảo', [
'user_id' => $user->id ?? 'guest',
'product_id' => $request->product_id ?? 'not_provided',
'error' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
return response()->json([
'error' => true,
'message' => __('Có lỗi xảy ra khi tắt máy ảo')
], 500);
}
}
/**
* Secure reboot VM using session authentication - NO BEARER TOKEN
*/
public function rebootVM(Request $request, vCenter $vCenterService)
{
try {
$user = customer();
if (!$user) {
return response()->json([
'error' => true,
'message' => __('Chưa đăng nhập. Vui lòng đăng nhập để sử dụng tính năng này.')
], 401);
}
$validator = \Validator::make($request->all(), [
'product_id' => 'required|string|max:255',
]);
if ($validator->fails()) {
return response()->json([
'error' => true,
'message' => __('Dữ liệu không hợp lệ'),
'errors' => $validator->errors()
], 422);
}
$productId = htmlspecialchars(strip_tags(trim($request->product_id)), ENT_QUOTES, 'UTF-8');
$userId = $user->id;
$product = ModuleVmware::where('vmware_id', $productId)
->where('customer_id', $userId)
->first();
if (!$product) {
return response()->json([
'error' => true,
'message' => __('Không tìm thấy VPS hoặc bạn không có quyền truy cập')
], 404);
}
$result = $vCenterService->RebootVirtualMachine($product, $product->vmware_id);
if (is_array($result) && isset($result['error']) && $result['error'] === false) {
return response()->json([
'error' => false,
'message' => __('Yêu cầu khởi động lại máy ảo đã được gửi thành công.')
]);
} else {
$msg = is_array($result) && isset($result['data']) ? $result['data'] : __('Không thể khởi động lại máy ảo');
return response()->json([
'error' => true,
'message' => $msg
], 500);
}
} catch (\Exception $e) {
\Log::error('Lỗi khi reboot VM', [
'user_id' => $user->id ?? 'guest',
'product_id' => $request->product_id ?? 'not_provided',
'error' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
return response()->json([
'error' => true,
'message' => __('Có lỗi xảy ra khi khởi động lại máy ảo')
], 500);
}
}
/**
* Sanitize input data
*/
private function sanitizeInput($input): string
{
return htmlspecialchars(strip_tags(trim($input)), ENT_QUOTES, 'UTF-8');
}
/**
* Sanitize output data
*/
private function sanitizeOutput($output): string
{
return htmlspecialchars($output, ENT_QUOTES, 'UTF-8');
}
/**
* Kiểm tra cache có hết hạn chưa
*/
private function isCacheExpired($cachedData): bool
{
if (!isset($cachedData['last_updated'])) {
return true;
}
$lastUpdated = \Carbon\Carbon::parse($cachedData['last_updated']);
return now()->diffInMinutes($lastUpdated) > 2; // Cache 2 phút
}
/**
* Tìm VPS với eager loading
*/
private function findVmwareProduct($productId, $userId)
{
return ModuleVmware::with(['ipAddress.host.datacenter.vCenter'])
->where('vmware_id', $productId)
->where('customer_id', $userId)
->first();
}
/**
* Validate vCenter configuration
*/
private function validateVcenterConfiguration($product)
{
if (!$product->ipAddress?->host?->datacenter?->vCenter) {
return null;
}
return $product->ipAddress->host->datacenter->vCenter;
}
/**
* Lấy snapshot từ vCenter
*/
private function fetchSnapshotsFromVCenter($serviceVCenter, $product, $vcenter)
{
try {
// Login to vCenter
if (!$serviceVCenter->loginServer($vcenter)) {
return false;
}
// Kiểm tra method tồn tại
if (!method_exists($serviceVCenter, 'getSnapShot')) {
Log::error('getSnapShot method không tồn tại trong ServiceVCenter');
return false;
}
$result = $serviceVCenter->getSnapShot($product);
// Retry logic
if ($result === "Login_Again") {
if ($serviceVCenter->loginServer($vcenter)) {
$result = $serviceVCenter->getSnapShot($product);
} else {
return false;
}
}
// Validate result
if (is_string($result) || (isset($result['error']) && $result['error'])) {
return false;
}
return $result['data'] ?? [];
} catch (\Exception $e) {
Log::error('Lỗi khi lấy snapshot từ vCenter', [
'product_id' => $product->id,
'error' => $e->getMessage()
]);
return false;
}
}
/**
* Lấy snapshot từ database
*/
private function getDatabaseSnapshots($userId, $productId)
{
return ModuleSnapshot::where('customer_id', $userId)
->where('module_vmware_id', $productId)
->get()
->keyBy('name');
}
/**
* Xử lý và sanitize snapshot data
*/
private function processSnapshotsData($snapshots, $dbSnapshots): array
{
$processed = [];
if (!is_array($snapshots)) {
return $processed;
}
foreach ($snapshots as $snapshot) {
$snapshotName = $this->sanitizeOutput($snapshot['name'] ?? $snapshot['Name'] ?? 'Unknown');
$dbSnapshot = $dbSnapshots->get($snapshotName);
$processed[] = [
'name' => $snapshotName,
'description' => $this->sanitizeOutput($snapshot['description'] ?? $snapshot['Description'] ?? ''),
'created' => $this->sanitizeOutput($snapshot['created'] ?? $snapshot['Created'] ?? ''),
'power_state' => $this->sanitizeOutput($snapshot['power_state'] ?? $snapshot['PowerState'] ?? ''),
'size_mb' => (int) ($snapshot['size_mb'] ?? $snapshot['SizeMB'] ?? 0),
'size_gb' => (float) ($snapshot['size_gb'] ?? $snapshot['SizeGB'] ?? 0),
'is_current' => (bool) ($snapshot['is_current'] ?? $snapshot['IsCurrent'] ?? false),
'is_replay_supported' => (bool) ($snapshot['is_replay_supported'] ?? $snapshot['IsReplaySupported'] ?? false),
'in_database' => $dbSnapshot ? true : false,
'db_created_at' => $dbSnapshot ? $dbSnapshot->created_at->format('d/m/Y H:i:s') : null
];
}
return $processed;
}
}