- VmProvisionException/VmProvisionRefund xử lý lỗi cấp phát VM - QueueJobInspector + QueueMonitorController xem chi tiết job - Thêm service uuid cho ticket, thời lượng cho activity_logs - Migration chuẩn hoá RAM addon sang MB, trạng thái deleting cho snapshot Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
134 lines
4.4 KiB
PHP
134 lines
4.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Service\Concerns;
|
|
|
|
use App\Http\Services\vCenter;
|
|
use App\Jobs\VirtualMachine\ChangeVmPasswordJob;
|
|
use App\Models\Os;
|
|
use App\Services\VmProvisionService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Validation\Rule;
|
|
|
|
trait ManagesVmAccess
|
|
{
|
|
private const CLICK_LABELS = [
|
|
'snapshot' => 'Snapshot',
|
|
'change-password' => 'Đổi mật khẩu',
|
|
'change-ip' => 'Đổi IP',
|
|
'change-port' => 'Đổi Remote Port',
|
|
'renew' => 'Gia hạn',
|
|
'console' => 'Truy cập console',
|
|
'rebuild' => 'Rebuild máy chủ',
|
|
'addons' => 'Addons',
|
|
];
|
|
|
|
public function actionClick(Request $request): JsonResponse
|
|
{
|
|
$data = $request->validate([
|
|
'product' => 'required',
|
|
'action' => ['required', 'string', Rule::in(array_keys(self::CLICK_LABELS))],
|
|
]);
|
|
|
|
$vm = $this->resolveVmById($data['product'], $request);
|
|
if ($vm instanceof JsonResponse) {
|
|
return $vm;
|
|
}
|
|
|
|
$this->activityLogger->log(
|
|
event: 'click_' . str_replace('-', '_', $data['action']),
|
|
logName: 'VM',
|
|
description: "Customer {$request->user()->email} bấm \"" . self::CLICK_LABELS[$data['action']] . "\" trên VM: {$vm->name} (ID: {$vm->vmware_id})",
|
|
subject: $vm,
|
|
newValues: ['action' => $data['action']],
|
|
);
|
|
|
|
return response()->json(['success' => true]);
|
|
}
|
|
|
|
public function consoleTicket(Request $request, vCenter $serviceVCenter): JsonResponse
|
|
{
|
|
$productId = $request->get('product');
|
|
if (!$productId) {
|
|
return response()->json(['error' => true, 'message' => 'Please choose product']);
|
|
}
|
|
|
|
$vm = $this->resolveVmById($productId, $request);
|
|
if ($vm instanceof JsonResponse) {
|
|
return $vm;
|
|
}
|
|
|
|
$result = $this->getConsoleTicket($serviceVCenter, $vm);
|
|
if ($result instanceof JsonResponse) {
|
|
return $result;
|
|
}
|
|
|
|
$this->activityLogger->log(
|
|
event: 'console_access',
|
|
logName: 'VM',
|
|
description: "Customer {$request->user()->email} truy cập console VM: {$vm->name} (ID: {$vm->vmware_id})",
|
|
subject: $vm,
|
|
newValues: ['product_id' => $productId, 'vm_name' => $vm->name],
|
|
);
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'data' => $result['data'],
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* POST /v1/system/vm-change-password
|
|
*
|
|
* Body: { product, current_password, new_password }
|
|
* Dispatches ChangeVmPasswordJob — returns immediately, runs async.
|
|
*/
|
|
public function changePassword(Request $request): JsonResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'product' => ['required'],
|
|
'current_password' => ['required', 'string'],
|
|
'new_password' => ['required', 'string', 'min:12', 'max:64', 'regex:/^[A-Za-z0-9!@#^*_+=?.,:~]+$/'],
|
|
]);
|
|
|
|
$vm = $this->resolveVmById($validated['product'], $request);
|
|
if ($vm instanceof JsonResponse) {
|
|
return $vm;
|
|
}
|
|
|
|
// ponytail: don't release — lock expires after 5 min while the async job runs
|
|
$lock = $this->acquireVmLock($vm, 300);
|
|
if (!$lock) {
|
|
return $this->vmLocked();
|
|
}
|
|
|
|
// Detect OS family from VM's os_id record
|
|
$os = $vm->os_id ? Os::with('osGroup')->find($vm->os_id) : null;
|
|
$osGroupName = strtolower($os?->osGroup?->name ?? '');
|
|
$osFamily = str_contains($osGroupName, 'windows')
|
|
? VmProvisionService::OS_WINDOWS
|
|
: VmProvisionService::OS_LINUX;
|
|
|
|
ChangeVmPasswordJob::dispatch(
|
|
$vm->id,
|
|
$vm->vmware_id,
|
|
$osFamily,
|
|
$validated['new_password'],
|
|
$validated['current_password'],
|
|
);
|
|
|
|
$this->activityLogger->log(
|
|
event: 'change_password',
|
|
logName: 'VM',
|
|
description: "Customer {$request->user()->email} yêu cầu đổi mật khẩu VM: {$vm->name}",
|
|
subject: $vm,
|
|
newValues: ['os_family' => $osFamily],
|
|
);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Yêu cầu đổi mật khẩu đã được ghi nhận. Hệ thống sẽ xử lý trong vài phút.',
|
|
]);
|
|
}
|
|
}
|