This commit is contained in:
130
internal/httpapp/dashboard_handlers.go
Normal file
130
internal/httpapp/dashboard_handlers.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package httpapp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// DashboardData represents aggregated dashboard statistics
|
||||
type DashboardData struct {
|
||||
Storage struct {
|
||||
TotalCapacity uint64 `json:"total_capacity"`
|
||||
TotalAllocated uint64 `json:"total_allocated"`
|
||||
TotalAvailable uint64 `json:"total_available"`
|
||||
PoolCount int `json:"pool_count"`
|
||||
DatasetCount int `json:"dataset_count"`
|
||||
ZVOLCount int `json:"zvol_count"`
|
||||
SnapshotCount int `json:"snapshot_count"`
|
||||
} `json:"storage"`
|
||||
Services struct {
|
||||
SMBShares int `json:"smb_shares"`
|
||||
NFSExports int `json:"nfs_exports"`
|
||||
ISCSITargets int `json:"iscsi_targets"`
|
||||
SMBStatus bool `json:"smb_status"`
|
||||
NFSStatus bool `json:"nfs_status"`
|
||||
ISCSIStatus bool `json:"iscsi_status"`
|
||||
} `json:"services"`
|
||||
Jobs struct {
|
||||
Total int `json:"total"`
|
||||
Running int `json:"running"`
|
||||
Completed int `json:"completed"`
|
||||
Failed int `json:"failed"`
|
||||
} `json:"jobs"`
|
||||
RecentAuditLogs []map[string]interface{} `json:"recent_audit_logs,omitempty"`
|
||||
}
|
||||
|
||||
// handleDashboardAPI returns aggregated dashboard data
|
||||
func (a *App) handleDashboardAPI(w http.ResponseWriter, r *http.Request) {
|
||||
data := DashboardData{}
|
||||
|
||||
// Storage statistics
|
||||
pools, err := a.zfs.ListPools()
|
||||
if err == nil {
|
||||
data.Storage.PoolCount = len(pools)
|
||||
for _, pool := range pools {
|
||||
data.Storage.TotalCapacity += pool.Size
|
||||
data.Storage.TotalAllocated += pool.Allocated
|
||||
data.Storage.TotalAvailable += pool.Free
|
||||
}
|
||||
}
|
||||
|
||||
datasets, err := a.zfs.ListDatasets("")
|
||||
if err == nil {
|
||||
data.Storage.DatasetCount = len(datasets)
|
||||
}
|
||||
|
||||
zvols, err := a.zfs.ListZVOLs("")
|
||||
if err == nil {
|
||||
data.Storage.ZVOLCount = len(zvols)
|
||||
}
|
||||
|
||||
snapshots, err := a.zfs.ListSnapshots("")
|
||||
if err == nil {
|
||||
data.Storage.SnapshotCount = len(snapshots)
|
||||
}
|
||||
|
||||
// Service statistics
|
||||
smbShares := a.smbStore.List()
|
||||
data.Services.SMBShares = len(smbShares)
|
||||
|
||||
nfsExports := a.nfsStore.List()
|
||||
data.Services.NFSExports = len(nfsExports)
|
||||
|
||||
iscsiTargets := a.iscsiStore.List()
|
||||
data.Services.ISCSITargets = len(iscsiTargets)
|
||||
|
||||
// Service status
|
||||
if a.smbService != nil {
|
||||
data.Services.SMBStatus, _ = a.smbService.GetStatus()
|
||||
}
|
||||
if a.nfsService != nil {
|
||||
data.Services.NFSStatus, _ = a.nfsService.GetStatus()
|
||||
}
|
||||
if a.iscsiService != nil {
|
||||
data.Services.ISCSIStatus, _ = a.iscsiService.GetStatus()
|
||||
}
|
||||
|
||||
// Job statistics
|
||||
allJobs := a.jobManager.List("")
|
||||
data.Jobs.Total = len(allJobs)
|
||||
for _, job := range allJobs {
|
||||
switch job.Status {
|
||||
case "running":
|
||||
data.Jobs.Running++
|
||||
case "completed":
|
||||
data.Jobs.Completed++
|
||||
case "failed":
|
||||
data.Jobs.Failed++
|
||||
}
|
||||
}
|
||||
|
||||
// Recent audit logs (last 5)
|
||||
auditLogs := a.auditStore.List("", "", "", 5)
|
||||
data.RecentAuditLogs = make([]map[string]interface{}, 0, len(auditLogs))
|
||||
for _, log := range auditLogs {
|
||||
data.RecentAuditLogs = append(data.RecentAuditLogs, map[string]interface{}{
|
||||
"id": log.ID,
|
||||
"actor": log.Actor,
|
||||
"action": log.Action,
|
||||
"resource": log.Resource,
|
||||
"result": log.Result,
|
||||
"timestamp": log.Timestamp.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, data)
|
||||
}
|
||||
|
||||
// formatBytes formats bytes to human-readable format
|
||||
func formatBytes(bytes uint64) string {
|
||||
const unit = 1024
|
||||
if bytes < unit {
|
||||
return fmt.Sprintf("%d B", bytes)
|
||||
}
|
||||
div, exp := int64(unit), 0
|
||||
for n := bytes / unit; n >= unit; n /= unit {
|
||||
div *= unit
|
||||
exp++
|
||||
}
|
||||
return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), "KMGTPE"[exp])
|
||||
}
|
||||
Reference in New Issue
Block a user