zlh-agent/internal/handlers/backups.go

107 lines
2.5 KiB
Go

package handlers
import (
"encoding/json"
"net/http"
"strings"
agentbackup "zlh-agent/internal/backup"
"zlh-agent/internal/state"
)
func HandleGameBackups(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
handleGameBackupsList(w, r)
case http.MethodPost:
handleGameBackupCreate(w, r)
default:
writeJSONError(w, http.StatusMethodNotAllowed, "GET or POST only")
}
}
func handleGameBackupsList(w http.ResponseWriter, r *http.Request) {
if _, ok := requireBackupConfig(w); !ok {
return
}
backups, err := agentbackup.List()
if err != nil {
writeJSONError(w, http.StatusInternalServerError, err.Error())
return
}
writeJSON(w, http.StatusOK, map[string]any{"backups": backups})
}
func handleGameBackupCreate(w http.ResponseWriter, r *http.Request) {
endOp, ok := beginHandlerOperation(w, "backup_create", true, "creating backup")
if !ok {
return
}
defer endOp()
cfg, ok := requireBackupConfig(w)
if !ok {
return
}
manifest, err := agentbackup.Create(cfg)
if err != nil {
writeJSONError(w, http.StatusInternalServerError, err.Error())
return
}
writeJSON(w, http.StatusOK, manifest)
}
func HandleGameBackupRestore(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
writeJSONError(w, http.StatusMethodNotAllowed, "POST only")
return
}
endOp, ok := beginHandlerOperation(w, "backup_restore", true, "restoring backup")
if !ok {
return
}
defer endOp()
cfg, ok := requireBackupConfig(w)
if !ok {
return
}
id := strings.TrimSpace(r.URL.Query().Get("id"))
if id == "" {
var req struct {
ID string `json:"id"`
}
_ = json.NewDecoder(r.Body).Decode(&req)
id = strings.TrimSpace(req.ID)
}
if id == "" {
writeJSONError(w, http.StatusBadRequest, "backup id required")
return
}
manifest, err := agentbackup.Restore(cfg, id)
if err != nil {
writeJSONError(w, http.StatusInternalServerError, err.Error())
return
}
writeJSON(w, http.StatusOK, map[string]any{"restored": true, "backup": manifest})
}
func requireBackupConfig(w http.ResponseWriter) (*state.Config, bool) {
cfg, err := state.LoadConfig()
if err != nil {
writeJSONError(w, http.StatusBadRequest, "no config loaded")
return nil, false
}
if !strings.EqualFold(cfg.ContainerType, "game") {
writeJSONError(w, http.StatusBadRequest, "not a game container")
return nil, false
}
if !strings.EqualFold(cfg.Game, "minecraft") {
writeJSONError(w, http.StatusNotImplemented, "backups are only implemented for minecraft")
return nil, false
}
return cfg, true
}