Files
Virtnet.bond/extensions/Servers/Proxmox/Admin/Resources/NodeResource.php

180 lines
6.8 KiB
PHP

<?php
namespace Paymenter\Extensions\Servers\Proxmox\Admin\Resources;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Paymenter\Extensions\Servers\Proxmox\Admin\Resources\NodeResource\Pages;
use Paymenter\Extensions\Servers\Proxmox\Models\Node;
use Paymenter\Extensions\Servers\Proxmox\Proxmox;
class NodeResource extends Resource
{
protected static ?string $model = Node::class;
protected static ?string $navigationGroup = 'Proxmox';
protected static ?string $label = 'Node';
protected static ?string $navigationIcon = 'ri-base-station-line';
protected static ?string $activeNavigationIcon = 'ri-base-station-fill';
protected static ?string $slug = 'proxmox-nodes';
public static function form(Form $form): Form
{
$proxmox = new Proxmox;
$nodes = once(function () use ($proxmox) {
try {
$nodes = $proxmox->request('/cluster/resources', data: [
'type' => 'node',
])->json()['data'] ?? [];
return collect($nodes)->map(function ($node) {
return [
'label' => $node['node'],
'value' => $node['node'],
];
})->pluck('label', 'value');
} catch (\Throwable $e) {
\Log::error('Failed to fetch Proxmox nodes: ' . $e->getMessage());
return collect();
}
});
return $form
->schema([
Forms\Components\Select::make('name')
->label('Node')
->required()
->searchable()
->options($nodes)
->disabledOn('edit')
->live(onBlur: true)
->reactive(),
Forms\Components\Select::make('location_id')
->label('Location')
->relationship('location', 'name')
->preload()
->searchable()
->required()
->disabled(fn (Get $get) => !$get('name'))
->helperText('Select a node group to assign this node to it.'),
Forms\Components\TextInput::make('memory')
->label('RAM (MiB)')
->numeric()
->default(0)
->required()
->helperText('0 means no limit')
->disabled(fn (Get $get) => !$get('name')),
Forms\Components\TextInput::make('disk')
->label('Disk (GiB)')
->numeric()
->default(0)
->required()
->helperText('0 means no limit')
->disabled(fn (Get $get) => !$get('name')),
Forms\Components\TextInput::make('cpu')
->label('CPU Cores')
->numeric()
->default(0)
->required()
->helperText('0 means no limit')
->disabled(fn (Get $get) => !$get('name')),
Forms\Components\TextInput::make('storage_location')
->label('Storage Location')
->required()
->default('local')
->maxLength(255)
->helperText('The storage location to use for this node, e.g., local, local-lvm')
->disabled(fn (Get $get) => !$get('name')),
Forms\Components\TextInput::make('notes')
->label('Common Name')
->required()
->default('local')
->maxLength(255)
->disabled(fn (Get $get) => !$get('name')),
Forms\Components\TextInput::make('backup_location')
->label('Backup Location')
->required()
->default('local')
->maxLength(255)
->helperText('The backup location to use for this node, e.g., local, local-lvm')
->disabled(fn (Get $get) => !$get('name')),
Forms\Components\Toggle::make('vnc_enabled')
->label('VNC Enabled')
->default(true)
->helperText('Enable or disable VNC access for this node. (this requires the Proxmox instance to be on the same domain as the Paymenter installation)')
->required(),
Forms\Components\Checkbox::make('is_lxc')
->label('LXC Container Node')
->default(false)
->helperText('Check to deploy LXC containers instead of KVM virtual machines on this node. Existing KVM nodes are unaffected.')
->disabled(fn (string $operation): bool => $operation === 'edit'),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name')
->label('Node')
->sortable()
->searchable()
->toggleable(),
Tables\Columns\TextColumn::make('notes')
->label('Common Name')
->sortable()
->searchable()
->toggleable(),
Tables\Columns\TextColumn::make('location.name')
->label('Location')
->sortable()
->searchable()
->toggleable(),
Tables\Columns\TextColumn::make('servers_count')
->label('Servers')
->counts('servers')
->sortable()
->searchable()
->toggleable(),
Tables\Columns\TextColumn::make('is_lxc')
->label('Type')
->formatStateUsing(fn (bool $state): string => $state ? 'Container' : 'VM')
->badge()
->color(fn (bool $state): string => $state ? 'info' : 'gray')
->toggleable(),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListNodes::route('/'),
'create' => Pages\CreateNode::route('/create'),
'edit' => Pages\EditNode::route('/{record}/edit'),
];
}
}