Files
portal-api/app/Jobs/VirtualMachine/Create/AssignIPJob.php
T
2025-07-29 22:49:14 +07:00

245 lines
9.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Jobs\VirtualMachine\Create;
use App\Http\Services\Telegram;
use App\Http\Services\vCenter;
use App\Models\ModuleVmware;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Http;
class AssignIPJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public string $vmId;
public int $moduleVmwareId;
public string $availableIP;
/**
* Create a new job instance.
*/
public function __construct(string $vmId, int $moduleVmwareId, string $availableIP)
{
$this->vmId = $vmId;
$this->moduleVmwareId = $moduleVmwareId;
$this->availableIP = $availableIP;
}
/**
* Execute the job.
*/
public function handle(vCenter $vCenter, Telegram $telegram)
{
try {
Log::info('🔧 Bắt đầu AssignIPJob', [
'vm_id' => $this->vmId,
'module_vmware_id' => $this->moduleVmwareId,
'assigned_ip' => $this->availableIP
]);
// Lấy thông tin ModuleVmware
$moduleVmware = ModuleVmware::with(['ipAddress.host.datacenter.vCenter'])->find($this->moduleVmwareId);
if (!$moduleVmware || !$moduleVmware->ipAddress) {
Log::error('❌ Không tìm thấy ModuleVmware hoặc IP address', [
'vm_id' => $this->vmId,
'module_vmware_id' => $this->moduleVmwareId
]);
$telegram->SendErrorMessage([
'error' => 'ModuleVmware or IP address not found',
'vm_id' => $this->vmId,
'module_vmware_id' => $this->moduleVmwareId
], 'AssignIPJob - Data Not Found');
return;
}
// Login vào vCenter
$vcenter = $moduleVmware->ipAddress->host->datacenter->vCenter;
if (!$vCenter->loginServer($vcenter)) {
Log::error('❌ Không thể login vào vCenter cho AssignIP', [
'vm_id' => $this->vmId,
'vcenter_host' => $vcenter->host
]);
$telegram->SendErrorMessage([
'error' => 'Cannot login to vCenter',
'vm_id' => $this->vmId,
'vcenter_host' => $vcenter->host
], 'AssignIPJob - vCenter Login Failed');
return;
}
// Kiểm tra OS family và assign IP
$this->handleIPAssignment($vCenter, $this->vmId, $moduleVmware, $this->availableIP, $telegram);
} catch (\Throwable $e) {
Log::error('❌ Lỗi trong AssignIPJob: ' . $e->getMessage(), [
'vm_id' => $this->vmId,
'module_vmware_id' => $this->moduleVmwareId,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
$telegram->SendErrorMessage([
'error' => $e->getMessage(),
'vm_id' => $this->vmId,
'module_vmware_id' => $this->moduleVmwareId,
'file' => $e->getFile(),
'line' => $e->getLine()
], 'AssignIPJob - Exception');
}
}
/**
* Handle IP assignment based on OS family
*/
private function handleIPAssignment(vCenter $vCenter, string $vmId, ModuleVmware $moduleVmware, string $availableIP, Telegram $telegram): void
{
try {
// Kiểm tra OS family trước khi assign IP
$osFamily = $this->checkVMOSFamily($vCenter, $vmId);
if ($osFamily === 'WINDOWS') {
Log::info('✅ Phát hiện Windows VM, bắt đầu assign IP', [
'vm_id' => $vmId,
'os_family' => $osFamily,
'assigned_ip' => $availableIP
]);
// Assign IP cho Windows VM
$assignIPResult = $vCenter->assignIPWindows($moduleVmware, $vmId);
if (is_array($assignIPResult) && !$assignIPResult['error']) {
Log::info('✅ Assign IP Windows thành công', [
'vm_id' => $vmId,
'result' => $assignIPResult['data']
]);
$telegram->SendJobRunInfo(
'AssignIPWindows',
'success',
[
'vm_id' => $vmId,
'assigned_ip' => $availableIP,
'result' => $assignIPResult['data']
]
);
} else {
Log::warning('⚠️ Assign IP Windows thất bại', [
'vm_id' => $vmId,
'error' => $assignIPResult['data'] ?? 'Unknown error'
]);
$telegram->SendErrorMessage([
'error' => 'Assign IP Windows failed',
'vm_id' => $vmId,
'details' => $assignIPResult['data'] ?? 'Unknown error'
], 'AssignIPWindows - Failed');
}
} elseif ($osFamily === 'LINUX' || $osFamily === 'OTHER') {
Log::info('ℹ️ Phát hiện non-Windows VM, hệ thống đang nâng cấp', [
'vm_id' => $vmId,
'os_family' => $osFamily
]);
$telegram->SendJobRunInfo(
'AssignIP',
'upgrade',
[
'vm_id' => $vmId,
'os_family' => $osFamily,
'message' => 'Hệ thống đang nâng cấp để hỗ trợ IP assignment cho ' . $osFamily
]
);
} else {
Log::warning('⚠️ Không thể xác định OS family', [
'vm_id' => $vmId,
'os_family' => $osFamily
]);
$telegram->SendErrorMessage([
'error' => 'Cannot determine OS family',
'vm_id' => $vmId,
'os_family' => $osFamily
], 'AssignIP - Unknown OS');
}
} catch (\Exception $e) {
Log::error('❌ Lỗi khi handle IP assignment: ' . $e->getMessage(), [
'vm_id' => $vmId,
'error' => $e->getMessage()
]);
$telegram->SendErrorMessage([
'error' => 'IP Assignment handling failed',
'vm_id' => $vmId,
'details' => $e->getMessage()
], 'HandleIPAssignment - Exception');
}
}
/**
* Check VM OS family using vCenter API
*/
private function checkVMOSFamily(vCenter $vCenter, string $vmId): string
{
try {
// Kiểm tra session còn valid không
$check = $vCenter->checkApiExits();
if (!$check) {
Log::warning('vCenter session expired, cannot check OS family');
return 'UNKNOWN';
}
// Gọi API để lấy guest identity
$response = Http::withoutVerifying()
->withHeaders([
'vmware-api-session-id' => $vCenter->token
])
->get("https://{$vCenter->apiUri}/rest/vcenter/vm/{$vmId}/guest/identity");
if ($response->successful()) {
$data = $response->json();
if (isset($data['value']['family'])) {
$family = strtoupper($data['value']['family']);
Log::info('✅ Phát hiện OS family', [
'vm_id' => $vmId,
'family' => $family,
'full_name' => $data['value']['full_name'] ?? 'Unknown'
]);
return $family;
} else {
Log::warning('⚠️ Không tìm thấy family trong response', [
'vm_id' => $vmId,
'response' => $data
]);
return 'UNKNOWN';
}
} else {
Log::warning('⚠️ API call thất bại khi check OS family', [
'vm_id' => $vmId,
'status' => $response->status(),
'response' => $response->body()
]);
return 'UNKNOWN';
}
} catch (\Exception $e) {
Log::error('❌ Exception khi check OS family: ' . $e->getMessage(), [
'vm_id' => $vmId,
'error' => $e->getMessage()
]);
return 'UNKNOWN';
}
}
}