mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-11 21:28:15 +00:00
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.
178 lines
No EOL
4.2 KiB
Go
178 lines
No EOL
4.2 KiB
Go
package models
|
|
|
|
import (
|
|
"strings"
|
|
)
|
|
|
|
// ToFrontend converts a State to StateFrontend
|
|
func (s *State) ToFrontend() StateFrontend {
|
|
// Convert nodes
|
|
nodes := make([]NodeFrontend, len(s.Nodes))
|
|
for i, n := range s.Nodes {
|
|
nodes[i] = n.ToFrontend()
|
|
}
|
|
|
|
// Convert VMs
|
|
vms := make([]VMFrontend, len(s.VMs))
|
|
for i, v := range s.VMs {
|
|
vms[i] = v.ToFrontend()
|
|
}
|
|
|
|
// Convert containers
|
|
containers := make([]ContainerFrontend, len(s.Containers))
|
|
for i, c := range s.Containers {
|
|
containers[i] = c.ToFrontend()
|
|
}
|
|
|
|
// Convert storage
|
|
storage := make([]StorageFrontend, len(s.Storage))
|
|
for i, st := range s.Storage {
|
|
storage[i] = st.ToFrontend()
|
|
}
|
|
|
|
return StateFrontend{
|
|
Nodes: nodes,
|
|
VMs: vms,
|
|
Containers: containers,
|
|
Storage: storage,
|
|
PBS: s.PBSInstances,
|
|
Metrics: make(map[string]any),
|
|
PVEBackups: s.PVEBackups,
|
|
Performance: make(map[string]any),
|
|
ConnectionHealth: s.ConnectionHealth,
|
|
Stats: make(map[string]any),
|
|
LastUpdate: s.LastUpdate.Unix() * 1000, // JavaScript timestamp
|
|
}
|
|
}
|
|
|
|
// ToFrontend converts a Node to NodeFrontend
|
|
func (n Node) ToFrontend() NodeFrontend {
|
|
return NodeFrontend{
|
|
ID: n.ID,
|
|
Node: n.Name,
|
|
Name: n.Name,
|
|
Instance: n.Instance,
|
|
Status: n.Status,
|
|
Type: n.Type,
|
|
CPU: n.CPU,
|
|
Mem: n.Memory.Used,
|
|
MaxMem: n.Memory.Total,
|
|
Disk: n.Disk.Used,
|
|
MaxDisk: n.Disk.Total,
|
|
Uptime: n.Uptime,
|
|
LoadAverage: n.LoadAverage,
|
|
KernelVersion: n.KernelVersion,
|
|
PVEVersion: n.PVEVersion,
|
|
CPUInfo: n.CPUInfo,
|
|
LastSeen: n.LastSeen.Unix() * 1000,
|
|
ConnectionHealth: n.ConnectionHealth,
|
|
}
|
|
}
|
|
|
|
// ToFrontend converts a VM to VMFrontend
|
|
func (v VM) ToFrontend() VMFrontend {
|
|
vm := VMFrontend{
|
|
ID: v.ID,
|
|
VMID: v.VMID,
|
|
Name: v.Name,
|
|
Node: v.Node,
|
|
Instance: v.Instance,
|
|
Status: v.Status,
|
|
Type: v.Type,
|
|
CPU: v.CPU,
|
|
CPUs: v.CPUs,
|
|
Mem: v.Memory.Used,
|
|
MaxMem: v.Memory.Total,
|
|
Disk: v.Disk.Used,
|
|
MaxDisk: v.Disk.Total,
|
|
NetIn: zeroIfNegative(v.NetworkIn),
|
|
NetOut: zeroIfNegative(v.NetworkOut),
|
|
DiskRead: zeroIfNegative(v.DiskRead),
|
|
DiskWrite: zeroIfNegative(v.DiskWrite),
|
|
Uptime: v.Uptime,
|
|
Template: v.Template,
|
|
Lock: v.Lock,
|
|
LastSeen: v.LastSeen.Unix() * 1000,
|
|
}
|
|
|
|
// Convert tags array to string
|
|
if len(v.Tags) > 0 {
|
|
vm.Tags = strings.Join(v.Tags, ",")
|
|
}
|
|
|
|
// Convert last backup time if not zero
|
|
if !v.LastBackup.IsZero() {
|
|
vm.LastBackup = v.LastBackup.Unix() * 1000
|
|
}
|
|
|
|
return vm
|
|
}
|
|
|
|
// ToFrontend converts a Container to ContainerFrontend
|
|
func (c Container) ToFrontend() ContainerFrontend {
|
|
ct := ContainerFrontend{
|
|
ID: c.ID,
|
|
VMID: c.VMID,
|
|
Name: c.Name,
|
|
Node: c.Node,
|
|
Instance: c.Instance,
|
|
Status: c.Status,
|
|
Type: c.Type,
|
|
CPU: c.CPU,
|
|
CPUs: c.CPUs,
|
|
Mem: c.Memory.Used,
|
|
MaxMem: c.Memory.Total,
|
|
Disk: c.Disk.Used,
|
|
MaxDisk: c.Disk.Total,
|
|
NetIn: zeroIfNegative(c.NetworkIn),
|
|
NetOut: zeroIfNegative(c.NetworkOut),
|
|
DiskRead: zeroIfNegative(c.DiskRead),
|
|
DiskWrite: zeroIfNegative(c.DiskWrite),
|
|
Uptime: c.Uptime,
|
|
Template: c.Template,
|
|
Lock: c.Lock,
|
|
LastSeen: c.LastSeen.Unix() * 1000,
|
|
}
|
|
|
|
// Convert tags array to string
|
|
if len(c.Tags) > 0 {
|
|
ct.Tags = strings.Join(c.Tags, ",")
|
|
}
|
|
|
|
// Convert last backup time if not zero
|
|
if !c.LastBackup.IsZero() {
|
|
ct.LastBackup = c.LastBackup.Unix() * 1000
|
|
}
|
|
|
|
return ct
|
|
}
|
|
|
|
// ToFrontend converts Storage to StorageFrontend
|
|
func (s Storage) ToFrontend() StorageFrontend {
|
|
return StorageFrontend{
|
|
ID: s.ID,
|
|
Storage: s.Name,
|
|
Name: s.Name,
|
|
Node: s.Node,
|
|
Instance: s.Instance,
|
|
Type: s.Type,
|
|
Status: s.Status,
|
|
Total: s.Total,
|
|
Used: s.Used,
|
|
Avail: s.Free,
|
|
Free: s.Free,
|
|
Usage: s.Usage,
|
|
Content: s.Content,
|
|
Shared: s.Shared,
|
|
Enabled: s.Enabled,
|
|
Active: s.Active,
|
|
}
|
|
}
|
|
|
|
// zeroIfNegative returns 0 for negative values (used for I/O metrics)
|
|
func zeroIfNegative(val int64) int64 {
|
|
if val < 0 {
|
|
return 0
|
|
}
|
|
return val
|
|
} |