client = $client; $this->powerShellService = $powerShellService; } public function CreateVirtualMachine($product_data): array|string { $vcenterModel = $product_data['vcenter']; Log::info('Vcenter Info', ['data' => $vcenterModel]); if (!$this->client->loginServer($vcenterModel)) { Log::error('Failed to create VM: API check failed, requires login.'); return 'Login_Again'; } $userName = customer()?->email; $item = $product_data['item']; $product = $product_data['product'] ?? null; $host = $product_data['host']; $datacenter = $product_data['datacenter']; $template = $product_data['template']; $addon = $product_data['addon'] ?? ['cpu' => 0, 'ram' => 0, 'disk' => 0]; $base_cpu = $product->cpu ?? ($host->cpu ?? 1); $base_ram = $product->ram ?? ($host->ram ?? 1); $base_disk = $product->disk ?? ($host->disk ?? 20); $base_cpu = max(1, (int) $base_cpu); $base_ram = max(1, (int) $base_ram); $base_disk = max(20, (int) $base_disk); Log::info("Cấu hình cơ bản", [ 'base_cpu' => $base_cpu, 'base_ram' => $base_ram, 'base_disk' => $base_disk, 'addon' => $addon ]); /** @var VmProviderSettingsService $providerSettings */ $providerSettings = app(VmProviderSettingsService::class); $datastore = $product_data['datastore'] ?? null; if (!$datastore) { throw new Exception("Host id={$host->id} chưa có datastore active để tạo VM."); } $datastoreId = $datastore->datastore; $body = [ 'spec' => [ 'name' => $item->server_name ?? ($userName . '-vm-' . $item->id), 'source' => $template, 'placement' => [ 'datacenter' => $datacenter->datacenter_id, 'folder' => $product_data['folder'] ?? $providerSettings->defaultFolder(), 'host' => $host->host_id, 'resource_pool' => $product_data['resource_pool'] ?? $providerSettings->defaultResourcePool(), 'datastore' => $datastoreId, ], 'power_on' => false, 'fallback_to_datastore_default_policy' => true, ], ]; Log::info('Data payload', ['data' => $body]); try { Log::info('Bắt đầu clone VM với timeout 300 giây', ['template' => $template, 'target_name' => $body['spec']['name']]); $response = TlsHttpClientFactory::vCenter() ->timeout(300) ->connectTimeout(30) ->withHeaders([ 'vmware-api-session-id' => $this->client->token, 'Content-Type' => 'application/json', ]) ->post("https://{$this->client->apiUri}/rest/vcenter/vm?action=clone", $body); $responseData = $response->json(); if ($response->successful() && !isset($responseData['type'])) { $vmId = $responseData['value'] ?? 'UNKNOWN'; Log::info("VM clone thành công, VM ID: {$vmId}", [ 'addon_data' => $addon, 'base_cpu' => $base_cpu, 'base_ram' => $base_ram, 'has_cpu_addon' => $addon['cpu'] > 0, 'has_ram_addon' => $addon['ram'] > 0, 'has_disk_addon' => $addon['disk'] > 0 ]); if ($vmId !== 'UNKNOWN' && ($addon['cpu'] > 0 || $addon['ram'] > 0 || $addon['disk'] > 0)) { Log::info("Bắt đầu cập nhật addon cho VM {$vmId}"); $this->updateVMHardware($vmId, $addon, $base_cpu, $base_ram); } else { Log::info("Không có addon nào cần cập nhật cho VM {$vmId}"); } $discord = app(Discord::class); $addonMsg = ''; if (!empty($addon)) { $addonMsg = "\n**Addon:** " . ($addon['cpu'] ? "CPU +{$addon['cpu']} " : "") . ($addon['ram'] ? "RAM +{$addon['ram']}GB " : "") . ($addon['disk'] ? "Disk +{$addon['disk']}GB " : ""); } $discord->SendMessage( message: "**User:** {$item->server_name}\n**VM ID:** `{$vmId}`{$addonMsg}\n**Thời gian:** " . now()->format('d/m/Y H:i:s'), color: Discord::COLOR_SUCCESS, title: '🎉 Tạo máy ảo thành công' ); return ['error' => false, 'data' => $vmId]; } Log::error('VM clone failed on vCenter', [ 'status' => $response->status(), 'request' => $body, 'response' => $responseData ?? $response->body(), ]); return ['error' => true, 'data' => $responseData['value'] ?? $response->body()]; } catch (Exception $e) { Log::error('Exception when creating VM', ['message' => $e->getMessage()]); return ['error' => true, 'data' => $e->getMessage()]; } } }