2021-11-22 18:26:51 +00:00
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
2022-01-10 17:45:10 +00:00
|
|
|
"net/url"
|
2021-11-22 18:26:51 +00:00
|
|
|
"os"
|
2022-01-05 18:49:21 +00:00
|
|
|
"runtime"
|
|
|
|
"strconv"
|
2022-01-10 17:45:10 +00:00
|
|
|
"strings"
|
2021-11-22 18:26:51 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Environment int
|
|
|
|
|
|
|
|
const (
|
|
|
|
EnvDevelopment Environment = iota
|
|
|
|
EnvProduction
|
|
|
|
)
|
|
|
|
|
2021-12-08 19:58:13 +00:00
|
|
|
type FileStore int
|
|
|
|
|
|
|
|
const (
|
2022-01-18 07:13:13 +00:00
|
|
|
FileSystemStore FileStore = iota
|
2021-12-08 19:58:13 +00:00
|
|
|
S3Store
|
|
|
|
)
|
|
|
|
|
2022-01-18 07:13:13 +00:00
|
|
|
const DefaultBindAddr = "localhost:8888"
|
|
|
|
|
2021-11-22 18:26:51 +00:00
|
|
|
type Config struct {
|
2021-12-09 03:05:34 +00:00
|
|
|
Environment Environment
|
|
|
|
BindAddr string
|
|
|
|
TLSCertFile string
|
|
|
|
TLSKeyFile string
|
|
|
|
DatabaseURL string
|
|
|
|
FileStore FileStore
|
|
|
|
FileStoreHTTPRoot string
|
2022-01-10 17:45:10 +00:00
|
|
|
FileStoreHTTPBaseURL *url.URL
|
2021-12-09 03:05:34 +00:00
|
|
|
AWSAccessKeyID string
|
|
|
|
AWSSecretAccessKey string
|
|
|
|
AWSRegion string
|
|
|
|
S3Bucket string
|
|
|
|
AssetsHTTPRoot string
|
2022-01-05 18:49:21 +00:00
|
|
|
FFmpegWorkerPoolSize int
|
2021-11-22 18:26:51 +00:00
|
|
|
}
|
|
|
|
|
2022-01-18 16:56:37 +00:00
|
|
|
const Prefix = "CLIPPER_"
|
2022-01-18 07:13:13 +00:00
|
|
|
|
|
|
|
func envPrefix(k string) string { return Prefix + k }
|
|
|
|
func getenvPrefix(k string) string { return os.Getenv(Prefix + k) }
|
|
|
|
|
2021-11-22 18:26:51 +00:00
|
|
|
func NewFromEnv() (Config, error) {
|
2022-01-18 07:13:13 +00:00
|
|
|
envVarName := envPrefix("ENV")
|
|
|
|
envString := os.Getenv(envVarName)
|
2021-11-22 18:26:51 +00:00
|
|
|
var env Environment
|
|
|
|
switch envString {
|
|
|
|
case "production":
|
|
|
|
env = EnvProduction
|
2022-01-18 07:13:13 +00:00
|
|
|
case "development", "":
|
2021-11-22 18:26:51 +00:00
|
|
|
env = EnvDevelopment
|
|
|
|
default:
|
2022-01-18 07:13:13 +00:00
|
|
|
return Config{}, fmt.Errorf("invalid %s value: %s", envVarName, envString)
|
2021-11-22 18:26:51 +00:00
|
|
|
}
|
|
|
|
|
2022-01-18 07:13:13 +00:00
|
|
|
bindAddr := getenvPrefix("BIND_ADDR")
|
2021-11-26 16:22:25 +00:00
|
|
|
if bindAddr == "" {
|
2022-01-18 07:13:13 +00:00
|
|
|
bindAddr = DefaultBindAddr
|
2021-11-26 16:22:25 +00:00
|
|
|
}
|
|
|
|
|
2022-01-18 07:13:13 +00:00
|
|
|
tlsCertFileName := envPrefix("TLS_CERT_FILE")
|
|
|
|
tlsKeyFileName := envPrefix("TLS_KEY_FILE")
|
|
|
|
tlsCertFile := os.Getenv(tlsCertFileName)
|
|
|
|
tlsKeyFile := os.Getenv(tlsKeyFileName)
|
2021-11-26 16:22:25 +00:00
|
|
|
if (tlsCertFile == "" && tlsKeyFile != "") || (tlsCertFile != "" && tlsKeyFile == "") {
|
2022-01-18 07:13:13 +00:00
|
|
|
return Config{}, fmt.Errorf("both %s and %s must be set", tlsCertFileName, tlsKeyFileName)
|
2021-11-26 16:22:25 +00:00
|
|
|
}
|
|
|
|
|
2022-01-18 07:13:13 +00:00
|
|
|
databaseURLName := envPrefix("DATABASE_URL")
|
|
|
|
databaseURL := os.Getenv(databaseURLName)
|
2021-11-22 18:26:51 +00:00
|
|
|
if databaseURL == "" {
|
2022-01-18 07:13:13 +00:00
|
|
|
return Config{}, fmt.Errorf("%s not set", databaseURLName)
|
2021-11-22 18:26:51 +00:00
|
|
|
}
|
|
|
|
|
2022-01-18 07:13:13 +00:00
|
|
|
fileStoreName := envPrefix("FILE_STORE")
|
|
|
|
fileStoreString := os.Getenv(fileStoreName)
|
2021-12-08 19:58:13 +00:00
|
|
|
var fileStore FileStore
|
2022-01-18 07:13:13 +00:00
|
|
|
switch getenvPrefix("FILE_STORE") {
|
2021-12-08 19:58:13 +00:00
|
|
|
case "s3":
|
|
|
|
fileStore = S3Store
|
|
|
|
case "filesystem", "":
|
|
|
|
fileStore = FileSystemStore
|
|
|
|
default:
|
2022-01-18 07:13:13 +00:00
|
|
|
return Config{}, fmt.Errorf("invalid %s value: %s", fileStoreName, fileStoreString)
|
2021-11-22 18:26:51 +00:00
|
|
|
}
|
|
|
|
|
2022-01-18 07:13:13 +00:00
|
|
|
fileStoreHTTPBaseURLName := envPrefix("FILE_STORE_HTTP_BASE_URL")
|
|
|
|
fileStoreHTTPBaseURLString := os.Getenv(fileStoreHTTPBaseURLName)
|
2022-01-10 17:45:10 +00:00
|
|
|
if !strings.HasSuffix(fileStoreHTTPBaseURLString, "/") {
|
|
|
|
fileStoreHTTPBaseURLString += "/"
|
|
|
|
}
|
|
|
|
fileStoreHTTPBaseURL, err := url.Parse(fileStoreHTTPBaseURLString)
|
|
|
|
if err != nil {
|
2022-01-18 07:13:13 +00:00
|
|
|
return Config{}, fmt.Errorf("invalid %s: %v", fileStoreHTTPBaseURLName, fileStoreHTTPBaseURLString)
|
2021-12-09 03:05:34 +00:00
|
|
|
}
|
|
|
|
|
2021-12-09 02:38:38 +00:00
|
|
|
var awsAccessKeyID, awsSecretAccessKey, awsRegion, s3Bucket, fileStoreHTTPRoot string
|
2021-12-08 19:58:13 +00:00
|
|
|
if fileStore == S3Store {
|
|
|
|
awsAccessKeyID = os.Getenv("AWS_ACCESS_KEY_ID")
|
|
|
|
if awsAccessKeyID == "" {
|
|
|
|
return Config{}, errors.New("AWS_ACCESS_KEY_ID not set")
|
|
|
|
}
|
2021-11-22 18:26:51 +00:00
|
|
|
|
2021-12-08 19:58:13 +00:00
|
|
|
awsSecretAccessKey = os.Getenv("AWS_SECRET_ACCESS_KEY")
|
|
|
|
if awsSecretAccessKey == "" {
|
|
|
|
return Config{}, errors.New("AWS_SECRET_ACCESS_KEY not set")
|
|
|
|
}
|
|
|
|
|
|
|
|
awsRegion = os.Getenv("AWS_REGION")
|
|
|
|
if awsRegion == "" {
|
|
|
|
return Config{}, errors.New("AWS_REGION not set")
|
|
|
|
}
|
2021-11-22 18:26:51 +00:00
|
|
|
|
2022-01-18 07:13:13 +00:00
|
|
|
s3Bucket = getenvPrefix("S3_BUCKET")
|
2021-12-08 19:58:13 +00:00
|
|
|
if s3Bucket == "" {
|
|
|
|
return Config{}, errors.New("S3_BUCKET not set")
|
|
|
|
}
|
|
|
|
} else {
|
2022-01-18 07:13:13 +00:00
|
|
|
if fileStoreHTTPRoot = getenvPrefix("FILE_STORE_HTTP_ROOT"); fileStoreHTTPRoot == "" {
|
2021-12-09 02:38:38 +00:00
|
|
|
return Config{}, errors.New("FILE_STORE_HTTP_ROOT not set")
|
2021-12-08 19:58:13 +00:00
|
|
|
}
|
2021-11-22 18:26:51 +00:00
|
|
|
}
|
|
|
|
|
2022-01-18 07:13:13 +00:00
|
|
|
assetsHTTPRoot := getenvPrefix("ASSETS_HTTP_ROOT")
|
2021-11-26 04:11:49 +00:00
|
|
|
|
2022-01-05 18:49:21 +00:00
|
|
|
ffmpegWorkerPoolSize := runtime.NumCPU()
|
2022-01-18 07:13:13 +00:00
|
|
|
ffmpegWorkerPoolSizeName := envPrefix("FFMPEG_WORKER_POOL_SIZE")
|
|
|
|
if s := os.Getenv(ffmpegWorkerPoolSizeName); s != "" {
|
2022-01-05 18:49:21 +00:00
|
|
|
if n, err := strconv.Atoi(s); err != nil {
|
2022-01-18 07:13:13 +00:00
|
|
|
return Config{}, fmt.Errorf("invalid %s value: %s", ffmpegWorkerPoolSizeName, s)
|
2022-01-05 18:49:21 +00:00
|
|
|
} else {
|
|
|
|
ffmpegWorkerPoolSize = n
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-22 18:26:51 +00:00
|
|
|
return Config{
|
2021-12-09 03:05:34 +00:00
|
|
|
Environment: env,
|
|
|
|
BindAddr: bindAddr,
|
|
|
|
TLSCertFile: tlsCertFile,
|
|
|
|
TLSKeyFile: tlsKeyFile,
|
|
|
|
DatabaseURL: databaseURL,
|
|
|
|
FileStore: fileStore,
|
|
|
|
AWSAccessKeyID: awsAccessKeyID,
|
|
|
|
AWSSecretAccessKey: awsSecretAccessKey,
|
|
|
|
AWSRegion: awsRegion,
|
|
|
|
S3Bucket: s3Bucket,
|
|
|
|
AssetsHTTPRoot: assetsHTTPRoot,
|
|
|
|
FileStoreHTTPRoot: fileStoreHTTPRoot,
|
|
|
|
FileStoreHTTPBaseURL: fileStoreHTTPBaseURL,
|
2022-01-05 18:49:21 +00:00
|
|
|
FFmpegWorkerPoolSize: ffmpegWorkerPoolSize,
|
2021-11-22 18:26:51 +00:00
|
|
|
}, nil
|
|
|
|
}
|