Skip to content

Commit 97ae118

Browse files
rcourtmanclaude
andcommitted
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>
1 parent a8896ac commit 97ae118

File tree

2 files changed

+233
-4
lines changed

2 files changed

+233
-4
lines changed

server/configApi.js

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,34 @@ class ConfigApi {
2626
host: config.PBS_HOST,
2727
port: config.PBS_PORT || '8007',
2828
tokenId: config.PBS_TOKEN_ID,
29+
nodeName: config.PBS_NODE_NAME,
2930
// Don't send the secret
30-
} : null
31+
} : null,
32+
advanced: {
33+
metricInterval: config.PULSE_METRIC_INTERVAL_MS,
34+
discoveryInterval: config.PULSE_DISCOVERY_INTERVAL_MS,
35+
alerts: {
36+
cpu: {
37+
enabled: config.ALERT_CPU_ENABLED !== 'false',
38+
threshold: config.ALERT_CPU_THRESHOLD
39+
},
40+
memory: {
41+
enabled: config.ALERT_MEMORY_ENABLED !== 'false',
42+
threshold: config.ALERT_MEMORY_THRESHOLD
43+
},
44+
disk: {
45+
enabled: config.ALERT_DISK_ENABLED !== 'false',
46+
threshold: config.ALERT_DISK_THRESHOLD
47+
},
48+
down: {
49+
enabled: config.ALERT_DOWN_ENABLED !== 'false'
50+
}
51+
}
52+
}
3153
};
3254
} catch (error) {
3355
console.error('Error reading configuration:', error);
34-
return { proxmox: null, pbs: null };
56+
return { proxmox: null, pbs: null, advanced: {} };
3557
}
3658
}
3759

@@ -58,10 +80,50 @@ class ConfigApi {
5880
existingConfig.PBS_PORT = config.pbs.port || '8007';
5981
existingConfig.PBS_TOKEN_ID = config.pbs.tokenId;
6082
existingConfig.PBS_TOKEN_SECRET = config.pbs.tokenSecret;
83+
if (config.pbs.nodeName) {
84+
existingConfig.PBS_NODE_NAME = config.pbs.nodeName;
85+
}
6186
// Always allow self-signed certificates by default for PBS
6287
existingConfig.PBS_ALLOW_SELF_SIGNED_CERT = 'true';
6388
}
6489

90+
// Add advanced settings
91+
if (config.advanced) {
92+
// Service intervals
93+
if (config.advanced.metricInterval) {
94+
existingConfig.PULSE_METRIC_INTERVAL_MS = config.advanced.metricInterval;
95+
}
96+
if (config.advanced.discoveryInterval) {
97+
existingConfig.PULSE_DISCOVERY_INTERVAL_MS = config.advanced.discoveryInterval;
98+
}
99+
100+
// Alert settings
101+
if (config.advanced.alerts) {
102+
const alerts = config.advanced.alerts;
103+
if (alerts.cpu) {
104+
existingConfig.ALERT_CPU_ENABLED = alerts.cpu.enabled ? 'true' : 'false';
105+
if (alerts.cpu.threshold) {
106+
existingConfig.ALERT_CPU_THRESHOLD = alerts.cpu.threshold;
107+
}
108+
}
109+
if (alerts.memory) {
110+
existingConfig.ALERT_MEMORY_ENABLED = alerts.memory.enabled ? 'true' : 'false';
111+
if (alerts.memory.threshold) {
112+
existingConfig.ALERT_MEMORY_THRESHOLD = alerts.memory.threshold;
113+
}
114+
}
115+
if (alerts.disk) {
116+
existingConfig.ALERT_DISK_ENABLED = alerts.disk.enabled ? 'true' : 'false';
117+
if (alerts.disk.threshold) {
118+
existingConfig.ALERT_DISK_THRESHOLD = alerts.disk.threshold;
119+
}
120+
}
121+
if (alerts.down) {
122+
existingConfig.ALERT_DOWN_ENABLED = alerts.down.enabled ? 'true' : 'false';
123+
}
124+
}
125+
}
126+
65127
// Write back to .env file
66128
await this.writeEnvFile(existingConfig);
67129

@@ -170,7 +232,14 @@ class ConfigApi {
170232
// Group related settings
171233
const groups = {
172234
'Proxmox VE Settings': ['PROXMOX_HOST', 'PROXMOX_PORT', 'PROXMOX_TOKEN_ID', 'PROXMOX_TOKEN_SECRET', 'PROXMOX_ALLOW_SELF_SIGNED_CERT'],
173-
'Proxmox Backup Server Settings': ['PBS_HOST', 'PBS_PORT', 'PBS_TOKEN_ID', 'PBS_TOKEN_SECRET', 'PBS_ALLOW_SELF_SIGNED_CERT'],
235+
'Proxmox Backup Server Settings': ['PBS_HOST', 'PBS_PORT', 'PBS_TOKEN_ID', 'PBS_TOKEN_SECRET', 'PBS_NODE_NAME', 'PBS_ALLOW_SELF_SIGNED_CERT'],
236+
'Pulse Service Settings': ['PULSE_METRIC_INTERVAL_MS', 'PULSE_DISCOVERY_INTERVAL_MS'],
237+
'Alert System Configuration': [
238+
'ALERT_CPU_ENABLED', 'ALERT_CPU_THRESHOLD', 'ALERT_CPU_DURATION',
239+
'ALERT_MEMORY_ENABLED', 'ALERT_MEMORY_THRESHOLD', 'ALERT_MEMORY_DURATION',
240+
'ALERT_DISK_ENABLED', 'ALERT_DISK_THRESHOLD', 'ALERT_DISK_DURATION',
241+
'ALERT_DOWN_ENABLED', 'ALERT_DOWN_DURATION'
242+
],
174243
'Other Settings': [] // Will contain all other keys
175244
};
176245

src/public/setup.html

Lines changed: 161 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,96 @@ <h2 class="text-xl font-semibold mb-4 text-gray-800 dark:text-gray-200">Primary
9999
</div>
100100
</div>
101101

102+
<!-- Advanced Settings (Optional) -->
103+
<details class="border border-gray-200 dark:border-gray-700 rounded-lg">
104+
<summary class="px-6 py-4 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors">
105+
<span class="text-lg font-medium text-gray-800 dark:text-gray-200">Advanced Settings (Optional)</span>
106+
</summary>
107+
<div class="p-6 pt-0 space-y-4">
108+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
109+
<div>
110+
<label for="metric-interval" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
111+
Metric Update Interval (ms)
112+
</label>
113+
<input type="number" id="metric-interval" name="metric-interval"
114+
placeholder="2000 (default)"
115+
min="1000" max="60000"
116+
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">
117+
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">How often to fetch VM/Container metrics</p>
118+
</div>
119+
120+
<div>
121+
<label for="discovery-interval" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
122+
Discovery Interval (ms)
123+
</label>
124+
<input type="number" id="discovery-interval" name="discovery-interval"
125+
placeholder="30000 (default)"
126+
min="5000" max="300000"
127+
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">
128+
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">How often to discover nodes and VMs</p>
129+
</div>
130+
</div>
131+
132+
<!-- Alert Settings -->
133+
<div class="border-t border-gray-200 dark:border-gray-700 pt-4">
134+
<h3 class="text-md font-medium text-gray-800 dark:text-gray-200 mb-3">Alert Settings</h3>
135+
136+
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-4">
137+
<label class="flex items-center">
138+
<input type="checkbox" id="alert-cpu-enabled" name="alert-cpu-enabled" checked
139+
class="mr-2 rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500">
140+
<span class="text-sm text-gray-700 dark:text-gray-300">CPU Alerts</span>
141+
</label>
142+
<label class="flex items-center">
143+
<input type="checkbox" id="alert-memory-enabled" name="alert-memory-enabled" checked
144+
class="mr-2 rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500">
145+
<span class="text-sm text-gray-700 dark:text-gray-300">Memory Alerts</span>
146+
</label>
147+
<label class="flex items-center">
148+
<input type="checkbox" id="alert-disk-enabled" name="alert-disk-enabled" checked
149+
class="mr-2 rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500">
150+
<span class="text-sm text-gray-700 dark:text-gray-300">Disk Alerts</span>
151+
</label>
152+
<label class="flex items-center">
153+
<input type="checkbox" id="alert-down-enabled" name="alert-down-enabled" checked
154+
class="mr-2 rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500">
155+
<span class="text-sm text-gray-700 dark:text-gray-300">Down Alerts</span>
156+
</label>
157+
</div>
158+
159+
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
160+
<div>
161+
<label for="alert-cpu-threshold" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
162+
CPU Alert Threshold (%)
163+
</label>
164+
<input type="number" id="alert-cpu-threshold" name="alert-cpu-threshold"
165+
placeholder="85 (default)"
166+
min="50" max="100"
167+
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">
168+
</div>
169+
<div>
170+
<label for="alert-memory-threshold" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
171+
Memory Alert Threshold (%)
172+
</label>
173+
<input type="number" id="alert-memory-threshold" name="alert-memory-threshold"
174+
placeholder="90 (default)"
175+
min="50" max="100"
176+
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">
177+
</div>
178+
<div>
179+
<label for="alert-disk-threshold" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
180+
Disk Alert Threshold (%)
181+
</label>
182+
<input type="number" id="alert-disk-threshold" name="alert-disk-threshold"
183+
placeholder="95 (default)"
184+
min="50" max="100"
185+
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">
186+
</div>
187+
</div>
188+
</div>
189+
</div>
190+
</details>
191+
102192
<!-- PBS Configuration (Optional) -->
103193
<div class="border border-gray-200 dark:border-gray-700 rounded-lg p-6">
104194
<h2 class="text-xl font-semibold mb-4 text-gray-800 dark:text-gray-200">Proxmox Backup Server (Optional)</h2>
@@ -122,6 +212,16 @@ <h2 class="text-xl font-semibold mb-4 text-gray-800 dark:text-gray-200">Proxmox
122212
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">
123213
</div>
124214

215+
<div>
216+
<label for="pbs-node-name" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
217+
PBS Node Name
218+
</label>
219+
<input type="text" id="pbs-node-name" name="pbs-node-name"
220+
placeholder="Internal hostname (run 'hostname' on PBS)"
221+
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">
222+
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Required unless token has Sys.Audit permission</p>
223+
</div>
224+
125225
<div>
126226
<label for="pbs-token-id" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
127227
API Token ID
@@ -301,9 +401,33 @@ <h3 class="text-sm font-medium text-green-800 dark:text-green-200">Success!</h3>
301401
host: formData.get('pbs-host'),
302402
port: formData.get('pbs-port') || '8007',
303403
tokenId: formData.get('pbs-token-id'),
304-
tokenSecret: formData.get('pbs-token-secret')
404+
tokenSecret: formData.get('pbs-token-secret'),
405+
nodeName: formData.get('pbs-node-name')
305406
};
306407
}
408+
409+
// Add advanced settings
410+
config.advanced = {
411+
metricInterval: formData.get('metric-interval'),
412+
discoveryInterval: formData.get('discovery-interval'),
413+
alerts: {
414+
cpu: {
415+
enabled: formData.get('alert-cpu-enabled') === 'on',
416+
threshold: formData.get('alert-cpu-threshold')
417+
},
418+
memory: {
419+
enabled: formData.get('alert-memory-enabled') === 'on',
420+
threshold: formData.get('alert-memory-threshold')
421+
},
422+
disk: {
423+
enabled: formData.get('alert-disk-enabled') === 'on',
424+
threshold: formData.get('alert-disk-threshold')
425+
},
426+
down: {
427+
enabled: formData.get('alert-down-enabled') === 'on'
428+
}
429+
}
430+
};
307431

308432
hideMessages();
309433
const button = document.getElementById('save-button');
@@ -353,6 +477,42 @@ <h3 class="text-sm font-medium text-green-800 dark:text-green-200">Success!</h3>
353477
document.getElementById('pbs-host').value = config.pbs.host || '';
354478
document.getElementById('pbs-port').value = config.pbs.port || '';
355479
document.getElementById('pbs-token-id').value = config.pbs.tokenId || '';
480+
document.getElementById('pbs-node-name').value = config.pbs.nodeName || '';
481+
}
482+
483+
if (config.advanced) {
484+
if (config.advanced.metricInterval) {
485+
document.getElementById('metric-interval').value = config.advanced.metricInterval;
486+
}
487+
if (config.advanced.discoveryInterval) {
488+
document.getElementById('discovery-interval').value = config.advanced.discoveryInterval;
489+
}
490+
491+
// Load alert settings
492+
if (config.advanced.alerts) {
493+
const alerts = config.advanced.alerts;
494+
if (alerts.cpu !== undefined) {
495+
document.getElementById('alert-cpu-enabled').checked = alerts.cpu.enabled !== false;
496+
if (alerts.cpu.threshold) {
497+
document.getElementById('alert-cpu-threshold').value = alerts.cpu.threshold;
498+
}
499+
}
500+
if (alerts.memory !== undefined) {
501+
document.getElementById('alert-memory-enabled').checked = alerts.memory.enabled !== false;
502+
if (alerts.memory.threshold) {
503+
document.getElementById('alert-memory-threshold').value = alerts.memory.threshold;
504+
}
505+
}
506+
if (alerts.disk !== undefined) {
507+
document.getElementById('alert-disk-enabled').checked = alerts.disk.enabled !== false;
508+
if (alerts.disk.threshold) {
509+
document.getElementById('alert-disk-threshold').value = alerts.disk.threshold;
510+
}
511+
}
512+
if (alerts.down !== undefined) {
513+
document.getElementById('alert-down-enabled').checked = alerts.down.enabled !== false;
514+
}
515+
}
356516
}
357517
}
358518
} catch (error) {

0 commit comments

Comments
 (0)