Files
skybridge/faas/internal/config/config.go
2025-08-30 21:17:23 -04:00

192 lines
4.9 KiB
Go

package config
import (
"fmt"
"os"
"strconv"
"strings"
"time"
)
type Config struct {
env map[string]string
}
type ConfigProvider interface {
GetString(key string) string
GetInt(key string) int
GetBool(key string) bool
GetDuration(key string) time.Duration
GetServerAddress() string
GetDatabaseDSN() string
GetDatabaseDSNForLogging() string
IsProduction() bool
Validate() error
}
func NewConfig() ConfigProvider {
env := make(map[string]string)
// Load environment variables
for _, pair := range os.Environ() {
parts := strings.SplitN(pair, "=", 2)
if len(parts) == 2 {
env[parts[0]] = parts[1]
}
}
// Set defaults
setDefault(env, "FAAS_SERVER_HOST", "0.0.0.0")
setDefault(env, "FAAS_SERVER_PORT", "8082")
setDefault(env, "FAAS_DB_HOST", "localhost")
setDefault(env, "FAAS_DB_PORT", "5432")
setDefault(env, "FAAS_DB_NAME", "faas")
setDefault(env, "FAAS_DB_USER", "postgres")
setDefault(env, "FAAS_DB_PASSWORD", "postgres")
setDefault(env, "FAAS_DB_SSLMODE", "disable")
setDefault(env, "FAAS_APP_ENV", "development")
setDefault(env, "FAAS_LOG_LEVEL", "debug")
setDefault(env, "FAAS_DEFAULT_RUNTIME", "docker")
setDefault(env, "FAAS_FUNCTION_TIMEOUT", "300s")
setDefault(env, "FAAS_MAX_MEMORY", "3008")
setDefault(env, "FAAS_MAX_CONCURRENT", "100")
setDefault(env, "FAAS_SANDBOX_ENABLED", "true")
setDefault(env, "FAAS_NETWORK_ISOLATION", "true")
setDefault(env, "FAAS_RESOURCE_LIMITS", "true")
setDefault(env, "SERVER_READ_TIMEOUT", "30s")
setDefault(env, "SERVER_WRITE_TIMEOUT", "30s")
setDefault(env, "SERVER_IDLE_TIMEOUT", "120s")
setDefault(env, "RATE_LIMIT_ENABLED", "true")
setDefault(env, "RATE_LIMIT_RPS", "100")
setDefault(env, "RATE_LIMIT_BURST", "200")
setDefault(env, "METRICS_ENABLED", "true")
setDefault(env, "METRICS_PORT", "9091")
setDefault(env, "AUTH_PROVIDER", "header")
setDefault(env, "AUTH_HEADER_USER_EMAIL", "X-User-Email")
return &Config{env: env}
}
func setDefault(env map[string]string, key, value string) {
if _, exists := env[key]; !exists {
env[key] = value
}
}
func (c *Config) GetString(key string) string {
return c.env[key]
}
func (c *Config) GetInt(key string) int {
val := c.env[key]
if val == "" {
return 0
}
intVal, err := strconv.Atoi(val)
if err != nil {
return 0
}
return intVal
}
func (c *Config) GetBool(key string) bool {
val := strings.ToLower(c.env[key])
return val == "true" || val == "1" || val == "yes" || val == "on"
}
func (c *Config) GetDuration(key string) time.Duration {
val := c.env[key]
if val == "" {
return 0
}
duration, err := time.ParseDuration(val)
if err != nil {
return 0
}
return duration
}
func (c *Config) GetServerAddress() string {
host := c.GetString("FAAS_SERVER_HOST")
port := c.GetString("FAAS_SERVER_PORT")
return fmt.Sprintf("%s:%s", host, port)
}
func (c *Config) GetDatabaseDSN() string {
host := c.GetString("FAAS_DB_HOST")
port := c.GetString("FAAS_DB_PORT")
name := c.GetString("FAAS_DB_NAME")
user := c.GetString("FAAS_DB_USER")
password := c.GetString("FAAS_DB_PASSWORD")
sslmode := c.GetString("FAAS_DB_SSLMODE")
return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
host, port, user, password, name, sslmode)
}
func (c *Config) GetDatabaseDSNForLogging() string {
host := c.GetString("FAAS_DB_HOST")
port := c.GetString("FAAS_DB_PORT")
name := c.GetString("FAAS_DB_NAME")
user := c.GetString("FAAS_DB_USER")
sslmode := c.GetString("FAAS_DB_SSLMODE")
return fmt.Sprintf("host=%s port=%s user=%s password=*** dbname=%s sslmode=%s",
host, port, user, name, sslmode)
}
func (c *Config) IsProduction() bool {
env := strings.ToLower(c.GetString("FAAS_APP_ENV"))
return env == "production" || env == "prod"
}
func (c *Config) GetMetricsAddress() string {
host := c.GetString("FAAS_SERVER_HOST")
port := c.GetString("METRICS_PORT")
return fmt.Sprintf("%s:%s", host, port)
}
func (c *Config) Validate() error {
required := []string{
"FAAS_SERVER_HOST",
"FAAS_SERVER_PORT",
"FAAS_DB_HOST",
"FAAS_DB_PORT",
"FAAS_DB_NAME",
"FAAS_DB_USER",
"FAAS_DB_PASSWORD",
}
for _, key := range required {
if c.GetString(key) == "" {
return fmt.Errorf("required environment variable %s is not set", key)
}
}
// Validate server port
if c.GetInt("FAAS_SERVER_PORT") <= 0 || c.GetInt("FAAS_SERVER_PORT") > 65535 {
return fmt.Errorf("invalid server port: %s", c.GetString("FAAS_SERVER_PORT"))
}
// Validate database port
if c.GetInt("FAAS_DB_PORT") <= 0 || c.GetInt("FAAS_DB_PORT") > 65535 {
return fmt.Errorf("invalid database port: %s", c.GetString("FAAS_DB_PORT"))
}
// Validate timeout
if c.GetDuration("FAAS_FUNCTION_TIMEOUT") <= 0 {
return fmt.Errorf("invalid function timeout: %s", c.GetString("FAAS_FUNCTION_TIMEOUT"))
}
// Validate memory limit
maxMemory := c.GetInt("FAAS_MAX_MEMORY")
if maxMemory <= 0 || maxMemory > 10240 { // Max 10GB
return fmt.Errorf("invalid max memory: %s", c.GetString("FAAS_MAX_MEMORY"))
}
return nil
}