vCenter = new ServiceVCenter; $this->telegram = new Telegram(); try { $data = vCenter::select('id', 'host', 'user', 'password', 'token')->get(); $vCenterCount = 0; $vmTotalCount = 0; foreach ($data as $item) { Log::info("Processing vCenter: {$item->host}"); $this->vCenter->apiUri = $item->host; // Always login to get a fresh token $token = $this->vCenter->loginServer($item); if ($token) { $item->token = $token; $item->save(); $this->vCenter->token = $token; } else { $this->vCenter->token = null; Log::error("Login failed for {$item->host}"); } if (!$this->vCenter->token) { continue; } $datacenters = ModuleDatacenter::where('vcenter_id', $item->id)->get(); if ($datacenters->count() > 0) { foreach ($datacenters as $dc) { // Get all hosts for this datacenter $hosts = ModuleHost::where('module_datacenter_id', $dc->id)->get(); if ($hosts->count() > 0) { foreach ($hosts as $host) { Log::info("Fetching VMs for host: {$host->host_id} in datacenter: {$dc->name}"); $vms = $this->vCenter->getAllVirtualMachine($dc->datacenter_id, $host->host_id); $vmCount = $this->processVMs($vms, $item, $dc->id, $host->id); $vmTotalCount += $vmCount; } } else { // Fallback: Sync VMs by datacenter only Log::info("No hosts found for datacenter {$dc->name}, fetching VMs by datacenter only"); $vms = $this->vCenter->getAllVirtualMachine($dc->datacenter_id); $vmCount = $this->processVMs($vms, $item, $dc->id, null); $vmTotalCount += $vmCount; } } } else { // Fallback: Sync all VMs without datacenter context Log::info("No datacenters found, fetching all VMs for {$item->host}"); $vms = $this->vCenter->getAllVirtualMachine(); $vmCount = $this->processVMs($vms, $item, null, null); $vmTotalCount += $vmCount; } $vCenterCount++; // Increment vCenter synced count } // Notify success via Telegram $this->telegram->SendJobRunInfo('SyncVirtualMachine', 'Success', [ 'message' => 'Sync VMs completed successfully', 'synced_vcenter_count' => $vCenterCount, 'synced_vm_count' => $vmTotalCount, ]); } catch (Throwable $e) { Log::error("SyncVirtualMachine Job Failed: " . $e->getMessage()); // Gửi log lỗi qua Telegram if (isset($this->telegram)) { $this->telegram->SendJobRunInfo('SyncVirtualMachine', 'Failed', [ 'error' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine(), ]); } } } private function processVMs($vms, $vCenterItem, $datacenterId, $hostId) { // If token expired, retry login (handled inside loop in previous logic, but simpler here if we just handle the array check) if ($vms === 'Login_Again') { Log::info("Token expired, retrying login for {$vCenterItem->host}"); $token = $this->vCenter->loginServer($vCenterItem); if ($token) { $vCenterItem->token = $token; $vCenterItem->save(); $this->vCenter->token = $token; // Retry fetch $datacenter = $datacenterId ? ModuleDatacenter::find($datacenterId) : null; $host = $hostId ? ModuleHost::find($hostId) : null; $vms = $this->vCenter->getAllVirtualMachine( $datacenter ? $datacenter->datacenter_id : '', $host ? $host->host_id : '' ); } } if (!is_array($vms)) { Log::warning("Failed to fetch VMs or empty response. Response: " . json_encode($vms)); return 0; } Log::info("Fetched " . count($vms) . " VMs"); $count = 0; foreach ($vms as $vmData) { $vmObj = VirtualMachines::firstOrNew(['vm_id' => $vmData['vm']]); if (!$vmObj->exists) { $vmObj->uuid = Str::uuid(); } $vmObj->name = $vmData['name']; $vmObj->power_state = $vmData['power_state']; $vmObj->cpu = $vmData['cpu_count'] ?? 0; $vmObj->ram_mb = $vmData['memory_size_MiB'] ?? 0; $vmObj->datacenter_id = $datacenterId; $vmObj->host_id = $hostId; $vmObj->folder = $vmData['folder'] ?? null; $vmObj->last_synced_at = now(); $vmObj->save(); $count++; } return $count; } }