Files
Virtnet.bond/app/Livewire/Services/Show.php

150 lines
4.4 KiB
PHP

<?php
namespace App\Livewire\Services;
use App\Helpers\ExtensionHelper;
use App\Livewire\Component;
use App\Models\Service;
use Paymenter\Extensions\Servers\Proxmox\Models\Server as ProxmoxServer;
use Paymenter\Extensions\Servers\Proxmox\Proxmox;
use Livewire\Attributes\Locked;
use Livewire\Attributes\Url;
class Show extends Component
{
public Service $service;
public ?ProxmoxServer $proxmoxServer = null;
/**
* Actual VM status from Proxmox API (includes maxmem, maxdisk, cpus, etc.)
*/
public ?array $vmStatus = null;
#[Locked]
public $buttons = [];
#[Locked]
public $views = [];
#[Url('tab', except: false), Locked]
public $currentView;
#[Url('cancel', except: false)]
public bool $showCancel = false;
public function mount()
{
// Attach Proxmox server (if any) so we can show hostname on the service page
$this->proxmoxServer = ProxmoxServer::with(['os', 'node'])->where('service_id', $this->service->id)->first();
// Fetch actual VM status from Proxmox API if server exists
if ($this->proxmoxServer) {
$this->loadVmStatus();
}
// Only fetch the actions if the service is active
if ($this->service->status == Service::STATUS_ACTIVE) {
$actions = [];
try {
$actions = ExtensionHelper::getActions($this->service);
} catch (\Exception $e) {
}
// separate the actions into buttons and views
foreach ($actions as $action) {
if ($action['type'] == 'button') {
$this->buttons[] = $action;
} elseif ($action['type'] == 'view') {
$this->views[] = $action;
}
}
$this->currentView = $this->currentView ?? ($this->views[0]['name'] ?? null);
}
}
public function changeView($view)
{
if (!$view) {
return;
}
if ($this->currentView === $view || !in_array($view, array_column($this->views, 'name'))) {
return $this->skipRender();
}
$this->currentView = $view;
}
public function updatedShowCancel($value)
{
if (!$this->service->cancellable) {
$this->notify('This service cannot be cancelled', 'error');
$this->showCancel = false;
return;
}
}
public function goto($function)
{
// Check if function is allowed
if (!in_array($function, array_column($this->buttons, 'function'))) {
$this->notify('This action is not allowed', 'error');
return;
}
$result = ExtensionHelper::callService($this->service, $function);
// If its a response, return it
if (!is_string($result)) {
return $result;
}
$this->redirect($result);
}
/**
* Load the actual VM status from Proxmox API.
*/
protected function loadVmStatus(): void
{
try {
if (!$this->proxmoxServer || !$this->proxmoxServer->node) {
return;
}
$proxmox = new Proxmox();
$data = $proxmox->request(
'/nodes/' . $this->proxmoxServer->node->name . '/qemu/' . $this->proxmoxServer->vm_id . '/status/current'
)->json()['data'] ?? null;
$this->vmStatus = $data;
} catch (\Throwable $e) {
$this->vmStatus = null;
}
}
public function render()
{
$view = null;
$previousView = $this->currentView;
if ($this->currentView) {
try {
// Search array for the current view
$currentViewObj = $this->views[array_search($this->currentView, array_column($this->views, 'name'))] ?? null;
if (!$currentViewObj) {
throw new \Exception('View not found');
}
$view = ExtensionHelper::getView($this->service, $currentViewObj);
} catch (\Exception $e) {
if ($previousView !== $this->views[0]['name'] ?? null) {
$this->notify('Got an error while trying to load the view', 'error');
}
$this->currentView = $this->views[0]['name'] ?? null;
}
}
return view('services.show', ['extensionView' => $view])->layoutData([
'title' => 'Services',
'sidebar' => true,
]);
}
}