Commit Graph

124 Commits

Author SHA1 Message Date
rcourtman cb772737e7 Fix platform identity source contracts 2026-05-08 14:54:08 +01:00
rcourtman 31d07e74ce Fix Unraid storage health explanations 2026-05-08 12:18:09 +01:00
rcourtman d7225a45a0 Fix Proxmox guest memory fallbacks
Also fixes Ceph pool threshold resource identity.

Refs #1341
2026-05-05 14:59:29 +01:00
rcourtman fed3b776e0 Fail closed on ambiguous email principal resolution 2026-05-05 09:26:10 +01:00
rcourtman 53a928ee2d Prevent contact-email principal takeover 2026-05-05 09:19:29 +01:00
rcourtman ea0b20cd19 Use strict org principals for runtime access 2026-05-04 23:16:15 +01:00
rcourtman 7af1276c3b Fail closed on blank magic-link principals 2026-05-04 22:43:35 +01:00
rcourtman 7829c3e6ed Pin hosted identity invariants
Resolve hosted magic-link verification through current organization membership so sessions bind to the stored stable user principal instead of token email.

Add the v6 identity invariant contract and static guards covering hosted handoff, checkout, provisioning, and magic-link boundaries.
2026-05-03 23:58:08 +01:00
rcourtman 3e497ecb70 Harden hosted tenant identity keys
Use stable control-plane user IDs as hosted tenant organization principals while preserving email as contact metadata and legacy fallback. Cloud handoff sessions now bind to the signed subject instead of email, seeded tenant orgs store owner/member email separately from durable user IDs, and the subsystem contracts pin that boundary.
2026-05-03 23:28:26 +01:00
rcourtman 82ba940524 Merge linked host disks into guest overviews
Fixes #1438
2026-04-30 14:37:43 +01:00
rcourtman af7d727d45 Gate RAID rebuild alerts on mdstat operation
Parse the /proc/mdstat operation keyword for mdadm arrays and propagate it through host reports, models, unified resources, monitoring views, alert metadata, and AI storage summaries.

Treat recovery and reshape as rebuild signals while silencing routine check and resync maintenance, with fallback rebuild detection only when no mdstat operation is available.

Tests cover mdstat operation parsing plus recovery, check, and resync alert behavior.

Fixes #1446
2026-04-30 14:31:14 +01:00
rcourtman 386099aeee Surface ZFS pool membership on physical disks 2026-04-23 20:38:33 +01:00
rcourtman 242c4b432d Restore linked host-agent disk inventory for guest VMs
Refs #1438
2026-04-22 09:22:46 +01:00
rcourtman c0ac251316 Require target-organization approval for org shares 2026-04-22 09:16:40 +01:00
rcourtman f7c1d9b629 Require accepted org invitations and stable runtime capabilities 2026-04-22 03:06:22 +01:00
rcourtman 847d09d17b Unify settings infrastructure ledger 2026-04-18 14:54:53 +01:00
rcourtman e6b0d47bd6 Gate Docker mutations on authz-plugin posture 2026-04-18 10:45:25 +01:00
rcourtman 31315fb594 Normalize Proxmox special ZFS groups
Refs #1413
2026-04-15 16:40:43 +01:00
rcourtman b38d0ac37e Stabilize RC release backend race proofs 2026-04-11 23:18:44 +01:00
rcourtman 1bde5976a0 Route physical disk drawer IO through canonical history 2026-04-01 23:33:43 +01:00
rcourtman e86494668a Forward-port Proxmox storage pool metadata 2026-04-01 22:54:51 +01:00
Richard Courtman 55df4927e9 fix(hosted): enforce tenant org membership during handoff 2026-03-26 23:14:54 +00:00
rcourtman 2b93a08558 Carry Proxmox pool membership into VM inventory export 2026-03-25 21:58:46 +00:00
rcourtman fadd3ef2bd Prefer linked host disk metrics for Proxmox nodes 2026-03-25 16:49:47 +00:00
rcourtman 27d44fd2bf Tighten connected infrastructure comments 2026-03-19 14:57:59 +00:00
rcourtman 778a2577b6 feat: Pulse v6 release 2026-03-18 16:06:30 +00:00
rcourtman 2fe22c3308 fix(backups): prevent template backups from being flagged as orphaned
Proxmox VM/LXC templates are intentionally excluded from the monitored
guest list, but their backup files exist on storage. The orphan-detection
logic was firing for every template backup because the VMID was never
in the guest lookup maps.

Fix: track template VMID→node pairs in State.templateVMIDs (unexported,
not serialised to API/frontend) during the resources poll loop, expose
via StateSnapshot.TemplateVMIDs, and use in both buildGuestLookups() and
the storage backup node-resolution map so orphan detection treats template
backups as valid. Also preserves the template map through the cluster
health grace-period path (zero-resource preservation), the partial-node
grace-period path, and clears it on instance removal.

Closes #1352
2026-03-17 09:04:22 +00:00
rcourtman caff845c1a fix(ui): use Proxmox tag colours from datacenter config
Pulse was generating tag colours from a hash of the tag name instead
of using the colours configured in Proxmox. Now polls /cluster/options
once per PVE instance and merges the tag-style colour map into state,
which the frontend uses as the first-priority colour source for tag
badges. Falls back to the existing special-tag and hash-based colours
when Proxmox hasn't set a custom colour for a tag.
2026-03-15 19:49:46 +00:00
rcourtman 7dab977d91 Add split memory bar showing Used | Cache | Free segments (#1302)
Show reclaimable buff/cache as a distinct amber segment between used
(green) and free (gray) in the memory bar. This explains why Pulse's
memory percentage differs from Proxmox: Pulse reports cache-aware
usage (MemAvailable) while Proxmox includes cache as used (Total-Free).

Backend: add Cache field to Memory model, derived from MemInfo
(Available - Free). Only uses MemInfo.Free (not FreeMem fallback) to
avoid inflating cache by the balloon gap on ballooned VMs.

Frontend: StackedMemoryBar renders three segments with tooltip
breakdown. Tooltip Free accounts for balloon limit when active.
Percentage label and alerts remain cache-aware (unchanged).
2026-03-10 10:16:14 +00:00
rcourtman a4b0771974 Prevent removed host agents from resurrecting via in-flight reports (#1331)
Host agents removed from the UI would reappear on the next report cycle
because there was no rejection mechanism — unlike Docker agents which
already had resurrection prevention. Mirror the Docker agent pattern:

- Track removed host IDs in a `removedHosts` map with 24hr TTL
- Persist removal records in `State.RemovedHosts` for frontend display
- Reject reports from removed hosts in `ApplyHostReport()`
- Add `AllowHostReenroll()` + API route to clear the block
- Show removed host agents in the Settings UI with "Allow re-enroll"
- Sync removed-agent maps from state on startup for all agent types
- Fix mock integration snapshot missing `RemovedDockerHosts` field
2026-03-09 17:52:34 +00:00
rcourtman 499ab812e3 Fix post-release regressions and lock v5 to single-tenant runtime 2026-03-05 23:46:35 +00:00
rcourtman a4571f580b fix(monitoring): harden VM memory selection and flag repeated VM usage 2026-03-03 16:19:17 +00:00
rcourtman 1170da6a57 fix(ai): serialize linkedVmId/linkedContainerId and harden mention status (#1252)
HostFrontend was missing LinkedVmId and LinkedContainerId fields, so the
frontend dedup aliases for VM/container agents resolved to undefined and
never matched. Also add .trim() to getStatusColor and default host agent
status to 'online' to fix grey status dots.
2026-02-21 22:00:43 +00:00
rcourtman 8c7d507ea4 fix(alerts): make --disk-exclude suppress Proxmox SSD wear/health alerts (#1142)
The --disk-exclude agent flag only filtered local metric collection but
had no effect on server-side Proxmox disk health and SSD wearout alerts,
which poll the Proxmox API directly. Users excluding disks (e.g.
--disk-exclude sda) still received alerts for those disks.

Agent now sends its DiskExclude patterns in each report. The server
stores them on the Host model and consults them during Proxmox disk
polling — excluded disks get a synthetic healthy status passed to
CheckDiskHealth so any existing alerts clear immediately.

Also adds FreeBSD pseudo-filesystem types (fdescfs, devfs, linprocfs,
linsysfs) to the virtual FS filter and /var/run/ to special mount
prefixes, fixing false disk-full alerts on FreeBSD for fdescfs mounts.
2026-02-20 13:31:52 +00:00
rcourtman 2735204638 fix: skip ambiguous shared-storage backups when VMID exists on multiple instances
When two standalone (non-clustered) PVE hosts share the same storage (NFS,
etc.), both instances see the same backup files during polling. Each instance
creates its own StorageBackup entry, causing guests with the same VMID on
different hosts to incorrectly show each other's backups.

Detect shared-storage duplicates by checking if the same volid appears across
multiple instances. When it does AND the VMID is ambiguous (exists on multiple
instances), skip the backup in SyncGuestBackupTimes rather than guessing which
instance owns it. This uses the same ambiguity pattern already applied to PBS
backups.

Fixes #1177
2026-02-11 11:07:28 +00:00
rcourtman c92ccc122e fix(state): deduplicate PVE nodes and AI mention resources (#1217, #1214)
Backend: nodes with the same logical identity (cluster+name) are merged
using a health-weighted preference, preserving host-agent links across
node-ID churn.

Frontend: extract buildMentionResources() with alias-based dedup so
docker hosts and standalone host agents sharing an ID/hostname appear
once in the @ mention autocomplete.
2026-02-09 22:19:55 +00:00
rcourtman 8a48acef1d fix: hotfix 5.1.5 — node duplication, alert scrambling, ntfy resolved formatting
- fix(models): filter nodes by instance in UpdateNodesForInstance to prevent
  PVE node duplication across poll cycles (#1214, #1192, #1217)
- fix(alerts): sort GetActiveAlerts output for stable ordering, preventing
  hostname scrambling in frontend (#1218)
- fix(notifications): add ntfy-specific resolved webhook formatting with
  plain-text body and proper headers (#1213)
- fix(frontend): respect "hide Docker update actions" setting in
  DockerFilter Update All button (#1219)
- fix(frontend): add missing v prefix to GitHub release tag URLs (#1195)
- fix(monitoring): reduce disk detection warning from Warn to Debug to
  eliminate log spam for pass-through disks (#1216)
- chore: bump VERSION to 5.1.5
2026-02-08 11:48:22 +00:00
rcourtman 05266d9062 Show node display name in alerts instead of raw Proxmox node name
Alerts previously showed the raw Proxmox node name (e.g., "on pve") even
when users configured a display name (e.g., "SPACEX") via Settings or the
host agent --hostname flag. This affected the alert UI, email notifications,
and webhook payloads.

Add NodeDisplayName field to the alert chain: cache display names in the
alert Manager (populated by CheckNode/CheckHost on every poll), resolve
them at alert creation via preserveAlertState, refresh on metric updates,
and enrich at read time in GetActiveAlerts. Update models.Alert, the
syncAlertsToState conversion, email templates, Apprise body text, webhook
payloads, and all frontend rendering paths.

Related to #1188
2026-02-04 14:26:44 +00:00
rcourtman 5c18748742 Add SMART disk lifecycle monitoring with historical charts
Expand the smartctl collector to capture detailed SMART attributes (SATA
and NVMe), propagate them through the full data pipeline, persist them
as time-series metrics, and display them in an interactive disk detail
drawer with historical sparkline charts.

Backend: add SMARTAttributes struct, writeSMARTMetrics for persistent
storage, "disk" resource type in metrics API with live fallback.
Frontend: enhanced DiskList with Power-On column and SMART warnings,
new DiskDetail drawer matching NodeDrawer styling patterns, generic
HistoryChart metric support with proper tooltip formatting.
2026-02-04 13:35:40 +00:00
rcourtman dcfa8cf0ba fix: prevent false PBS backup indicators when VMIDs collide across PVE instances (#1177)
When namespace matching fails, the VMID-only fallback now checks whether
the VMID appears on multiple PVE instances. If ambiguous, the fallback
is skipped — preventing backups from being falsely attributed to the
wrong guest. Unique VMIDs still fall back as before.
2026-02-04 10:11:35 +00:00
rcourtman 19a67dd4f3 Update core infrastructure components
Config:
- AI configuration improvements
- API tokens handling
- Persistence layer updates

Host Agent:
- Command execution improvements
- Better test coverage

Infrastructure Discovery:
- Service improvements
- Enhanced test coverage

Models:
- State snapshot updates
- Model improvements

Monitoring:
- Polling improvements
- Guest config handling
- Storage config support

WebSocket:
- Hub tenant test updates

Service Discovery:
- New service discovery module
2026-01-28 16:52:35 +00:00
rcourtman 7f7edfceb4 test: expand backend coverage 2026-01-25 21:08:44 +00:00
rcourtman 0844f2b976 chore: UI improvements and branding updates
Frontend Updates:
- Add AI Intelligence page routing in App.tsx
- Add PulsePatrolLogo brand component
- Update Settings with Pulse Assistant branding
- Update FeaturesStep wizard text
- Minor fixes across Dashboard, Backups, Storage, Kubernetes components

Backend:
- Update license feature handling
- Improve model converters

Tooling:
- Add pulse-check diagnostic script
2026-01-24 22:45:42 +00:00
rcourtman c4ca169e2b feat: add multi-tenant isolation foundation (disabled by default)
Implements multi-tenant infrastructure for organization-based data isolation.
Feature is gated behind PULSE_MULTI_TENANT_ENABLED env var and requires
Enterprise license - no impact on existing users.

Core components:
- TenantMiddleware: extracts org ID, validates access, 501/402 responses
- AuthorizationChecker: token/user access validation for organizations
- MultiTenantChecker: WebSocket upgrade gating with license check
- Per-tenant audit logging via LogAuditEventForTenant
- Organization model with membership support

Gating behavior:
- Feature flag disabled: 501 Not Implemented for non-default orgs
- Flag enabled, no license: 402 Payment Required
- Default org always works regardless of flag/license

Documentation added: docs/MULTI_TENANT.md
2026-01-23 21:42:27 +00:00
rcourtman 289d95374f feat: add multi-tenancy foundation (directory-per-tenant)
Implements Phase 1-2 of multi-tenancy support using a directory-per-tenant
strategy that preserves existing file-based persistence.

Key changes:
- Add MultiTenantPersistence manager for org-scoped config routing
- Add TenantMiddleware for X-Pulse-Org-ID header extraction and context propagation
- Add MultiTenantMonitor for per-tenant monitor lifecycle management
- Refactor handlers (ConfigHandlers, AlertHandlers, AIHandlers, etc.) to be
  context-aware with getConfig(ctx)/getMonitor(ctx) helpers
- Add Organization model for future tenant metadata
- Update server and router to wire multi-tenant components

All handlers maintain backward compatibility via legacy field fallbacks
for single-tenant deployments using the "default" org.
2026-01-22 13:39:06 +00:00
rcourtman ebc29b4fdb feat: show pending apt updates for Proxmox nodes (#1083)
- Add PendingUpdates and PendingUpdatesCheckedAt fields to Node model
- Add GetNodePendingUpdates method to Proxmox client (calls /nodes/{node}/apt/update)
- Add 30-minute polling cache to avoid excessive API calls
- Add pendingUpdates to frontend Node type
- Add color-coded badge in NodeSummaryTable (yellow: 1-9, orange: 10+)
- Update test stubs for interface compliance

Requires Sys.Audit permission on Proxmox API token to read apt updates.
2026-01-21 10:53:36 +00:00
rcourtman 103eb9c3e0 feat(monitoring): auto-detect Docker inside LXC containers
Adds automatic Docker detection for Proxmox LXC containers:
- New HasDocker and DockerCheckedAt fields on Container model
- Docker socket check via connected agents on first run, restart, or start
- Parallel checking with timeouts for efficiency
- Caches results and only re-checks after state transitions

This enables the AI to know which LXC containers are Docker hosts
for better infrastructure guidance.
2026-01-17 14:42:52 +00:00
rcourtman 8c7581d32c feat(profiles): add AI-assisted profile suggestions
Add ability for users to describe what kind of agent profile they need
in natural language, and have AI generate a suggestion with name,
description, config values, and rationale.

- Add ProfileSuggestionHandler with schema-aware prompting
- Add SuggestProfileModal component with example prompts
- Update AgentProfilesPanel with suggest button and description field
- Streamline ValidConfigKeys to only agent-supported settings
- Update profile validation tests for simplified schema
2026-01-15 13:24:18 +00:00
rcourtman 2fdf7906e6 feat(models): add agent profile validation
- Add profile validation for agent configuration
- Implement validation rules for profile fields
2026-01-12 15:21:05 +00:00
rcourtman 1dda538265 fix(models): extend namespace disambiguation to SyncGuestBackupTimes (#1095)
The previous commit fixed namespace disambiguation for backup alerts,
but the Overview display uses SyncGuestBackupTimes to populate backup
timestamps on VMs/Containers. This commit extends the same namespace
matching logic to that function.

Also tightened the matching algorithm to use suffix matching instead
of substring matching, preventing false positives like "pve" matching
"pve-nat".
2026-01-12 15:11:59 +00:00