diff --git a/app/Http/Controllers/admin/vm/VirtualMachineController.php b/app/Http/Controllers/admin/vm/VirtualMachineController.php
index 449212d..c63e075 100644
--- a/app/Http/Controllers/admin/vm/VirtualMachineController.php
+++ b/app/Http/Controllers/admin/vm/VirtualMachineController.php
@@ -66,6 +66,7 @@ class VirtualMachineController extends Controller
if (!$vm) {
return back()->withErrors('Invalid request.');
}
+ $vm->load('datacenter', 'host');
$title = 'Edit Virtual Machine';
return view('administrator.pages.package.vm.edit', compact('title', 'vm'));
}
@@ -137,10 +138,18 @@ class VirtualMachineController extends Controller
->editColumn('updated_at', function ($d) {
return $d->updated_at ? $d->updated_at->format('H:i:s d/m/Y') : '';
})
+ ->editColumn('power_state', function ($d) {
+ if ($d->power_state == 'POWERED_ON') {
+ return 'Đang bật';
+ } elseif ($d->power_state == 'POWERED_OFF') {
+ return 'Đang tắt';
+ }
+ return $d->power_state ?? 'N/A';
+ })
->editColumn('datacenter.name', function ($d) {
return $d->datacenter ? $d->datacenter->name . ' - ' . $d->datacenter->datacenter_id : 'N/A';
})
- ->rawColumns(['action'])
+ ->rawColumns(['action', 'power_state'])
->make(true);
}
}
\ No newline at end of file
diff --git a/app/Http/Services/vCenter.php b/app/Http/Services/vCenter.php
index 309bdb1..3898ece 100644
--- a/app/Http/Services/vCenter.php
+++ b/app/Http/Services/vCenter.php
@@ -1141,6 +1141,74 @@ PS;
];
}
+ public function GetVMStats($vmware_id = ''): array
+ {
+ $stats = [
+ 'cpu' => null,
+ 'memory' => null,
+ 'disk' => null,
+ ];
+
+ try {
+ $hardwareResponse = Http::withoutVerifying()
+ ->withHeaders([
+ 'vmware-api-session-id' => $this->token
+ ])
+ ->get("https://$this->apiUri/rest/vcenter/vm/$vmware_id/hardware")->json();
+
+ if (is_array($hardwareResponse) && !isset($hardwareResponse['type']) && isset($hardwareResponse['value'])) {
+ foreach ($hardwareResponse['value'] as $hardware) {
+ if (isset($hardware['label']) && $hardware['label'] === 'CPU') {
+ $stats['cpu'] = [
+ 'cores' => $hardware['spec']['num_cores'] ?? 0,
+ 'cores_per_socket' => $hardware['spec']['cores_per_socket'] ?? 0,
+ ];
+ }
+ if (isset($hardware['label']) && $hardware['label'] === 'Memory') {
+ $stats['memory'] = [
+ 'size_MiB' => $hardware['spec']['size_MiB'] ?? 0,
+ 'size_GB' => round(($hardware['spec']['size_MiB'] ?? 0) / 1024, 2),
+ ];
+ }
+ if (isset($hardware['label']) && $hardware['label'] === 'Hard disk') {
+ $stats['disk'][] = [
+ 'capacity' => $hardware['capacity'] ?? 0,
+ 'capacity_GB' => round(($hardware['capacity'] ?? 0) / (1024 * 1024 * 1024), 2),
+ ];
+ }
+ }
+ }
+
+ $guestMemoryResponse = Http::withoutVerifying()
+ ->withHeaders([
+ 'vmware-api-session-id' => $this->token
+ ])
+ ->get("https://$this->apiUri/rest/vcenter/vm/$vmware_id/guest/memory")->json();
+
+ if (is_array($guestMemoryResponse) && !isset($guestMemoryResponse['type']) && isset($guestMemoryResponse['value'])) {
+ $stats['memory']['used_MiB'] = $guestMemoryResponse['value']['used'] ?? 0;
+ $stats['memory']['used_GB'] = round(($guestMemoryResponse['value']['used'] ?? 0) / 1024, 2);
+ $stats['memory']['usage_percent'] = $stats['memory']['size_MiB'] > 0
+ ? round(($guestMemoryResponse['value']['used'] ?? 0) / $stats['memory']['size_MiB'] * 100, 1)
+ : 0;
+ }
+
+ $guestCpuResponse = Http::withoutVerifying()
+ ->withHeaders([
+ 'vmware-api-session-id' => $this->token
+ ])
+ ->get("https://$this->apiUri/rest/vcenter/vm/$vmware_id/guest/cpu")->json();
+
+ if (is_array($guestCpuResponse) && !isset($guestCpuResponse['type']) && isset($guestCpuResponse['value'])) {
+ $stats['cpu']['used_percent'] = $guestCpuResponse['value']['used'] ?? 0;
+ }
+
+ return ['error' => false, 'data' => $stats];
+ } catch (\Exception $e) {
+ return ['error' => true, 'message' => $e->getMessage(), 'data' => $stats];
+ }
+ }
+
public function ConfigCentOSVersion8($vmware_id = '', $product = [], $password = ''): void
{
$this->SetConfig($product->IpAddress->Host->Datacenter->vCenter);
diff --git a/resources/views/administrator/pages/package/vm/datatable/action.blade.php b/resources/views/administrator/pages/package/vm/datatable/action.blade.php
index 0b48d43..87c432b 100644
--- a/resources/views/administrator/pages/package/vm/datatable/action.blade.php
+++ b/resources/views/administrator/pages/package/vm/datatable/action.blade.php
@@ -1,6 +1,68 @@
-
-
Edit
-
Delete
+
+
+
+
+
+
\ No newline at end of file
diff --git a/resources/views/administrator/pages/package/vm/edit.blade.php b/resources/views/administrator/pages/package/vm/edit.blade.php
index a1fc033..a559448 100644
--- a/resources/views/administrator/pages/package/vm/edit.blade.php
+++ b/resources/views/administrator/pages/package/vm/edit.blade.php
@@ -1,46 +1,92 @@
@extends("administrator.layout.master")
+
+@section('breadcrumb')
+ @php
+ $breadcrumbItems = [
+ ['label' => 'Modules'],
+ ['label' => 'Package vCenter'],
+ ['label' => 'Virtual Machine', 'route' => 'package.vm.index'],
+ ['label' => $vm->name ?? $vm->vm_id ?? 'Edit', 'active' => true],
+ ];
+ @endphp
+
+@endsection
+
@section("content")
@if(auth()->guard('admins')->user()->can("add module vcenter"))
diff --git a/resources/views/administrator/pages/vm_console.blade.php b/resources/views/administrator/pages/vm_console.blade.php
new file mode 100644
index 0000000..55a3cb2
--- /dev/null
+++ b/resources/views/administrator/pages/vm_console.blade.php
@@ -0,0 +1,314 @@
+@extends('administrator.layout.master')
+
+@push('style')
+
+
+@endpush
+
+@section('breadcrumb')
+ @php
+ $breadcrumbItems = [
+ ['label' => 'Modules'],
+ ['label' => 'Package vCenter'],
+ ['label' => 'Virtual Machine', 'route' => 'package.vm.index'],
+ ['label' => $vm->name ?? $vm->vm_id ?? 'Console', 'active' => true],
+ ];
+ @endphp
+
+@endsection
+
+@section('content')
+
+
+
+
+
+
+
+
+
+
Power State
+
{{ $vm->power_state ?? 'N/A' }}
+
+
+
CPU
+ @if($vmStats && isset($vmStats['cpu']))
+
+ {{ $vmStats['cpu']['cores'] ?? $vm->cpu ?? 'N/A' }} vCore
+ @if(isset($vmStats['cpu']['used_percent']))
+
+ {{ $vmStats['cpu']['used_percent'] }}%
+
+ @endif
+
+ @else
+
{{ $vm->cpu ?? 'N/A' }} vCore
+ @endif
+
+
+
RAM
+ @if($vmStats && isset($vmStats['memory']))
+
+ {{ $vmStats['memory']['size_GB'] ?? round(($vm->ram_mb ?? 0) / 1024, 2) }} GB
+ @if(isset($vmStats['memory']['used_GB']))
+
+ {{ $vmStats['memory']['used_GB'] }} GB ({{ $vmStats['memory']['usage_percent'] }}%)
+
+ @endif
+
+ @else
+
{{ $vm->ram_mb ? round($vm->ram_mb / 1024, 2) : 'N/A' }} GB
+ @endif
+
+
+
Disk
+ @if($vmStats && isset($vmStats['disk']) && count($vmStats['disk']) > 0)
+
+ @foreach($vmStats['disk'] as $disk)
+ {{ $disk['capacity_GB'] }} GB
+ @endforeach
+
+ @else
+
N/A
+ @endif
+
+
+
Datacenter
+
{{ $vm->datacenter->name ?? 'N/A' }}
+
+
+
vCenter
+
+ @if($vm->datacenter && $vm->datacenter->vCenter)
+ {{ $vm->datacenter->vCenter->host }}
+ @else
+ N/A
+ @endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Connecting to vCenter...
+
Initializing console
+
+
+
+
+
+
+ Setting up session...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+@endsection
diff --git a/routes/admin.php b/routes/admin.php
index 235edfc..86f76d0 100644
--- a/routes/admin.php
+++ b/routes/admin.php
@@ -37,8 +37,10 @@ use App\Http\Controllers\admin\UserController;
use App\Http\Controllers\admin\vm\VirtualMachineController;
use App\Http\Controllers\Api\VpsActionController;
use App\Http\Controllers\rest\ModuleController;
+use App\Http\Services\vCenter;
+use App\Models\ModuleVmware;
+use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cookie;
-use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Route;
@@ -381,6 +383,92 @@ Route::prefix('')->group(function () {
Route::post('task-reinstall', 'Reinstall')->name('task.reinstall');
});
+ //Console Ticket API for Admin - using vm_id from VirtualMachines
+ Route::get('admin-get-console-ticket', function (Request $request, vCenter $serviceVCenter) {
+ $vm_id = $request->get('vm_id');
+ if (!$vm_id) {
+ return response()->json(['error' => true, 'message' => "Please provide vm_id"]);
+ }
+ $vm = \App\Models\VirtualMachines::with('datacenter.vCenter')->where('vm_id', $vm_id)->first();
+ if (!$vm) {
+ return response()->json(['error' => true, 'message' => "Can't find VM with vm_id: " . $vm_id]);
+ }
+
+ $vcenter = null;
+ if ($vm->datacenter && $vm->datacenter->vCenter) {
+ $vcenter = $vm->datacenter->vCenter;
+ }
+
+ if (!$vcenter) {
+ return response()->json(['error' => true, 'message' => "Can't find vCenter information"]);
+ }
+
+ if (!$serviceVCenter->loginServer($vcenter)) {
+ return response()->json([
+ 'error' => true,
+ 'message' => 'Không thể đăng nhập vào vCenter'
+ ]);
+ }
+
+ $ConsoleTicket = $serviceVCenter->GetConsoleTickets($vm->vm_id);
+
+ if ($ConsoleTicket === 'Login_Again') {
+ if ($serviceVCenter->loginServer($vcenter)) {
+ $ConsoleTicket = $serviceVCenter->GetConsoleTickets($vm->vm_id);
+ } else {
+ return response()->json([
+ 'error' => true,
+ 'message' => 'Không thể đăng nhập lại vào vCenter'
+ ]);
+ }
+ }
+
+ if (is_string($ConsoleTicket)) {
+ return response()->json([
+ 'error' => true,
+ 'message' => "Failed to get console ticket: $ConsoleTicket"
+ ]);
+ }
+
+ if ($ConsoleTicket['error']) {
+ return response()->json([
+ 'error' => true,
+ 'message' => $ConsoleTicket['data']
+ ]);
+ }
+
+ return response()->json([
+ 'error' => false,
+ 'data' => $ConsoleTicket['data'],
+ 'host' => $vcenter->host,
+ 'vmware-api-session-id' => $serviceVCenter->token
+ ])->cookie('vmware-api-session-id', $serviceVCenter->token, 60, '/', null, false, false);
+ })->name('admin.getConsoleTicket');
+
+ //Admin VM Console View - using vm_id
+ Route::get('view-admin-console/{vm_id}', function (Request $request, $vm_id, vCenter $serviceVCenter) {
+ $vm = \App\Models\VirtualMachines::with('datacenter.vCenter', 'host')->where('vm_id', $vm_id)->first();
+ if (!$vm) {
+ return back()->withErrors("Can't find VM with vm_id: " . $vm_id);
+ }
+
+ $vmStats = null;
+ if ($vm->datacenter && $vm->datacenter->vCenter) {
+ $vcenter = $vm->datacenter->vCenter;
+ if ($serviceVCenter->loginServer($vcenter)) {
+ $vmStats = $serviceVCenter->GetVMStats($vm->vm_id);
+ if ($vmStats['error']) {
+ $vmStats = null;
+ } else {
+ $vmStats = $vmStats['data'];
+ }
+ }
+ }
+
+ $title = 'Console - ' . ($vm->name ?? 'VM ' . $vm_id);
+ return view('administrator.pages.vm_console', compact('title', 'vm', 'vmStats'));
+ })->name('admin.vm.console');
+
//Invoice
Route::controller(InvoiceController::class)->group(function () {
Route::get('list-all-invoice', 'index')->name('administrator.pages.invoice.index');