feat: Implement VM suspension feature with email notification

- Added suspend method in VCenterManagerController to handle VM suspension requests.
- Introduced VmSuspendedMail for notifying customers about VM suspension.
- Created email template for VM suspension notification.
- Updated API routes to include VM suspend functionality.
- Modified cors.php to allow additional local development URL.
- Updated DatabaseSeeder to include AdminSeeder and commented out unused seeders.
- Removed deprecated Livewire components related to cart, customer email history, invoices, orders, tickets, transactions, user settings, and VPS reinstall modal.
This commit is contained in:
baodev0
2026-05-21 10:17:16 +07:00
parent 4a308cd19a
commit a31d238135
18 changed files with 226 additions and 796 deletions
@@ -3,6 +3,7 @@
namespace App\Http\Controllers\admin;
use App\Http\Controllers\Controller;
use App\Mail\VmSuspendedMail;
use App\Models\ModuleIpAddress;
use App\Models\ModuleVmware;
use App\Models\VirtualMachines;
@@ -15,6 +16,7 @@ use App\Repositories\Module\Network\NetworkRepositoryInterface;
use App\Repositories\vCenter\vCenterRepositoryInterface;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Mail;
use Yajra\DataTables\Facades\DataTables;
class VCenterManagerController extends Controller
@@ -678,4 +680,71 @@ class VCenterManagerController extends Controller
'data' => $vms
]);
}
public function suspend(Request $request)
{
$vmId = $request->input('vm_id');
$vm = VirtualMachines::where('vm_id', $vmId)->first();
if (!$vm) {
return response()->json(['error' => true, 'message' => 'VM not found'], 404);
}
if ($vm->power_state === 'SUSPENDED') {
return response()->json(['error' => true, 'message' => 'VM is already suspended'], 400);
}
$vcenter = $vm->datacenter?->vCenter ?? $vm->host?->datacenter?->vCenter;
if (!$vcenter) {
return response()->json(['error' => true, 'message' => 'vCenter not found'], 400);
}
$vCenterService = new \App\Http\Services\vCenter();
if (!$vCenterService->loginServer($vcenter)) {
return response()->json(['error' => true, 'message' => 'Cannot login to vCenter'], 400);
}
$response = Http::withoutVerifying()
->withHeaders(['vmware-api-session-id' => $vCenterService->token])
->post("https://{$vCenterService->apiUri}/rest/vcenter/vm/$vmId/power/suspend");
if ($response->status() === 200) {
$vm->update(['power_state' => 'SUSPENDED']);
$this->sendSuspendNotification($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);
return response()->json(['error' => false, 'message' => 'VM is already suspended']);
}
return response()->json([
'error' => true,
'message' => $errorData['value'] ?? $errorData['error_type'] ?? 'Failed to suspend VM',
], 400);
}
private function sendSuspendNotification(VirtualMachines $vm): void
{
$vmware = ModuleVmware::with('customer')
->where('vmware_id', $vm->vm_id)
->first();
if (!$vmware || !$vmware->customer || !$vmware->customer->email) {
return;
}
try {
Mail::to($vmware->customer->email)
->queue(new VmSuspendedMail($vmware->customer, $vm->name, $vm->vm_id));
} catch (\Throwable) {
// Email failure must not block the suspend response
}
}
}