- ntfy template headers contained Go template syntax that wasn't being processed
- Added special handling for ntfy webhooks to set Title, Priority, and Tags dynamically
- Headers are now set based on actual alert level and details
- Ignores template-syntax headers from webhook config to prevent errors
- Fixes issue where ntfy webhooks with preset headers would fail to send
- Automatically detects the machine's IP address for webhook 'View in Pulse' links
- Checks multiple methods: Proxmox container, outbound IP, Docker, network interfaces
- Falls back through detection methods to find the best IP
- Users no longer need to manually set PULSE_PUBLIC_URL in most cases
- Manual configuration still takes precedence if set
When a VM doesn't have QEMU guest agent configured, Proxmox returns a 500 error.
This was incorrectly marking the entire cluster node as unhealthy, preventing
all operations on that node. Now we treat these as VM-specific errors that
don't affect node health status.
- Storage queries can timeout on large clusters or slow storage backends
- Extended timeout specifically for GetStorage, GetStorageContent, and GetAllStorage
- Preserves existing context deadlines if they're shorter than 120s
- Should resolve 'context deadline exceeded' errors during storage polling
Critical fix: Local storage (local, local-zfs) should NEVER be deduplicated
as each node has its own physical storage with different capacities and usage.
Only shared storage (like PBS) should be deduplicated. Each node's local
storage now correctly appears as a separate entry.
PBS storage should respect Proxmox's shared configuration. When PBS
storage is configured without node restrictions in Proxmox, it appears
as shared storage accessible by all nodes. Updated mock data to match
real cluster behavior where PBS entries appear under 'cluster' group.
PBS storage entries pointing to the same server (same capacity) are now
truly deduplicated. Instead of showing 3 entries for pbs-pve1, pbs-pve2,
and pbs-pve3, it now shows a single 'PBS Storage' entry with all namespaces
listed. This provides actual deduplication for identical storage resources.
The storage view now deduplicates identical storage entries (like PBS
storage that appears on multiple nodes). Instead of showing pbs-pve1
three times, it shows it once with all nodes listed (pve1, pve2, pve3).
This provides a cleaner view of actual storage resources.
Mock data now accurately replicates production PBS storage where:
- Each node sees ALL PBS storage entries (pbs-pve1, pbs-pve2, pbs-pve3)
- Storage sizes and usage match production (~950GB, 14% used)
- Each PBS entry has a node-specific namespace but appears on all nodes
- PBS storage is correctly marked as not shared
Mock data now properly simulates PBS storage behavior where each node
reports all PBS namespaces (pbs-pve1, pbs-pve2, pbs-pve3). This accurately
replicates real cluster behavior where each node has access to all PBS
namespaces but they're node-specific and not shared.
PBS storage was being marked as shared when it shouldn't be. Each PBS
namespace is node-specific even when connecting to the same PBS server.
Now PBS storage correctly shows under its respective node instead of
all being assigned to the last node.
Mock cluster nodes now correctly show degraded state (yellow) when
some nodes are offline. This properly demonstrates the degraded cluster
functionality for issue #379.
Mock cluster endpoints were showing grey dots because the Online field
wasn't being set based on the node status. Now properly reflects the
node's online/offline status with green/grey indicators.
When some cluster nodes are offline but the main node can still reach others,
show a yellow status dot instead of red to indicate partial connectivity.
This better represents the actual cluster health state.
Added built-in Pushover template alongside Discord, Telegram, Gotify, and ntfy. Users can now select Pushover from the service dropdown instead of manually configuring it as a generic webhook.
PMG host configuration backups (VMID=0) are now correctly shown as "Host" type
in the backup list instead of being incorrectly labeled as "LXC" containers.
Also added mock data for testing VMID 0 host backups.
The acknowledge/unacknowledge/clear endpoints were returning 404 due to incorrect path trimming in HandleAlerts. The router was registered with /api/alerts/ but the handler was trimming /api/alerts, causing path parsing to be off by one character.
- Added migration to automatically enable MonitorBackups for PBS instances
- This fixes the issue where PBS backups weren't showing for some users
- The migration runs on startup and persists the changes
- All new PBS instances already have MonitorBackups enabled by default
- Added to CONFIGURATION.md environment variables section
- Added to WEBHOOKS.md for Gotify and ntfy services
- Added to DOCKER.md environment variables reference and compose example
- Explains how to configure the full Pulse URL for webhook notification links
- Added PULSE_PUBLIC_URL config option to specify the full URL to access Pulse
- Updated notification manager to use publicURL when constructing webhook payloads
- Modified prepareWebhookData to construct full URLs instead of just paths
- Fixed test webhooks to use configured publicURL instead of hardcoded values
- Gotify and ntfy notifications now include clickable links that work properly
- Windows System Reserved partitions now excluded from disk usage
- Added better handling for filesystems with zero total bytes
- Improved debug logging for skipped filesystems
- Prevents incorrect disk usage display for Windows VMs
- Added storage permission errors (403) to exception list
- Permission denied errors no longer mark nodes as unhealthy
- Storage polling can now continue even with permission issues
- Prevents cascading failures when storage permissions are missing
- Nodes remain healthy for VM/container operations even if storage fails
- Removed all complex recovery mechanisms from documentation
- Clear stance: forgotten password = start fresh (takes 2 minutes)
- No recovery mechanisms = no security vulnerabilities
- Pulse's simplicity is a feature, not a bug
- Updated both TROUBLESHOOTING.md and SECURITY.md
- Addresses GitHub discussion #413 with security-first approach
- Changed cluster client initialization to be optimistic (assume healthy)
- Nodes now start as healthy and are marked unhealthy only on actual failures
- This prevents the issue where all nodes were marked unhealthy during init
- Storage operations can now proceed even if initial health checks fail
- Allows recovery from temporary network or auth issues during startup
- Added Custom Headers section explaining the new UI feature
- Updated ntfy instructions with security note about topic names
- Added common header examples table for authentication
- Clarified how to add Bearer tokens and API keys
- Added custom headers section to webhook configuration UI
- Users can now add, edit, and remove custom headers for authentication
- Updated ntfy instructions to be clearer about adding Authorization headers
- Supports Bearer tokens, API keys, and other custom headers
- Created nodeColors utility to generate consistent colors based on node names
- Provides a palette of 15 distinct colors that work in light/dark modes
- Can be used for future visual identification needs without conflicting with existing indicators
Tag indicators next to guest names now properly update their colors when switching between dark and light modes. Previously they would only update on the next data refresh cycle.
- Added reactive DarkModeContext for theme state management
- Updated TagBadges component to use reactive dark mode signal
- Made color calculations reactive to respond to theme changes
- Fixed shared storage jumping between nodes on each update by using consistent deduplication
- Shared storage now displays with node="cluster" to indicate it's cluster-wide
- Improved error logging when storage API calls fail to help diagnose permission issues
- Added specific warning when all nodes fail to retrieve storage (helps with #385, #411)
The jumping storage issue (#410) was caused by a race condition where parallel goroutines
would report shared storage under whichever node completed first, causing it to randomly
"jump" between nodes on each polling cycle.
- Enhanced WebSocket sync prevention with smarter pending change detection
- Increased protection timeout from 2s to 5s with smart clearing
- Server state now properly checked before clearing pending flags
- Button remains disabled for 1.5s after action to prevent race conditions
- API calls now complete before local state updates
- No local state update on API errors to maintain consistency
This should prevent the acknowledge/unacknowledge flip-flopping issue
- Added CheckStorage calls in parallel storage polling (was missing, causing storage alerts to not trigger)
- Fixed node cleanup logic to use alert.Node field directly instead of parsing IDs
- Removed auto-acknowledge on alert click - now only acknowledge button toggles state
- Added unacknowledge button for acknowledged alerts
- Fixed double-toggle issue with acknowledge button using race condition prevention
- Fixed tab menu width in Alerts and Settings pages (changed flex-shrink-0 to flex-1)
addresses #228 (storage alert threshold issue)
- Replace border-left with inset box-shadow for alert indicators
- Prevents unprofessional gaps between background and table edges
- Add alert support to NodeSummaryTable with same gap-free technique
- Generate offline alerts in mock data for testing
- Fix alert matching to use full resource ID for nodes
- Enable alert cooldown by default (5 minutes) to prevent notification spam
- Enable rate limiting by default (10 alerts/hour) to prevent flooding
- Enable smart grouping by default (30 second window, group by node)
- Keep quiet hours disabled by default (requires user configuration)
- Keep escalation disabled by default (requires user setup)
These defaults provide sensible protection against notification overload
while allowing users to opt-in to more advanced scheduling features