fix: enhance firewall request handling in Proxmox component to support form data for PUT/POST requests and improve error handling during state toggling

This commit is contained in:
2025-12-01 13:08:02 -05:00
parent 6f775a1eaf
commit 8a6b0b6f74
2 changed files with 38 additions and 8 deletions

View File

@@ -63,13 +63,19 @@ class Firewall extends Component
// Proxmox API token format: PVEAPIToken=USER@REALM!TOKENID=SECRET
$authHeader = 'PVEAPIToken=' . $user . '!' . $tokenId . '=' . $secret;
return Http::withHeaders([
$request = Http::withHeaders([
'Authorization' => $authHeader,
'Accept' => 'application/json',
'Content-Type' => 'application/json',
])->withOptions([
'verify' => true,
])->$method($fullUrl, $data)->throw();
]);
// For PUT/POST requests, Proxmox API typically expects form data, not JSON
if (in_array(strtolower($method), ['put', 'post']) && !empty($data)) {
return $request->asForm()->$method($fullUrl, $data)->throw();
}
return $request->$method($fullUrl, $data)->throw();
}
public function loadFirewallOptions(): void
@@ -91,22 +97,46 @@ class Firewall extends Component
{
$this->loading = true;
try {
// Store the current state before toggling
$currentState = $this->firewallEnabled;
// Calculate the new desired state (opposite of current)
$newState = $currentState ? 0 : 1;
$payload = ['enable' => $newState];
$response = $this->firewallRequest(
'/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/options',
'put',
['enable' => $this->firewallEnabled ? 0 : 1]
$payload
);
if ($response->successful()) {
$this->firewallEnabled = !$this->firewallEnabled;
$this->notify('Firewall ' . ($this->firewallEnabled ? 'enabled' : 'disabled') . ' successfully', 'success');
// Reload from API to get the actual state (don't assume it worked)
$this->loadFirewallOptions();
$this->notify('Firewall ' . ($this->firewallEnabled ? 'enabled' : 'disabled') . ' successfully', 'success');
} else {
$message = $response->json()['errors'][0]['message'] ?? 'Unknown error';
$this->notify('Failed to toggle firewall: ' . $message, 'error');
// Reload to ensure UI matches actual state
$this->loadFirewallOptions();
}
} catch (\Illuminate\Http\Client\RequestException $e) {
$errorMessage = $e->getMessage();
// Try to extract more detailed error from response
if ($e->response()) {
$errorData = $e->response()->json();
if (isset($errorData['errors']) && is_array($errorData['errors']) && !empty($errorData['errors'])) {
$errorMessage = $errorData['errors'][0]['message'] ?? $errorMessage;
} elseif (isset($errorData['message'])) {
$errorMessage = $errorData['message'];
}
}
$this->notify('Failed to toggle firewall: ' . $errorMessage, 'error');
// Reload to ensure UI matches actual state
$this->loadFirewallOptions();
} catch (\Exception $e) {
$this->notify('Failed to toggle firewall: ' . $e->getMessage(), 'error');
// Reload to ensure UI matches actual state
$this->loadFirewallOptions();
} finally {
$this->loading = false;
}

View File

@@ -68,8 +68,8 @@
<label class="firewall-toggle-switch" wire:loading.attr="disabled" wire:target="toggleFirewall">
<input
type="checkbox"
wire:model="firewallEnabled"
wire:change="toggleFirewall"
@if($firewallEnabled) checked @endif
wire:click="toggleFirewall"
wire:loading.attr="disabled">
<span class="firewall-toggle-slider"></span>
</label>