first commit, i i have no idea what i have done
This commit is contained in:
205
server/internal/config/config.go
Normal file
205
server/internal/config/config.go
Normal file
@@ -0,0 +1,205 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"smoop-api/internal/vault"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
DB struct {
|
||||
DSN string
|
||||
}
|
||||
MinIO struct {
|
||||
Endpoint string
|
||||
AccessKey string
|
||||
SecretKey string
|
||||
UseSSL bool
|
||||
RecordsBucket string
|
||||
LivestreamBucket string
|
||||
PresignTTL time.Duration
|
||||
}
|
||||
JWTSecret []byte
|
||||
}
|
||||
|
||||
func Load() (*Config, error) {
|
||||
addr := os.Getenv("VAULT_ADDR")
|
||||
token := os.Getenv("VAULT_TOKEN")
|
||||
|
||||
// New style: explicit KV v2 mount + key
|
||||
mount := os.Getenv("VAULT_KV_MOUNT") // e.g. "kv" or "secret"
|
||||
key := os.Getenv("VAULT_KV_KEY") // e.g. "snoop"
|
||||
|
||||
// Back-compat: allow legacy VAULT_KV_PATH like "kv/data/snoop" and derive mount+key
|
||||
if (mount == "" || key == "") && os.Getenv("VAULT_KV_PATH") != "" {
|
||||
legacy := strings.Trim(os.Getenv("VAULT_KV_PATH"), "/")
|
||||
parts := strings.Split(legacy, "/")
|
||||
if len(parts) >= 2 {
|
||||
mount = parts[0]
|
||||
key = parts[len(parts)-1]
|
||||
}
|
||||
}
|
||||
|
||||
if addr == "" || token == "" || mount == "" || key == "" {
|
||||
return nil, fmt.Errorf("VAULT_ADDR, VAULT_TOKEN, VAULT_KV_MOUNT and VAULT_KV_KEY must be set (or provide legacy VAULT_KV_PATH)")
|
||||
}
|
||||
|
||||
raw, err := vault.ReadKVv2(addr, token, mount, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
getStr := func(k string) (string, error) {
|
||||
v, ok := raw[k].(string)
|
||||
if !ok || v == "" {
|
||||
return "", fmt.Errorf("missing secret key: %s", k)
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
getBool := func(k string) (bool, error) {
|
||||
v, ok := raw[k]
|
||||
if !ok {
|
||||
return false, fmt.Errorf("missing secret key: %s", k)
|
||||
}
|
||||
switch t := v.(type) {
|
||||
case bool:
|
||||
return t, nil
|
||||
case string:
|
||||
if t == "true" || t == "1" {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
default:
|
||||
return false, fmt.Errorf("invalid bool for key %s", k)
|
||||
}
|
||||
}
|
||||
|
||||
dbDSN, err := getStr("db_dsn")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
endpoint, err := getStr("minio_endpoint")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ak, err := getStr("minio_access_key")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sk, err := getStr("minio_secret_key")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
useSSL, err := getBool("minio_use_ssl")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
jwt, err := getStr("jwt_secret")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
recordsBucket := "records"
|
||||
if v, ok := raw["minio_records_bucket"].(string); ok && v != "" {
|
||||
recordsBucket = v
|
||||
}
|
||||
liveBucket := "livestream"
|
||||
if v, ok := raw["minio_livestream_bucket"].(string); ok && v != "" {
|
||||
liveBucket = v
|
||||
}
|
||||
presignTTL := 15 * time.Minute
|
||||
if v, ok := raw["minio_presign_ttl_seconds"].(string); ok && v != "" {
|
||||
var sec int
|
||||
fmt.Sscanf(v, "%d", &sec)
|
||||
if sec > 0 {
|
||||
presignTTL = time.Duration(sec) * time.Second
|
||||
}
|
||||
}
|
||||
|
||||
cfg := &Config{}
|
||||
cfg.DB.DSN = dbDSN
|
||||
cfg.MinIO.Endpoint = endpoint
|
||||
cfg.MinIO.AccessKey = ak
|
||||
cfg.MinIO.SecretKey = sk
|
||||
cfg.MinIO.UseSSL = useSSL
|
||||
cfg.MinIO.RecordsBucket = recordsBucket
|
||||
cfg.MinIO.LivestreamBucket = liveBucket
|
||||
cfg.MinIO.PresignTTL = presignTTL
|
||||
cfg.JWTSecret = []byte(jwt)
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func LoadDev() (*Config, error) {
|
||||
getRequired := func(k string) (string, error) {
|
||||
v := os.Getenv(k)
|
||||
if v == "" {
|
||||
return "", fmt.Errorf("missing required env %s", k)
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
getBoolEnv := func(k string, def bool) bool {
|
||||
v := strings.ToLower(strings.TrimSpace(os.Getenv(k)))
|
||||
if v == "true" || v == "1" || v == "yes" {
|
||||
return true
|
||||
}
|
||||
if v == "false" || v == "0" || v == "no" {
|
||||
return false
|
||||
}
|
||||
return def
|
||||
}
|
||||
getIntEnv := func(k string, def int) int {
|
||||
if v := strings.TrimSpace(os.Getenv(k)); v != "" {
|
||||
if n, err := strconv.Atoi(v); err == nil {
|
||||
return n
|
||||
}
|
||||
}
|
||||
return def
|
||||
}
|
||||
dbDSN, err := getRequired("DB_DSN")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
endpoint, err := getRequired("MINIO_ENDPOINT")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ak, err := getRequired("MINIO_ACCESS_KEY")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sk, err := getRequired("MINIO_SECRET_KEY")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
jwt, err := getRequired("JWT_SECRET")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
useSSL := getBoolEnv("MINIO_USE_SSL", false)
|
||||
recordsBucket := os.Getenv("MINIO_RECORDS_BUCKET")
|
||||
if recordsBucket == "" {
|
||||
recordsBucket = "records"
|
||||
}
|
||||
liveBucket := os.Getenv("MINIO_LIVESTREAM_BUCKET")
|
||||
if liveBucket == "" {
|
||||
liveBucket = "livestream"
|
||||
}
|
||||
presignTTL := time.Duration(getIntEnv("MINIO_PRESIGN_TTL_SECONDS", 900)) * time.Second
|
||||
|
||||
cfg := &Config{}
|
||||
cfg.DB.DSN = dbDSN
|
||||
cfg.MinIO.Endpoint = endpoint
|
||||
cfg.MinIO.AccessKey = ak
|
||||
cfg.MinIO.SecretKey = sk
|
||||
cfg.MinIO.UseSSL = useSSL
|
||||
cfg.MinIO.RecordsBucket = recordsBucket
|
||||
cfg.MinIO.LivestreamBucket = liveBucket
|
||||
cfg.MinIO.PresignTTL = presignTTL
|
||||
cfg.JWTSecret = []byte(jwt)
|
||||
return cfg, nil
|
||||
}
|
||||
Reference in New Issue
Block a user