2025-03-25 21:39:12 +01:00

111 lines
3.6 KiB
Go

package strategy
import (
"backea/internal/backup/models"
"backea/internal/backup/strategy/kopia"
"fmt"
"os"
"path/filepath"
"time"
)
// Factory handles backup strategy creation
type Factory struct {
Config *models.Configuration
ConfigPath string
}
// NewFactory initializes and returns a Factory
func NewFactory(configPath string) (*Factory, error) {
cfg, err := models.LoadConfig(configPath)
if err != nil {
return nil, fmt.Errorf("failed to load config: %w", err)
}
return &Factory{Config: cfg, ConfigPath: configPath}, nil
}
// CreateBackupStrategyForService returns a backup strategy based on config
func (f *Factory) CreateBackupStrategyForService(groupName, serviceIndex string) (Strategy, error) {
serviceConfig, err := f.getServiceConfig(groupName, serviceIndex)
if err != nil {
return nil, err
}
sourcePath, err := f.getServicePath(groupName)
if err != nil {
return nil, err
}
switch serviceConfig.BackupStrategy.Type {
case "kopia":
return f.createKopiaStrategy(serviceConfig, sourcePath)
default:
return nil, fmt.Errorf("unknown strategy type: %s", serviceConfig.BackupStrategy.Type)
}
}
// createKopiaStrategy initializes a Kopia strategy
func (f *Factory) createKopiaStrategy(serviceConfig *models.BackupConfig, sourcePath string) (Strategy, error) {
provider, err := f.createKopiaProvider(serviceConfig.BackupStrategy)
if err != nil {
return nil, fmt.Errorf("failed to create kopia provider: %w", err)
}
retention := kopia.Retention(serviceConfig.BackupStrategy.Retention)
configPath := generateTempConfigPath(provider.GetProviderType())
return kopia.NewStrategy(retention, provider, configPath, sourcePath), nil
}
// createKopiaProvider returns a Kopia storage provider
func (f *Factory) createKopiaProvider(strategyConfig models.StrategyConfig) (kopia.Provider, error) {
switch strategyConfig.Provider {
case "local":
return kopia.NewLocalProvider(strategyConfig.Destination.Path), nil
case "b2", "backblaze":
return kopia.NewB2Provider(), nil
case "sftp":
host := strategyConfig.Destination.Host
basepath := strategyConfig.Destination.Path
username := strategyConfig.Destination.Username
keyFile := strategyConfig.Destination.SSHKey
return kopia.NewSFTPProvider(host, basepath, username, keyFile), nil
default:
return nil, fmt.Errorf("unknown kopia provider type: %s", strategyConfig.Provider)
}
}
// getServicePath returns a service's path
func (f *Factory) getServicePath(groupName string) (string, error) {
if serviceGroup, exists := f.Config.Services[groupName]; exists {
return serviceGroup.Source.Path, nil
}
return "", fmt.Errorf("service group not found: %s", groupName)
}
// getServiceConfig returns a service's config
func (f *Factory) getServiceConfig(groupName, serviceIndex string) (*models.BackupConfig, error) {
if serviceGroup, exists := f.Config.Services[groupName]; exists {
if backupConfig, exists := serviceGroup.BackupConfigs[serviceIndex]; exists {
return &backupConfig, nil
}
}
return nil, fmt.Errorf("backup config not found: %s.%s", groupName, serviceIndex)
}
// ReloadConfig reloads configuration
func (f *Factory) ReloadConfig() error {
cfg, err := models.LoadConfig(f.ConfigPath)
if err != nil {
return fmt.Errorf("could not reload config: %w", err)
}
f.Config = cfg
return nil
}
// generateTempConfigPath creates a temp Kopia config path
func generateTempConfigPath(providerType string) string {
tmpConfigDir := filepath.Join(os.TempDir(), "kopia_configs")
_ = os.MkdirAll(tmpConfigDir, 0755) // Ensure directory exists
return filepath.Join(tmpConfigDir, fmt.Sprintf("kopia_%s_%d.config", providerType, time.Now().UnixNano()))
}