package httpapp import ( "encoding/json" "net/http" "gitea.avt.data-center.id/othman.suseno/atlas/internal/backup" "gitea.avt.data-center.id/othman.suseno/atlas/internal/errors" "gitea.avt.data-center.id/othman.suseno/atlas/internal/models" ) // handleGetMaintenanceStatus returns the current maintenance mode status func (a *App) handleGetMaintenanceStatus(w http.ResponseWriter, r *http.Request) { if a.maintenanceService == nil { writeError(w, errors.NewAPIError( errors.ErrCodeInternal, "maintenance service not available", http.StatusInternalServerError, )) return } status := a.maintenanceService.GetStatus() writeJSON(w, http.StatusOK, status) } // handleEnableMaintenance enables maintenance mode func (a *App) handleEnableMaintenance(w http.ResponseWriter, r *http.Request) { if a.maintenanceService == nil { writeError(w, errors.NewAPIError( errors.ErrCodeInternal, "maintenance service not available", http.StatusInternalServerError, )) return } // Require administrator role user, ok := getUserFromContext(r) if !ok { writeError(w, errors.NewAPIError( errors.ErrCodeUnauthorized, "authentication required", http.StatusUnauthorized, )) return } if user.Role != models.RoleAdministrator { writeError(w, errors.NewAPIError( errors.ErrCodeForbidden, "administrator role required", http.StatusForbidden, )) return } var req struct { Reason string `json:"reason"` AllowedUsers []string `json:"allowed_users,omitempty"` CreateBackup bool `json:"create_backup,omitempty"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { // Description is optional, so we'll continue even if body is empty _ = err } // Create backup before entering maintenance if requested var backupID string if req.CreateBackup && a.backupService != nil { // Collect all configuration data backupData := backup.BackupData{ Users: a.userStore.List(), SMBShares: a.smbStore.List(), NFSExports: a.nfsStore.List(), ISCSITargets: a.iscsiStore.List(), Policies: a.snapshotPolicy.List(), Config: map[string]interface{}{ "database_conn": a.cfg.DatabaseConn, }, } id, err := a.backupService.CreateBackup(backupData, "Automatic backup before maintenance mode") if err != nil { writeError(w, errors.NewAPIError( errors.ErrCodeInternal, "failed to create backup", http.StatusInternalServerError, ).WithDetails(err.Error())) return } backupID = id } // Enable maintenance mode if err := a.maintenanceService.Enable(user.ID, req.Reason, req.AllowedUsers); err != nil { writeError(w, errors.NewAPIError( errors.ErrCodeInternal, "failed to enable maintenance mode", http.StatusInternalServerError, ).WithDetails(err.Error())) return } // Set backup ID if created if backupID != "" { a.maintenanceService.SetLastBackupID(backupID) } status := a.maintenanceService.GetStatus() writeJSON(w, http.StatusOK, map[string]interface{}{ "message": "maintenance mode enabled", "status": status, "backup_id": backupID, }) } // handleDisableMaintenance disables maintenance mode func (a *App) handleDisableMaintenance(w http.ResponseWriter, r *http.Request) { if a.maintenanceService == nil { writeError(w, errors.NewAPIError( errors.ErrCodeInternal, "maintenance service not available", http.StatusInternalServerError, )) return } // Require administrator role user, ok := getUserFromContext(r) if !ok { writeError(w, errors.NewAPIError( errors.ErrCodeUnauthorized, "authentication required", http.StatusUnauthorized, )) return } if user.Role != models.RoleAdministrator { writeError(w, errors.NewAPIError( errors.ErrCodeForbidden, "administrator role required", http.StatusForbidden, )) return } if err := a.maintenanceService.Disable(user.ID); err != nil { writeError(w, errors.NewAPIError( errors.ErrCodeInternal, "failed to disable maintenance mode", http.StatusInternalServerError, ).WithDetails(err.Error())) return } writeJSON(w, http.StatusOK, map[string]string{ "message": "maintenance mode disabled", }) }