[ci skip] more suggested improvements
This commit is contained in:
@@ -2,7 +2,6 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@@ -10,6 +9,7 @@ import (
|
||||
"time"
|
||||
"vctp/db"
|
||||
"vctp/internal/report"
|
||||
"vctp/server/models"
|
||||
)
|
||||
|
||||
// SnapshotRepair scans existing daily summaries and backfills missing SnapshotTime and lifecycle fields.
|
||||
@@ -21,20 +21,18 @@ import (
|
||||
// @Router /api/snapshots/repair [post]
|
||||
func (h *Handler) SnapshotRepair(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
writeJSONError(w, http.StatusMethodNotAllowed, "method not allowed")
|
||||
return
|
||||
}
|
||||
h.Logger.Info("snapshot repair started", "scope", "daily")
|
||||
repaired, failed := h.repairDailySummaries(r.Context(), time.Now())
|
||||
h.Logger.Info("snapshot repair finished", "daily_repaired", repaired, "daily_failed", failed)
|
||||
|
||||
resp := map[string]string{
|
||||
"status": "ok",
|
||||
"repaired": strconv.Itoa(repaired),
|
||||
"failed": strconv.Itoa(failed),
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_ = json.NewEncoder(w).Encode(resp)
|
||||
writeJSON(w, http.StatusOK, models.SnapshotRepairResponse{
|
||||
Status: "OK",
|
||||
Repaired: strconv.Itoa(repaired),
|
||||
Failed: strconv.Itoa(failed),
|
||||
})
|
||||
}
|
||||
|
||||
func (h *Handler) repairDailySummaries(ctx context.Context, now time.Time) (repaired int, failed int) {
|
||||
@@ -42,8 +40,8 @@ func (h *Handler) repairDailySummaries(ctx context.Context, now time.Time) (repa
|
||||
|
||||
dailyRecs, err := report.SnapshotRecordsWithFallback(ctx, h.Database, "daily", "inventory_daily_summary_", "20060102", time.Time{}, now)
|
||||
if err != nil {
|
||||
h.Logger.Warn("failed to list daily summaries", "error", err)
|
||||
return 0, 1
|
||||
h.Logger.Warn("failed to list daily summaries", "error", err)
|
||||
return 0, 1
|
||||
}
|
||||
|
||||
for _, rec := range dailyRecs {
|
||||
@@ -53,27 +51,27 @@ func (h *Handler) repairDailySummaries(ctx context.Context, now time.Time) (repa
|
||||
|
||||
if err := db.EnsureSummaryTable(ctx, dbConn, rec.TableName); err != nil {
|
||||
h.Logger.Warn("ensure summary table failed", "table", rec.TableName, "error", err)
|
||||
failed++
|
||||
continue
|
||||
}
|
||||
failed++
|
||||
continue
|
||||
}
|
||||
|
||||
hourlyRecs, err := report.SnapshotRecordsWithFallback(ctx, h.Database, "hourly", "inventory_hourly_", "epoch", dayStart, dayEnd)
|
||||
if err != nil || len(hourlyRecs) == 0 {
|
||||
h.Logger.Warn("no hourly snapshots for repair window", "table", rec.TableName, "error", err)
|
||||
failed++
|
||||
continue
|
||||
}
|
||||
hourlyRecs, err := report.SnapshotRecordsWithFallback(ctx, h.Database, "hourly", "inventory_hourly_", "epoch", dayStart, dayEnd)
|
||||
if err != nil || len(hourlyRecs) == 0 {
|
||||
h.Logger.Warn("no hourly snapshots for repair window", "table", rec.TableName, "error", err)
|
||||
failed++
|
||||
continue
|
||||
}
|
||||
|
||||
cols := []string{
|
||||
`"InventoryId"`, `"Name"`, `"Vcenter"`, `"VmId"`, `"EventKey"`, `"CloudId"`, `"CreationTime"`,
|
||||
`"DeletionTime"`, `"ResourcePool"`, `"Datacenter"`, `"Cluster"`, `"Folder"`,
|
||||
`"ProvisionedDisk"`, `"VcpuCount"`, `"RamGB"`, `"IsTemplate"`, `"PoweredOn"`,
|
||||
`"SrmPlaceholder"`, `"VmUuid"`, `"SnapshotTime"`,
|
||||
}
|
||||
union, err := buildUnionFromRecords(hourlyRecs, cols, `COALESCE(CAST("IsTemplate" AS TEXT), '') NOT IN ('TRUE','true','1')`)
|
||||
if err != nil {
|
||||
h.Logger.Warn("failed to build union for repair", "table", rec.TableName, "error", err)
|
||||
failed++
|
||||
cols := []string{
|
||||
`"InventoryId"`, `"Name"`, `"Vcenter"`, `"VmId"`, `"EventKey"`, `"CloudId"`, `"CreationTime"`,
|
||||
`"DeletionTime"`, `"ResourcePool"`, `"Datacenter"`, `"Cluster"`, `"Folder"`,
|
||||
`"ProvisionedDisk"`, `"VcpuCount"`, `"RamGB"`, `"IsTemplate"`, `"PoweredOn"`,
|
||||
`"SrmPlaceholder"`, `"VmUuid"`, `"SnapshotTime"`,
|
||||
}
|
||||
union, err := buildUnionFromRecords(hourlyRecs, cols, `COALESCE(CAST("IsTemplate" AS TEXT), '') NOT IN ('TRUE','true','1')`)
|
||||
if err != nil {
|
||||
h.Logger.Warn("failed to build union for repair", "table", rec.TableName, "error", err)
|
||||
failed++
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -106,7 +104,7 @@ func (h *Handler) repairDailySummaries(ctx context.Context, now time.Time) (repa
|
||||
// @Router /api/snapshots/repair/all [post]
|
||||
func (h *Handler) SnapshotRepairSuite(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
writeJSONError(w, http.StatusMethodNotAllowed, "method not allowed")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -135,15 +133,13 @@ func (h *Handler) SnapshotRepairSuite(w http.ResponseWriter, r *http.Request) {
|
||||
h.Logger.Info("repair suite step", "step", "monthly_refine")
|
||||
monthlyRefined, monthlyFailed := h.refineMonthlyFromDaily(ctx, time.Now())
|
||||
|
||||
resp := map[string]string{
|
||||
"status": "ok",
|
||||
"daily_repaired": strconv.Itoa(dailyRepaired),
|
||||
"daily_failed": strconv.Itoa(dailyFailed),
|
||||
"monthly_refined": strconv.Itoa(monthlyRefined),
|
||||
"monthly_failed": strconv.Itoa(monthlyFailed),
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_ = json.NewEncoder(w).Encode(resp)
|
||||
writeJSON(w, http.StatusOK, models.SnapshotRepairSuiteResponse{
|
||||
Status: "OK",
|
||||
DailyRepaired: strconv.Itoa(dailyRepaired),
|
||||
DailyFailed: strconv.Itoa(dailyFailed),
|
||||
MonthlyRefined: strconv.Itoa(monthlyRefined),
|
||||
MonthlyFailed: strconv.Itoa(monthlyFailed),
|
||||
})
|
||||
}
|
||||
|
||||
func (h *Handler) refineMonthlyFromDaily(ctx context.Context, now time.Time) (refined int, failed int) {
|
||||
@@ -178,11 +174,11 @@ func (h *Handler) refineMonthlyFromDaily(ctx context.Context, now time.Time) (re
|
||||
continue
|
||||
}
|
||||
|
||||
union, err := buildUnionFromRecords(recs, cols, `COALESCE(CAST("IsTemplate" AS TEXT), '') NOT IN ('TRUE','true','1')`)
|
||||
if err != nil {
|
||||
h.Logger.Warn("failed to build union for monthly refine", "table", summaryTable, "error", err)
|
||||
failed++
|
||||
continue
|
||||
union, err := buildUnionFromRecords(recs, cols, `COALESCE(CAST("IsTemplate" AS TEXT), '') NOT IN ('TRUE','true','1')`)
|
||||
if err != nil {
|
||||
h.Logger.Warn("failed to build union for monthly refine", "table", summaryTable, "error", err)
|
||||
failed++
|
||||
continue
|
||||
}
|
||||
|
||||
if err := db.RefineCreationDeletionFromUnion(ctx, dbConn, summaryTable, union); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user