Implement VM deletion functionality and update related services; add confirmation check and logging
This commit is contained in:
@@ -313,20 +313,20 @@ class VCenterManagerController extends Controller
|
||||
{
|
||||
$vcenterId = $request->input('vcenter_id');
|
||||
$vcenter = $this->vCenterRepo->find($vcenterId);
|
||||
|
||||
|
||||
if (!$vcenter) {
|
||||
return response()->json(['error' => 'vCenter not found'], 404);
|
||||
}
|
||||
|
||||
$vcenterService = new \App\Http\Services\vCenter();
|
||||
$loginResult = $vcenterService->loginServer($vcenter);
|
||||
|
||||
|
||||
if (!$loginResult) {
|
||||
return response()->json(['error' => 'Cannot login to vCenter'], 400);
|
||||
}
|
||||
|
||||
$datacenters = $vcenterService->getAllDatacenter();
|
||||
|
||||
|
||||
if ($datacenters === false || $datacenters === 'Login_Again') {
|
||||
return response()->json(['error' => 'Cannot get datacenters'], 400);
|
||||
}
|
||||
@@ -341,9 +341,9 @@ class VCenterManagerController extends Controller
|
||||
{
|
||||
$vcenterId = $request->input('vcenter_id');
|
||||
$datacenterId = $request->input('datacenter_id');
|
||||
|
||||
|
||||
$vcenter = $this->vCenterRepo->find($vcenterId);
|
||||
|
||||
|
||||
if (!$vcenter) {
|
||||
return response()->json(['error' => 'vCenter not found'], 404);
|
||||
}
|
||||
@@ -352,7 +352,7 @@ class VCenterManagerController extends Controller
|
||||
$vcenterService->loginServer($vcenter);
|
||||
|
||||
$hosts = $vcenterService->getAllHost($datacenterId);
|
||||
|
||||
|
||||
if ($hosts === false || $hosts === 'Login_Again') {
|
||||
return response()->json(['error' => 'Cannot get hosts'], 400);
|
||||
}
|
||||
@@ -367,9 +367,9 @@ class VCenterManagerController extends Controller
|
||||
{
|
||||
$vcenterId = $request->input('vcenter_id');
|
||||
$hostId = $request->input('host_id');
|
||||
|
||||
|
||||
$vcenter = $this->vCenterRepo->find($vcenterId);
|
||||
|
||||
|
||||
if (!$vcenter) {
|
||||
return response()->json(['error' => 'vCenter not found'], 404);
|
||||
}
|
||||
@@ -445,15 +445,15 @@ class VCenterManagerController extends Controller
|
||||
public function powerOn(Request $request)
|
||||
{
|
||||
$vmId = (int) $request->input('vm_id');
|
||||
|
||||
|
||||
$vm = VirtualMachines::find($vmId);
|
||||
|
||||
|
||||
if (!$vm) {
|
||||
return response()->json(['error' => true, 'message' => 'VM not found'], 404);
|
||||
}
|
||||
|
||||
$vmwareId = $vm->vm_id;
|
||||
|
||||
|
||||
if (!$vmwareId) {
|
||||
return response()->json(['error' => true, 'message' => 'VM VMware ID not found'], 400);
|
||||
}
|
||||
@@ -463,7 +463,7 @@ class VCenterManagerController extends Controller
|
||||
}
|
||||
|
||||
$vcenter = null;
|
||||
|
||||
|
||||
if ($vm->datacenter?->vCenter) {
|
||||
$vcenter = $vm->datacenter->vCenter;
|
||||
}
|
||||
@@ -477,7 +477,7 @@ class VCenterManagerController extends Controller
|
||||
}
|
||||
|
||||
$vCenterService = new \App\Http\Services\vCenter();
|
||||
|
||||
|
||||
if (!$vCenterService->loginServer($vcenter)) {
|
||||
return response()->json(['error' => true, 'message' => 'Cannot login to vCenter'], 400);
|
||||
}
|
||||
@@ -505,15 +505,15 @@ class VCenterManagerController extends Controller
|
||||
public function powerOff(Request $request)
|
||||
{
|
||||
$vmId = (int) $request->input('vm_id');
|
||||
|
||||
|
||||
$vm = VirtualMachines::find($vmId);
|
||||
|
||||
|
||||
if (!$vm) {
|
||||
return response()->json(['error' => true, 'message' => 'VM not found'], 404);
|
||||
}
|
||||
|
||||
$vmwareId = $vm->vm_id;
|
||||
|
||||
|
||||
if (!$vmwareId) {
|
||||
return response()->json(['error' => true, 'message' => 'VM VMware ID not found'], 400);
|
||||
}
|
||||
@@ -523,7 +523,7 @@ class VCenterManagerController extends Controller
|
||||
}
|
||||
|
||||
$vcenter = null;
|
||||
|
||||
|
||||
if ($vm->datacenter?->vCenter) {
|
||||
$vcenter = $vm->datacenter->vCenter;
|
||||
}
|
||||
@@ -537,7 +537,7 @@ class VCenterManagerController extends Controller
|
||||
}
|
||||
|
||||
$vCenterService = new \App\Http\Services\vCenter();
|
||||
|
||||
|
||||
if (!$vCenterService->loginServer($vcenter)) {
|
||||
return response()->json(['error' => true, 'message' => 'Cannot login to vCenter'], 400);
|
||||
}
|
||||
@@ -683,19 +683,28 @@ class VCenterManagerController extends Controller
|
||||
|
||||
public function suspend(Request $request)
|
||||
{
|
||||
$vmId = $request->input('vm_id');
|
||||
$vmId = (int) $request->input('vm_id');
|
||||
|
||||
$vm = VirtualMachines::where('vm_id', $vmId)->first();
|
||||
// vm_id from frontend = services.vm_id = module_vmware.id (FK)
|
||||
$vmware = ModuleVmware::with('vCenter')->find($vmId);
|
||||
|
||||
if (!$vm) {
|
||||
if (!$vmware) {
|
||||
return response()->json(['error' => true, 'message' => 'VM not found'], 404);
|
||||
}
|
||||
|
||||
if ($vm->power_state === 'SUSPENDED') {
|
||||
$vmwareId = $vmware->vmware_id;
|
||||
|
||||
if (!$vmwareId) {
|
||||
return response()->json(['error' => true, 'message' => 'VM VMware ID not found'], 400);
|
||||
}
|
||||
|
||||
$vm = VirtualMachines::where('vm_id', $vmwareId)->first();
|
||||
|
||||
if ($vm?->power_state === 'SUSPENDED') {
|
||||
return response()->json(['error' => true, 'message' => 'VM is already suspended'], 400);
|
||||
}
|
||||
|
||||
$vcenter = $vm->datacenter?->vCenter ?? $vm->host?->datacenter?->vCenter;
|
||||
$vcenter = $vmware->vCenter;
|
||||
|
||||
if (!$vcenter) {
|
||||
return response()->json(['error' => true, 'message' => 'vCenter not found'], 400);
|
||||
@@ -709,18 +718,18 @@ class VCenterManagerController extends Controller
|
||||
|
||||
$response = Http::withoutVerifying()
|
||||
->withHeaders(['vmware-api-session-id' => $vCenterService->token])
|
||||
->post("https://{$vCenterService->apiUri}/rest/vcenter/vm/$vmId/power/suspend");
|
||||
->post("https://{$vCenterService->apiUri}/rest/vcenter/vm/$vmwareId/power/suspend");
|
||||
|
||||
if ($response->status() === 200) {
|
||||
$vm->update(['power_state' => 'SUSPENDED']);
|
||||
$this->sendSuspendNotification($vm);
|
||||
$vm?->update(['power_state' => 'SUSPENDED']);
|
||||
$this->sendSuspendNotification($vmware, $vm);
|
||||
return response()->json(['error' => false, 'message' => 'Suspend command sent successfully']);
|
||||
}
|
||||
|
||||
$errorData = $response->json();
|
||||
if (isset($errorData['error_type']) && $errorData['error_type'] === 'ALREADY_IN_DESIRED_STATE') {
|
||||
$vm->update(['power_state' => 'SUSPENDED']);
|
||||
$this->sendSuspendNotification($vm);
|
||||
$vm?->update(['power_state' => 'SUSPENDED']);
|
||||
$this->sendSuspendNotification($vmware, $vm);
|
||||
return response()->json(['error' => false, 'message' => 'VM is already suspended']);
|
||||
}
|
||||
|
||||
@@ -730,19 +739,69 @@ class VCenterManagerController extends Controller
|
||||
], 400);
|
||||
}
|
||||
|
||||
private function sendSuspendNotification(VirtualMachines $vm): void
|
||||
public function deleteVM(Request $request)
|
||||
{
|
||||
$vmware = ModuleVmware::with('customer')
|
||||
->where('vmware_id', $vm->vm_id)
|
||||
->first();
|
||||
$request->validate([
|
||||
'vm_id' => 'required|integer',
|
||||
'confirm_name' => 'required|string',
|
||||
]);
|
||||
|
||||
if (!$vmware || !$vmware->customer || !$vmware->customer->email) {
|
||||
$vmId = (int) $request->input('vm_id');
|
||||
$vm = VirtualMachines::find($vmId);
|
||||
|
||||
if (!$vm) {
|
||||
return response()->json(['error' => true, 'message' => 'VM not found'], 404);
|
||||
}
|
||||
|
||||
if ($request->input('confirm_name') !== $vm->name) {
|
||||
return response()->json(['error' => true, 'message' => "Tên xác nhận không khớp. Vui lòng nhập đúng: {$vm->name}"], 422);
|
||||
}
|
||||
|
||||
if ($vm->power_state !== 'POWERED_OFF') {
|
||||
return response()->json(['error' => true, 'message' => 'Vui lòng tắt máy ảo trước khi xoá'], 400);
|
||||
}
|
||||
|
||||
$vcenter = $vm->datacenter?->vCenter ?? $vm->host?->datacenter?->vCenter;
|
||||
|
||||
if (!$vcenter) {
|
||||
return response()->json(['error' => true, 'message' => 'vCenter not found'], 400);
|
||||
}
|
||||
|
||||
$powerShellService = app(\App\Http\Services\vCenter\PowerShellService::class);
|
||||
|
||||
$q = fn(string $v) => str_replace("'", "''", $v);
|
||||
$vmName = $vm->name;
|
||||
$host = $vcenter->host;
|
||||
$user = $vcenter->user;
|
||||
$password = \App\Http\Facade\SignRSA::DecryptFunc($vcenter->password);
|
||||
|
||||
$command = "& 'C:\\CLISave\\DeleteVM\\deleteVM.ps1' -VmName '" . $q($vmName) . "' -VCenterHost '" . $q($host) . "' -VCenterUser '" . $q($user) . "' -VCenterPassword '" . $q($password) . "'";
|
||||
$cmdResult = $powerShellService->runPsCommand($command);
|
||||
|
||||
if (strpos($cmdResult, 'Login_Fail') !== false) {
|
||||
return response()->json(['error' => true, 'message' => 'SSH Login to PowerShell server failed'], 400);
|
||||
}
|
||||
|
||||
if (strpos($cmdResult, 'SUCCESS') === false) {
|
||||
return response()->json(['error' => true, 'message' => 'Xoá VM thất bại: ' . $cmdResult], 400);
|
||||
}
|
||||
|
||||
$vm->delete();
|
||||
|
||||
return response()->json(['error' => false, 'message' => 'VM đã được xoá thành công']);
|
||||
}
|
||||
|
||||
private function sendSuspendNotification(ModuleVmware $vmware, ?VirtualMachines $vm = null): void
|
||||
{
|
||||
$vmware->loadMissing('customer');
|
||||
|
||||
if (!$vmware->customer || !$vmware->customer->email) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Mail::to($vmware->customer->email)
|
||||
->queue(new VmSuspendedMail($vmware->customer, $vm->name, $vm->vm_id));
|
||||
->queue(new VmSuspendedMail($vmware->customer, $vm?->name ?? $vmware->name, $vmware->vmware_id));
|
||||
} catch (\Throwable) {
|
||||
// Email failure must not block the suspend response
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user