Files
orbits/internal/server/bootstrap/bootstrap.go
T

105 lines
3.0 KiB
Go

package bootstrap
import (
"os"
"reflect"
"strconv"
flag "github.com/spf13/pflag"
)
type Environment struct {
Version string `env:"VERSION" default:"0.0.1" flag:"version"`
Codename string `env:"CODENAME" default:"Magical Anomaly" flag:"codename"`
LogLevel string `env:"LOG_LEVEL" default:"debug" flag:"log-level"`
DataDirectory string `env:"DATA_DIR" default:"./data" flag:"data-dir" usage:"option to specify where the state data gets stored"`
ContentDirectory string `env:"CONTENT_DIR" default:"./content" flag:"content-dir" usage:"option to specify where the content gets stored"`
Hostname string `env:"HOSTNAME" default:"0.0.0.0" flag:"hostname" usage:"option to specify the address/hostname to bind the api server to"`
Port int `env:"PORT" default:"8080" flag:"port" usage:"option to specify the port to bind the api server to"`
Authentication bool `env:"AUTHENTICATION" default:"true" flag:"authentication" usage:"option to disable authentication"`
Watchdog bool `env:"WATCHDOG" default:"true" flag:"watchdog" usage:"option to disable watchdog"`
WatchdogInterval int `env:"WATCHDOG_INTERVAL" default:"60" flag:"watchdog-interval" usage:"option to specify the interval in second(s) on which watchdog runs"`
WatchdogSyncMode string `env:"WATCHDOG_SYNC_MODE" default:"strict" flag:"watchdog-mode" usage:"option to specify the mode watchdog will run with: strict|sync|dry"`
}
func loadFromEnv(env *Environment) {
v := reflect.ValueOf(env).Elem()
t := v.Type()
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
valueField := v.Field(i)
// It is of great importance we set these fields above
key := field.Tag.Get("env")
fallback := field.Tag.Get("default")
// If the variable is not found or is empty
raw, ok := os.LookupEnv(key)
if !ok || len(raw) == 0 {
raw = fallback
}
switch valueField.Kind() {
case reflect.String:
valueField.SetString(raw)
case reflect.Int:
if parsed, err := strconv.Atoi(raw); err == nil {
valueField.SetInt(int64(parsed))
}
case reflect.Bool:
if parsed, err := strconv.ParseBool(raw); err == nil {
valueField.SetBool(parsed)
}
}
}
}
func bindFlags(env *Environment) {
v := reflect.ValueOf(env).Elem()
t := v.Type()
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
valueField := v.Field(i)
flagName := field.Tag.Get("flag")
flagUsage := field.Tag.Get("usage")
if len(flagName) == 0 {
continue
}
switch valueField.Kind() {
case reflect.String:
flag.StringVar(
valueField.Addr().Interface().(*string), flagName,
valueField.String(), flagUsage,
)
case reflect.Int:
flag.IntVar(
valueField.Addr().Interface().(*int), flagName,
int(valueField.Int()), flagUsage,
)
case reflect.Bool:
flag.BoolVar(
valueField.Addr().Interface().(*bool), flagName,
valueField.Bool(), flagUsage,
)
}
}
}
func LoadConfig() Environment {
var env Environment
loadFromEnv(&env)
bindFlags(&env)
flag.Parse()
return env
}