update assign ip windows
This commit is contained in:
@@ -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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user