Files
dokku-ui/internal/server/api/services/backups.go
2023-04-25 14:33:14 +08:00

210 lines
5.8 KiB
Go

package services
import (
"fmt"
"github.com/labstack/echo/v4"
"github.com/rs/zerolog/log"
"github.com/texm/dokku-go"
"gitlab.com/texm/shokku/internal/env"
"gitlab.com/texm/shokku/internal/server/commands"
"gitlab.com/texm/shokku/internal/server/dto"
"net/http"
)
func GetServiceBackupReport(e *env.Env, c echo.Context) error {
var req dto.GetServiceBackupReportRequest
if err := dto.BindRequest(c, &req); err != nil {
return err.ToHTTP()
}
dbSvc, err := lookupDBServiceByName(e, req.Name)
if err != nil {
return echo.ErrNotFound
}
cmd := fmt.Sprintf("%s:backup-schedule-cat %s", dbSvc.Type, req.Name)
backupSchedule, err := e.Dokku.Exec(cmd)
if err != nil {
backupSchedule = ""
}
report := dto.ServiceBackupReport{
AuthSet: dbSvc.BackupAuthSet,
EncryptionSet: dbSvc.BackupEncryptionSet,
Bucket: dbSvc.BackupBucket,
Schedule: backupSchedule,
}
return c.JSON(http.StatusOK, dto.GetServiceBackupReportResponse{
Report: report,
})
}
func SetServiceBackupAuth(e *env.Env, c echo.Context) error {
var req dto.SetServiceBackupsAuthRequest
if err := dto.BindRequest(c, &req); err != nil {
return err.ToHTTP()
}
dbSvc, err := lookupDBServiceByName(e, req.Name)
if err != nil {
return echo.ErrNotFound
}
cfg := req.Config
args := fmt.Sprintf("%s %s %s %s %s", cfg.AccessKeyId, cfg.SecretKey,
cfg.Region, cfg.SignatureVersion, cfg.EndpointUrl)
cmd := fmt.Sprintf("%s:backup-auth %s %s", dbSvc.Type, req.Name, args)
if _, execErr := e.Dokku.Exec(cmd); execErr != nil {
return fmt.Errorf("setting backup auth: %w", execErr)
}
dbSvc.BackupAuthSet = true
if err := e.DB.Save(&dbSvc).Error; err != nil {
log.Error().Err(err).Msg("error updating service backup auth")
return echo.ErrInternalServerError
}
return c.NoContent(http.StatusOK)
}
func SetServiceBackupBucket(e *env.Env, c echo.Context) error {
var req dto.SetServiceBackupsBucketRequest
if err := dto.BindRequest(c, &req); err != nil {
return err.ToHTTP()
}
dbSvc, err := lookupDBServiceByName(e, req.Name)
if err != nil {
return echo.ErrNotFound
}
dbSvc.BackupBucket = req.Bucket
if dbErr := e.DB.Save(&dbSvc).Error; dbErr != nil {
log.Error().Err(dbErr).Msg("error updating service backup bucket")
return echo.ErrInternalServerError
}
return c.NoContent(http.StatusOK)
}
func RunServiceBackup(e *env.Env, c echo.Context) error {
var req dto.RunServiceBackupRequest
if err := dto.BindRequest(c, &req); err != nil {
return err.ToHTTP()
}
dbSvc, err := lookupDBServiceByName(e, req.Name)
if err != nil {
return echo.ErrNotFound
}
if dbSvc.BackupBucket == "" {
return echo.NewHTTPError(http.StatusBadRequest, "backup bucket not set")
} else if !dbSvc.BackupAuthSet {
return echo.NewHTTPError(http.StatusBadRequest, "backup auth not set")
}
dokkuCmd := fmt.Sprintf("%s:backup %s %s", dbSvc.Type, dbSvc.Name, dbSvc.BackupBucket)
cmd := func() (*dokku.CommandOutputStream, error) {
return e.Dokku.ExecStreaming(dokkuCmd)
}
return c.JSON(http.StatusOK, dto.CommandExecutionResponse{
ExecutionID: commands.RequestExecution(cmd, nil),
})
}
func SetServiceBackupSchedule(e *env.Env, c echo.Context) error {
var req dto.SetServiceBackupsScheduleRequest
if err := dto.BindRequest(c, &req); err != nil {
return err.ToHTTP()
}
dbSvc, err := lookupDBServiceByName(e, req.Name)
if err != nil {
return echo.ErrNotFound
}
if dbSvc.BackupBucket == "" {
return echo.NewHTTPError(http.StatusBadRequest,
"service backup bucket not set")
}
cmd := fmt.Sprintf(`%s:backup-schedule %s "%s" %s`, dbSvc.Type,
req.Name, req.Schedule, dbSvc.BackupBucket)
if out, err := e.Dokku.Exec(cmd); err != nil {
log.Debug().Str("output", out).Msg("backup schedule output")
return fmt.Errorf("setting backup schedule: %w", err)
}
return c.NoContent(http.StatusOK)
}
func RemoveServiceBackupSchedule(e *env.Env, c echo.Context) error {
var req dto.ManageServiceRequest
if err := dto.BindRequest(c, &req); err != nil {
return err.ToHTTP()
}
cmd := fmt.Sprintf(`%s:backup-unschedule %s`, req.Type, req.Name)
if out, err := e.Dokku.Exec(cmd); err != nil {
log.Debug().Str("output", out).Msg("backup schedule output")
return fmt.Errorf("removing backup schedule: %w", err)
}
return c.NoContent(http.StatusOK)
}
func SetServiceBackupEncryption(e *env.Env, c echo.Context) error {
var req dto.SetServiceBackupsEncryptionRequest
if err := dto.BindRequest(c, &req); err != nil {
return err.ToHTTP()
}
dbSvc, err := lookupDBServiceByName(e, req.Name)
if err != nil {
return echo.ErrNotFound
}
cmd := fmt.Sprintf(`%s:backup-set-encryption %s %s`, dbSvc.Type,
req.Name, req.Passphrase)
if out, err := e.Dokku.Exec(cmd); err != nil {
log.Debug().Str("output", out).Msg("set backup encryption output")
return fmt.Errorf("setting backup encryption: %w", err)
}
dbSvc.BackupEncryptionSet = true
if saveErr := e.DB.Save(&dbSvc).Error; saveErr != nil {
log.Error().Err(saveErr).Msg("error updating service backup encryption")
return echo.ErrInternalServerError
}
return c.NoContent(http.StatusOK)
}
func RemoveServiceBackupEncryption(e *env.Env, c echo.Context) error {
var req dto.ManageServiceRequest
if err := dto.BindRequest(c, &req); err != nil {
return err.ToHTTP()
}
dbSvc, err := lookupDBServiceByName(e, req.Name)
if err != nil {
return echo.ErrNotFound
}
cmd := fmt.Sprintf(`%s:backup-unset-encryption %s`, req.Type, req.Name)
if out, err := e.Dokku.Exec(cmd); err != nil {
log.Debug().Str("output", out).Msg("unset backup encryption output")
return fmt.Errorf("removing backup encryption: %w", err)
}
dbSvc.BackupEncryptionSet = false
if saveErr := e.DB.Save(&dbSvc).Error; saveErr != nil {
log.Error().Err(saveErr).Msg("error updating service backup encryption")
return echo.ErrInternalServerError
}
return c.NoContent(http.StatusOK)
}