Files
RenewCMS/internal/infrastructure/config/storageSettings.go
T

115 lines
3.0 KiB
Go

package config
import (
"fmt"
"os"
"slices"
"strconv"
)
const (
StorageDriverLocal = "local"
StorageDriverS3 = "s3"
DefaultStorageDriver = StorageDriverLocal
DefaultS3Region = "us-east-1"
DefaultS3PathStyle = "false"
DefaultS3TLS = "true"
EnvStorageDriver = "STORAGE_DRIVER"
envS3Bucket = "S3_BUCKET"
envS3Region = "S3_REGION"
envS3Endpoint = "S3_ENDPOINT"
envS3AccessKeyID = "S3_ACCESS_KEY_ID"
envS3SecretKey = "S3_SECRET_ACCESS_KEY"
envS3KeyPrefix = "S3_KEY_PREFIX"
envS3PathStyle = "S3_PATH_STYLE"
envS3TLS = "S3_TLS"
)
var s3RequiredEnvVars = []string{envS3Bucket}
type S3Settings struct {
Bucket string
Region string
Endpoint string
AccessKeyID string
SecretAccessKey string
KeyPrefix string
PathStyle bool
TLS bool
}
type StorageSettings struct {
Driver string
S3 S3Settings
}
func StorageRequiredEnvVars(driver string) []string {
if driver == StorageDriverS3 {
return slices.Clone(s3RequiredEnvVars)
}
return nil
}
func storageSettingsFromEnv() (StorageSettings, error) {
driver := envOrDefault(EnvStorageDriver, DefaultStorageDriver)
switch driver {
case StorageDriverLocal:
return StorageSettings{Driver: driver}, nil
case StorageDriverS3:
s3, err := s3SettingsFromEnv()
if err != nil {
return StorageSettings{}, err
}
return StorageSettings{Driver: driver, S3: s3}, nil
default:
return StorageSettings{}, fmt.Errorf("unsupported storage driver %q", driver)
}
}
func s3SettingsFromEnv() (S3Settings, error) {
if err := MissingEnvVarError(s3RequiredEnvVars, nonEmptyEnvLookup); err != nil {
return S3Settings{}, err
}
accessKeyID := os.Getenv(envS3AccessKeyID)
secretKey := os.Getenv(envS3SecretKey)
if accessKeyID != "" && secretKey == "" {
return S3Settings{}, fmt.Errorf("Environment variable %s is not set (it is required when %s is set)", envS3SecretKey, envS3AccessKeyID)
}
if secretKey != "" && accessKeyID == "" {
return S3Settings{}, fmt.Errorf("Environment variable %s is not set (it is required when %s is set)", envS3AccessKeyID, envS3SecretKey)
}
pathStyle, err := boolEnv(envS3PathStyle, DefaultS3PathStyle)
if err != nil {
return S3Settings{}, err
}
tls, err := boolEnv(envS3TLS, DefaultS3TLS)
if err != nil {
return S3Settings{}, err
}
return S3Settings{
Bucket: os.Getenv(envS3Bucket),
Region: envOrDefault(envS3Region, DefaultS3Region),
Endpoint: os.Getenv(envS3Endpoint),
AccessKeyID: accessKeyID,
SecretAccessKey: secretKey,
KeyPrefix: os.Getenv(envS3KeyPrefix),
PathStyle: pathStyle,
TLS: tls,
}, nil
}
func nonEmptyEnvLookup(name string) (string, bool) {
value := os.Getenv(name)
return value, value != ""
}
func boolEnv(name string, fallback string) (bool, error) {
raw := envOrDefault(name, fallback)
value, err := strconv.ParseBool(raw)
if err != nil {
return false, fmt.Errorf("%s must be true or false, got %q", name, raw)
}
return value, nil
}