140 lines
3.4 KiB
Go
140 lines
3.4 KiB
Go
package config
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/kelseyhightower/envconfig"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
const (
|
|
defaultHTTPPort = "8000"
|
|
defaultHTTPRWTimeout = 10 * time.Second
|
|
defaultHTTPMaxHeaderMegabytes = 1
|
|
defaultAccessTokenTTL = 15 * time.Minute
|
|
defaultRefreshTokenTTL = 24 * time.Hour * 30
|
|
defaultLimiterRPS = 10
|
|
defaultLimiterBurst = 2
|
|
defaultLimiterTTL = 10 * time.Minute
|
|
defaultVerificationCodeLength = 8
|
|
|
|
EnvLocal = "local"
|
|
Prod = "prod"
|
|
)
|
|
|
|
type (
|
|
Config struct {
|
|
Environment string
|
|
HTTP HTTPConfig
|
|
Auth AuthConfig
|
|
Database string `mapstructure:"database"`
|
|
Limiter LimiterConfig
|
|
CacheTTL time.Duration `mapstructure:"ttl"`
|
|
}
|
|
|
|
AuthConfig struct {
|
|
ApiKeys map[string]string `mapstructure:"api_keys"`
|
|
}
|
|
|
|
HTTPConfig struct {
|
|
Host string `mapstructure:"host"`
|
|
Port string `mapstructure:"port"`
|
|
ReadTimeout time.Duration `mapstructure:"readTimeout"`
|
|
WriteTimeout time.Duration `mapstructure:"writeTimeout"`
|
|
MaxHeaderMegabytes int `mapstructure:"maxHeaderBytes"`
|
|
}
|
|
|
|
LimiterConfig struct {
|
|
RPS int
|
|
Burst int
|
|
TTL time.Duration
|
|
}
|
|
)
|
|
|
|
// Init populates Config struct with values from config file
|
|
// located at filepath and environment variables.
|
|
func Init(configsDir string) (*Config, error) {
|
|
populateDefaults()
|
|
|
|
if err := parseConfigFile(configsDir, os.Getenv("APP_ENV")); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var cfg Config
|
|
if err := unmarshal(&cfg); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
//setFromEnv(&cfg)
|
|
|
|
return &cfg, nil
|
|
}
|
|
|
|
func unmarshal(cfg *Config) error {
|
|
if err := viper.UnmarshalKey("environment", &cfg.Environment); err != nil {
|
|
return err
|
|
}
|
|
if err := viper.UnmarshalKey("cache.ttl", &cfg.CacheTTL); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := viper.UnmarshalKey("http", &cfg.HTTP); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := viper.UnmarshalKey("auth", &cfg.Auth); err != nil {
|
|
return err
|
|
}
|
|
|
|
database := viper.GetString("database")
|
|
configDir := filepath.Dir(viper.ConfigFileUsed())
|
|
databaseAbsPath := filepath.Join(configDir, database)
|
|
viper.Set("database", databaseAbsPath)
|
|
|
|
if err := viper.UnmarshalKey("database", &cfg.Database); err != nil {
|
|
return err
|
|
}
|
|
|
|
return viper.UnmarshalKey("limiter", &cfg.Limiter)
|
|
|
|
}
|
|
|
|
func setFromEnv(cfg *Config) {
|
|
err := envconfig.Process("cvvvvv", &cfg)
|
|
if err != nil {
|
|
log.Fatal(err.Error())
|
|
}
|
|
}
|
|
|
|
func parseConfigFile(folder, env string) error {
|
|
viper.AddConfigPath(folder)
|
|
viper.SetConfigName("config")
|
|
|
|
if err := viper.ReadInConfig(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if env == EnvLocal {
|
|
return nil
|
|
}
|
|
|
|
viper.SetConfigName(env)
|
|
|
|
return viper.MergeInConfig()
|
|
}
|
|
|
|
func populateDefaults() {
|
|
viper.SetDefault("http.port", defaultHTTPPort)
|
|
viper.SetDefault("http.max_header_megabytes", defaultHTTPMaxHeaderMegabytes)
|
|
viper.SetDefault("http.timeouts.read", defaultHTTPRWTimeout)
|
|
viper.SetDefault("http.timeouts.write", defaultHTTPRWTimeout)
|
|
viper.SetDefault("auth.accessTokenTTL", defaultAccessTokenTTL)
|
|
viper.SetDefault("auth.refreshTokenTTL", defaultRefreshTokenTTL)
|
|
viper.SetDefault("auth.verificationCodeLength", defaultVerificationCodeLength)
|
|
viper.SetDefault("limiter.rps", defaultLimiterRPS)
|
|
viper.SetDefault("limiter.burst", defaultLimiterBurst)
|
|
viper.SetDefault("limiter.ttl", defaultLimiterTTL)
|
|
}
|