Commit Graph

474 Commits

Author SHA1 Message Date
rcourtman b47845ecb8 fix: add instance field to backup/snapshot structs for duplicate node names
addresses #476

added Instance field to StorageBackup and GuestSnapshot structs in both
backend and frontend to properly handle nodes with duplicate hostnames.
updated backup and snapshot counting logic to use instance ID instead of
hostname, consistent with the VM/container/storage count fixes.

this completes the fix for #476 - all counts and groupings now use unique
instance IDs instead of hostnames.
2025-09-30 21:57:05 +00:00
rcourtman 645c97850b fix temperature struct field names in mock generator
fixes build error from using wrong field names (ID/Temperature instead of Core/Temp)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 21:42:12 +00:00
rcourtman 286eba9985 add temperature data to mock nodes
addresses mock data not keeping up with new features added in v4.16.0. mock nodes now generate realistic CPU package, core, and NVMe temperatures to match the temperature monitoring feature.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 21:36:43 +00:00
rcourtman 86d240e70e chore: bump version to v4.16.0 2025-09-30 21:10:14 +00:00
rcourtman 6bfaa8b79a fix: OIDC redirect URL now respects X-Forwarded-Proto header
Addresses #327 - Users behind reverse proxies (Traefik, nginx, etc) were
experiencing redirect loop issues because the redirect URL was being built
with http:// instead of https:// when X-Forwarded-Proto was set.

Changes:
- Build OIDC redirect URL dynamically from each request instead of at startup
- Respect X-Forwarded-Proto and X-Forwarded-Host headers from reverse proxies
- Update UI help text to clarify auto-detection behavior
- Add debug logging to show how redirect URL is constructed

When redirect URL is not explicitly configured, Pulse now builds it from
the incoming request headers, properly detecting HTTPS when behind a proxy.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 21:06:20 +00:00
rcourtman 386bee1aa6 fix: improve OIDC redirect URL validation and help text
addresses #327

Fixed issues when PUBLIC_URL is not set:
- Better error message explaining how to fix missing redirect URL
- Help text now shows actionable guidance instead of incomplete message
- Hide IdP redirect URL hint when no default is available
2025-09-30 20:33:11 +00:00
rcourtman edb8702e77 fix CI errors: remove unused imports and format Go code
addresses unused TypeScript variables and gofmt formatting issues
2025-09-30 19:59:55 +00:00
rcourtman fd52a7add1 improve oidc error logging and documentation
addresses #327

- added detailed logging when ID token verification fails
- added better error messages for common OIDC issues
- updated docs with Authentik-specific configuration
- added troubleshooting section for redirect loops and invalid_id_token errors

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 19:52:55 +00:00
rcourtman 50036fde58 add temperature display and alerting to UI
- add dedicated Temperature column in node summary table with color coding
- add temperature threshold configuration in alert settings
- default threshold: 80°C trigger / 75°C clear
- temperature alerts integrated with existing alert system
- configurable per-node or globally via alert overrides

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 19:31:51 +00:00
rcourtman 745c2b4c6b rebalance temperature monitoring messaging - reassuring but honest
Changed from scary warnings to confident, reassuring tone:

Before:
- "⚠️ IMPORTANT: This grants SSH access..."
- Emphasized risks and compromise scenarios
- Made users feel unsafe enabling the feature

After:
- "Works just like Ansible, Saltstack, etc."
- Emphasizes this is industry-standard approach
- Compares to trusted automation tools
- Focuses on what it does, not what could go wrong
- Still transparent about security model
- Removes duplicate/contradictory sections

The feature is secure and follows best practices. The messaging should
reflect confidence in the design while still being transparent.

Users should feel good about enabling it, not scared.
2025-09-30 19:16:30 +00:00
rcourtman d5bd6c7676 improve SSH setup security messaging for temperature monitoring
- Make it clear SSH setup is OPTIONAL
- Explain security model upfront before user commits
- Detail exactly what access is being granted (root SSH, sensors only)
- Warn users to only proceed if they trust Pulse server
- Better differentiate public vs private keys
- Show exactly where the key is stored
- Explain how to revoke access
- Add comprehensive security documentation
- Include advanced option for command restrictions in authorized_keys
- Add risk assessment and best practices

This ensures users make informed decisions about SSH access to their
critical Proxmox infrastructure.
2025-09-30 19:13:23 +00:00
rcourtman d78c388cd0 add SSH key setup to auto-setup script for temperature monitoring
- Prompts user to set up SSH access during auto-setup
- Guides user to paste their Pulse server's public key
- Adds key to /root/.ssh/authorized_keys
- Installs lm-sensors automatically
- Runs sensors-detect --auto for proper sensor detection
- Optional: user can skip and set up later manually
- Includes validation of SSH key format
- Shows clear instructions for manual setup if skipped

This ensures temperature monitoring works out-of-the-box for users
who run the auto-setup script.
2025-09-30 19:10:45 +00:00
rcourtman 92b3bcd33c add node temperature monitoring via SSH
addresses #101

- Implement SSH-based temperature collector using lm-sensors
- Add Temperature struct to node models (CPU package, cores, NVMe)
- Collect temps during node polling (5s timeout, non-blocking)
- Display temperature in node cards with color coding:
  - Green: <60°C
  - Yellow: 60-80°C
  - Red: >80°C
- Shows CPU temp or falls back to load average if unavailable
- Tooltip includes NVMe drive temps when present
- Uses root SSH access (no additional auth setup needed for now)
- Temperature data only collected for online nodes
2025-09-30 19:08:31 +00:00
rcourtman f7842a0892 improve: add comprehensive debug logging for OIDC troubleshooting
Added detailed debug-level logs throughout the OIDC flow:
- Provider initialization (issuer, endpoints, scopes)
- Login flow tracking (client ID, redirect URL)
- Token exchange success/failure details
- Claims extraction (username, email, groups)
- Access control checks (why restrictions passed/failed)

Enhanced error logs to include issuer URL and actual error details in
audit events instead of generic "failed" messages.

Updated docs with Debug Logging section showing example output and
troubleshooting guidance for common issues like group restrictions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 18:45:30 +00:00
rcourtman 113c20ffe6 fix: prevent silent encryption key regeneration that orphans data
addresses data loss issue where encryption key regeneration silently
orphaned all encrypted configuration (nodes, email, webhooks).

Changes:
- Check for existing .enc files before generating new encryption key
- Refuse to start if encrypted data exists but key is missing/invalid
- Forces explicit user action (restore key backup or delete .enc files)
- Prevents silent data loss from key regeneration

This ensures encrypted data is never accidentally orphaned when the
encryption key is lost or corrupted.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 18:23:24 +00:00
rcourtman 6d35c210be fix: expand timezone list in quiet hours configuration
addresses #477

Expanded the timezone dropdown from 11 options to 70+ common IANA
timezones covering all major regions (Africa, Americas, Asia,
Australia, Europe, Pacific).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 18:13:15 +00:00
rcourtman 88915dce4c chore: bump version to v4.15.1 2025-09-30 17:31:28 +00:00
rcourtman 22fb25ac00 fix: send notifications for critical alerts restored from disk after restart
addresses #471

when pulse restarts (service restart, container restart, etc), active alerts
are loaded from disk but notifications were never sent for these restored
alerts. this caused users to miss critical ongoing alerts that existed before
the restart.

the issue was particularly noticeable with memory alerts on VMs - if a VM's
memory was genuinely high and an alert was created, then pulse restarted, the
alert would show in 'Active Alerts' but no webhook notification would be sent.
however, manually creating a 'fake' alert by lowering thresholds would work
because those are new alerts.

fix: now sends notifications for restored critical alerts that started within
the last 2 hours. adds a 10-second delay after restart to allow the system
to stabilize before sending notifications. warning-level alerts are not
re-notified to avoid spam on restart.
2025-09-30 17:13:53 +00:00
rcourtman 334dbc490d chore: bump version to v4.15.0 2025-09-30 16:21:43 +00:00
rcourtman f9b8037486 fix: resolve install script unbound variables and add update command
Addresses #450, #451, #406

- Initialize all variables at top of script to prevent "unbound variable" errors with set -u
  - BUILD_FROM_SOURCE, SKIP_DOWNLOAD, IN_CONTAINER, IN_DOCKER now set at line 20-27
  - ENABLE_AUTO_UPDATES, FORCE_VERSION, FORCE_CHANNEL, SOURCE_BRANCH also moved to top
  - Removed duplicate assignments from argument parsing section

- Restore /bin/update command creation for ProxmoxVE LXC installations
  - Creates update script that re-runs install.sh for easy updates
  - Allows backend to properly detect ProxmoxVE deployment type
  - Users can now run "update" in LXC console as documented

- Update deployment detection to recognize install.sh in update command
  - Previously only looked for legacy "pulse.sh" reference
  - Now checks for both pulse.sh and install.sh
2025-09-30 16:16:10 +00:00
rcourtman 413ef73953 improve webhook system security and robustness
addresses security vulnerabilities and improves webhook reliability

Changes:
- Add SSRF protection with redirect controls and strict URL validation
- Add response size limits (1MB cap) to prevent memory exhaustion
- Fix race condition in SendTestNotification
- Add per-webhook rate limiting (10 req/min)
- Add Retry-After header support for proper backoff
- Extract magic numbers to configurable constants
- Block localhost, link-local, and cloud metadata endpoints
- Add secure HTTP client with redirect validation
- Remove duplicate function definitions
- Clean up unused code

Security improvements:
- Prevents SSRF attacks via redirect chains
- Protects against DoS via large responses
- Rate limits prevent webhook flooding
- Thread-safe webhook operations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 15:57:28 +00:00
rcourtman 552173b262 fix: improve alert system robustness and security
Addresses multiple issues identified during comprehensive alert system audit:

1. Fix ZFS device loop lock issue
   - Moved lock acquisition outside loop in checkZFSPoolHealth
   - Changed clearAlert to clearAlertNoLock when lock already held
   - Prevents multiple lock acquisitions in same iteration

2. Add alert deduplication on restore
   - Prevents duplicate alerts after service restart
   - Tracks seen alert IDs during LoadActiveAlerts
   - Logs warnings for any duplicates found

3. Add API input validation
   - validateAlertID function prevents DOS attacks
   - Limit alert ID length to 500 characters
   - Whitelist allowed characters (alphanumeric, -, _, :, /, .)
   - Cap history limit parameter at 10,000 records
   - Applied validation to acknowledge, unacknowledge, and clear endpoints

4. Add panic recovery to goroutines
   - All SaveActiveAlerts goroutines now have defer/recover
   - Cleanup goroutines protected from panics
   - Contextual error logging for each goroutine type

5. Document lock ordering
   - Added comprehensive documentation for Manager mutexes
   - Explains m.mu and resolvedMutex relationship
   - Clarifies acquisition rules to prevent deadlocks
   - Inline comments for resolvedMutex field

These fixes improve stability, security, data integrity, and maintainability
of the alert system without breaking API compatibility.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 15:35:39 +00:00
rcourtman 1d987efcc9 docs: fix VM disk monitoring documentation and remove false token limitation claims
Corrected widespread misinformation claiming API tokens cannot access guest agent data on Proxmox 9.

Changes:
- Rewrote VM_DISK_MONITORING.md with accurate technical explanation
- Deleted VM_DISK_STATS_TROUBLESHOOTING.md (contained false information)
- Updated FAQ.md with correct quick reference and troubleshooting link
- Added comprehensive VM disk troubleshooting section to TROUBLESHOOTING.md
- Fixed README.md troubleshooting reference
- Updated frontend tooltip to show accurate permission requirements
- Corrected backend log messages to remove "known limitation" language
- Updated test-vm-disk.sh diagnostic script with accurate guidance

Key corrections:
- API tokens work fine for guest agent queries on both PVE 8 and 9
- Proxmox API returning disk=0 is normal behavior, not a bug
- Both tokens and passwords work equally well
- Only requirements: guest agent installed + proper permissions
- Permission issues are config problems, not authentication method limitations

Documentation now provides clear user journey: FAQ → Troubleshooting → Full Guide

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 15:14:23 +00:00
Pulse Monitor e0e5528fe3 feat: add demo mode with read-only protection
Adds DEMO_MODE environment variable that blocks all write operations
while allowing full read/view functionality. Includes banner notification
in UI when demo mode is active.

Addresses need for safe public demo instances.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 14:46:20 +00:00
Pulse Monitor 3331e1f2ab feat: add real-time streaming discovery and improve dev/mock mode switching
- Added streaming discovery that shows servers as they're found
- Backend sends WebSocket updates for each discovered server
- Frontend displays servers immediately without waiting for full scan
- Created sync-production-config.sh to preserve nodes when switching modes
- Updated toggle-mock.sh to sync config when disabling mock mode
- Dev environment now maintains separate config that syncs from production
- Enabled discovery service in dev environment by default

addresses real-time discovery UX and mock/production mode configuration persistence
2025-09-30 13:13:32 +00:00
rcourtman 5470d2350b Add runtime mock toggles and auth-safe dev assets 2025-09-30 10:02:26 +00:00
rcourtman 013431a139 chore: tidy repo formatting and linting 2025-09-29 20:19:18 +00:00
rcourtman e72d12d86e Refine security settings UI and credential rotation flow 2025-09-29 17:42:10 +00:00
rcourtman 8910e1e379 Fix installer defaults, auth fallbacks, alert persistence, and docs helper 2025-09-29 16:36:33 +00:00
rcourtman 3d78c0a9fa Improve security settings UX and fix alerts typing 2025-09-29 15:52:03 +00:00
rcourtman 9852ef9047 Align dev ports and improve auto-register UX 2025-09-29 15:05:59 +00:00
rcourtman 645c793f82 feat: add OIDC single sign-on 2025-09-29 10:22:27 +00:00
rcourtman 6f4771ae2d feat: unify styling and improve cluster detection 2025-09-28 18:46:52 +00:00
Pulse Monitor 9331ef53ae Revert "fix: only use cluster/resources when IsCluster is true (addresses #448)"
This reverts commit 4a9912f410.
2025-09-11 20:21:08 +00:00
Pulse Monitor 6e8e2d14f5 fix: only use cluster/resources when IsCluster is true (addresses #448)
The aggressive use of cluster/resources was breaking storage collection
for setups with multiple standalone nodes or improperly clustered nodes.
Now only uses cluster/resources when explicitly configured as a cluster,
falling back to traditional node-by-node polling otherwise.

This should fix the missing storage issue where one node's storage
wasn't showing after upgrading to rc5.
2025-09-11 20:18:18 +00:00
Pulse Monitor 1412105f99 fix: preserve storage when node returns empty result but has existing data (addresses #448)
The issue was that when a node was successfully polled but returned empty storage
(e.g., due to API permissions), it was still marked as 'successfully polled'.
This prevented the preservation logic from keeping existing storage data.

Now if a node returns empty storage but we have existing storage for that node,
we don't mark it as polled, allowing the preservation logic to keep the data.

This should fix the issue where storage disappears from one node in #448.
2025-09-11 16:00:25 +00:00
Pulse Monitor d514458fbb fix: improve storage collection resilience when nodes timeout (addresses #448)
- Send error result to channel when storage query times out so preservation logic works
- Ensures storage data is preserved for nodes that experience timeouts
- Fixes issue where storage/backups would disappear when a node times out
2025-09-11 15:51:37 +00:00
Pulse Monitor 47c12a2897 test: create test version for issue #448 2025-09-11 15:01:23 +00:00
Pulse Monitor fea7cbd5d3 fix: preserve storage data when node times out (addresses #448)
When a node's storage query times out, don't return empty storage which would wipe out existing data. Instead, skip the node entirely so the preservation logic can maintain the existing storage information.
2025-09-11 14:55:50 +00:00
Pulse Monitor d1dc451f61 chore: bump version to v4.15.0-rc.7 2025-09-11 14:19:58 +00:00
Pulse Monitor a7ac3a50da chore: bump version to v4.15.0-rc.6 2025-09-11 14:02:05 +00:00
Pulse Monitor 496ab7acdb simplify: remove complex override matching logic in favor of consistent ID generation
Removed the flexible ID matching code that was added for backward compatibility. Since we've fixed the frontend to generate IDs consistently with the backend, we don't need the complexity of trying multiple ID formats.

This keeps the codebase simpler and more maintainable.
2025-09-11 13:34:03 +00:00
Pulse Monitor 9d40e56223 fix: improve alert override ID matching to handle various frontend ID formats (addresses #441)
The frontend can save alert overrides with different ID formats depending on how the cluster is configured. This fix makes the backend more flexible in matching these overrides by:

1. Trying the exact guest ID first
2. Checking for partial matches that end with -node-vmid
3. Trying alternative ID formats like node-vmid and instance-node-vmid

This ensures custom alert thresholds work correctly regardless of the cluster name format used when saving overrides.
2025-09-11 13:25:51 +00:00
Pulse Monitor 67676b291c improve: use efficient cluster/resources endpoint for all nodes
- Always try cluster/resources endpoint first (works on standalone nodes too)
- Only fall back to traditional polling for very old Proxmox versions
- Confirmed working on standalone nodes like pimox
- Significantly reduces API calls and improves performance
- Addresses efficiency concerns from #447
2025-09-11 12:57:32 +00:00
Pulse Monitor e386a83778 cleanup: remove legacy POLLING_INTERVAL env variable (addresses #447)
PVE polling is hardcoded to 10s since Proxmox cluster/resources endpoint only updates every 10s internally. Setting faster polling intervals was wasteful and provided no benefit.

Removed:
- POLLING_INTERVAL env variable and all references
- pollingInterval from config structs and API responses
- UI settings for polling interval (already removed)
- Dynamic polling interval updates via SIGHUP
- Legacy persistence code for saving polling settings

The monitoring loop now uses a hardcoded 10s interval matching Proxmox's update frequency.
2025-09-11 12:33:44 +00:00
Pulse Monitor bd0c817056 fix: handle trailing slashes in node URLs (addresses #428)
Strip trailing slashes and paths from URLs before parsing host:port
to prevent "invalid port number" errors when users add nodes with
URLs like https://192.168.xxx.xxx:8006/
2025-09-11 12:27:24 +00:00
Pulse Monitor 9646f8ed59 fix: correct mock generator guest ID format to match alert system (addresses #441)
Mock VMs and containers were using 'node:qemu/vmid' format but the alert
system expects 'instance-node-vmid' format. This caused custom thresholds
to be ignored for mock guests.
2025-09-11 12:05:55 +00:00
Pulse Monitor 9486e8679d improve: enhance VM disk usage detection for Windows guests (addresses #416)
- Add debug logging to guest agent filesystem API responses
- Better handle Windows drive mountpoints (C:\, D:\, etc.)
- Improve empty filesystem list detection and logging
- Add specific handling for Windows filesystems that may report differently

This should help diagnose why some VMs with guest agents installed still show 0% or missing disk usage, particularly on Windows systems.
2025-09-11 08:47:23 +00:00
Pulse Monitor 1a147bec86 revert: version back to 4.15.0-rc.4 2025-09-11 07:36:48 +00:00
Pulse Monitor b4c7240865 chore: bump version to v4.15.0-rc.5 2025-09-11 07:33:12 +00:00