Refactor VM creation and configuration process
- 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.
This commit is contained in:
@@ -2,14 +2,13 @@
|
||||
|
||||
namespace App\Http\Controllers\Api\Service;
|
||||
|
||||
use App\Actions\VM\ChangeIpVMAction;
|
||||
use App\Actions\VM\ChangePortVMAction;
|
||||
use App\Actions\VM\PowerOffVMAction;
|
||||
use App\Actions\VM\PowerOnVMAction;
|
||||
use App\Http\Controllers\Api\Service\Concerns\ResolvesVm;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Services\Telegram;
|
||||
use App\Http\Services\vCenter;
|
||||
use App\Jobs\VirtualMachine\ChangeIpVMJob;
|
||||
use App\Jobs\VirtualMachine\ChangeVmPasswordJob;
|
||||
use App\Models\ModuleVmware;
|
||||
use App\Models\Os;
|
||||
@@ -19,7 +18,6 @@ use App\Services\VmProvisionService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class VmController extends Controller
|
||||
{
|
||||
@@ -124,7 +122,10 @@ class VmController extends Controller
|
||||
* ip_address string New IP to assign
|
||||
* gateway string (optional) Gateway — falls back to existing IP record
|
||||
*/
|
||||
public function changeIp(Request $request, ChangeIpVMAction $action): JsonResponse
|
||||
/**
|
||||
* Dispatches ChangeIpVMJob — returns immediately, runs async.
|
||||
*/
|
||||
public function changeIp(Request $request): JsonResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'server_name' => ['required', 'string', 'max:255'],
|
||||
@@ -165,87 +166,35 @@ class VmController extends Controller
|
||||
: 'windows';
|
||||
|
||||
$gateway = $validated['gateway'] ?? '';
|
||||
$dns = $validated['dns'] ?? '8.8.8.8';
|
||||
|
||||
$dns = $validated['dns'] ?? '8.8.8.8';
|
||||
|
||||
$lock = $this->acquireVmLock($vm, 120);
|
||||
// ponytail: don't release — lock expires after 5 min while the async job runs
|
||||
$lock = $this->acquireVmLock($vm, 300);
|
||||
if (!$lock) {
|
||||
return $this->vmLocked();
|
||||
}
|
||||
|
||||
try {
|
||||
$raw = $action->execute(
|
||||
$vm,
|
||||
$validated['ip_address'],
|
||||
$gateway,
|
||||
$osType,
|
||||
$dns,
|
||||
$validated['guest_user'],
|
||||
$validated['guest_password']
|
||||
);
|
||||
} finally {
|
||||
$lock->release();
|
||||
}
|
||||
|
||||
// Always log the raw PowerShell output for debugging
|
||||
Log::channel('Custom')->info('[changeIp] raw output', [
|
||||
'server_name' => $validated['server_name'],
|
||||
'ip_address' => $validated['ip_address'],
|
||||
'gateway' => $gateway,
|
||||
'os_type' => $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 [{$osType}]\n"
|
||||
. "🖥 VM: {$vm->name} ({$vm->vmware_id})\n"
|
||||
. "📍 IP mới: {$validated['ip_address']}\n"
|
||||
. "🔗 GW: {$gateway}\n"
|
||||
. "🚫 Lỗi: {$errMsg}");
|
||||
|
||||
return response()->json(['success' => false, 'message' => $errMsg], 400);
|
||||
}
|
||||
|
||||
if (str_starts_with((string) $raw, 'Error:') || str_contains((string) $raw, '[STDERR]')) {
|
||||
$telegram->SendErrorMessage("❌ Đổi IP thất bại [{$osType}]\n"
|
||||
. "🖥 VM: {$vm->name} ({$vm->vmware_id})\n"
|
||||
. "📍 IP mới: {$validated['ip_address']}\n"
|
||||
. "🔗 GW: {$gateway}\n"
|
||||
. "📋 Output:\n" . mb_substr((string) $raw, 0, 800));
|
||||
|
||||
return response()->json(['success' => false, 'message' => 'Lệnh đổi IP thất bại. Admin đã được thông báo.', 'data' => ['raw' => $raw]], 400);
|
||||
}
|
||||
|
||||
// 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 [{$osType}] - Script chạy nhưng không có output\n"
|
||||
. "🖥 VM: {$vm->name} ({$vm->vmware_id})\n"
|
||||
. "📍 IP mới: {$validated['ip_address']}\n"
|
||||
. "🔗 GW: {$gateway}\n"
|
||||
. "ℹ️ Kiểm tra lại VM để xác nhận IP đã thay đổi chưa.");
|
||||
}
|
||||
ChangeIpVMJob::dispatch(
|
||||
$vm->id,
|
||||
$validated['ip_address'],
|
||||
$gateway,
|
||||
$osType,
|
||||
$dns,
|
||||
$validated['guest_user'],
|
||||
$validated['guest_password'],
|
||||
);
|
||||
|
||||
$this->activityLogger->log(
|
||||
event: 'change_ip',
|
||||
logName: 'VM',
|
||||
description: "Customer {$request->user()->email} đổi IP VM: {$vm->name} → {$validated['ip_address']}",
|
||||
description: "Customer {$request->user()->email} yêu cầu đổi IP VM: {$vm->name} → {$validated['ip_address']}",
|
||||
subject: $vm,
|
||||
newValues: ['ip_address' => $validated['ip_address'], 'gateway' => $gateway, 'os_type' => $osType],
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Đã gửi lệnh đổi IP.',
|
||||
'data' => ['raw' => $raw],
|
||||
'message' => 'Yêu cầu đổi IP đã được ghi nhận. Hệ thống sẽ xử lý trong vài phút.',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user