feat(api): add /v1/maintenance policies and run endpoints

OpenAPI, httpapi CRUD/run/dry-run, job maintenance_policy_run и audit с policy_id.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Denozordec
2026-06-12 13:23:10 +07:00
co-authored by Cursor
parent 6510a9ca22
commit f548d0671f
8 changed files with 653 additions and 15 deletions
+63
View File
@@ -0,0 +1,63 @@
package jobs
import (
"errors"
"strings"
"evobgp/internal/maintenance"
"evobgp/internal/pgmonitor"
"evobgp/internal/store"
)
func (w *Worker) maintenanceExecutor() *maintenance.PolicyExecutor {
if w == nil {
return nil
}
return &maintenance.PolicyExecutor{Store: w.Store, Pool: w.PgPool}
}
func (w *Worker) runMaintenancePolicy(j *Job) {
if w == nil || w.PgPool == nil {
j.Fail("postgresql not configured")
return
}
policyID, _ := j.Meta["policy_id"].(string)
policyID = strings.TrimSpace(policyID)
if policyID == "" {
j.Fail("missing policy_id in job meta")
return
}
dryRun, _ := j.Meta["dry_run"].(bool)
actor, _ := j.Meta["actor_prefix"].(string)
ctx, cancel := j.workContext()
defer cancel()
pol, err := w.Store.GetMaintenancePolicy(policyID)
if err != nil {
if errors.Is(err, store.ErrNotFound) {
j.Fail("maintenance policy not found")
return
}
j.Fail(err.Error())
return
}
auditID, _ := pgmonitor.InsertMaintenanceAuditWithPolicy(ctx, w.PgPool, j.TenantID, actor, "maintenance_policy_run", pol.TableName, policyID, dryRun)
exec := w.maintenanceExecutor()
detail, err := exec.Execute(ctx, pol, dryRun)
var errMsg *string
status := StatusSucceeded
if err != nil {
s := err.Error()
errMsg = &s
status = StatusFailed
_ = w.Store.TouchMaintenancePolicyRun(policyID, status, s)
j.Fail(s)
} else {
j.mergeMeta(map[string]any{"maintenance": detail, "audit_id": auditID, "policy_id": policyID})
j.Succeed()
}
if auditID != "" {
_ = pgmonitor.FinishMaintenanceAudit(ctx, w.PgPool, auditID, status, detail, errMsg)
}
}
+3
View File
@@ -61,6 +61,7 @@ const (
KindPostgresAnalyze = "postgres_analyze"
KindPostgresReindex = "postgres_reindex"
KindPostgresCleanup = "postgres_cleanup"
KindMaintenancePolicyRun = "maintenance_policy_run"
)
// Worker executes queued jobs against store.Backend (memory or SQL).
@@ -188,6 +189,8 @@ func (w *Worker) Process(j *Job) {
w.runPostgresMaint(j, "reindex")
case KindPostgresCleanup:
w.runPostgresCleanup(j)
case KindMaintenancePolicyRun:
w.runMaintenancePolicy(j)
default:
j.Fail("unknown job kind")
}