package maker import ( "context" "fmt" "os" "path/filepath" "gitea.loveuer.com/yizhisec/pkg3/logger" "yizhisec.com/hsv2/forge/internal/opt" "yizhisec.com/hsv2/forge/pkg/downloader" "yizhisec.com/hsv2/forge/pkg/model" ) type RedisOpt func(*redisOpt) type redisOpt struct { ReplicaCount int Password string Storage string } func WithRedisReplicaCount(replica int) RedisOpt { return func(o *redisOpt) { if replica > 0 { o.ReplicaCount = replica } } } func WithRedisPassword(password string) RedisOpt { return func(o *redisOpt) { if password != "" { o.Password = password } } } func WithRedisStorage(storage string) RedisOpt { return func(o *redisOpt) { if opt.StorageSizeReg.MatchString(storage) { o.Storage = storage } } } func (m *maker) Redis(ctx context.Context, opts ...RedisOpt) error { const ( valuesTemplate = `# Redis configuration architecture: replication image: registry: docker.io repository: bitnami/redis tag: 8.2.2 pullPolicy: IfNotPresent auth: enabled: true password: "%s" master: persistence: enabled: true storageClass: "longhorn" size: %s replica: replicaCount: %d persistence: enabled: true storageClass: "longhorn" size: %s metrics: enabled: false serviceMonitor: enabled: false ` defaultPassword = "HybridScope0xRed1s." chartURL = "https://artifactory.yizhisec.com:443/artifactory/filestore/hsv3/charts/redis-23.2.2.tgz" chartFilename = "redis-23.2.2.tgz" ) o := &redisOpt{ ReplicaCount: 2, Password: "HybridScope0xRed1s.", Storage: "5Gi", } for _, fn := range opts { fn(o) } location := filepath.Join(m.workdir, "dependency", "redis") chartFile := filepath.Join(location, chartFilename) valuesFile := filepath.Join(location, "values.yaml") logger.Info("☑️ maker.Redis: 开始构建 Redis 资源...") logger.Debug("☑️ maker.Redis: 开始构建 Redis 资源..., opt = %#v", o) logger.Debug("☑️ maker.Redis: 创建目录 %s", location) if err := os.MkdirAll(location, 0755); err != nil { logger.Debug("❌ maker.Redis: 创建目录失败: %v", err) return err } logger.Debug("✅ maker.Redis: 创建目录 %s 成功", location) logger.Debug("☑️ maker.Redis: 下载 Redis chart..., url = %s, dest = %s", chartURL, chartFile) if err := downloader.Download( ctx, chartURL, chartFile, downloader.WithInsecureSkipVerify(), ); err != nil { logger.Debug("❌ maker.Redis: 下载 Redis chart 失败, url = %s, err = %v", chartURL, err) return err } logger.Debug("✅ maker.Redis: 下载 Redis chart 成功, url = %s", chartURL) logger.Debug("☑️ maker.Redis: 写入 values.yaml 文件..., dest = %s", valuesFile) bs := fmt.Sprintf(valuesTemplate, o.Password, o.Storage, o.ReplicaCount, o.Storage) if err := os.WriteFile(valuesFile, []byte(bs), 0644); err != nil { logger.Debug("❌ maker.Redis: 写入 values.yaml 文件失败, dest = %s, err = %v", valuesFile, err) return err } logger.Debug("✅ maker.Redis: 写入 values.yaml 文件成功, dest = %s", valuesFile) logger.Debug("☑️ maker.Redis: 开始获取镜像...") img := &model.Image{Name: "docker.io/bitnami/redis:8.2.2", Fallback: "hub.yizhisec.com/external/bitnami/redis:8.2.2", Save: "bitnami.redis.8.2.2.tar"} if err := m.Image(ctx, img.Name, WithImageFallback(img.Fallback), WithImageSave(filepath.Join(location, img.Save))); err != nil { logger.Debug("❌ maker.Redis: 获取镜像失败: %s, %v", img.Name, err) return err } logger.Debug("✅ maker.Redis: 获取镜像成功!!!") logger.Info("✅ maker.Redis: 构建 Redis 资源成功!!!") return nil }