Add firewall, network, VNC, backup, resource management and UsageUpdate

New features implemented:
- Firewall management: enable/disable, status display, apply rules
- IP address management: add/remove IPv4 and IPv6 with client UI
- VNC console access integration (VirtFusion v6.1.0+)
- Backup plan assignment/removal via API
- Resource modification: in-place memory/CPU/traffic changes
- UsageUpdate cron: automated bandwidth and disk usage sync to WHMCS
- Dry run validation: test server creation config before provisioning
- Admin "Validate Server Config" button for dry run testing

Client area additions:
- Firewall panel with enable/disable/apply controls and status badge
- Network panel with IPv4/IPv6 listing, add, and remove buttons
- VNC Console panel with browser-based access
- All panels load asynchronously with spinner indicators

Comprehensive README rewrite with:
- Table of contents, requirements matrix, step-by-step installation
- Detailed configuration guide for all features
- Theme compatibility documentation (Six, Twenty-One, Lagom)
- Complete API endpoints reference organized by category
- UsageUpdate cron documentation with data format details
- Troubleshooting tables for common issues
- Known issues section covering version requirements
- Security architecture documentation
- File structure reference

https://claude.ai/code/session_01TCsJ4WZCGuEX3zqh1tQ2zx
This commit is contained in:
Claude
2026-02-07 12:43:02 +00:00
parent c93072b1c6
commit cad1af18c1
8 changed files with 1628 additions and 118 deletions

View File

@@ -176,6 +176,232 @@ switch ($action) {
$vf->output(['success' => false, 'errors' => 'Unable to fetch OS templates'], true, true, 500);
break;
// =================================================================
// Firewall Management
// =================================================================
/**
* Get firewall status and rules.
*/
case 'firewallStatus':
$serviceID = $vf->validateServiceID(true);
if (!$vf->validateUserOwnsService($serviceID)) {
$vf->output(['success' => false, 'errors' => 'service <> owner mismatch'], true, true, 403);
}
$result = $vf->getFirewallStatus($serviceID);
if ($result !== false) {
$vf->output(['success' => true, 'data' => $result], true, true, 200);
}
$vf->output(['success' => false, 'errors' => 'Unable to retrieve firewall status'], true, true, 500);
break;
/**
* Enable firewall.
*/
case 'firewallEnable':
$serviceID = $vf->validateServiceID(true);
if (!$vf->validateUserOwnsService($serviceID)) {
$vf->output(['success' => false, 'errors' => 'service <> owner mismatch'], true, true, 403);
}
$result = $vf->enableFirewall($serviceID);
if ($result) {
$vf->output(['success' => true, 'data' => ['message' => 'Firewall enabled successfully']], true, true, 200);
}
$vf->output(['success' => false, 'errors' => 'Failed to enable firewall'], true, true, 500);
break;
/**
* Disable firewall.
*/
case 'firewallDisable':
$serviceID = $vf->validateServiceID(true);
if (!$vf->validateUserOwnsService($serviceID)) {
$vf->output(['success' => false, 'errors' => 'service <> owner mismatch'], true, true, 403);
}
$result = $vf->disableFirewall($serviceID);
if ($result) {
$vf->output(['success' => true, 'data' => ['message' => 'Firewall disabled successfully']], true, true, 200);
}
$vf->output(['success' => false, 'errors' => 'Failed to disable firewall'], true, true, 500);
break;
/**
* Apply/sync firewall rules.
*/
case 'firewallApplyRules':
$serviceID = $vf->validateServiceID(true);
if (!$vf->validateUserOwnsService($serviceID)) {
$vf->output(['success' => false, 'errors' => 'service <> owner mismatch'], true, true, 403);
}
$result = $vf->applyFirewallRules($serviceID);
if ($result) {
$vf->output(['success' => true, 'data' => ['message' => 'Firewall rules applied successfully']], true, true, 200);
}
$vf->output(['success' => false, 'errors' => 'Failed to apply firewall rules'], true, true, 500);
break;
// =================================================================
// IP Address Management
// =================================================================
/**
* Get server IP addresses (from server data).
*/
case 'serverIPs':
$serviceID = $vf->validateServiceID(true);
if (!$vf->validateUserOwnsService($serviceID)) {
$vf->output(['success' => false, 'errors' => 'service <> owner mismatch'], true, true, 403);
}
$data = $vf->fetchServerData($serviceID);
if ($data) {
$resource = (new ServerResource())->process($data);
$vf->output(['success' => true, 'data' => [
'ipv4' => $resource['primaryNetwork']['ipv4Unformatted'],
'ipv6' => $resource['primaryNetwork']['ipv6Unformatted'],
]], true, true, 200);
}
$vf->output(['success' => false, 'errors' => 'Unable to retrieve IP addresses'], true, true, 500);
break;
/**
* Add an IPv4 address.
*/
case 'addIPv4':
$serviceID = $vf->validateServiceID(true);
if (!$vf->validateUserOwnsService($serviceID)) {
$vf->output(['success' => false, 'errors' => 'service <> owner mismatch'], true, true, 403);
}
$result = $vf->addIPv4($serviceID);
if ($result) {
$vf->output(['success' => true, 'data' => ['message' => 'IPv4 address added successfully']], true, true, 200);
}
$vf->output(['success' => false, 'errors' => 'Failed to add IPv4 address. No available addresses or limit reached.'], true, true, 500);
break;
/**
* Remove an IPv4 address.
*/
case 'removeIPv4':
$serviceID = $vf->validateServiceID(true);
if (!$vf->validateUserOwnsService($serviceID)) {
$vf->output(['success' => false, 'errors' => 'service <> owner mismatch'], true, true, 403);
}
$ipAddress = isset($_GET['ip']) ? trim($_GET['ip']) : '';
if (!filter_var($ipAddress, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
$vf->output(['success' => false, 'errors' => 'Invalid IPv4 address'], true, true, 400);
}
$result = $vf->removeIPv4($serviceID, $ipAddress);
if ($result) {
$vf->output(['success' => true, 'data' => ['message' => 'IPv4 address removed successfully']], true, true, 200);
}
$vf->output(['success' => false, 'errors' => 'Failed to remove IPv4 address'], true, true, 500);
break;
/**
* Add an IPv6 subnet.
*/
case 'addIPv6':
$serviceID = $vf->validateServiceID(true);
if (!$vf->validateUserOwnsService($serviceID)) {
$vf->output(['success' => false, 'errors' => 'service <> owner mismatch'], true, true, 403);
}
$result = $vf->addIPv6($serviceID);
if ($result) {
$vf->output(['success' => true, 'data' => ['message' => 'IPv6 subnet added successfully']], true, true, 200);
}
$vf->output(['success' => false, 'errors' => 'Failed to add IPv6 subnet. No available subnets or limit reached.'], true, true, 500);
break;
/**
* Remove an IPv6 subnet.
*/
case 'removeIPv6':
$serviceID = $vf->validateServiceID(true);
if (!$vf->validateUserOwnsService($serviceID)) {
$vf->output(['success' => false, 'errors' => 'service <> owner mismatch'], true, true, 403);
}
$subnet = isset($_GET['subnet']) ? trim($_GET['subnet']) : '';
if (empty($subnet)) {
$vf->output(['success' => false, 'errors' => 'Invalid IPv6 subnet'], true, true, 400);
}
$result = $vf->removeIPv6($serviceID, $subnet);
if ($result) {
$vf->output(['success' => true, 'data' => ['message' => 'IPv6 subnet removed successfully']], true, true, 200);
}
$vf->output(['success' => false, 'errors' => 'Failed to remove IPv6 subnet'], true, true, 500);
break;
// =================================================================
// VNC Console
// =================================================================
/**
* Get VNC console URL.
*/
case 'vnc':
$serviceID = $vf->validateServiceID(true);
if (!$vf->validateUserOwnsService($serviceID)) {
$vf->output(['success' => false, 'errors' => 'service <> owner mismatch'], true, true, 403);
}
$result = $vf->getVncConsole($serviceID);
if ($result !== false) {
$vf->output(['success' => true, 'data' => $result], true, true, 200);
}
$vf->output(['success' => false, 'errors' => 'VNC console unavailable. The server may be powered off or VNC is not supported.'], true, true, 500);
break;
default:
$vf->output(['success' => false, 'errors' => 'invalid action'], true, true, 400);
}