feat(config): app-config registry, env-var renames, wire session.duration from DB
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,9 +8,7 @@ package config
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Config holds geniusrund's process-level configuration.
|
||||
@@ -26,7 +24,7 @@ type Config struct {
|
||||
GarminPythonPath string
|
||||
// GarminTokenStoreRoot is the root directory under which each user's
|
||||
// Garmin session cache lives (one subdirectory per user id, e.g.
|
||||
// "<root>/3"). Read from the GARMIN_TOKENSTORE env var, configured
|
||||
// "<root>/3"). Read from the GENIUSRUN_TOKENSTORE_PATH env var, configured
|
||||
// independently of DBPath -- if unset, it defaults to a ".garmin"
|
||||
// directory relative to the working directory the process is started
|
||||
// from, not derived from DBPath in any way, so every deployment gets
|
||||
@@ -35,7 +33,6 @@ type Config struct {
|
||||
// api.Server.garminFor), so it can never be silently left empty.
|
||||
GarminTokenStoreRoot string
|
||||
|
||||
MinConfidence float64
|
||||
// LogLevel controls internal/applog's JSON logger ("debug"|"info"|"warn"|"error").
|
||||
LogLevel string
|
||||
|
||||
@@ -62,7 +59,6 @@ type Config struct {
|
||||
OIDCRedirectURL string
|
||||
OIDCRequiredRole string
|
||||
SessionSecret []byte
|
||||
SessionDuration time.Duration
|
||||
SessionSecure bool
|
||||
}
|
||||
|
||||
@@ -70,18 +66,16 @@ type Config struct {
|
||||
// for anything optional. Returns an error if a required variable is unset.
|
||||
func Load() (Config, error) {
|
||||
cfg := Config{
|
||||
Addr: getEnvDefault("GENIUSRUN_ADDR", ":8080"),
|
||||
Addr: getEnvDefault("GENIUSRUN_BACKEND_ADDR", ":8080"),
|
||||
DBPath: getEnvDefault("GENIUSRUN_DB_PATH", "geniusrun.db"),
|
||||
GarminPythonPath: getEnvDefault("GARMIN_WRAPPER_PYTHON", "python3"),
|
||||
GarminTokenStoreRoot: getEnvDefault("GARMIN_TOKENSTORE", ".garmin"),
|
||||
MinConfidence: getEnvFloat("GENIUSRUN_MIN_CONFIDENCE", 0.6),
|
||||
GarminPythonPath: getEnvDefault("GENIUSRUN_PYTHON_PATH", "python3"),
|
||||
GarminTokenStoreRoot: getEnvDefault("GENIUSRUN_TOKENSTORE_PATH", ".garmin"),
|
||||
LogLevel: getEnvDefault("GENIUSRUN_LOG_LEVEL", "info"),
|
||||
BackendURL: strings.TrimRight(os.Getenv("GENIUSRUN_BACKEND_URL"), "/"),
|
||||
OIDCIssuerURL: os.Getenv("GENIUSRUN_OIDC_ISSUER_URL"),
|
||||
OIDCClientID: os.Getenv("GENIUSRUN_OIDC_CLIENT_ID"),
|
||||
OIDCClientSecret: os.Getenv("GENIUSRUN_OIDC_CLIENT_SECRET"),
|
||||
OIDCRequiredRole: getEnvDefault("GENIUSRUN_OIDC_REQUIRED_ROLE", "geniusrun-user"),
|
||||
SessionDuration: getEnvDuration("GENIUSRUN_SESSION_DURATION", 720*time.Hour),
|
||||
}
|
||||
|
||||
if cfg.BackendURL == "" {
|
||||
@@ -117,20 +111,35 @@ func getEnvDefault(key, def string) string {
|
||||
return def
|
||||
}
|
||||
|
||||
func getEnvFloat(key string, def float64) float64 {
|
||||
if v := os.Getenv(key); v != "" {
|
||||
if f, err := strconv.ParseFloat(v, 64); err == nil {
|
||||
return f
|
||||
}
|
||||
}
|
||||
return def
|
||||
// EnvEntry is one environment-configuration variable as displayed on the
|
||||
// config page. Display-only: secrets are masked here, so raw values never
|
||||
// leave the process.
|
||||
type EnvEntry struct {
|
||||
Name string
|
||||
Value string
|
||||
}
|
||||
|
||||
func getEnvDuration(key string, def time.Duration) time.Duration {
|
||||
if v := os.Getenv(key); v != "" {
|
||||
if d, err := time.ParseDuration(v); err == nil {
|
||||
return d
|
||||
// DisplayEnv returns the environment configuration as a display-safe
|
||||
// list, in stable order, secrets masked.
|
||||
func (c Config) DisplayEnv() []EnvEntry {
|
||||
mask := func(set bool) string {
|
||||
if set {
|
||||
return "•••• (set)"
|
||||
}
|
||||
return "(unset)"
|
||||
}
|
||||
return []EnvEntry{
|
||||
{Name: "GENIUSRUN_BACKEND_ADDR", Value: c.Addr},
|
||||
{Name: "GENIUSRUN_DB_PATH", Value: c.DBPath},
|
||||
{Name: "GENIUSRUN_PYTHON_PATH", Value: c.GarminPythonPath},
|
||||
{Name: "GENIUSRUN_TOKENSTORE_PATH", Value: c.GarminTokenStoreRoot},
|
||||
{Name: "GENIUSRUN_LOG_LEVEL", Value: c.LogLevel},
|
||||
{Name: "GENIUSRUN_BACKEND_URL", Value: c.BackendURL},
|
||||
{Name: "GENIUSRUN_FRONTEND_URL", Value: c.FrontendURL},
|
||||
{Name: "GENIUSRUN_OIDC_ISSUER_URL", Value: c.OIDCIssuerURL},
|
||||
{Name: "GENIUSRUN_OIDC_CLIENT_ID", Value: c.OIDCClientID},
|
||||
{Name: "GENIUSRUN_OIDC_CLIENT_SECRET", Value: mask(c.OIDCClientSecret != "")},
|
||||
{Name: "GENIUSRUN_OIDC_REQUIRED_ROLE", Value: c.OIDCRequiredRole},
|
||||
{Name: "GENIUSRUN_SESSION_SECRET", Value: mask(len(c.SessionSecret) > 0)},
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user