package collector import ( "encoding/json" "fmt" "log" "os" "os/exec" "strings" "time" ) type BackupTask struct { UPID string `json:"upid"` Status string `json:"status"` StartTime int64 `json:"starttime"` EndTime int64 `json:"endtime"` Node string `json:"node"` } type BackupData struct { Jobs []map[string]interface{} `json:"jobs"` Tasks []BackupTask `json:"tasks"` } func CollectBackups() *BackupData { if _, err := os.Stat("/usr/bin/pvesh"); err != nil { return nil } result := &BackupData{ Jobs: []map[string]interface{}{}, Tasks: []BackupTask{}, } // Hostname fuer Node-Filterung hostname, _ := os.Hostname() nodeName := strings.TrimSpace(hostname) // Backup Jobs aus Cluster-Config — nur Jobs die auf diesem Node laufen cmd := exec.Command("/usr/bin/pvesh", "get", "/cluster/backup", "--output-format", "json") if out, err := cmd.Output(); err == nil { var allJobs []map[string]interface{} if err := json.Unmarshal(out, &allJobs); err == nil { for _, j := range allJobs { // next-run -> next_run umbenennen fuer Frontend-Kompatibilitaet if nr, ok := j["next-run"]; ok { j["next_run"] = nr delete(j, "next-run") } // Filtern: Job gehoert zu diesem Node wenn: // - node == unser hostname // - node leer/nicht gesetzt (= alle Nodes) jobNode, _ := j["node"].(string) if jobNode == "" || strings.EqualFold(jobNode, nodeName) { result.Jobs = append(result.Jobs, j) } } log.Printf("Backups: %d/%d Jobs fuer Node %s", len(result.Jobs), len(allJobs), nodeName) } } else { log.Printf("Backups: Jobs laden fehlgeschlagen: %v", err) } if nodeName == "" { return result } since := fmt.Sprintf("%d", time.Now().AddDate(0, 0, -30).Unix()) cmd = exec.Command("/usr/bin/pvesh", "get", "/nodes/"+nodeName+"/tasks", "--output-format", "json", "--typefilter", "vzdump", "--limit", "500", "--since", since, ) if out, err := cmd.Output(); err == nil { var tasks []BackupTask if err := json.Unmarshal(out, &tasks); err == nil { result.Tasks = tasks log.Printf("Backups: %d Tasks (letzte 30 Tage)", len(tasks)) } else { log.Printf("Backups: Tasks JSON parse fehler: %v", err) } } else { log.Printf("Backups: Tasks laden fehlgeschlagen: %v", err) } return result }