loadFirewallOptions(); $this->loadFirewallRules(); $this->loadAliases(); $this->loadIpsets(); } public function loadFirewallOptions(): void { try { $proxmox = new Proxmox; $response = $proxmox->request( '/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/options' ); $data = $response->json()['data'] ?? []; $this->firewallEnabled = isset($data['enable']) && $data['enable'] == 1; $this->error = ''; } catch (\Exception $e) { $this->error = 'Failed to load firewall options: ' . $e->getMessage(); $this->firewallEnabled = false; } } public function toggleFirewall(): void { $this->loading = true; try { $proxmox = new Proxmox; $response = $proxmox->request( '/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/options', 'put', ['enable' => $this->firewallEnabled ? 0 : 1] ); if ($response->successful()) { $this->firewallEnabled = !$this->firewallEnabled; $this->notify('Firewall ' . ($this->firewallEnabled ? 'enabled' : 'disabled') . ' successfully', 'success'); $this->loadFirewallOptions(); } else { $message = $response->json()['errors'][0]['message'] ?? 'Unknown error'; $this->notify('Failed to toggle firewall: ' . $message, 'error'); } } catch (\Exception $e) { $this->notify('Failed to toggle firewall: ' . $e->getMessage(), 'error'); } finally { $this->loading = false; } } public function loadFirewallRules(): void { try { $proxmox = new Proxmox; $response = $proxmox->request( '/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/rules' ); $data = $response->json()['data'] ?? []; $this->rules = is_array($data) ? $data : []; $this->error = ''; } catch (\Exception $e) { $this->error = 'Failed to load firewall rules: ' . $e->getMessage(); $this->rules = []; } } public function startCreateRule(): void { $this->resetRuleForm(); $this->editingRulePos = null; } public function startEditRule(int $pos): void { $rule = collect($this->rules)->firstWhere('pos', $pos); if ($rule) { $this->editingRulePos = $pos; $this->ruleAction = $rule['action'] ?? 'ACCEPT'; $this->ruleSource = $rule['source'] ?? ''; $this->ruleDest = $rule['dest'] ?? ''; $this->ruleProto = $rule['proto'] ?? ''; $this->ruleDport = $rule['dport'] ?? ''; $this->ruleSport = $rule['sport'] ?? ''; $this->ruleComment = $rule['comment'] ?? ''; $this->ruleEnable = !isset($rule['enable']) || $rule['enable'] == 1; $this->ruleMacro = $rule['macro'] ?? ''; $this->ruleIface = $rule['iface'] ?? ''; $this->ruleLog = $rule['log'] ?? ''; } } public function resetRuleForm(): void { $this->ruleAction = 'ACCEPT'; $this->ruleSource = ''; $this->ruleDest = ''; $this->ruleProto = ''; $this->ruleDport = ''; $this->ruleSport = ''; $this->ruleComment = ''; $this->ruleEnable = true; $this->ruleMacro = ''; $this->ruleIface = ''; $this->ruleLog = ''; } public function saveRule(): void { $this->loading = true; try { $proxmox = new Proxmox; $payload = array_filter([ 'action' => $this->ruleAction, 'source' => $this->ruleSource ?: null, 'dest' => $this->ruleDest ?: null, 'proto' => $this->ruleProto ?: null, 'dport' => $this->ruleDport ?: null, 'sport' => $this->ruleSport ?: null, 'comment' => $this->ruleComment ?: null, 'enable' => $this->ruleEnable ? 1 : 0, 'macro' => $this->ruleMacro ?: null, 'iface' => $this->ruleIface ?: null, 'log' => $this->ruleLog ?: null, ], fn($value) => $value !== null); if ($this->editingRulePos !== null) { // Update existing rule $response = $proxmox->request( '/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/rules/' . $this->editingRulePos, 'put', $payload ); } else { // Create new rule $response = $proxmox->request( '/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/rules', 'post', $payload ); } if ($response->successful()) { $this->notify('Rule ' . ($this->editingRulePos !== null ? 'updated' : 'created') . ' successfully', 'success'); $this->resetRuleForm(); $this->editingRulePos = null; $this->loadFirewallRules(); } else { $message = $response->json()['errors'][0]['message'] ?? 'Unknown error'; $this->notify('Failed to save rule: ' . $message, 'error'); } } catch (\Exception $e) { $this->notify('Failed to save rule: ' . $e->getMessage(), 'error'); } finally { $this->loading = false; } } public function deleteRule(int $pos): void { $this->loading = true; try { $proxmox = new Proxmox; $response = $proxmox->request( '/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/rules/' . $pos, 'delete' ); if ($response->successful()) { $this->notify('Rule deleted successfully', 'success'); $this->loadFirewallRules(); } else { $message = $response->json()['errors'][0]['message'] ?? 'Unknown error'; $this->notify('Failed to delete rule: ' . $message, 'error'); } } catch (\Exception $e) { $this->notify('Failed to delete rule: ' . $e->getMessage(), 'error'); } finally { $this->loading = false; } } public function loadAliases(): void { try { $proxmox = new Proxmox; $response = $proxmox->request( '/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/aliases' ); $data = $response->json()['data'] ?? []; $this->aliases = is_array($data) ? $data : []; } catch (\Exception $e) { $this->aliases = []; } } public function createAlias(): void { if (empty($this->aliasName) || empty($this->aliasCidr)) { $this->notify('Name and CIDR are required', 'error'); return; } $this->loading = true; try { $proxmox = new Proxmox; $payload = [ 'name' => $this->aliasName, 'cidr' => $this->aliasCidr, ]; if ($this->aliasComment) { $payload['comment'] = $this->aliasComment; } $response = $proxmox->request( '/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/aliases', 'post', $payload ); if ($response->successful()) { $this->notify('Alias created successfully', 'success'); $this->aliasName = ''; $this->aliasCidr = ''; $this->aliasComment = ''; $this->loadAliases(); } else { $message = $response->json()['errors'][0]['message'] ?? 'Unknown error'; $this->notify('Failed to create alias: ' . $message, 'error'); } } catch (\Exception $e) { $this->notify('Failed to create alias: ' . $e->getMessage(), 'error'); } finally { $this->loading = false; } } public function deleteAlias(string $name): void { $this->loading = true; try { $proxmox = new Proxmox; $response = $proxmox->request( '/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/aliases/' . $name, 'delete' ); if ($response->successful()) { $this->notify('Alias deleted successfully', 'success'); $this->loadAliases(); } else { $message = $response->json()['errors'][0]['message'] ?? 'Unknown error'; $this->notify('Failed to delete alias: ' . $message, 'error'); } } catch (\Exception $e) { $this->notify('Failed to delete alias: ' . $e->getMessage(), 'error'); } finally { $this->loading = false; } } public function loadIpsets(): void { try { $proxmox = new Proxmox; $response = $proxmox->request( '/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/ipset' ); $data = $response->json()['data'] ?? []; $this->ipsets = is_array($data) ? $data : []; } catch (\Exception $e) { $this->ipsets = []; } } public function createIpset(): void { if (empty($this->ipsetName)) { $this->notify('Name is required', 'error'); return; } $this->loading = true; try { $proxmox = new Proxmox; $payload = [ 'name' => $this->ipsetName, ]; if ($this->ipsetComment) { $payload['comment'] = $this->ipsetComment; } $response = $proxmox->request( '/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/ipset', 'post', $payload ); if ($response->successful()) { $this->notify('IP set created successfully', 'success'); $this->ipsetName = ''; $this->ipsetComment = ''; $this->loadIpsets(); } else { $message = $response->json()['errors'][0]['message'] ?? 'Unknown error'; $this->notify('Failed to create IP set: ' . $message, 'error'); } } catch (\Exception $e) { $this->notify('Failed to create IP set: ' . $e->getMessage(), 'error'); } finally { $this->loading = false; } } public function deleteIpset(string $name): void { $this->loading = true; try { $proxmox = new Proxmox; $response = $proxmox->request( '/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/ipset/' . $name, 'delete' ); if ($response->successful()) { $this->notify('IP set deleted successfully', 'success'); $this->loadIpsets(); } else { $message = $response->json()['errors'][0]['message'] ?? 'Unknown error'; $this->notify('Failed to delete IP set: ' . $message, 'error'); } } catch (\Exception $e) { $this->notify('Failed to delete IP set: ' . $e->getMessage(), 'error'); } finally { $this->loading = false; } } }