mirror of
https://github.com/GlueOps/autoglue.git
synced 2026-02-13 12:50:05 +01:00
feat: sdk migration in progress
This commit is contained in:
194
internal/config/config.go
Normal file
194
internal/config/config.go
Normal file
@@ -0,0 +1,194 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/spf13/viper"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
DbURL string
|
||||
Port string
|
||||
Host string
|
||||
JWTIssuer string
|
||||
JWTAudience string
|
||||
JWTPrivateEncKey string
|
||||
OAuthRedirectBase string
|
||||
GoogleClientID string
|
||||
GoogleClientSecret string
|
||||
GithubClientID string
|
||||
GithubClientSecret string
|
||||
|
||||
UIDev bool
|
||||
Env string
|
||||
Debug bool
|
||||
Swagger bool
|
||||
}
|
||||
|
||||
var (
|
||||
once sync.Once
|
||||
cached Config
|
||||
loadErr error
|
||||
)
|
||||
|
||||
func Load() (Config, error) {
|
||||
once.Do(func() {
|
||||
_ = godotenv.Load()
|
||||
|
||||
// Use a private viper to avoid global mutation/races
|
||||
v := viper.New()
|
||||
|
||||
// Defaults
|
||||
v.SetDefault("bind.address", "127.0.0.1")
|
||||
v.SetDefault("bind.port", "8080")
|
||||
v.SetDefault("database.url", "postgres://user:pass@localhost:5432/db?sslmode=disable")
|
||||
|
||||
v.SetDefault("ui.dev", false)
|
||||
v.SetDefault("env", "development")
|
||||
v.SetDefault("debug", false)
|
||||
v.SetDefault("swagger", false)
|
||||
|
||||
// Env setup and binding
|
||||
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
v.AutomaticEnv()
|
||||
|
||||
keys := []string{
|
||||
"bind.address",
|
||||
"bind.port",
|
||||
"database.url",
|
||||
"jwt.issuer",
|
||||
"jwt.audience",
|
||||
"jwt.private.enc.key",
|
||||
"oauth.redirect.base",
|
||||
"google.client.id",
|
||||
"google.client.secret",
|
||||
"github.client.id",
|
||||
"github.client.secret",
|
||||
"ui.dev",
|
||||
"env",
|
||||
"debug",
|
||||
"swagger",
|
||||
}
|
||||
for _, k := range keys {
|
||||
_ = v.BindEnv(k)
|
||||
}
|
||||
|
||||
// Build config
|
||||
cfg := Config{
|
||||
DbURL: v.GetString("database.url"),
|
||||
Port: v.GetString("bind.port"),
|
||||
Host: v.GetString("bind.address"),
|
||||
JWTIssuer: v.GetString("jwt.issuer"),
|
||||
JWTAudience: v.GetString("jwt.audience"),
|
||||
JWTPrivateEncKey: v.GetString("jwt.private.enc.key"),
|
||||
OAuthRedirectBase: v.GetString("oauth.redirect.base"),
|
||||
GoogleClientID: v.GetString("google.client.id"),
|
||||
GoogleClientSecret: v.GetString("google.client.secret"),
|
||||
GithubClientID: v.GetString("github.client.id"),
|
||||
GithubClientSecret: v.GetString("github.client.secret"),
|
||||
|
||||
UIDev: v.GetBool("ui.dev"),
|
||||
Env: v.GetString("env"),
|
||||
Debug: v.GetBool("debug"),
|
||||
Swagger: v.GetBool("swagger"),
|
||||
}
|
||||
|
||||
// Validate
|
||||
if err := validateConfig(cfg); err != nil {
|
||||
loadErr = err
|
||||
return
|
||||
}
|
||||
|
||||
cached = cfg
|
||||
})
|
||||
return cached, loadErr
|
||||
}
|
||||
|
||||
func validateConfig(cfg Config) error {
|
||||
var errs []string
|
||||
|
||||
// Required general settings
|
||||
req := map[string]string{
|
||||
"jwt.issuer": cfg.JWTIssuer,
|
||||
"jwt.audience": cfg.JWTAudience,
|
||||
"jwt.private.enc.key": cfg.JWTPrivateEncKey,
|
||||
"oauth.redirect.base": cfg.OAuthRedirectBase,
|
||||
}
|
||||
for k, v := range req {
|
||||
if strings.TrimSpace(v) == "" {
|
||||
errs = append(errs, fmt.Sprintf("missing required config key %q (env %s)", k, envNameFromKey(k)))
|
||||
}
|
||||
}
|
||||
|
||||
// OAuth provider requirements:
|
||||
googleOK := strings.TrimSpace(cfg.GoogleClientID) != "" && strings.TrimSpace(cfg.GoogleClientSecret) != ""
|
||||
githubOK := strings.TrimSpace(cfg.GithubClientID) != "" && strings.TrimSpace(cfg.GithubClientSecret) != ""
|
||||
|
||||
// If partially configured, report what's missing for each
|
||||
if !googleOK && (cfg.GoogleClientID != "" || cfg.GoogleClientSecret != "") {
|
||||
if cfg.GoogleClientID == "" {
|
||||
errs = append(errs, fmt.Sprintf("google.client.id is missing (env %s) while google.client.secret is set", envNameFromKey("google.client.id")))
|
||||
}
|
||||
if cfg.GoogleClientSecret == "" {
|
||||
errs = append(errs, fmt.Sprintf("google.client.secret is missing (env %s) while google.client.id is set", envNameFromKey("google.client.secret")))
|
||||
}
|
||||
}
|
||||
if !githubOK && (cfg.GithubClientID != "" || cfg.GithubClientSecret != "") {
|
||||
if cfg.GithubClientID == "" {
|
||||
errs = append(errs, fmt.Sprintf("github.client.id is missing (env %s) while github.client.secret is set", envNameFromKey("github.client.id")))
|
||||
}
|
||||
if cfg.GithubClientSecret == "" {
|
||||
errs = append(errs, fmt.Sprintf("github.client.secret is missing (env %s) while github.client.id is set", envNameFromKey("github.client.secret")))
|
||||
}
|
||||
}
|
||||
|
||||
// Enforce minimum: at least one full provider
|
||||
if !googleOK && !githubOK {
|
||||
errs = append(errs, "at least one OAuth provider must be fully configured: either Google (google.client.id + google.client.secret) or GitHub (github.client.id + github.client.secret)")
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return errors.New(strings.Join(errs, "; "))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func envNameFromKey(key string) string {
|
||||
return strings.ToUpper(strings.ReplaceAll(key, ".", "_"))
|
||||
}
|
||||
|
||||
func DebugPrintConfig() {
|
||||
cfg, _ := Load()
|
||||
b, err := yaml.Marshal(cfg)
|
||||
if err != nil {
|
||||
fmt.Println("error marshalling config:", err)
|
||||
return
|
||||
}
|
||||
fmt.Println("Loaded configuration:")
|
||||
fmt.Println(string(b))
|
||||
}
|
||||
|
||||
func IsUIDev() bool {
|
||||
cfg, _ := Load()
|
||||
return cfg.UIDev
|
||||
}
|
||||
|
||||
func IsDev() bool {
|
||||
cfg, _ := Load()
|
||||
return strings.EqualFold(cfg.Env, "development")
|
||||
}
|
||||
|
||||
func IsDebug() bool {
|
||||
cfg, _ := Load()
|
||||
return cfg.Debug
|
||||
}
|
||||
|
||||
func IsSwaggerEnabled() bool {
|
||||
cfg, _ := Load()
|
||||
return cfg.Swagger
|
||||
}
|
||||
Reference in New Issue
Block a user