update assign ip windows

This commit is contained in:
Pham Bao
2025-07-29 23:49:33 +07:00
parent 21a2dfe855
commit 5d6e2060a8
4 changed files with 132 additions and 28 deletions
+50 -17
View File
@@ -456,9 +456,11 @@ class vCenter
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 = Http::withoutVerifying()
->timeout(120)
->connectTimeout(120)
->timeout(300) // Tăng timeout lên 5 phút cho quá trình clone
->connectTimeout(30) // Giữ connect timeout ngắn để phát hiện lỗi kết nối sớm
->withHeaders([
'vmware-api-session-id' => $this->token,
'Content-Type' => 'application/json',
@@ -2130,29 +2132,60 @@ class vCenter
public function assignIPWindows($product, $vmware_id = ''): array|string
{
try {
// Kiểm tra null safety
if (!$product || !$product->ipAddress || !$product->ipAddress->host || !$product->ipAddress->host->datacenter || !$product->ipAddress->host->datacenter->vCenter) {
// Support both old Product structure and new ModuleVmware structure
$ipAddress = null;
$gateway = null;
$netmask = '255.255.255.0';
$dns = '8.8.8.8';
$vmware_name = '';
$vCenter = null;
// Check if it's ModuleVmware (new structure)
if ($product && isset($product->ipAddress) && $product->ipAddress) {
Log::info('✅ Using ModuleVmware structure for assignIPWindows', [
'module_vmware_id' => $product->id,
'vmware_id' => $vmware_id
]);
// Extract from ModuleVmware->ipAddress relationship
$ipAddress = $product->ipAddress->ip ?? null;
$gateway = $product->ipAddress->gateway ?? null;
$netmask = $product->ipAddress->netmask ?? '255.255.255.0';
$dns = $product->ipAddress->dns ?? '8.8.8.8';
$vmware_name = $product->name ?? $vmware_id;
$vCenter = $product->ipAddress->host->datacenter->vCenter ?? null;
} elseif ($product && isset($product->IpAddress) && $product->IpAddress) {
Log::info('✅ Using old Product structure for assignIPWindows', [
'product_id' => $product->id,
'vmware_id' => $vmware_id
]);
// Extract from old Product->IpAddress relationship
$ipAddress = $product->IpAddress->ip ?? null;
$gateway = $product->IpAddress->gateway ?? null;
$netmask = $product->IpAddress->netmask ?? '255.255.255.0';
$dns = $product->IpAddress->dns ?? '8.8.8.8';
$vmware_name = $product->name ?? $vmware_id;
$vCenter = $product->IpAddress->Host->Datacenter->vCenter ?? null;
}
// Validate required data
if (!$ipAddress || !$gateway || !$vCenter) {
Log::error('❌ assignIPWindows: Missing required data', [
'vmware_id' => $vmware_id,
'product_id' => $product?->id ?? 'unknown',
'ip_address' => $product?->ipAddress?->ip ?? 'unknown',
'host' => $product?->ipAddress?->host?->name ?? 'unknown',
'datacenter' => $product?->ipAddress?->host?->datacenter?->name ?? 'unknown',
'vcenter' => $product?->ipAddress?->host?->datacenter?->vCenter?->host ?? 'unknown'
'ip_address' => $ipAddress,
'gateway' => $gateway,
'has_vcenter' => $vCenter ? 'yes' : 'no',
'product_class' => get_class($product)
]);
return [
'error' => true,
'data' => 'Missing required data for IP assignment'
'data' => 'Missing required data for IP assignment (IP, Gateway, or vCenter)'
];
}
$this->SetConfig($product->ipAddress->host->datacenter->vCenter);
$vmware_name = (string) $product->name;
$ipAddress = $product->ipAddress->ip;
$gateway = $product->ipAddress->gateway;
$netmask = $product->ipAddress->netmask ?? '255.255.255.0';
$dns = $product->ipAddress->dns ?? '8.8.8.8';
$this->SetConfig($vCenter);
// Convert netmask to prefix length (e.g., 255.255.255.0 = 24)
$maskBits = $this->convertNetmaskToPrefixLength($netmask);
@@ -44,8 +44,48 @@ class CheckIPAddress implements ShouldQueue
throw new \Exception(json_encode($DetailVirtualMachine['message']));
}
if (!$DetailVirtualMachine['data']['ip_address'] === $this->data->IpAddress->ip) {
throw new \Exception(json_encode($DetailVirtualMachine['message']));
// Get expected IP address with null safety
$expectedIP = null;
// Try to get IP from old relationship first
if ($this->data && isset($this->data->IpAddress) && $this->data->IpAddress) {
$expectedIP = $this->data->IpAddress->ip;
}
// If no IP from old relationship, try to get from ModuleVmware
if (!$expectedIP && $this->data) {
// Try to find ModuleVmware by vmware_id
$moduleVmware = \App\Models\ModuleVmware::with('ipAddress')
->where('vmware_id', $this->vmware_id)
->first();
if ($moduleVmware && $moduleVmware->ipAddress) {
$expectedIP = $moduleVmware->ipAddress->ip;
}
}
// If still no expected IP, log warning but don't fail
if (!$expectedIP) {
\Illuminate\Support\Facades\Log::warning('⚠️ Không tìm thấy expected IP cho VM', [
'vmware_id' => $this->vmware_id,
'data_class' => $this->data ? get_class($this->data) : 'null',
'has_ip_address_relation' => isset($this->data->IpAddress) && $this->data->IpAddress ? 'yes' : 'no'
]);
// Skip IP check and continue to next job
$jobs_configDB = new ConfigDatabase($this->data, $this->info);
dispatch($jobs_configDB)->delay(now()->addSeconds(5));
return;
}
// Compare actual vs expected IP
if ($DetailVirtualMachine['data']['ip_address'] !== $expectedIP) {
\Illuminate\Support\Facades\Log::warning('⚠️ IP address mismatch', [
'vmware_id' => $this->vmware_id,
'actual_ip' => $DetailVirtualMachine['data']['ip_address'],
'expected_ip' => $expectedIP
]);
throw new \Exception('IP address mismatch: actual=' . $DetailVirtualMachine['data']['ip_address'] . ', expected=' . $expectedIP);
}
$jobs_configDB = new ConfigDatabase($this->data,$this->info);
dispatch($jobs_configDB)->delay(now()->addSeconds(5));
@@ -247,11 +247,7 @@ class CreateVirtualMachineJob implements ShouldQueue
'customer_id' => $customer->id,
'status' => 1
]);
// 4. Cập nhật product với module_vmware_id
$product->module_vmware_id = $moduleVmware->id;
$product->save();
Log::info('✅ Lưu dữ liệu VM và IP address thành công', [
'vmware_id' => $vmId,
'module_vmware_id' => $moduleVmware->id,
@@ -163,11 +163,18 @@ class ProcessOrderPaymentJob implements ShouldQueue
// Thử lại nếu chưa vượt quá số lần thử
if ($this->retryCount < self::MAX_RETRIES) {
Log::warning("Có lỗi khi tạo VM, thử lại lần " . ($this->retryCount + 1), $errorDetails);
// Kiểm tra nếu lỗi là timeout, tăng delay time
$isTimeoutError = $this->isTimeoutError($failedVMs);
$delayMinutes = $isTimeoutError ? 10 : 5; // Timeout thì chờ 10 phút, lỗi khác chờ 5 phút
Log::warning("Có lỗi khi tạo VM, thử lại lần " . ($this->retryCount + 1), array_merge($errorDetails, [
'is_timeout_error' => $isTimeoutError,
'delay_minutes' => $delayMinutes
]));
// Thử lại sau 5 phút
// Thử lại với delay tùy theo loại lỗi
self::dispatch($this->order, $this->retryCount + 1)
->delay(now()->addMinutes(5));
->delay(now()->addMinutes($delayMinutes));
} else {
// Đã thử hết số lần, gửi thông báo lỗi
Log::error("Đã thử tạo VM {$this->retryCount} lần nhưng vẫn thất bại", $errorDetails);
@@ -183,9 +190,14 @@ class ProcessOrderPaymentJob implements ShouldQueue
}
} catch (\Throwable $e) {
$isTimeoutException = strpos(strtolower($e->getMessage()), 'timeout') !== false ||
strpos(strtolower($e->getMessage()), 'curl error 28') !== false;
Log::error("Lỗi trong ProcessOrderPaymentJob: " . $e->getMessage(), [
'order_id' => $this->order->id,
'order_num' => $this->order->order_num,
'is_timeout' => $isTimeoutException,
'retry_count' => $this->retryCount,
'trace' => $e->getTraceAsString()
]);
@@ -194,7 +206,9 @@ class ProcessOrderPaymentJob implements ShouldQueue
'order_id' => $this->order->id,
'order_num' => $this->order->order_num,
'file' => $e->getFile(),
'line' => $e->getLine()
'line' => $e->getLine(),
'is_timeout' => $isTimeoutException,
'retry_count' => $this->retryCount
], 'ProcessOrderPaymentJob - Exception');
}
}
@@ -243,6 +257,27 @@ class ProcessOrderPaymentJob implements ShouldQueue
}
}
/**
* Check if the error is a timeout error
*/
private function isTimeoutError(array $failedVMs): bool
{
foreach ($failedVMs as $vmResult) {
if (isset($vmResult['error'])) {
$errorMessage = strtolower($vmResult['error']);
// Kiểm tra các dấu hiệu của timeout error
if (strpos($errorMessage, 'timeout') !== false ||
strpos($errorMessage, 'curl error 28') !== false ||
strpos($errorMessage, 'operation timed out') !== false ||
strpos($errorMessage, 'connection timeout') !== false) {
return true;
}
}
}
return false;
}
/**
* Send failure notification to customer
*/