115 lines
3.0 KiB
Go
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
|
|
}
|