123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- package backup
- import (
- "net/http"
- "github.com/0xJacky/Nginx-UI/internal/backup"
- "github.com/0xJacky/Nginx-UI/internal/cron"
- "github.com/0xJacky/Nginx-UI/model"
- "github.com/gin-gonic/gin"
- "github.com/uozi-tech/cosy"
- "github.com/uozi-tech/cosy/logger"
- )
- // GetAutoBackupList retrieves a paginated list of auto backup configurations.
- // This endpoint supports fuzzy search by backup name and filtering by backup type and enabled status.
- //
- // Query Parameters:
- // - page: Page number for pagination
- // - page_size: Number of items per page
- // - name: Fuzzy search filter for backup name
- // - backup_type: Filter by backup type (nginx_config/nginx_ui_config/both_config/custom_dir)
- // - enabled: Filter by enabled status (true/false)
- //
- // Response: Paginated list of auto backup configurations
- func GetAutoBackupList(c *gin.Context) {
- cosy.Core[model.AutoBackup](c).
- SetFussy("name").
- SetEqual("backup_type", "enabled", "storage_type", "last_backup_status").
- PagingList()
- }
- // CreateAutoBackup creates a new auto backup configuration with comprehensive validation.
- // This endpoint validates all required fields, path permissions, and S3 configuration.
- //
- // Request Body: AutoBackup model with required fields
- // Response: Created auto backup configuration
- func CreateAutoBackup(c *gin.Context) {
- ctx := cosy.Core[model.AutoBackup](c).SetValidRules(gin.H{
- "name": "required",
- "backup_type": "required",
- "storage_type": "required",
- "storage_path": "required",
- "cron_expression": "required",
- "enabled": "omitempty",
- "backup_path": "omitempty",
- "s3_endpoint": "omitempty",
- "s3_access_key_id": "omitempty",
- "s3_secret_access_key": "omitempty",
- "s3_bucket": "omitempty",
- "s3_region": "omitempty",
- }).BeforeExecuteHook(func(ctx *cosy.Ctx[model.AutoBackup]) {
- // Validate backup configuration before creation
- if err := backup.ValidateAutoBackupConfig(&ctx.Model); err != nil {
- ctx.AbortWithError(err)
- return
- }
- })
- ctx.Create()
- // Register cron job only if the backup is enabled
- if ctx.Model.Enabled {
- if err := cron.AddAutoBackupJob(ctx.Model.ID, ctx.Model.CronExpression); err != nil {
- logger.Errorf("Failed to add auto backup job %d: %v", ctx.Model.ID, err)
- }
- }
- }
- // GetAutoBackup retrieves a single auto backup configuration by ID.
- //
- // Path Parameters:
- // - id: Auto backup configuration ID
- //
- // Response: Auto backup configuration details
- func GetAutoBackup(c *gin.Context) {
- cosy.Core[model.AutoBackup](c).Get()
- }
- // ModifyAutoBackup updates an existing auto backup configuration with validation.
- // This endpoint performs the same validation as creation for modified fields.
- //
- // Path Parameters:
- // - id: Auto backup configuration ID
- //
- // Request Body: Partial AutoBackup model with fields to update
- // Response: Updated auto backup configuration
- func ModifyAutoBackup(c *gin.Context) {
- ctx := cosy.Core[model.AutoBackup](c).SetValidRules(gin.H{
- "name": "omitempty",
- "backup_type": "omitempty",
- "storage_type": "omitempty",
- "storage_path": "omitempty",
- "cron_expression": "omitempty",
- "backup_path": "omitempty",
- "enabled": "omitempty",
- "s3_endpoint": "omitempty",
- "s3_access_key_id": "omitempty",
- "s3_secret_access_key": "omitempty",
- "s3_bucket": "omitempty",
- "s3_region": "omitempty",
- }).BeforeExecuteHook(func(ctx *cosy.Ctx[model.AutoBackup]) {
- // Validate backup configuration before modification
- if err := backup.ValidateAutoBackupConfig(&ctx.Model); err != nil {
- ctx.AbortWithError(err)
- return
- }
- })
- ctx.Modify()
- // Update cron job based on enabled status
- if ctx.Model.Enabled {
- if err := cron.UpdateAutoBackupJob(ctx.Model.ID, ctx.Model.CronExpression); err != nil {
- logger.Errorf("Failed to update auto backup job %d: %v", ctx.Model.ID, err)
- }
- } else {
- if err := cron.RemoveAutoBackupJob(ctx.Model.ID); err != nil {
- logger.Errorf("Failed to remove auto backup job %d: %v", ctx.Model.ID, err)
- }
- }
- }
- // DestroyAutoBackup deletes an auto backup configuration and removes its cron job.
- // This endpoint ensures proper cleanup of both database records and scheduled tasks.
- //
- // Path Parameters:
- // - id: Auto backup configuration ID
- //
- // Response: Success confirmation
- func DestroyAutoBackup(c *gin.Context) {
- cosy.Core[model.AutoBackup](c).BeforeExecuteHook(func(ctx *cosy.Ctx[model.AutoBackup]) {
- // Remove cron job before deleting the backup task
- if err := cron.RemoveAutoBackupJob(ctx.Model.ID); err != nil {
- logger.Errorf("Failed to remove auto backup job %d: %v", ctx.Model.ID, err)
- }
- }).Destroy()
- }
- // TestS3Connection tests the S3 connection for auto backup configuration.
- // This endpoint allows users to verify their S3 settings before saving the configuration.
- //
- // Request Body: AutoBackup model with S3 configuration
- // Response: Success confirmation or error details
- func TestS3Connection(c *gin.Context) {
- var autoBackup model.AutoBackup
- if !cosy.BindAndValid(c, &autoBackup) {
- return
- }
- // Validate S3 configuration
- if err := backup.ValidateS3Config(&autoBackup); err != nil {
- cosy.ErrHandler(c, err)
- return
- }
- // Test S3 connection
- if err := backup.TestS3ConnectionForConfig(&autoBackup); err != nil {
- cosy.ErrHandler(c, err)
- return
- }
- c.JSON(http.StatusOK, gin.H{"message": "S3 connection test successful"})
- }
- // RestoreAutoBackup restores a soft-deleted auto backup configuration.
- // This endpoint restores the backup configuration and re-registers the cron job if enabled.
- //
- // Path Parameters:
- // - id: Auto backup configuration ID to restore
- //
- // Response: Success confirmation
- func RestoreAutoBackup(c *gin.Context) {
- var autoBackup model.AutoBackup
- if err := c.ShouldBindUri(&autoBackup); err != nil {
- cosy.ErrHandler(c, err)
- return
- }
- // Restore the backup configuration
- if err := backup.RestoreAutoBackup(autoBackup.ID); err != nil {
- cosy.ErrHandler(c, err)
- return
- }
- // Get the restored backup configuration to check if it's enabled
- restoredBackup, err := backup.GetAutoBackupByID(autoBackup.ID)
- if err != nil {
- logger.Errorf("Failed to get restored auto backup %d: %v", autoBackup.ID, err)
- } else if restoredBackup.Enabled {
- // Register cron job if the backup is enabled
- if err := cron.AddAutoBackupJob(restoredBackup.ID, restoredBackup.CronExpression); err != nil {
- logger.Errorf("Failed to add auto backup job %d after restore: %v", restoredBackup.ID, err)
- }
- }
- c.JSON(http.StatusOK, gin.H{"message": "Auto backup restored successfully"})
- }
|