mirror of
https://github.com/databasus/databasus.git
synced 2026-04-06 00:32:03 +02:00
210 lines
7.2 KiB
Go
210 lines
7.2 KiB
Go
package backups_config
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
|
|
users_middleware "databasus-backend/internal/features/users/middleware"
|
|
)
|
|
|
|
type BackupConfigController struct {
|
|
backupConfigService *BackupConfigService
|
|
}
|
|
|
|
func (c *BackupConfigController) RegisterRoutes(router *gin.RouterGroup) {
|
|
router.POST("/backup-configs/save", c.SaveBackupConfig)
|
|
router.GET("/backup-configs/database/:id", c.GetBackupConfigByDbID)
|
|
router.GET("/backup-configs/storage/:id/is-using", c.IsStorageUsing)
|
|
router.GET("/backup-configs/storage/:id/databases-count", c.CountDatabasesForStorage)
|
|
router.POST("/backup-configs/database/:id/transfer", c.TransferDatabase)
|
|
}
|
|
|
|
// SaveBackupConfig
|
|
// @Summary Save backup configuration
|
|
// @Description Save or update backup configuration for a database. Encryption can be set to NONE (no encryption) or ENCRYPTED (AES-256-GCM encryption).
|
|
// @Tags backup-configs
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param request body BackupConfig true "Backup configuration data (encryption field: NONE or ENCRYPTED)"
|
|
// @Success 200 {object} BackupConfig "Returns the saved backup configuration including encryption settings"
|
|
// @Failure 400 {object} map[string]string "Invalid encryption value or other validation errors"
|
|
// @Failure 401 {object} map[string]string "User not authenticated"
|
|
// @Failure 500 {object} map[string]string "Internal server error"
|
|
// @Router /backup-configs/save [post]
|
|
func (c *BackupConfigController) SaveBackupConfig(ctx *gin.Context) {
|
|
user, ok := users_middleware.GetUserFromContext(ctx)
|
|
if !ok {
|
|
ctx.JSON(http.StatusUnauthorized, gin.H{"error": "User not authenticated"})
|
|
return
|
|
}
|
|
|
|
var requestDTO BackupConfig
|
|
if err := ctx.ShouldBindJSON(&requestDTO); err != nil {
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
// make sure we rely on full .Storage object
|
|
requestDTO.StorageID = nil
|
|
|
|
savedConfig, err := c.backupConfigService.SaveBackupConfigWithAuth(user, &requestDTO)
|
|
if err != nil {
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
ctx.JSON(http.StatusOK, savedConfig)
|
|
}
|
|
|
|
// GetBackupConfigByDbID
|
|
// @Summary Get backup configuration by database ID
|
|
// @Description Get backup configuration for a specific database including encryption settings (NONE or ENCRYPTED)
|
|
// @Tags backup-configs
|
|
// @Produce json
|
|
// @Param id path string true "Database ID"
|
|
// @Success 200 {object} BackupConfig "Returns backup configuration with encryption field"
|
|
// @Failure 400 {object} map[string]string "Invalid database ID"
|
|
// @Failure 401 {object} map[string]string "User not authenticated"
|
|
// @Failure 404 {object} map[string]string "Backup configuration not found"
|
|
// @Router /backup-configs/database/{id} [get]
|
|
func (c *BackupConfigController) GetBackupConfigByDbID(ctx *gin.Context) {
|
|
user, ok := users_middleware.GetUserFromContext(ctx)
|
|
if !ok {
|
|
ctx.JSON(http.StatusUnauthorized, gin.H{"error": "User not authenticated"})
|
|
return
|
|
}
|
|
|
|
id, err := uuid.Parse(ctx.Param("id"))
|
|
if err != nil {
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid database ID"})
|
|
return
|
|
}
|
|
|
|
backupConfig, err := c.backupConfigService.GetBackupConfigByDbIdWithAuth(user, id)
|
|
if err != nil {
|
|
ctx.JSON(http.StatusNotFound, gin.H{"error": "backup configuration not found"})
|
|
return
|
|
}
|
|
|
|
ctx.JSON(http.StatusOK, backupConfig)
|
|
}
|
|
|
|
// IsStorageUsing
|
|
// @Summary Check if storage is being used
|
|
// @Description Check if a storage is currently being used by any backup configuration
|
|
// @Tags backup-configs
|
|
// @Produce json
|
|
// @Param id path string true "Storage ID"
|
|
// @Success 200 {object} map[string]bool
|
|
// @Failure 400
|
|
// @Failure 401
|
|
// @Failure 500
|
|
// @Router /backup-configs/storage/{id}/is-using [get]
|
|
func (c *BackupConfigController) IsStorageUsing(ctx *gin.Context) {
|
|
user, ok := users_middleware.GetUserFromContext(ctx)
|
|
if !ok {
|
|
ctx.JSON(http.StatusUnauthorized, gin.H{"error": "User not authenticated"})
|
|
return
|
|
}
|
|
|
|
id, err := uuid.Parse(ctx.Param("id"))
|
|
if err != nil {
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid storage ID"})
|
|
return
|
|
}
|
|
|
|
isUsing, err := c.backupConfigService.IsStorageUsing(user, id)
|
|
if err != nil {
|
|
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
ctx.JSON(http.StatusOK, gin.H{"isUsing": isUsing})
|
|
}
|
|
|
|
// CountDatabasesForStorage
|
|
// @Summary Count databases using a storage
|
|
// @Description Get the count of databases that are using a specific storage
|
|
// @Tags backup-configs
|
|
// @Produce json
|
|
// @Param id path string true "Storage ID"
|
|
// @Success 200 {object} map[string]int
|
|
// @Failure 400
|
|
// @Failure 401
|
|
// @Failure 500
|
|
// @Router /backup-configs/storage/{id}/databases-count [get]
|
|
func (c *BackupConfigController) CountDatabasesForStorage(ctx *gin.Context) {
|
|
user, ok := users_middleware.GetUserFromContext(ctx)
|
|
if !ok {
|
|
ctx.JSON(http.StatusUnauthorized, gin.H{"error": "User not authenticated"})
|
|
return
|
|
}
|
|
|
|
id, err := uuid.Parse(ctx.Param("id"))
|
|
if err != nil {
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid storage ID"})
|
|
return
|
|
}
|
|
|
|
count, err := c.backupConfigService.CountDatabasesForStorage(user, id)
|
|
if err != nil {
|
|
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
ctx.JSON(http.StatusOK, gin.H{"count": count})
|
|
}
|
|
|
|
// TransferDatabase
|
|
// @Summary Transfer database to another workspace
|
|
// @Description Transfer a database from one workspace to another. Can transfer to a new storage or transfer with the existing storage. Can also specify target notifiers from the target workspace.
|
|
// @Tags backup-configs
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path string true "Database ID"
|
|
// @Param request body TransferDatabaseRequest true "Transfer request with targetWorkspaceId, storage options (targetStorageId or isTransferWithStorage), and optional targetNotifierIds"
|
|
// @Success 200 {object} map[string]string "Database transferred successfully"
|
|
// @Failure 400 {object} map[string]string "Invalid request, target storage/notifier not in target workspace, or transfer failed"
|
|
// @Failure 401 {object} map[string]string "User not authenticated"
|
|
// @Failure 403 {object} map[string]string "Insufficient permissions"
|
|
// @Router /backup-configs/database/{id}/transfer [post]
|
|
func (c *BackupConfigController) TransferDatabase(ctx *gin.Context) {
|
|
user, ok := users_middleware.GetUserFromContext(ctx)
|
|
if !ok {
|
|
ctx.JSON(http.StatusUnauthorized, gin.H{"error": "User not authenticated"})
|
|
return
|
|
}
|
|
|
|
id, err := uuid.Parse(ctx.Param("id"))
|
|
if err != nil {
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid database ID"})
|
|
return
|
|
}
|
|
|
|
var request TransferDatabaseRequest
|
|
if err := ctx.ShouldBindJSON(&request); err != nil {
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
if request.TargetWorkspaceID == uuid.Nil {
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": "targetWorkspaceId is required"})
|
|
return
|
|
}
|
|
|
|
if err := c.backupConfigService.TransferDatabaseToWorkspace(user, id, &request); err != nil {
|
|
if errors.Is(err, ErrInsufficientPermissionsInSourceWorkspace) ||
|
|
errors.Is(err, ErrInsufficientPermissionsInTargetWorkspace) {
|
|
ctx.JSON(http.StatusForbidden, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
ctx.JSON(http.StatusOK, gin.H{"message": "database transferred successfully"})
|
|
}
|