mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-25 04:33:03 +00:00
feat: add comprehensive configuration options to setup page
- Add advanced settings section with all .env.example options - Include metric/discovery intervals configuration - Add alert system configuration (enabled/thresholds) - Add PBS node name field (required for non-Sys.Audit tokens) - Update config API to handle all settings - Group settings logically in generated .env file - Load and save all configuration options properly 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+72
-3
@@ -26,12 +26,34 @@ class ConfigApi {
|
||||
host: config.PBS_HOST,
|
||||
port: config.PBS_PORT || '8007',
|
||||
tokenId: config.PBS_TOKEN_ID,
|
||||
nodeName: config.PBS_NODE_NAME,
|
||||
// Don't send the secret
|
||||
} : null
|
||||
} : null,
|
||||
advanced: {
|
||||
metricInterval: config.PULSE_METRIC_INTERVAL_MS,
|
||||
discoveryInterval: config.PULSE_DISCOVERY_INTERVAL_MS,
|
||||
alerts: {
|
||||
cpu: {
|
||||
enabled: config.ALERT_CPU_ENABLED !== 'false',
|
||||
threshold: config.ALERT_CPU_THRESHOLD
|
||||
},
|
||||
memory: {
|
||||
enabled: config.ALERT_MEMORY_ENABLED !== 'false',
|
||||
threshold: config.ALERT_MEMORY_THRESHOLD
|
||||
},
|
||||
disk: {
|
||||
enabled: config.ALERT_DISK_ENABLED !== 'false',
|
||||
threshold: config.ALERT_DISK_THRESHOLD
|
||||
},
|
||||
down: {
|
||||
enabled: config.ALERT_DOWN_ENABLED !== 'false'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error reading configuration:', error);
|
||||
return { proxmox: null, pbs: null };
|
||||
return { proxmox: null, pbs: null, advanced: {} };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,10 +80,50 @@ class ConfigApi {
|
||||
existingConfig.PBS_PORT = config.pbs.port || '8007';
|
||||
existingConfig.PBS_TOKEN_ID = config.pbs.tokenId;
|
||||
existingConfig.PBS_TOKEN_SECRET = config.pbs.tokenSecret;
|
||||
if (config.pbs.nodeName) {
|
||||
existingConfig.PBS_NODE_NAME = config.pbs.nodeName;
|
||||
}
|
||||
// Always allow self-signed certificates by default for PBS
|
||||
existingConfig.PBS_ALLOW_SELF_SIGNED_CERT = 'true';
|
||||
}
|
||||
|
||||
// Add advanced settings
|
||||
if (config.advanced) {
|
||||
// Service intervals
|
||||
if (config.advanced.metricInterval) {
|
||||
existingConfig.PULSE_METRIC_INTERVAL_MS = config.advanced.metricInterval;
|
||||
}
|
||||
if (config.advanced.discoveryInterval) {
|
||||
existingConfig.PULSE_DISCOVERY_INTERVAL_MS = config.advanced.discoveryInterval;
|
||||
}
|
||||
|
||||
// Alert settings
|
||||
if (config.advanced.alerts) {
|
||||
const alerts = config.advanced.alerts;
|
||||
if (alerts.cpu) {
|
||||
existingConfig.ALERT_CPU_ENABLED = alerts.cpu.enabled ? 'true' : 'false';
|
||||
if (alerts.cpu.threshold) {
|
||||
existingConfig.ALERT_CPU_THRESHOLD = alerts.cpu.threshold;
|
||||
}
|
||||
}
|
||||
if (alerts.memory) {
|
||||
existingConfig.ALERT_MEMORY_ENABLED = alerts.memory.enabled ? 'true' : 'false';
|
||||
if (alerts.memory.threshold) {
|
||||
existingConfig.ALERT_MEMORY_THRESHOLD = alerts.memory.threshold;
|
||||
}
|
||||
}
|
||||
if (alerts.disk) {
|
||||
existingConfig.ALERT_DISK_ENABLED = alerts.disk.enabled ? 'true' : 'false';
|
||||
if (alerts.disk.threshold) {
|
||||
existingConfig.ALERT_DISK_THRESHOLD = alerts.disk.threshold;
|
||||
}
|
||||
}
|
||||
if (alerts.down) {
|
||||
existingConfig.ALERT_DOWN_ENABLED = alerts.down.enabled ? 'true' : 'false';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write back to .env file
|
||||
await this.writeEnvFile(existingConfig);
|
||||
|
||||
@@ -170,7 +232,14 @@ class ConfigApi {
|
||||
// Group related settings
|
||||
const groups = {
|
||||
'Proxmox VE Settings': ['PROXMOX_HOST', 'PROXMOX_PORT', 'PROXMOX_TOKEN_ID', 'PROXMOX_TOKEN_SECRET', 'PROXMOX_ALLOW_SELF_SIGNED_CERT'],
|
||||
'Proxmox Backup Server Settings': ['PBS_HOST', 'PBS_PORT', 'PBS_TOKEN_ID', 'PBS_TOKEN_SECRET', 'PBS_ALLOW_SELF_SIGNED_CERT'],
|
||||
'Proxmox Backup Server Settings': ['PBS_HOST', 'PBS_PORT', 'PBS_TOKEN_ID', 'PBS_TOKEN_SECRET', 'PBS_NODE_NAME', 'PBS_ALLOW_SELF_SIGNED_CERT'],
|
||||
'Pulse Service Settings': ['PULSE_METRIC_INTERVAL_MS', 'PULSE_DISCOVERY_INTERVAL_MS'],
|
||||
'Alert System Configuration': [
|
||||
'ALERT_CPU_ENABLED', 'ALERT_CPU_THRESHOLD', 'ALERT_CPU_DURATION',
|
||||
'ALERT_MEMORY_ENABLED', 'ALERT_MEMORY_THRESHOLD', 'ALERT_MEMORY_DURATION',
|
||||
'ALERT_DISK_ENABLED', 'ALERT_DISK_THRESHOLD', 'ALERT_DISK_DURATION',
|
||||
'ALERT_DOWN_ENABLED', 'ALERT_DOWN_DURATION'
|
||||
],
|
||||
'Other Settings': [] // Will contain all other keys
|
||||
};
|
||||
|
||||
|
||||
+161
-1
@@ -99,6 +99,96 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Advanced Settings (Optional) -->
|
||||
<details class="border border-gray-200 dark:border-gray-700 rounded-lg">
|
||||
<summary class="px-6 py-4 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors">
|
||||
<span class="text-lg font-medium text-gray-800 dark:text-gray-200">Advanced Settings (Optional)</span>
|
||||
</summary>
|
||||
<div class="p-6 pt-0 space-y-4">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label for="metric-interval" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||
Metric Update Interval (ms)
|
||||
</label>
|
||||
<input type="number" id="metric-interval" name="metric-interval"
|
||||
placeholder="2000 (default)"
|
||||
min="1000" max="60000"
|
||||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">How often to fetch VM/Container metrics</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="discovery-interval" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||
Discovery Interval (ms)
|
||||
</label>
|
||||
<input type="number" id="discovery-interval" name="discovery-interval"
|
||||
placeholder="30000 (default)"
|
||||
min="5000" max="300000"
|
||||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">How often to discover nodes and VMs</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Alert Settings -->
|
||||
<div class="border-t border-gray-200 dark:border-gray-700 pt-4">
|
||||
<h3 class="text-md font-medium text-gray-800 dark:text-gray-200 mb-3">Alert Settings</h3>
|
||||
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-4">
|
||||
<label class="flex items-center">
|
||||
<input type="checkbox" id="alert-cpu-enabled" name="alert-cpu-enabled" checked
|
||||
class="mr-2 rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500">
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">CPU Alerts</span>
|
||||
</label>
|
||||
<label class="flex items-center">
|
||||
<input type="checkbox" id="alert-memory-enabled" name="alert-memory-enabled" checked
|
||||
class="mr-2 rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500">
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">Memory Alerts</span>
|
||||
</label>
|
||||
<label class="flex items-center">
|
||||
<input type="checkbox" id="alert-disk-enabled" name="alert-disk-enabled" checked
|
||||
class="mr-2 rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500">
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">Disk Alerts</span>
|
||||
</label>
|
||||
<label class="flex items-center">
|
||||
<input type="checkbox" id="alert-down-enabled" name="alert-down-enabled" checked
|
||||
class="mr-2 rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500">
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">Down Alerts</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div>
|
||||
<label for="alert-cpu-threshold" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||
CPU Alert Threshold (%)
|
||||
</label>
|
||||
<input type="number" id="alert-cpu-threshold" name="alert-cpu-threshold"
|
||||
placeholder="85 (default)"
|
||||
min="50" max="100"
|
||||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||
</div>
|
||||
<div>
|
||||
<label for="alert-memory-threshold" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||
Memory Alert Threshold (%)
|
||||
</label>
|
||||
<input type="number" id="alert-memory-threshold" name="alert-memory-threshold"
|
||||
placeholder="90 (default)"
|
||||
min="50" max="100"
|
||||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||
</div>
|
||||
<div>
|
||||
<label for="alert-disk-threshold" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||
Disk Alert Threshold (%)
|
||||
</label>
|
||||
<input type="number" id="alert-disk-threshold" name="alert-disk-threshold"
|
||||
placeholder="95 (default)"
|
||||
min="50" max="100"
|
||||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<!-- PBS Configuration (Optional) -->
|
||||
<div class="border border-gray-200 dark:border-gray-700 rounded-lg p-6">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-800 dark:text-gray-200">Proxmox Backup Server (Optional)</h2>
|
||||
@@ -122,6 +212,16 @@
|
||||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="pbs-node-name" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||
PBS Node Name
|
||||
</label>
|
||||
<input type="text" id="pbs-node-name" name="pbs-node-name"
|
||||
placeholder="Internal hostname (run 'hostname' on PBS)"
|
||||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Required unless token has Sys.Audit permission</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="pbs-token-id" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||
API Token ID
|
||||
@@ -301,9 +401,33 @@
|
||||
host: formData.get('pbs-host'),
|
||||
port: formData.get('pbs-port') || '8007',
|
||||
tokenId: formData.get('pbs-token-id'),
|
||||
tokenSecret: formData.get('pbs-token-secret')
|
||||
tokenSecret: formData.get('pbs-token-secret'),
|
||||
nodeName: formData.get('pbs-node-name')
|
||||
};
|
||||
}
|
||||
|
||||
// Add advanced settings
|
||||
config.advanced = {
|
||||
metricInterval: formData.get('metric-interval'),
|
||||
discoveryInterval: formData.get('discovery-interval'),
|
||||
alerts: {
|
||||
cpu: {
|
||||
enabled: formData.get('alert-cpu-enabled') === 'on',
|
||||
threshold: formData.get('alert-cpu-threshold')
|
||||
},
|
||||
memory: {
|
||||
enabled: formData.get('alert-memory-enabled') === 'on',
|
||||
threshold: formData.get('alert-memory-threshold')
|
||||
},
|
||||
disk: {
|
||||
enabled: formData.get('alert-disk-enabled') === 'on',
|
||||
threshold: formData.get('alert-disk-threshold')
|
||||
},
|
||||
down: {
|
||||
enabled: formData.get('alert-down-enabled') === 'on'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
hideMessages();
|
||||
const button = document.getElementById('save-button');
|
||||
@@ -353,6 +477,42 @@
|
||||
document.getElementById('pbs-host').value = config.pbs.host || '';
|
||||
document.getElementById('pbs-port').value = config.pbs.port || '';
|
||||
document.getElementById('pbs-token-id').value = config.pbs.tokenId || '';
|
||||
document.getElementById('pbs-node-name').value = config.pbs.nodeName || '';
|
||||
}
|
||||
|
||||
if (config.advanced) {
|
||||
if (config.advanced.metricInterval) {
|
||||
document.getElementById('metric-interval').value = config.advanced.metricInterval;
|
||||
}
|
||||
if (config.advanced.discoveryInterval) {
|
||||
document.getElementById('discovery-interval').value = config.advanced.discoveryInterval;
|
||||
}
|
||||
|
||||
// Load alert settings
|
||||
if (config.advanced.alerts) {
|
||||
const alerts = config.advanced.alerts;
|
||||
if (alerts.cpu !== undefined) {
|
||||
document.getElementById('alert-cpu-enabled').checked = alerts.cpu.enabled !== false;
|
||||
if (alerts.cpu.threshold) {
|
||||
document.getElementById('alert-cpu-threshold').value = alerts.cpu.threshold;
|
||||
}
|
||||
}
|
||||
if (alerts.memory !== undefined) {
|
||||
document.getElementById('alert-memory-enabled').checked = alerts.memory.enabled !== false;
|
||||
if (alerts.memory.threshold) {
|
||||
document.getElementById('alert-memory-threshold').value = alerts.memory.threshold;
|
||||
}
|
||||
}
|
||||
if (alerts.disk !== undefined) {
|
||||
document.getElementById('alert-disk-enabled').checked = alerts.disk.enabled !== false;
|
||||
if (alerts.disk.threshold) {
|
||||
document.getElementById('alert-disk-threshold').value = alerts.disk.threshold;
|
||||
}
|
||||
}
|
||||
if (alerts.down !== undefined) {
|
||||
document.getElementById('alert-down-enabled').checked = alerts.down.enabled !== false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user