github.com/hellofresh/janus@v0.0.0-20230925145208-ce8de8183c67/pkg/config/specification.go (about) 1 package config 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/hellofresh/logging-go" 8 "github.com/kelseyhightower/envconfig" 9 "github.com/mitchellh/go-homedir" 10 "github.com/spf13/viper" 11 ) 12 13 // Specification for basic configurations 14 type Specification struct { 15 Port int `envconfig:"PORT"` 16 GraceTimeOut int64 `envconfig:"GRACE_TIMEOUT"` 17 MaxIdleConnsPerHost int `envconfig:"MAX_IDLE_CONNS_PER_HOST"` 18 BackendFlushInterval time.Duration `envconfig:"BACKEND_FLUSH_INTERVAL"` 19 IdleConnTimeout time.Duration `envconfig:"IDLE_CONN_TIMEOUT"` 20 ConnPurgeInterval time.Duration `envconfig:"CONN_PURGE_INTERVAL"` 21 RequestID bool `envconfig:"REQUEST_ID_ENABLED"` 22 Log logging.LogConfig 23 Web Web 24 Database Database 25 Stats Stats 26 Tracing Tracing 27 TLS TLS 28 Cluster Cluster 29 RespondingTimeouts RespondingTimeouts 30 } 31 32 // Cluster represents the cluster configuration 33 type Cluster struct { 34 UpdateFrequency time.Duration `envconfig:"BACKEND_UPDATE_FREQUENCY"` 35 } 36 37 // RespondingTimeouts contains timeout configurations for incoming requests to the Janus instance. 38 type RespondingTimeouts struct { 39 ReadTimeout time.Duration `envconfig:"RESPONDING_TIMEOUTS_READ_TIMEOUT"` 40 WriteTimeout time.Duration `envconfig:"RESPONDING_TIMEOUTS_WRITE_TIMEOUT"` 41 IdleTimeout time.Duration `envconfig:"RESPONDING_TIMEOUTS_IDLE_TIMEOUT"` 42 } 43 44 // Web represents the API configurations 45 type Web struct { 46 Port int `envconfig:"API_PORT"` 47 Credentials Credentials 48 TLS TLS 49 } 50 51 // TLS represents the TLS configurations 52 type TLS struct { 53 Port int `envconfig:"PORT"` 54 CertFile string `envconfig:"CERT_PATH"` 55 KeyFile string `envconfig:"KEY_PATH"` 56 Redirect bool `envconfig:"REDIRECT"` 57 } 58 59 // IsHTTPS checks if you have https enabled 60 func (s *TLS) IsHTTPS() bool { 61 return s.CertFile != "" && s.KeyFile != "" 62 } 63 64 // Database holds the configuration for a database 65 type Database struct { 66 DSN string `envconfig:"DATABASE_DSN"` 67 } 68 69 // Stats holds the configuration for stats 70 type Stats struct { 71 DSN string `envconfig:"STATS_DSN"` 72 IDs string `envconfig:"STATS_IDS"` 73 AutoDiscoverThreshold uint `envconfig:"STATS_AUTO_DISCOVER_THRESHOLD"` 74 AutoDiscoverWhiteList []string `envconfig:"STATS_AUTO_DISCOVER_WHITE_LIST"` 75 ErrorsSection string `envconfig:"STATS_ERRORS_SECTION"` 76 Exporter string `envconfig:"STATS_EXPORTER"` 77 } 78 79 // Credentials represents the credentials that are going to be 80 // used by admin JWT configuration 81 type Credentials struct { 82 // Algorithm defines admin JWT signing algorithm. 83 // Currently the following algorithms are supported: HS256, HS384, HS512. 84 Algorithm string `envconfig:"ALGORITHM"` 85 Secret string `envconfig:"SECRET"` 86 JanusAdminTeam string `envconfig:"JANUS_ADMIN_TEAM"` 87 Timeout time.Duration `envconfig:"TOKEN_TIMEOUT"` 88 Github Github 89 Basic Basic 90 } 91 92 // Basic holds the basic users configurations 93 type Basic struct { 94 Users map[string]string `envconfig:"BASIC_USERS"` 95 } 96 97 // Github holds the github configurations 98 type Github struct { 99 Organizations []string `envconfig:"GITHUB_ORGANIZATIONS"` 100 Teams map[string]string `envconfig:"GITHUB_TEAMS"` 101 } 102 103 // IsConfigured checks if github is enabled 104 func (auth *Github) IsConfigured() bool { 105 return len(auth.Organizations) > 0 || 106 len(auth.Teams) > 0 107 } 108 109 // Tracing represents the distributed tracing configuration 110 type Tracing struct { 111 Exporter string `envconfig:"TRACING_EXPORTER"` 112 ServiceName string `envconfig:"TRACING_SERVICE_NAME"` 113 SamplingStrategy string `envconfig:"TRACING_SAMPLING_STRATEGY"` 114 SamplingParam float64 `envconfig:"TRACING_SAMPLING_PARAM"` 115 DebugTraceKey string `envconfig:"TRACING_DEBUG_TRACE_KEY"` 116 IsPublicEndpoint bool `envconfig:"TRACING_IS_PUBLIC_ENDPOINT"` 117 JaegerTracing JaegerTracing `mapstructure:"jaeger"` 118 } 119 120 // JaegerTracing holds the Jaeger tracing configuration 121 type JaegerTracing struct { 122 SamplingServerURL string `envconfig:"TRACING_JAEGER_SAMPLING_SERVER_URL"` 123 SamplingServerHost string `envconfig:"JAEGER_AGENT_HOST"` 124 SamplingServerPort string `envconfig:"JAEGER_AGENT_PORT"` 125 } 126 127 func init() { 128 serviceName := "janus" 129 130 viper.SetDefault("port", "8080") 131 viper.SetDefault("tls.port", "8433") 132 viper.SetDefault("tls.redirect", true) 133 viper.SetDefault("backendFlushInterval", "20ms") 134 viper.SetDefault("requestID", true) 135 136 viper.SetDefault("respondingTimeouts.IdleTimeout", 180*time.Second) 137 138 viper.SetDefault("cluster.updateFrequency", "10s") 139 viper.SetDefault("database.dsn", "file:///etc/janus") 140 141 viper.SetDefault("web.port", "8081") 142 viper.SetDefault("web.tls.port", "8444") 143 viper.SetDefault("web.tls.redirect", true) 144 viper.SetDefault("web.credentials.algorithm", "HS256") 145 viper.SetDefault("web.credentials.timeout", time.Hour) 146 viper.SetDefault("web.credentials.basic.users", map[string]string{"admin": "admin"}) 147 viper.SetDefault("web.credentials.github.teams", make(map[string]string)) 148 149 viper.SetDefault("stats.dsn", "log://") 150 viper.SetDefault("stats.errorsSection", "error-log") 151 viper.SetDefault("stats.namespace", serviceName) 152 153 viper.SetDefault("tracing.serviceName", serviceName) 154 viper.SetDefault("tracing.samplingStrategy", "probabilistic") 155 viper.SetDefault("tracing.samplingParam", 0.15) 156 viper.SetDefault("tracing.debugTraceKey", "") 157 viper.SetDefault("tracing.isPublicEndpoint", true) 158 159 logging.InitDefaults(viper.GetViper(), "log") 160 } 161 162 // Load configuration variables 163 func Load(configFile string) (*Specification, error) { 164 if configFile != "" { 165 viper.SetConfigFile(configFile) 166 } else { 167 dir, err := homedir.Dir() 168 if err != nil { 169 return nil, err 170 } 171 172 viper.SetConfigName("janus") 173 viper.AddConfigPath(".") 174 viper.AddConfigPath(dir) 175 viper.AddConfigPath("/etc/janus") 176 } 177 178 if err := viper.ReadInConfig(); err != nil { 179 return nil, fmt.Errorf("config file not found: %w", err) 180 } 181 182 var config Specification 183 if err := viper.Unmarshal(&config); err != nil { 184 return nil, err 185 } 186 187 return &config, nil 188 } 189 190 // LoadEnv loads configuration from environment variables 191 func LoadEnv() (*Specification, error) { 192 var config Specification 193 194 // ensure the defaults are loaded 195 if err := viper.Unmarshal(&config); err != nil { 196 return nil, err 197 } 198 199 err := envconfig.Process("", &config) 200 if err != nil { 201 return nil, err 202 } 203 204 return &config, nil 205 }