Commit graph

4826 commits

Author SHA1 Message Date
rcourtman
032d12db8f deps: Update systemd, grpc-gateway, and pflag packages
- github.com/coreos/go-systemd/v22 v22.5.0 => v22.6.0
- github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 => v2.27.3
- github.com/spf13/pflag v1.0.9 => v1.0.10
2025-12-02 17:44:07 +00:00
rcourtman
95bcda21da deps: Update prometheus, compress, and protobuf packages
- github.com/klauspost/compress v1.18.0 => v1.18.2
- github.com/prometheus/common v0.66.1 => v0.67.4
- github.com/prometheus/procfs v0.16.1 => v0.19.2
- go.yaml.in/yaml/v2 v2.4.2 => v2.4.3
- google.golang.org/protobuf v1.36.8 => v1.36.10
2025-12-02 17:42:03 +00:00
rcourtman
e74b09557d fix: trigger Docker publish workflow in release pipeline
The release workflow publishes via GitHub API (patching draft to
published), which doesn't fire the release webhook. This meant the
Docker publish workflow was never triggered automatically.

Added explicit workflow dispatch for publish-docker.yml after release
publish, similar to how update-demo-server.yml was already dispatched.

Related to #797
2025-12-02 17:32:30 +00:00
rcourtman
4f824ab148 style: Apply gofmt to 37 files
Standardize code formatting across test files and monitor.go.
No functional changes.
2025-12-02 17:21:48 +00:00
rcourtman
1a5acc2542 refactor: Remove duplicate IsPasswordHashed from auth package
The config package has a more robust IsPasswordHashed function that
handles truncated hashes. The auth package had a simpler duplicate
that was only used in tests. Removed the duplicate and its test
(already covered by config/config_utils_test.go).

Reduces deadcode findings from 7 to 6.
2025-12-02 17:19:07 +00:00
rcourtman
b66eb5cc83 deps: Update golang.org/x packages to latest versions
Updated direct dependencies:
- golang.org/x/oauth2: v0.31.0 -> v0.33.0
- golang.org/x/sync: v0.13.0 -> v0.18.0
- golang.org/x/time: v0.13.0 -> v0.14.0

All tests pass.
2025-12-02 17:03:16 +00:00
rcourtman
7075c8118e deps: Update key dependencies to latest versions
Updated direct dependencies:
- github.com/coreos/go-oidc/v3: v3.15.0 -> v3.17.0 (OIDC authentication)
- github.com/docker/docker: v28.5.1 -> v28.5.2 (Docker client)
- github.com/shirou/gopsutil/v4: v4.25.9 -> v4.25.11 (system monitoring)
- github.com/spf13/cobra: v1.9.1 -> v1.10.1 (CLI framework)

Transitive dependency updates:
- github.com/go-jose/go-jose/v4: v4.0.5 -> v4.1.3 (JWT library)
- github.com/spf13/pflag: v1.0.7 -> v1.0.9
- github.com/ebitengine/purego: v0.9.0 -> v0.9.1
- github.com/tklauser/go-sysconf: v0.3.15 -> v0.3.16
- github.com/tklauser/numcpus: v0.10.0 -> v0.11.0

All tests pass with updated dependencies.
2025-12-02 16:59:13 +00:00
rcourtman
e5f1289239 refactor: Remove duplicate isLoopback function from hostagent
The isLoopback function in internal/hostagent/agent.go was unused in
production code - it was a duplicate of the same function in
internal/hostmetrics/collector.go which is actively used.

Removed the dead code along with its associated tests to reduce
maintenance burden and improve code clarity.
2025-12-02 16:52:55 +00:00
rcourtman
cf26ed7f12 security: Add request body size limits to remaining API handlers
Add http.MaxBytesReader to 8 additional handlers to complete API
hardening against memory exhaustion attacks:

- guest_metadata.go: HandleUpdateMetadata (16KB)
- notification_queue.go: RetryDLQItem, DeleteDLQItem (8KB each)
- temperature_proxy.go: HandleRegister (8KB)
- host_agents.go: HandleReport (256KB)
- updates.go: HandleApplyUpdate (8KB)
- docker_metadata.go: HandleUpdateMetadata (16KB)
- system_settings.go: UpdateSystemSettings (64KB)

All API handlers that decode JSON request bodies now have size limits.
2025-12-02 16:47:13 +00:00
rcourtman
b4d497ce3b security: Add request body size limits to API handlers
Add http.MaxBytesReader to 16 additional handlers to prevent memory
exhaustion attacks via oversized request bodies:

- docker_agents.go: HandleReport (512KB), HandleCommandAck (8KB),
  HandleSetCustomDisplayName (8KB)
- alerts.go: UpdateAlertConfig (64KB), BulkAcknowledgeAlerts (32KB),
  BulkClearAlerts (32KB)
- config_handlers.go: HandleAddNode, HandleTestConnection,
  HandleUpdateNode, HandleTestNodeConfig (32KB each),
  HandleVerifyTemperatureSSH, HandleExportConfig, HandleDiscoverServers,
  HandleSetupScriptURL (8KB each), HandleImportConfig (1MB),
  HandleUpdateMockMode (16KB)
2025-12-02 16:43:13 +00:00
rcourtman
6eb7f06df1 security: Add request body size limits to notification handlers
Add http.MaxBytesReader limits to prevent memory exhaustion attacks:
- UpdateEmailConfig: 32KB limit
- UpdateAppriseConfig: 64KB limit
- CreateWebhook: 64KB limit
- UpdateWebhook: 64KB limit

This follows the pattern already used in system_settings.go for
SSH config validation.
2025-12-02 16:37:30 +00:00
rcourtman
c4fef5e560 test: Fix unreachable code warning in panic recovery test
Refactor the test to avoid unreachable code after panic by
checking a flag set before the panic instead of after. This
resolves the go vet warning while maintaining test coverage.
2025-12-02 16:30:31 +00:00
rcourtman
322573157e refactor: Use zerolog instead of fmt.Printf in config export
Replace raw fmt.Printf calls with structured zerolog logging for
consistency with the rest of the codebase. This improves log
formatting and enables proper log level filtering.
2025-12-02 16:27:54 +00:00
rcourtman
ed9907accb test: Add tests for SyncGuestBackupTimes and UpdateStorageBackupsForInstance
Add tests for the remaining uncovered State methods:
- SyncGuestBackupTimes: Tests backup time sync from storage and PBS backups
- UpdateStorageBackupsForInstance: Tests storage backup updates with instance isolation

Improves internal/models coverage from 89.6% to 95.6%.
2025-12-02 16:22:38 +00:00
rcourtman
1df5897369 test: Add tests for Ceph, backup, replication, and snapshot methods
Add tests for previously uncovered State methods:
- UpdateCephClustersForInstance
- UpdateBackupTasksForInstance
- UpdateReplicationJobsForInstance
- UpdateGuestSnapshotsForInstance

Improves internal/models coverage from 80.4% to 89.6%.
2025-12-02 16:20:11 +00:00
rcourtman
f044b42e39 test: Add more State method tests for coverage
Add tests for previously uncovered State methods:
- UpdatePhysicalDisks
- UpdateStorageForInstance
- UpdatePBSInstances / UpdatePBSInstance
- UpdatePMGInstances / UpdatePMGInstance

Improves internal/models coverage from 71.9% to 80.4%.
2025-12-02 16:17:04 +00:00
rcourtman
9d57025a88 test: Add tests for state connection health and backup methods
Add tests for previously uncovered State methods:
- SetConnectionHealth / RemoveConnectionHealth
- UpdatePBSBackups
- UpdatePMGBackups

Improves internal/models coverage from 67.0% to 71.9%.
2025-12-02 16:14:40 +00:00
rcourtman
b9db9c140b docs: Add godoc comments to more exported functions
Add missing godoc comments to:
- BuildGuestKey in alerts/alerts.go
- GenerateMockData in mock/generator.go
- NewDockerUpdater, NewAURUpdater in updates/adapter_installsh.go
- NewMockUpdater in updates/mock_updater.go
2025-12-02 16:03:57 +00:00
rcourtman
c05817f9de docs: Add godoc comments to exported functions
Add missing godoc comments to:
- NewRateLimiter and Allow in ratelimit.go
- SnapshotSyncStatus in temperature_proxy.go
- NewClient and GetVersion in pkg/pmg/client.go
2025-12-02 15:58:59 +00:00
rcourtman
097976321b perf: Cache hostname lowercase in temperature proxy lookups
Pre-compute strings.ToLower(hostname) before loops that search for
matching PVE instances. Avoids repeated lowercasing in two functions.
2025-12-02 15:43:41 +00:00
rcourtman
98d170e087 perf: Cache err.Error() in cluster node validation
Cache err.Error() result in two locations in config_handlers.go:
- TLS mismatch detection (3x calls to 1)
- Standalone node detection (2x calls to 1)
2025-12-02 15:41:18 +00:00
rcourtman
0bc58f678e perf: Cache err.Error() in storage timeout error handling
Cache err.Error() result in two locations:
- monitor.go: storage query retry logic (2x calls to 1)
- monitor_polling.go: storage timeout handling (2x calls to 1)
2025-12-02 15:39:37 +00:00
rcourtman
dc707b2225 perf: Cache err.Error() in disk monitoring error handling
Compute err.Error() once and reuse errStr instead of calling Error()
four times when checking disk monitoring error types.
2025-12-02 15:37:48 +00:00
rcourtman
85487b0058 perf: Cache lowercase RAID state in alerts processing
Compute strings.ToLower(array.State) once and reuse stateLower instead
of calling ToLower three times when checking RAID array status.
2025-12-02 15:35:32 +00:00
rcourtman
884c85c2ab chore: Remove debug logging that exposed config JSON
Removed two DEBUG log statements that were logging full nodes config
JSON at Info level. This was verbose and potentially exposed sensitive
configuration data (credentials, tokens) in logs.
2025-12-02 15:32:02 +00:00
rcourtman
a4edd6229f perf: Cache lowercase error string in guest agent error handling
Compute strings.ToLower(errStr) once and reuse errStrLower instead of
calling ToLower three times on the same string in permission check.
2025-12-02 15:26:40 +00:00
rcourtman
9dbfc3216c perf: Remove redundant fmt.Sprintf in tempproxy contains function
The fmt.Sprintf("%v", s) call was pointless since s is already a string.
Removing this unnecessary conversion.
2025-12-02 15:24:40 +00:00
rcourtman
c81bbba8a3 perf: Use strconv.Itoa instead of fmt.Sprintf for int conversion
strconv.Itoa is faster than fmt.Sprintf("%d", ...) because it doesn't
need to parse a format string. Changed 4 occurrences in monitoring
package where integers are converted to strings.
2025-12-02 15:21:41 +00:00
rcourtman
0989e9c671 perf: Pre-compile regexes in updates/version package
Move regex compilation from function bodies to package-level variables
to avoid recompilation when parsing version strings.

Affected regexes:
- semverRe: Matches semantic version format (X.Y.Z-prerelease+build)
- rcNumRe: Extracts RC number from prerelease strings

These are called multiple times during version comparison and update checks.
2025-12-02 15:14:15 +00:00
rcourtman
5d7bb8d461 perf: Pre-compile regexes in mdadm package
Move regex compilation from function bodies to package-level variables
to avoid recompilation on each RAID array check during polling cycles.

Affected regexes:
- mdDeviceRe: Matches md device names in /proc/mdstat
- slotRe: Matches device slot lines in mdadm --detail output
- speedRe: Extracts rebuild speed from /proc/mdstat
2025-12-02 15:11:04 +00:00
rcourtman
f0da506524 fix: Properly show disabled storage status from Proxmox
Storage that is disabled in Proxmox (Datacenter > Storage > enabled=no)
was incorrectly showing as "available" in Pulse. The issue was that
Enabled/Active fields defaulted to true and were never set to false
from the per-node API response.

Now the model correctly initializes Enabled/Active from the Proxmox
per-node storage API response, and the status determination prioritizes
checking the disabled state first.

Related to #796
2025-12-02 15:03:40 +00:00
rcourtman
3cba9a32ee refactor: Remove unreachable dead code branches
- parseDetail: Remove len(parts) != 2 check after SplitN(line, ":", 2)
  when we already verified line contains ":" (SplitN always returns 2)

Function improved from 96.4% to 98.1% coverage.
2025-12-02 15:00:26 +00:00
rcourtman
80baf3ad95 refactor: Remove unreachable dead code branches
- checkOrigin: Remove redundant same-origin check at line 155 that was
  already handled at line 116 (origin == requestOrigin)

Function improved from 95.1% to 97.4% coverage.
2025-12-02 14:56:35 +00:00
rcourtman
fe77d44620 refactor: Remove unreachable dead code branches
- Host.ToFrontend: Remove redundant h.DisplayName check after struct
  initialization already set host.DisplayName = h.DisplayName

Function now at 100% coverage.
2025-12-02 14:53:07 +00:00
rcourtman
b6ae5d5e24 refactor: Remove unreachable dead code branches
- errors.isRetryable: Convert final case to default (all ErrorType values covered)
- scheduler.SelectInterval: Remove bounds checks after mathematical computation
  that guarantees target ∈ [min, max]

Both functions now at 100% coverage.
2025-12-02 14:48:57 +00:00
rcourtman
158669296e refactor: Remove unreachable dead code branches
- firstForwardedValue: strings.Split always returns at least one element
- shouldRunBackupPoll: remaining is always >= 1 by math
- convertContainerDiskInfo: lowerLabel is never empty for non-rootfs

All three functions now at 100% coverage.
2025-12-02 14:41:53 +00:00
rcourtman
629645a2a0 test: Add UpdateStatus not found test for notifications package 2025-12-02 14:26:17 +00:00
rcourtman
049d6946ae test: Add DispatchDue enqueue error test for monitoring package 2025-12-02 14:21:25 +00:00
rcourtman
89b624c731 test: Add NewNotificationQueue invalid path test for notifications package 2025-12-02 14:17:05 +00:00
rcourtman
69bcd6ab0f test: Add SessionStore.load legacy format tests for API package 2025-12-02 14:12:32 +00:00
rcourtman
463d1087ba test: Add CSRFTokenStore.load format tests for API package
Cover legacy JSON format migration and current format with nil/expired
entries. Improves load function coverage from 67.9% to 100%.
2025-12-02 14:07:00 +00:00
rcourtman
9a40157aea test: Add CheckAuth tests for API package
Add tests for sliding expiration session validation and no-auth
configured scenarios. These test explicit paths for better coverage
documentation even though they were already exercised indirectly.
2025-12-02 13:57:23 +00:00
rcourtman
bbbeb45973 test: Add CheckCSRF valid token test for 100% coverage
Test the success path where a valid CSRF token is provided with a
matching session. This covers the final branch in CheckCSRF.
2025-12-02 13:51:27 +00:00
rcourtman
fca712430e test: Add singleAlertTemplate type coverage tests
Cover io type (formats as "I/O") and custom type (uses titleCase)
branches that were previously untested in the email template.
2025-12-02 13:45:49 +00:00
rcourtman
f4397b1512 test: Add ValidateWebhookURL edge case tests for notifications package
Cover empty URL, invalid scheme, missing hostname, cloud metadata
endpoints, loopback variants, and IPv6 link-local addresses.
2025-12-02 13:41:34 +00:00
rcourtman
f2fdec9bd3 test: Add HandleSetupScript PBS path tests for API package
Cover the PBS script generation branch that was previously untested.
Verifies PBS-specific content, auth token handling, and placeholder host.
2025-12-02 13:36:23 +00:00
rcourtman
3970b9f9f5 test: Add CheckAuth tests for API package
Cover proxy auth headers, OIDC session validation, and session cookie
paths that were previously untested.
2025-12-02 13:32:21 +00:00
rcourtman
6065e9fbb0 test: Add CheckProxyAuth tests for API package
Add comprehensive direct tests for the CheckProxyAuth function covering:
- Not configured (returns false)
- Invalid secret (returns false)
- Missing secret header (returns false)
- Valid secret without user header configured (returns true, admin)
- Missing user header when configured (returns false)
- Valid auth with username (returns true with username)
- Role checking with empty roles header (defaults to admin)
- Role checking with admin role present (returns admin=true)
- Role checking without admin role (returns admin=false)
- Custom role separator (comma instead of pipe)
- Role with whitespace (trimmed correctly)

Coverage: CheckProxyAuth 89.3% → 100%
2025-12-02 13:28:02 +00:00
rcourtman
347f75541c test: Add ValidateSession tests for API package
Add comprehensive tests for the ValidateSession wrapper function covering:
- Non-existent token (returns false)
- Empty token (returns false)
- Valid token (returns true)
- Expired token (returns false)

The ValidateSession function is a simple wrapper around the SessionStore's
ValidateSession method, but having direct tests ensures the wrapper is
exercised and documents its expected behavior.

Coverage: ValidateSession 0% → 100%
2025-12-02 13:22:45 +00:00
rcourtman
0b5cbbe335 test: Add ensureScope tests for API package
Add comprehensive tests for the ensureScope function covering:
- Empty scope parameter (always allows access)
- No token in context (session-based request, allows access)
- Token with matching scope (allows access)
- Token with multiple scopes including required one (allows access)
- Token missing required scope (rejects with 403)
- Token with empty scopes (defaults to wildcard, allows access)
- Rejection returns proper JSON response format

Coverage: ensureScope 0% → 100%
Coverage: API package 32.1% → 32.2%
2025-12-02 13:19:11 +00:00