This commit is contained in:
130
internal/maintenance/service.go
Normal file
130
internal/maintenance/service.go
Normal file
@@ -0,0 +1,130 @@
|
||||
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"`
|
||||
}
|
||||
Reference in New Issue
Block a user