mirror of
https://github.com/prymitive/karma
synced 2026-05-05 03:16:51 +00:00
Let envconfig handle defaults, setting it for flags means that we'll always pass a value to the env if there was a default one, meaning that we're unable to override via env
131 lines
3.9 KiB
Go
131 lines
3.9 KiB
Go
package config
|
|
|
|
import (
|
|
"bytes"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"reflect"
|
|
"strings"
|
|
"time"
|
|
"unicode"
|
|
|
|
log "github.com/Sirupsen/logrus"
|
|
"github.com/kelseyhightower/envconfig"
|
|
)
|
|
|
|
type spaceSeparatedList []string
|
|
|
|
func (mvd *spaceSeparatedList) Decode(value string) error {
|
|
*mvd = spaceSeparatedList(strings.Split(value, " "))
|
|
return nil
|
|
}
|
|
|
|
type configEnvs struct {
|
|
AlertmanagerTimeout time.Duration `envconfig:"ALERTMANAGER_TIMEOUT" default:"40s" help:"Timeout for all request send to Alertmanager"`
|
|
AlertmanagerTTL time.Duration `envconfig:"ALERTMANAGER_TTL" default:"1m" help:"TTL for Alertmanager alerts and silences"`
|
|
AlertmanagerURI string `envconfig:"ALERTMANAGER_URI" required:"true" help:"Alertmanager URI"`
|
|
ColorLabelsStatic spaceSeparatedList `envconfig:"COLOR_LABELS_STATIC" help:"List of label names that should have the same (but distinct) color"`
|
|
ColorLabelsUnique spaceSeparatedList `envconfig:"COLOR_LABELS_UNIQUE" help:"List of label names that should have unique color"`
|
|
Debug bool `envconfig:"DEBUG" default:"false" help:"Enable debug mode"`
|
|
FilterDefault string `envconfig:"FILTER_DEFAULT" help:"Default filter string"`
|
|
JiraRegexp spaceSeparatedList `envconfig:"JIRA_REGEX" help:"List of JIRA regex rules"`
|
|
Port int `envconfig:"PORT" default:"8080" help:"HTTP port to listen on"`
|
|
SentryDSN string `envconfig:"SENTRY_DSN" help:"Sentry DSN for Go exceptions"`
|
|
SentryPublicDSN string `envconfig:"SENTRY_PUBLIC_DSN" help:"Sentry DSN for javascript exceptions"`
|
|
StripLabels spaceSeparatedList `envconfig:"STRIP_LABELS" help:"List of labels to ignore"`
|
|
}
|
|
|
|
// Config exposes all options required to run
|
|
var Config configEnvs
|
|
|
|
// generate flag name from the option name, a dot will be injected between
|
|
// <lower case char><upper case char>
|
|
func makeFlagName(s string) string {
|
|
var buffer bytes.Buffer
|
|
prevUpper := true
|
|
for _, rune := range s {
|
|
if unicode.IsUpper(rune) && !prevUpper {
|
|
buffer.WriteRune('.')
|
|
}
|
|
prevUpper = unicode.IsUpper(rune)
|
|
buffer.WriteRune(unicode.ToLower(rune))
|
|
}
|
|
return buffer.String()
|
|
}
|
|
|
|
// Iterate all defined envconfig variables and generate a flag for each key.
|
|
// Next parse those flags and for each set flag inject env variable which will
|
|
// be read by envconfig later on.
|
|
type flagMapper struct {
|
|
isBool bool
|
|
stringVal *string
|
|
boolVal *bool
|
|
}
|
|
|
|
func mapEnvConfigToFlags() {
|
|
flags := make(map[string]flagMapper)
|
|
s := reflect.ValueOf(Config)
|
|
typeOfSpec := s.Type()
|
|
for i := 0; i < s.NumField(); i++ {
|
|
f := typeOfSpec.Field(i)
|
|
|
|
flagName := makeFlagName(f.Name)
|
|
// check if flag was already set, this usually happens only during testing
|
|
if flag.Lookup(flagName) != nil {
|
|
continue
|
|
}
|
|
|
|
envName := f.Tag.Get("envconfig")
|
|
|
|
helpMsg := fmt.Sprintf("%s. This flag can also be set via %s environment variable.", f.Tag.Get("help"), f.Tag.Get("envconfig"))
|
|
if f.Tag.Get("required") == "true" {
|
|
helpMsg = fmt.Sprintf("%s This option is required.", helpMsg)
|
|
}
|
|
|
|
mapper := flagMapper{}
|
|
if s.Field(i).Kind() == reflect.Bool {
|
|
mapper.isBool = true
|
|
mapper.boolVal = flag.Bool(flagName, false, helpMsg)
|
|
} else {
|
|
mapper.stringVal = flag.String(flagName, "", helpMsg)
|
|
}
|
|
flags[envName] = mapper
|
|
}
|
|
flag.Parse()
|
|
for envName, mapper := range flags {
|
|
if mapper.isBool {
|
|
if *mapper.boolVal == true {
|
|
err := os.Setenv(envName, "true")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
} else {
|
|
if *mapper.stringVal != "" {
|
|
err := os.Setenv(envName, *mapper.stringVal)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (config *configEnvs) Read() {
|
|
mapEnvConfigToFlags()
|
|
|
|
err := envconfig.Process("", config)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
s := reflect.ValueOf(config).Elem()
|
|
typeOfT := s.Type()
|
|
for i := 0; i < s.NumField(); i++ {
|
|
f := s.Field(i)
|
|
log.Infof("%20s => %v", typeOfT.Field(i).Tag.Get("envconfig"), f.Interface())
|
|
}
|
|
|
|
}
|