Pulse/internal/models/state_snapshot.go
Pulse Monitor 7f5dae9b05 feat: Implement security, type safety, and error handling improvements
Security Enhancements:
- Add TLS fingerprint verification for Proxmox and PBS clients
- Create shared tlsutil package for secure TLS handling
- Implement proper CORS checking for WebSocket connections
- Add configurable allowed origins for WebSocket hub

Type Safety Improvements:
- Replace all TypeScript 'any' types with proper interfaces
- Add proper types for connectionHealth, apiCallDuration, metrics values
- Create typed BackupTask and StorageBackup interfaces
- Ensure all TypeScript code passes strict type checking

Error Handling Enhancements:
- Add comprehensive error handling middleware for API routes
- Implement structured error responses with proper status codes
- Add error boundaries to critical frontend components
- Fix WebSocket upgrade issues by preserving http.Hijacker interface
- Implement storage details endpoint (was TODO)

Code Quality:
- Fix Go vet mutex copy issues by creating StateSnapshot type
- Update ToFrontend() to use pointer receiver
- Ensure all code compiles without warnings
- Add proper error recovery and retry mechanisms

All changes tested and verified to work correctly.
2025-07-29 17:53:51 +00:00

56 lines
No EOL
2.1 KiB
Go

package models
import "time"
// StateSnapshot represents a snapshot of the state without mutex
type StateSnapshot struct {
Nodes []Node `json:"nodes"`
VMs []VM `json:"vms"`
Containers []Container `json:"containers"`
Storage []Storage `json:"storage"`
PBSInstances []PBSInstance `json:"pbs"`
PBSBackups []PBSBackup `json:"pbsBackups"`
Metrics []Metric `json:"metrics"`
PVEBackups PVEBackups `json:"pveBackups"`
Performance Performance `json:"performance"`
ConnectionHealth map[string]bool `json:"connectionHealth"`
Stats Stats `json:"stats"`
ActiveAlerts []Alert `json:"activeAlerts"`
RecentlyResolved []ResolvedAlert `json:"recentlyResolved"`
LastUpdate time.Time `json:"lastUpdate"`
}
// GetSnapshot returns a snapshot of the current state without mutex
func (s *State) GetSnapshot() StateSnapshot {
s.mu.RLock()
defer s.mu.RUnlock()
// Create a snapshot without mutex
snapshot := StateSnapshot{
Nodes: append([]Node{}, s.Nodes...),
VMs: append([]VM{}, s.VMs...),
Containers: append([]Container{}, s.Containers...),
Storage: append([]Storage{}, s.Storage...),
PBSInstances: append([]PBSInstance{}, s.PBSInstances...),
PBSBackups: append([]PBSBackup{}, s.PBSBackups...),
Metrics: append([]Metric{}, s.Metrics...),
PVEBackups: PVEBackups{
BackupTasks: append([]BackupTask{}, s.PVEBackups.BackupTasks...),
StorageBackups: append([]StorageBackup{}, s.PVEBackups.StorageBackups...),
GuestSnapshots: append([]GuestSnapshot{}, s.PVEBackups.GuestSnapshots...),
},
Performance: s.Performance,
ConnectionHealth: make(map[string]bool),
Stats: s.Stats,
ActiveAlerts: append([]Alert{}, s.ActiveAlerts...),
RecentlyResolved: append([]ResolvedAlert{}, s.RecentlyResolved...),
LastUpdate: s.LastUpdate,
}
// Copy map
for k, v := range s.ConnectionHealth {
snapshot.ConnectionHealth[k] = v
}
return snapshot
}