package bootstrap import ( "context" "fmt" "log" "time" "github.com/google/uuid" "github.com/ocdp/cluster-service/internal/adapter/output" "github.com/ocdp/cluster-service/internal/domain/entity" "github.com/ocdp/cluster-service/internal/pkg/password" ) // Seeder 预注入管理器 type Seeder struct { repos *output.Repositories passwordHasher *password.Hasher config *BootstrapConfig } // NewSeeder 创建预注入管理器 func NewSeeder(repos *output.Repositories, passwordHasher *password.Hasher, config *BootstrapConfig) *Seeder { return &Seeder{ repos: repos, passwordHasher: passwordHasher, config: config, } } // SeedAll 执行所有预注入 func (s *Seeder) SeedAll(ctx context.Context) error { if !s.config.Enabled { log.Println(" ℹ️ Bootstrap seeding is disabled") return nil } log.Println(" 🌱 Starting bootstrap seeding...") // 1. 注入用户 if err := s.seedUsers(ctx); err != nil { return fmt.Errorf("failed to seed users: %w", err) } // 2. 注入 Registries if err := s.seedRegistries(ctx); err != nil { return fmt.Errorf("failed to seed registries: %w", err) } // 3. 注入 Clusters if err := s.seedClusters(ctx); err != nil { return fmt.Errorf("failed to seed clusters: %w", err) } log.Println(" ✅ Bootstrap seeding completed") return nil } // seedUsers 注入用户 func (s *Seeder) seedUsers(ctx context.Context) error { if len(s.config.Users) == 0 { log.Println(" ↳ No users to seed") return nil } log.Printf(" ↳ Seeding %d user(s)...", len(s.config.Users)) for _, userSeed := range s.config.Users { // 检查用户是否已存在 existingUser, _ := s.repos.UserRepo.GetByUsername(ctx, userSeed.Username) if existingUser != nil { log.Printf(" ⊙ User '%s' already exists, skipping", userSeed.Username) continue } // 哈希密码 passwordHash, err := s.passwordHasher.Hash(userSeed.Password) if err != nil { log.Printf(" ✗ Failed to hash password for user '%s': %v", userSeed.Username, err) continue } // 创建用户 user := entity.NewUser(userSeed.Username, passwordHash, userSeed.Email) user.ID = uuid.New().String() if err := s.repos.UserRepo.Create(ctx, user); err != nil { log.Printf(" ✗ Failed to create user '%s': %v", userSeed.Username, err) continue } log.Printf(" ✓ User '%s' created", userSeed.Username) } return nil } // seedRegistries 注入 Registries func (s *Seeder) seedRegistries(ctx context.Context) error { if len(s.config.Registries) == 0 { log.Println(" ↳ No registries to seed") return nil } log.Printf(" ↳ Seeding %d registry(ies)...", len(s.config.Registries)) for _, registrySeed := range s.config.Registries { // 检查 Registry 是否已存在 existingRegistry, _ := s.repos.RegistryRepo.GetByName(ctx, registrySeed.Name) if existingRegistry != nil { log.Printf(" ⊙ Registry '%s' already exists, skipping", registrySeed.Name) continue } // 创建 Registry registry := &entity.Registry{ ID: uuid.New().String(), Name: registrySeed.Name, URL: registrySeed.URL, Description: registrySeed.Description, Username: registrySeed.Username, Password: registrySeed.Password, Insecure: registrySeed.Insecure, CreatedAt: time.Now(), UpdatedAt: time.Now(), } if err := s.repos.RegistryRepo.Create(ctx, registry); err != nil { log.Printf(" ✗ Failed to create registry '%s': %v", registrySeed.Name, err) continue } log.Printf(" ✓ Registry '%s' created (credentials encrypted)", registrySeed.Name) } return nil } // seedClusters 注入 Clusters func (s *Seeder) seedClusters(ctx context.Context) error { if len(s.config.Clusters) == 0 { log.Println(" ↳ No clusters to seed") return nil } log.Printf(" ↳ Seeding %d cluster(s)...", len(s.config.Clusters)) for _, clusterSeed := range s.config.Clusters { // 检查 Cluster 是否已存在 existingCluster, _ := s.repos.ClusterRepo.GetByName(ctx, clusterSeed.Name) if existingCluster != nil { log.Printf(" ⊙ Cluster '%s' already exists, skipping", clusterSeed.Name) continue } // 创建 Cluster cluster := &entity.Cluster{ ID: uuid.New().String(), Name: clusterSeed.Name, Host: clusterSeed.Host, Description: clusterSeed.Description, CAData: clusterSeed.CAData, CertData: clusterSeed.CertData, KeyData: clusterSeed.KeyData, Token: clusterSeed.Token, CreatedAt: time.Now(), UpdatedAt: time.Now(), } if err := s.repos.ClusterRepo.Create(ctx, cluster); err != nil { log.Printf(" ✗ Failed to create cluster '%s': %v", clusterSeed.Name, err) continue } log.Printf(" ✓ Cluster '%s' created (credentials encrypted)", clusterSeed.Name) } return nil }