119 lines
2.8 KiB
Go
119 lines
2.8 KiB
Go
package backup
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/atlasos/calypso/internal/common/logger"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// Handler handles backup-related API requests
|
|
type Handler struct {
|
|
service *Service
|
|
logger *logger.Logger
|
|
}
|
|
|
|
// NewHandler creates a new backup handler
|
|
func NewHandler(service *Service, log *logger.Logger) *Handler {
|
|
return &Handler{
|
|
service: service,
|
|
logger: log,
|
|
}
|
|
}
|
|
|
|
// ListJobs lists backup jobs with optional filters
|
|
func (h *Handler) ListJobs(c *gin.Context) {
|
|
opts := ListJobsOptions{
|
|
Status: c.Query("status"),
|
|
JobType: c.Query("job_type"),
|
|
ClientName: c.Query("client_name"),
|
|
JobName: c.Query("job_name"),
|
|
}
|
|
|
|
// Parse pagination
|
|
var limit, offset int
|
|
if limitStr := c.Query("limit"); limitStr != "" {
|
|
if _, err := fmt.Sscanf(limitStr, "%d", &limit); err == nil {
|
|
opts.Limit = limit
|
|
}
|
|
}
|
|
if offsetStr := c.Query("offset"); offsetStr != "" {
|
|
if _, err := fmt.Sscanf(offsetStr, "%d", &offset); err == nil {
|
|
opts.Offset = offset
|
|
}
|
|
}
|
|
|
|
jobs, totalCount, err := h.service.ListJobs(c.Request.Context(), opts)
|
|
if err != nil {
|
|
h.logger.Error("Failed to list jobs", "error", err)
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list jobs"})
|
|
return
|
|
}
|
|
|
|
if jobs == nil {
|
|
jobs = []Job{}
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"jobs": jobs,
|
|
"total": totalCount,
|
|
"limit": opts.Limit,
|
|
"offset": opts.Offset,
|
|
})
|
|
}
|
|
|
|
// GetJob retrieves a job by ID
|
|
func (h *Handler) GetJob(c *gin.Context) {
|
|
id := c.Param("id")
|
|
|
|
job, err := h.service.GetJob(c.Request.Context(), id)
|
|
if err != nil {
|
|
if err.Error() == "job not found" {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "job not found"})
|
|
return
|
|
}
|
|
h.logger.Error("Failed to get job", "error", err)
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get job"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, job)
|
|
}
|
|
|
|
// CreateJob creates a new backup job
|
|
func (h *Handler) CreateJob(c *gin.Context) {
|
|
var req CreateJobRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
// Validate job type
|
|
validJobTypes := map[string]bool{
|
|
"Backup": true, "Restore": true, "Verify": true, "Copy": true, "Migrate": true,
|
|
}
|
|
if !validJobTypes[req.JobType] {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid job_type"})
|
|
return
|
|
}
|
|
|
|
// Validate job level
|
|
validJobLevels := map[string]bool{
|
|
"Full": true, "Incremental": true, "Differential": true, "Since": true,
|
|
}
|
|
if !validJobLevels[req.JobLevel] {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid job_level"})
|
|
return
|
|
}
|
|
|
|
job, err := h.service.CreateJob(c.Request.Context(), req)
|
|
if err != nil {
|
|
h.logger.Error("Failed to create job", "error", err)
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create job"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusCreated, job)
|
|
}
|