- Updated VpsServiceResource to return product UUID instead of ID. - Modified VirtualMachineService to utilize product data for CPU, RAM, and disk settings. - Replaced AssignIpToGuestJob with UpdateVmConfigJob in CreateVirtualMachineJob to streamline VM configuration after cloning. - Adjusted AssignIpToGuestJob to remove unnecessary UpdateVmConfigJob dispatch and focus on IP assignment. - Enhanced UpdateVmConfigJob to handle CPU/RAM configuration and power cycling more effectively. - Introduced ChangeIpVMJob for handling customer-initiated IP changes asynchronously. - Updated InvoiceRepository to set invoice due date based on maximum months instead of a fixed 7 days. - Improved web design quote PDF layout for better readability. - Added Times-Roman font metrics for PDF generation.
121 lines
4.2 KiB
PHP
121 lines
4.2 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace App\Jobs\VirtualMachine;
|
||
|
||
use App\Actions\VM\ChangeIpVMAction;
|
||
use App\Http\Services\Telegram;
|
||
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;
|
||
|
||
/**
|
||
* ChangeIpVMJob
|
||
*
|
||
* Customer-initiated VM IP change. Runs the same ChangeIpVMAction that used
|
||
* to execute synchronously inside VmController::changeIp — moved to a queued
|
||
* job so the SSH → PowerCLI round trip can no longer blow past nginx/php-fpm's
|
||
* timeout and surface as a 502.
|
||
*/
|
||
class ChangeIpVMJob implements ShouldQueue
|
||
{
|
||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||
|
||
/** No auto-retry — mirrors the previous synchronous behaviour (single attempt). */
|
||
public int $tries = 1;
|
||
public int $timeout = 180;
|
||
|
||
public function __construct(
|
||
public readonly int $moduleVmwareId,
|
||
public readonly string $ipAddress,
|
||
public readonly string $gateway,
|
||
public readonly string $osType,
|
||
public readonly string $dns,
|
||
public readonly string $guestUser,
|
||
public readonly string $guestPassword,
|
||
) {}
|
||
|
||
public function handle(ChangeIpVMAction $action): void
|
||
{
|
||
$vm = ModuleVmware::with([
|
||
'vCenter',
|
||
'ipAddress.host.datacenter.vCenter',
|
||
])->find($this->moduleVmwareId);
|
||
|
||
if (!$vm) {
|
||
Log::error('[ChangeIpVMJob] ModuleVmware not found', ['module_vmware_id' => $this->moduleVmwareId]);
|
||
return;
|
||
}
|
||
|
||
$raw = $action->execute(
|
||
$vm,
|
||
$this->ipAddress,
|
||
$this->gateway,
|
||
$this->osType,
|
||
$this->dns,
|
||
$this->guestUser,
|
||
$this->guestPassword,
|
||
);
|
||
|
||
Log::channel('Custom')->info('[ChangeIpVMJob] raw output', [
|
||
'module_vmware_id' => $this->moduleVmwareId,
|
||
'ip_address' => $this->ipAddress,
|
||
'gateway' => $this->gateway,
|
||
'os_type' => $this->osType,
|
||
'vm_name' => $vm->name,
|
||
'vmware_id' => $vm->vmware_id,
|
||
'raw' => $raw,
|
||
]);
|
||
|
||
$telegram = new Telegram();
|
||
|
||
if ($raw === 'Login_Again' || $raw === 'vCenter_Not_Found') {
|
||
$errMsg = $raw === 'vCenter_Not_Found'
|
||
? 'Không tìm thấy vCenter cho VM này.'
|
||
: 'Không thể đăng nhập vào vCenter.';
|
||
|
||
$telegram->SendErrorMessage("❌ Đổi IP thất bại [{$this->osType}]\n"
|
||
. "🖥 VM: {$vm->name} ({$vm->vmware_id})\n"
|
||
. "📍 IP mới: {$this->ipAddress}\n"
|
||
. "🔗 GW: {$this->gateway}\n"
|
||
. "🚫 Lỗi: {$errMsg}");
|
||
|
||
return;
|
||
}
|
||
|
||
if (str_starts_with((string) $raw, 'Error:') || str_contains((string) $raw, '[STDERR]')) {
|
||
$telegram->SendErrorMessage("❌ Đổi IP thất bại [{$this->osType}]\n"
|
||
. "🖥 VM: {$vm->name} ({$vm->vmware_id})\n"
|
||
. "📍 IP mới: {$this->ipAddress}\n"
|
||
. "🔗 GW: {$this->gateway}\n"
|
||
. "📋 Output:\n" . mb_substr((string) $raw, 0, 800));
|
||
|
||
return;
|
||
}
|
||
|
||
// Empty raw = script chạy không có output → coi là thành công (PowerShell script không echo)
|
||
// Nhưng vẫn gửi cảnh báo để theo dõi
|
||
if (trim((string) $raw) === '') {
|
||
$telegram->SendMessage("⚠️ Đổi IP [{$this->osType}] - Script chạy nhưng không có output\n"
|
||
. "🖥 VM: {$vm->name} ({$vm->vmware_id})\n"
|
||
. "📍 IP mới: {$this->ipAddress}\n"
|
||
. "🔗 GW: {$this->gateway}\n"
|
||
. "ℹ️ Kiểm tra lại VM để xác nhận IP đã thay đổi chưa.");
|
||
}
|
||
}
|
||
|
||
public function failed(\Throwable $e): void
|
||
{
|
||
Log::error('[ChangeIpVMJob] job failed with exception', [
|
||
'module_vmware_id' => $this->moduleVmwareId,
|
||
'ip_address' => $this->ipAddress,
|
||
'error' => $e->getMessage(),
|
||
]);
|
||
}
|
||
}
|