Files
atlas/internal/maintenance/service.go
othman.suseno 9779b30a65
Some checks failed
CI / test-build (push) Failing after 2m12s
add maintenance mode
2025-12-15 01:11:51 +07:00

131 lines
2.9 KiB
Go

package maintenance
import (
"fmt"
"sync"
"time"
)
// Mode represents the maintenance mode state
type Mode struct {
mu sync.RWMutex
enabled bool
enabledAt time.Time
enabledBy string
reason string
allowedUsers []string // Users allowed to operate during maintenance
lastBackupID string // ID of backup created before entering maintenance
}
// Service manages maintenance mode
type Service struct {
mode *Mode
}
// NewService creates a new maintenance service
func NewService() *Service {
return &Service{
mode: &Mode{
allowedUsers: []string{},
},
}
}
// IsEnabled returns whether maintenance mode is currently enabled
func (s *Service) IsEnabled() bool {
s.mode.mu.RLock()
defer s.mode.mu.RUnlock()
return s.mode.enabled
}
// Enable enables maintenance mode
func (s *Service) Enable(enabledBy, reason string, allowedUsers []string) error {
s.mode.mu.Lock()
defer s.mode.mu.Unlock()
if s.mode.enabled {
return fmt.Errorf("maintenance mode is already enabled")
}
s.mode.enabled = true
s.mode.enabledAt = time.Now()
s.mode.enabledBy = enabledBy
s.mode.reason = reason
if allowedUsers != nil {
s.mode.allowedUsers = allowedUsers
} else {
s.mode.allowedUsers = []string{}
}
return nil
}
// Disable disables maintenance mode
func (s *Service) Disable(disabledBy string) error {
s.mode.mu.Lock()
defer s.mode.mu.Unlock()
if !s.mode.enabled {
return fmt.Errorf("maintenance mode is not enabled")
}
s.mode.enabled = false
s.mode.enabledBy = ""
s.mode.reason = ""
s.mode.allowedUsers = []string{}
s.mode.lastBackupID = ""
return nil
}
// GetStatus returns the current maintenance mode status
func (s *Service) GetStatus() Status {
s.mode.mu.RLock()
defer s.mode.mu.RUnlock()
return Status{
Enabled: s.mode.enabled,
EnabledAt: s.mode.enabledAt,
EnabledBy: s.mode.enabledBy,
Reason: s.mode.reason,
AllowedUsers: s.mode.allowedUsers,
LastBackupID: s.mode.lastBackupID,
}
}
// SetLastBackupID sets the backup ID created before entering maintenance
func (s *Service) SetLastBackupID(backupID string) {
s.mode.mu.Lock()
defer s.mode.mu.Unlock()
s.mode.lastBackupID = backupID
}
// IsUserAllowed checks if a user is allowed to operate during maintenance
func (s *Service) IsUserAllowed(userID string) bool {
s.mode.mu.RLock()
defer s.mode.mu.RUnlock()
if !s.mode.enabled {
return true // No restrictions when not in maintenance
}
// Check if user is in allowed list
for _, allowed := range s.mode.allowedUsers {
if allowed == userID {
return true
}
}
return false
}
// Status represents the maintenance mode status
type Status struct {
Enabled bool `json:"enabled"`
EnabledAt time.Time `json:"enabled_at,omitempty"`
EnabledBy string `json:"enabled_by,omitempty"`
Reason string `json:"reason,omitempty"`
AllowedUsers []string `json:"allowed_users,omitempty"`
LastBackupID string `json:"last_backup_id,omitempty"`
}