fix: enhance firewall rule handling with improved payload structure and error logging
This commit is contained in:
@@ -660,74 +660,110 @@ class Firewall extends Component
|
|||||||
$this->loading = true;
|
$this->loading = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Build the payload according to Proxmox API requirements
|
||||||
$payload = [
|
$payload = [
|
||||||
'action' => $this->ruleAction,
|
'action' => strtoupper($this->ruleAction), // Ensure uppercase (ACCEPT, REJECT, DROP)
|
||||||
'type' => $this->ruleType,
|
'type' => $this->ruleType, // 'in' or 'out'
|
||||||
'enable' => $this->ruleEnable ? 1 : 0,
|
'enable' => $this->ruleEnable ? 1 : 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
// Note: ruleMacro is only used for UI convenience to auto-populate fields
|
// Add optional fields only if they have values
|
||||||
// It is NOT sent to Proxmox API - only the actual proto/dport values are sent
|
// Proxmox API is strict about empty values
|
||||||
|
if (!empty($this->ruleIface)) {
|
||||||
if (!empty(trim($this->ruleIface))) {
|
|
||||||
$payload['iface'] = trim($this->ruleIface);
|
$payload['iface'] = trim($this->ruleIface);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty(trim($this->ruleSource))) {
|
if (!empty($this->ruleSource)) {
|
||||||
$payload['source'] = trim($this->ruleSource);
|
$payload['source'] = trim($this->ruleSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty(trim($this->ruleDest))) {
|
if (!empty($this->ruleDest)) {
|
||||||
$payload['dest'] = trim($this->ruleDest);
|
$payload['dest'] = trim($this->ruleDest);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty(trim($this->ruleProto))) {
|
// Protocol must be lowercase for Proxmox API
|
||||||
$payload['proto'] = trim($this->ruleProto);
|
if (!empty($this->ruleProto)) {
|
||||||
|
$payload['proto'] = strtolower(trim($this->ruleProto));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty(trim($this->ruleDport))) {
|
if (!empty($this->ruleDport)) {
|
||||||
$payload['dport'] = trim($this->ruleDport);
|
$payload['dport'] = trim($this->ruleDport);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty(trim($this->ruleSport))) {
|
if (!empty($this->ruleSport)) {
|
||||||
$payload['sport'] = trim($this->ruleSport);
|
$payload['sport'] = trim($this->ruleSport);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty(trim($this->ruleComment))) {
|
if (!empty($this->ruleComment)) {
|
||||||
$payload['comment'] = trim($this->ruleComment);
|
$payload['comment'] = trim($this->ruleComment);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty(trim($this->ruleLog)) && $this->ruleLog !== 'nolog') {
|
if (!empty($this->ruleLog) && $this->ruleLog !== 'nolog') {
|
||||||
$payload['log'] = $this->ruleLog;
|
$payload['log'] = $this->ruleLog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine if we're editing an existing rule or creating a new one
|
||||||
if ($this->editingRuleIndex !== null && isset($this->rules[$this->editingRuleIndex])) {
|
if ($this->editingRuleIndex !== null && isset($this->rules[$this->editingRuleIndex])) {
|
||||||
|
// EDIT EXISTING RULE
|
||||||
$pos = $this->rules[$this->editingRuleIndex]['pos'];
|
$pos = $this->rules[$this->editingRuleIndex]['pos'];
|
||||||
$response = $this->firewallRequest(
|
$url = '/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/rules/' . $pos;
|
||||||
'/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/rules/' . $pos,
|
|
||||||
'put',
|
Log::info('Updating firewall rule', [
|
||||||
$payload
|
'url' => $url,
|
||||||
);
|
'payload' => $payload,
|
||||||
|
'pos' => $pos
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $this->firewallRequest($url, 'put', $payload);
|
||||||
} else {
|
} else {
|
||||||
$response = $this->firewallRequest(
|
// CREATE NEW RULE
|
||||||
'/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/rules',
|
$url = '/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/rules';
|
||||||
'post',
|
|
||||||
$payload
|
Log::info('Creating firewall rule', [
|
||||||
);
|
'url' => $url,
|
||||||
|
'payload' => $payload
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $this->firewallRequest($url, 'post', $payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log the response for debugging
|
||||||
|
Log::info('Firewall rule API response', [
|
||||||
|
'status' => $response->status(),
|
||||||
|
'successful' => $response->successful(),
|
||||||
|
'body' => $response->body()
|
||||||
|
]);
|
||||||
|
|
||||||
if ($response->successful()) {
|
if ($response->successful()) {
|
||||||
$this->dispatch('notify', 'Rule ' . ($this->editingRuleIndex !== null ? 'updated' : 'created') . ' successfully', 'success');
|
$this->dispatch('notify', 'Rule ' . ($this->editingRuleIndex !== null ? 'updated' : 'created') . ' successfully', 'success');
|
||||||
|
|
||||||
|
// Reset the form
|
||||||
$this->resetRuleForm();
|
$this->resetRuleForm();
|
||||||
$this->editingRuleIndex = null;
|
$this->editingRuleIndex = null;
|
||||||
$this->showRuleForm = false;
|
$this->showRuleForm = false;
|
||||||
|
|
||||||
|
// Reload rules from Proxmox to get the updated list
|
||||||
$this->loadFirewallRules();
|
$this->loadFirewallRules();
|
||||||
} else {
|
} else {
|
||||||
$message = $response->json()['errors'][0]['message'] ?? 'Unknown error';
|
// Extract error message from Proxmox API response
|
||||||
|
$responseData = $response->json();
|
||||||
|
$message = $responseData['errors'][0]['message'] ?? $responseData['message'] ?? $response->body();
|
||||||
|
|
||||||
|
Log::error('Failed to save firewall rule', [
|
||||||
|
'status' => $response->status(),
|
||||||
|
'response' => $responseData,
|
||||||
|
'payload' => $payload
|
||||||
|
]);
|
||||||
|
|
||||||
$this->error = 'Failed to save rule: ' . $message;
|
$this->error = 'Failed to save rule: ' . $message;
|
||||||
$this->showErrorModal = true;
|
$this->showErrorModal = true;
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
Log::error('Exception saving firewall rule', [
|
||||||
|
'message' => $e->getMessage(),
|
||||||
|
'trace' => $e->getTraceAsString()
|
||||||
|
]);
|
||||||
|
|
||||||
$this->error = 'Failed to save rule: ' . $e->getMessage();
|
$this->error = 'Failed to save rule: ' . $e->getMessage();
|
||||||
$this->showErrorModal = true;
|
$this->showErrorModal = true;
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
Reference in New Issue
Block a user