mirror of
https://github.com/prymitive/karma
synced 2026-05-05 03:16:51 +00:00
Merge pull request #1406 from prymitive/refactor-flags
chore(backend): refactor config flag setup for better test coverage
This commit is contained in:
@@ -190,18 +190,24 @@ func setupLogger() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func mainSetup() (*gin.Engine, error) {
|
||||
printVersion := pflag.Bool("version", false, "Print version and exit")
|
||||
validateConfig := pflag.Bool("check-config", false, "Validate configuration and exit")
|
||||
pflag.Parse()
|
||||
func mainSetup(errorHandling pflag.ErrorHandling) (*gin.Engine, error) {
|
||||
f := pflag.NewFlagSet("karma", errorHandling)
|
||||
printVersion := f.Bool("version", false, "Print version and exit")
|
||||
validateConfig := f.Bool("check-config", false, "Validate configuration and exit")
|
||||
config.SetupFlags(f)
|
||||
|
||||
err := f.Parse(os.Args[1:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if *printVersion {
|
||||
fmt.Println(version)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
configFile := config.Config.Read()
|
||||
err := setupLogger()
|
||||
configFile := config.Config.Read(f)
|
||||
err = setupLogger()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -212,7 +218,7 @@ func mainSetup() (*gin.Engine, error) {
|
||||
|
||||
// timer duration cannot be zero second or a negative one
|
||||
if config.Config.Alertmanager.Interval <= time.Second*0 {
|
||||
return nil, fmt.Errorf("Invalid AlertmanagerTTL value '%v'", config.Config.Alertmanager.Interval)
|
||||
return nil, fmt.Errorf("Invalid alertmanager.interval value '%v'", config.Config.Alertmanager.Interval)
|
||||
}
|
||||
|
||||
log.Infof("Version: %s", version)
|
||||
@@ -285,7 +291,7 @@ func mainSetup() (*gin.Engine, error) {
|
||||
}
|
||||
|
||||
func main() {
|
||||
router, err := mainSetup()
|
||||
router, err := mainSetup(pflag.ExitOnError)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -5,14 +5,21 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/rogpeppe/go-internal/testscript"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func mainShoulFail() int {
|
||||
_, err := mainSetup()
|
||||
defer func() { log.StandardLogger().ExitFunc = nil }()
|
||||
var wasFatal bool
|
||||
log.StandardLogger().ExitFunc = func(int) { wasFatal = true }
|
||||
|
||||
_, err := mainSetup(pflag.ContinueOnError)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
} else if wasFatal {
|
||||
return 100
|
||||
} else {
|
||||
log.Error("No error logged")
|
||||
return 100
|
||||
@@ -20,8 +27,15 @@ func mainShoulFail() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func mainShoulFailNoTimestamp() int {
|
||||
log.SetFormatter(&log.TextFormatter{
|
||||
DisableTimestamp: true,
|
||||
})
|
||||
return mainShoulFail()
|
||||
}
|
||||
|
||||
func mainShouldWork() int {
|
||||
_, err := mainSetup()
|
||||
_, err := mainSetup(pflag.ContinueOnError)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return 100
|
||||
@@ -31,8 +45,9 @@ func mainShouldWork() int {
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(testscript.RunMain(m, map[string]func() int{
|
||||
"karma.bin-should-fail": mainShoulFail,
|
||||
"karma.bin-should-work": mainShouldWork,
|
||||
"karma.bin-should-fail": mainShoulFail,
|
||||
"karma.bin-should-fail-no-timestamp": mainShoulFailNoTimestamp,
|
||||
"karma.bin-should-work": mainShouldWork,
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
11
cmd/karma/testdata/invalid_config_alertmanager_timeout.txt
vendored
Normal file
11
cmd/karma/testdata/invalid_config_alertmanager_timeout.txt
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# Raises an error if we pass alertmanager.interval value that doesn't parse
|
||||
karma.bin-should-fail-no-timestamp --log.format=text --log.config=false --log.level=error --config.file karma.yaml
|
||||
! stdout .
|
||||
stderr 'level=fatal msg="yaml: unmarshal errors:\\n line 2: cannot unmarshal !!str `abc123` into time.Duration"'
|
||||
|
||||
-- karma.yaml --
|
||||
alertmanager:
|
||||
interval: abc123
|
||||
servers:
|
||||
- name: am
|
||||
uri: https://localhost:9093
|
||||
4
cmd/karma/testdata/invalid_flag_alertmanager_timeout.txt
vendored
Normal file
4
cmd/karma/testdata/invalid_flag_alertmanager_timeout.txt
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# Raises an error if we pass alertmanager.timeout value that doesn't parse
|
||||
karma.bin-should-fail --log.format=text --log.config=false --log.level=error --alertmanager.timeout=abc123 --alertmanager.uri=http://localhost
|
||||
! stdout .
|
||||
stderr 'level=error msg="invalid argument \\"abc123\\" for \\"--alertmanager.timeout\\" flag: time: invalid duration abc123"'
|
||||
2
cmd/karma/testdata/invalid_ttl.txt
vendored
2
cmd/karma/testdata/invalid_ttl.txt
vendored
@@ -1,4 +1,4 @@
|
||||
# Raises an error if negative refresh interval is passed
|
||||
karma.bin-should-fail --log.format=text --log.config=false --log.level=error --alertmanager.interval=-4s
|
||||
! stdout .
|
||||
stderr 'msg="Invalid AlertmanagerTTL value ''-4s''"'
|
||||
stderr 'msg="Invalid alertmanager.interval value ''-4s''"'
|
||||
|
||||
64
cmd/karma/testdata/log_full_config_file_invalid_values.txt
vendored
Normal file
64
cmd/karma/testdata/log_full_config_file_invalid_values.txt
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
# Print out and compare logged config set via config file that includes invalid values
|
||||
karma.bin-should-fail-no-timestamp --config.file=karma.yaml --check-config
|
||||
! stdout .
|
||||
cmp stderr expected.stderr
|
||||
|
||||
-- karma.yaml --
|
||||
alertmanager:
|
||||
interval: jjs88
|
||||
servers:
|
||||
- name: ha1
|
||||
uri: "http://localhost:9093"
|
||||
timeout: bbb
|
||||
proxy: YEs
|
||||
- name: ha2
|
||||
uri: "http://localhost:9094"
|
||||
timeout: 11
|
||||
readonly: 1
|
||||
- name: local
|
||||
uri: http://localhost:9095
|
||||
timeout: z
|
||||
proxy: true
|
||||
readonly: 0
|
||||
headers:
|
||||
- X-Auth-Test=some-token-or-other-string
|
||||
- name: client-auth
|
||||
uri: https://localhost:9096
|
||||
timeout: 10s
|
||||
tls:
|
||||
ca: ca.pem
|
||||
cert: cert.pem
|
||||
key: key.pem
|
||||
alertAcknowledgement:
|
||||
enabled: zzz
|
||||
duration: 7m0s
|
||||
author: karma
|
||||
commentPrefix: ACK!
|
||||
annotations:
|
||||
default:
|
||||
hidden: z
|
||||
hidden: {}
|
||||
visible:
|
||||
- visible
|
||||
filters:
|
||||
default: []
|
||||
karma:
|
||||
name: karma-demo
|
||||
log:
|
||||
level: 123
|
||||
format: foo
|
||||
ui:
|
||||
refresh: 10sm
|
||||
hideFiltersWhenIdle: z
|
||||
colorTitlebar: yum
|
||||
theme: x
|
||||
minimalGroupWidth: abc4
|
||||
alertsPerGroup: 5a
|
||||
collapseGroups: collapsedOanMobile
|
||||
|
||||
-- expected.stderr --
|
||||
level=fatal msg="4 error(s) decoding:\n\n* '[2].Headers[0]' expected a map, got 'string'\n* cannot parse '[0].Proxy' as bool: strconv.ParseBool: parsing \"YEs\": invalid syntax\n* error decoding '[0].Timeout': time: invalid duration bbb\n* error decoding '[2].Timeout': time: invalid duration z"
|
||||
level=fatal msg="Invalid ui.collapseGroups value 'collapsedOanMobile', allowed options: expanded, collapsed, collapsedOnMobile"
|
||||
level=fatal msg="Invalid ui.theme value 'x', allowed options: light, dark, auto"
|
||||
level=fatal msg="yaml: unmarshal errors:\n line 2: cannot unmarshal !!str `jjs88` into time.Duration\n line 6: cannot unmarshal !!str `bbb` into time.Duration\n line 7: cannot unmarshal !!str `YEs` into bool\n line 11: cannot unmarshal !!int `1` into bool\n line 14: cannot unmarshal !!str `z` into time.Duration\n line 16: cannot unmarshal !!int `0` into bool\n line 18: cannot unmarshal !!seq into map[string]string\n line 27: cannot unmarshal !!str `zzz` into bool\n line 33: cannot unmarshal !!str `z` into bool\n line 34: cannot unmarshal !!map into []string\n line 45: cannot unmarshal !!str `10sm` into time.Duration\n line 46: cannot unmarshal !!str `z` into bool\n line 47: cannot unmarshal !!str `yum` into bool\n line 49: cannot unmarshal !!str `abc4` into int\n line 50: cannot unmarshal !!str `5a` into int"
|
||||
level=error msg="Unknown log level '123'"
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/prymitive/karma/internal/mock"
|
||||
"github.com/prymitive/karma/internal/models"
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
cache "github.com/patrickmn/go-cache"
|
||||
log "github.com/sirupsen/logrus"
|
||||
@@ -30,7 +31,11 @@ func mockConfig() {
|
||||
log.SetLevel(log.ErrorLevel)
|
||||
os.Setenv("ALERTMANAGER_URI", "http://localhost")
|
||||
os.Setenv("LABELS_COLOR_UNIQUE", "alertname")
|
||||
config.Config.Read()
|
||||
|
||||
f := pflag.NewFlagSet(".", pflag.ExitOnError)
|
||||
config.SetupFlags(f)
|
||||
config.Config.Read(f)
|
||||
|
||||
if !upstreamSetup {
|
||||
upstreamSetup = true
|
||||
err := setupUpstreams()
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/prymitive/karma/internal/alertmanager"
|
||||
"github.com/prymitive/karma/internal/config"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func BenchmarkDedupAlerts(b *testing.B) {
|
||||
@@ -29,7 +30,11 @@ func BenchmarkDedupAutocomplete(b *testing.B) {
|
||||
func BenchmarkDedupColors(b *testing.B) {
|
||||
os.Setenv("LABELS_COLOR_UNIQUE", "cluster instance @receiver")
|
||||
os.Setenv("ALERTMANAGER_URI", "http://localhost")
|
||||
config.Config.Read()
|
||||
|
||||
f := pflag.NewFlagSet(".", pflag.ExitOnError)
|
||||
config.SetupFlags(f)
|
||||
config.Config.Read(f)
|
||||
|
||||
if err := pullAlerts(); err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/jarcoal/httpmock"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"github.com/prymitive/karma/internal/alertmanager"
|
||||
"github.com/prymitive/karma/internal/config"
|
||||
@@ -50,6 +51,12 @@ func pullAlerts() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func mockConfigRead() {
|
||||
f := pflag.NewFlagSet(".", pflag.ExitOnError)
|
||||
config.SetupFlags(f)
|
||||
config.Config.Read(f)
|
||||
}
|
||||
|
||||
func TestDedupAlerts(t *testing.T) {
|
||||
if err := pullAlerts(); err != nil {
|
||||
t.Error(err)
|
||||
@@ -92,7 +99,7 @@ func TestDedupAlertsWithoutLabels(t *testing.T) {
|
||||
|
||||
func TestDedupSilences(t *testing.T) {
|
||||
os.Setenv("ALERTMANAGER_URI", "http://localhost")
|
||||
config.Config.Read()
|
||||
mockConfigRead()
|
||||
if err := pullAlerts(); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -123,7 +130,7 @@ func TestDedupAutocomplete(t *testing.T) {
|
||||
func TestDedupColors(t *testing.T) {
|
||||
os.Setenv("LABELS_COLOR_UNIQUE", "cluster instance @receiver")
|
||||
os.Setenv("ALERTMANAGER_URI", "http://localhost")
|
||||
config.Config.Read()
|
||||
mockConfigRead()
|
||||
if err := pullAlerts(); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -136,7 +143,7 @@ func TestDedupColors(t *testing.T) {
|
||||
|
||||
func TestDedupKnownLabels(t *testing.T) {
|
||||
os.Setenv("ALERTMANAGER_URI", "http://localhost")
|
||||
config.Config.Read()
|
||||
mockConfigRead()
|
||||
if err := pullAlerts(); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -149,7 +156,7 @@ func TestDedupKnownLabels(t *testing.T) {
|
||||
|
||||
func TestDedupKnownLabelValues(t *testing.T) {
|
||||
os.Setenv("ALERTMANAGER_URI", "http://localhost")
|
||||
config.Config.Read()
|
||||
mockConfigRead()
|
||||
if err := pullAlerts(); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -163,7 +170,7 @@ func TestDedupKnownLabelValues(t *testing.T) {
|
||||
func TestStripReceivers(t *testing.T) {
|
||||
os.Setenv("RECEIVERS_STRIP", "by-name by-cluster-service")
|
||||
os.Setenv("ALERTMANAGER_URI", "http://localhost")
|
||||
config.Config.Read()
|
||||
mockConfigRead()
|
||||
if err := pullAlerts(); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -23,99 +23,100 @@ var (
|
||||
Config configSchema
|
||||
)
|
||||
|
||||
func init() {
|
||||
pflag.Duration("alertmanager.interval", time.Minute,
|
||||
// SetupFlags is used to attach configuration flags to the main flag set
|
||||
func SetupFlags(f *pflag.FlagSet) {
|
||||
f.Duration("alertmanager.interval", time.Minute,
|
||||
"Interval for fetching data from Alertmanager servers")
|
||||
pflag.String("alertmanager.name", "default",
|
||||
f.String("alertmanager.name", "default",
|
||||
"Name for the Alertmanager server (only used with simplified config)")
|
||||
pflag.String("alertmanager.uri", "",
|
||||
f.String("alertmanager.uri", "",
|
||||
"Alertmanager server URI (only used with simplified config)")
|
||||
pflag.String("alertmanager.external_uri", "",
|
||||
f.String("alertmanager.external_uri", "",
|
||||
"Alertmanager server URI used for web UI links (only used with simplified config)")
|
||||
pflag.Duration("alertmanager.timeout", time.Second*40,
|
||||
f.Duration("alertmanager.timeout", time.Second*40,
|
||||
"Timeout for requests sent to the Alertmanager server (only used with simplified config)")
|
||||
pflag.Bool("alertmanager.proxy", false,
|
||||
f.Bool("alertmanager.proxy", false,
|
||||
"Proxy all client requests to Alertmanager via karma (only used with simplified config)")
|
||||
pflag.Bool("alertmanager.readonly", false,
|
||||
f.Bool("alertmanager.readonly", false,
|
||||
"Enable read-only mode that disable silence management (only used with simplified config)")
|
||||
|
||||
pflag.String("karma.name", "karma", "Name for the karma instance")
|
||||
f.String("karma.name", "karma", "Name for the karma instance")
|
||||
|
||||
pflag.Bool("alertAcknowledgement.enabled", false, "Enable alert acknowledging")
|
||||
pflag.Duration("alertAcknowledgement.duration", time.Minute*15, "Initial silence duration when acknowledging alerts with short lived silences")
|
||||
pflag.String("alertAcknowledgement.author", "karma", "Default silence author when acknowledging alerts with short lived silences")
|
||||
pflag.String("alertAcknowledgement.commentPrefix", "ACK!", "Comment prefix used when acknowledging alerts with short lived silences")
|
||||
f.Bool("alertAcknowledgement.enabled", false, "Enable alert acknowledging")
|
||||
f.Duration("alertAcknowledgement.duration", time.Minute*15, "Initial silence duration when acknowledging alerts with short lived silences")
|
||||
f.String("alertAcknowledgement.author", "karma", "Default silence author when acknowledging alerts with short lived silences")
|
||||
f.String("alertAcknowledgement.commentPrefix", "ACK!", "Comment prefix used when acknowledging alerts with short lived silences")
|
||||
|
||||
pflag.Bool(
|
||||
f.Bool(
|
||||
"annotations.default.hidden", false,
|
||||
"Hide all annotations by default unless explicitly listed in the 'visible' list")
|
||||
pflag.StringSlice("annotations.hidden", []string{},
|
||||
f.StringSlice("annotations.hidden", []string{},
|
||||
"List of annotations that are hidden by default")
|
||||
pflag.StringSlice("annotations.visible", []string{},
|
||||
f.StringSlice("annotations.visible", []string{},
|
||||
"List of annotations that are visible by default")
|
||||
pflag.StringSlice("annotations.keep", []string{},
|
||||
f.StringSlice("annotations.keep", []string{},
|
||||
"List of annotations to keep, all other annotations will be stripped")
|
||||
pflag.StringSlice("annotations.strip", []string{}, "List of annotations to ignore")
|
||||
f.StringSlice("annotations.strip", []string{}, "List of annotations to ignore")
|
||||
|
||||
pflag.String("config.file", "", "Full path to the configuration file")
|
||||
f.String("config.file", "", "Full path to the configuration file")
|
||||
|
||||
pflag.String("custom.css", "", "Path to a file with custom CSS to load")
|
||||
pflag.String("custom.js", "", "Path to a file with custom JavaScript to load")
|
||||
f.String("custom.css", "", "Path to a file with custom CSS to load")
|
||||
f.String("custom.js", "", "Path to a file with custom JavaScript to load")
|
||||
|
||||
pflag.Bool("debug", false, "Enable debug mode")
|
||||
f.Bool("debug", false, "Enable debug mode")
|
||||
|
||||
pflag.StringSlice("filters.default", []string{}, "List of default filters")
|
||||
f.StringSlice("filters.default", []string{}, "List of default filters")
|
||||
|
||||
pflag.StringSlice("labels.color.static", []string{},
|
||||
f.StringSlice("labels.color.static", []string{},
|
||||
"List of label names that should have the same (but distinct) color")
|
||||
pflag.StringSlice("labels.color.unique", []string{},
|
||||
f.StringSlice("labels.color.unique", []string{},
|
||||
"List of label names that should have unique color")
|
||||
pflag.StringSlice("labels.keep", []string{},
|
||||
f.StringSlice("labels.keep", []string{},
|
||||
"List of labels to keep, all other labels will be stripped")
|
||||
pflag.StringSlice("labels.strip", []string{}, "List of labels to ignore")
|
||||
f.StringSlice("labels.strip", []string{}, "List of labels to ignore")
|
||||
|
||||
pflag.String("grid.sorting.order", "startsAt", "Default sort order for alert grid")
|
||||
pflag.Bool("grid.sorting.reverse", true, "Reverse sort order")
|
||||
pflag.String("grid.sorting.label", "alertname", "Label name to use when sorting alert grid by label")
|
||||
f.String("grid.sorting.order", "startsAt", "Default sort order for alert grid")
|
||||
f.Bool("grid.sorting.reverse", true, "Reverse sort order")
|
||||
f.String("grid.sorting.label", "alertname", "Label name to use when sorting alert grid by label")
|
||||
|
||||
pflag.Bool("log.config", true, "Log used configuration to log on startup")
|
||||
pflag.String("log.level", "info",
|
||||
f.Bool("log.config", true, "Log used configuration to log on startup")
|
||||
f.String("log.level", "info",
|
||||
"Log level, one of: debug, info, warning, error, fatal and panic")
|
||||
pflag.String("log.format", "text",
|
||||
f.String("log.format", "text",
|
||||
"Log format, one of: text, json")
|
||||
pflag.Bool("log.timestamp", true, "Add timestamps to all log messages")
|
||||
f.Bool("log.timestamp", true, "Add timestamps to all log messages")
|
||||
|
||||
pflag.StringSlice("receivers.keep", []string{},
|
||||
f.StringSlice("receivers.keep", []string{},
|
||||
"List of receivers to keep, all alerts with different receivers will be ignored")
|
||||
pflag.StringSlice("receivers.strip", []string{},
|
||||
f.StringSlice("receivers.strip", []string{},
|
||||
"List of receivers to not display alerts for")
|
||||
|
||||
pflag.StringSlice("silenceform.strip.labels", []string{}, "List of labels to ignore when auto-filling silence form from alerts")
|
||||
pflag.String("silenceform.author.populate_from_header.header", "", "Header to read the default silence author from")
|
||||
pflag.String("silenceform.author.populate_from_header.value_re", "", "Header value regex to read the default silence author")
|
||||
f.StringSlice("silenceform.strip.labels", []string{}, "List of labels to ignore when auto-filling silence form from alerts")
|
||||
f.String("silenceform.author.populate_from_header.header", "", "Header to read the default silence author from")
|
||||
f.String("silenceform.author.populate_from_header.value_re", "", "Header value regex to read the default silence author")
|
||||
|
||||
pflag.String("listen.address", "", "IP/Hostname to listen on")
|
||||
pflag.Int("listen.port", 8080, "HTTP port to listen on")
|
||||
pflag.String("listen.prefix", "/", "URL prefix")
|
||||
f.String("listen.address", "", "IP/Hostname to listen on")
|
||||
f.Int("listen.port", 8080, "HTTP port to listen on")
|
||||
f.String("listen.prefix", "/", "URL prefix")
|
||||
|
||||
pflag.String("sentry.public", "", "Sentry DSN for Go exceptions")
|
||||
pflag.String("sentry.private", "", "Sentry DSN for JavaScript exceptions")
|
||||
f.String("sentry.public", "", "Sentry DSN for Go exceptions")
|
||||
f.String("sentry.private", "", "Sentry DSN for JavaScript exceptions")
|
||||
|
||||
pflag.Duration("ui.refresh", time.Second*30, "UI refresh interval")
|
||||
pflag.Bool("ui.hideFiltersWhenIdle", true, "Hide the filters bar when idle")
|
||||
pflag.Bool("ui.colorTitlebar", false, "Color alert group titlebar based on alert state")
|
||||
pflag.String("ui.theme", "auto", "Default theme, 'light', 'dark' or 'auto' (follow browser preference)")
|
||||
pflag.Int("ui.minimalGroupWidth", 420, "Minimal width for each alert group on the grid")
|
||||
pflag.Int("ui.alertsPerGroup", 5, "Default number of alerts to show for each alert group")
|
||||
pflag.String("ui.collapseGroups", "collapsedOnMobile", "Default state for alert groups")
|
||||
f.Duration("ui.refresh", time.Second*30, "UI refresh interval")
|
||||
f.Bool("ui.hideFiltersWhenIdle", true, "Hide the filters bar when idle")
|
||||
f.Bool("ui.colorTitlebar", false, "Color alert group titlebar based on alert state")
|
||||
f.String("ui.theme", "auto", "Default theme, 'light', 'dark' or 'auto' (follow browser preference)")
|
||||
f.Int("ui.minimalGroupWidth", 420, "Minimal width for each alert group on the grid")
|
||||
f.Int("ui.alertsPerGroup", 5, "Default number of alerts to show for each alert group")
|
||||
f.String("ui.collapseGroups", "collapsedOnMobile", "Default state for alert groups")
|
||||
}
|
||||
|
||||
// ReadConfig will read all sources of configuration, merge all keys and
|
||||
// populate global Config variable, it should be only called on startup
|
||||
func (config *configSchema) Read() string {
|
||||
func (config *configSchema) Read(flags *pflag.FlagSet) string {
|
||||
v := viper.New()
|
||||
|
||||
err := v.BindPFlags(pflag.CommandLine)
|
||||
err := v.BindPFlags(flags)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to bind flag set to the configuration: %s", err)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/prymitive/karma/internal/uri"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"github.com/pmezard/go-difflib/difflib"
|
||||
|
||||
@@ -173,6 +174,12 @@ ui:
|
||||
}
|
||||
}
|
||||
|
||||
func mockConfigRead() {
|
||||
f := pflag.NewFlagSet(".", pflag.ExitOnError)
|
||||
SetupFlags(f)
|
||||
Config.Read(f)
|
||||
}
|
||||
|
||||
func TestReadConfig(t *testing.T) {
|
||||
resetEnv()
|
||||
log.SetLevel(log.ErrorLevel)
|
||||
@@ -194,7 +201,7 @@ func TestReadConfig(t *testing.T) {
|
||||
os.Setenv("LISTEN_PORT", "80")
|
||||
os.Setenv("SENTRY_PRIVATE", "secret key")
|
||||
os.Setenv("SENTRY_PUBLIC", "public key")
|
||||
Config.Read()
|
||||
mockConfigRead()
|
||||
testReadConfig(t)
|
||||
}
|
||||
|
||||
@@ -206,7 +213,7 @@ func TestReadSimpleConfig(t *testing.T) {
|
||||
os.Setenv("ALERTMANAGER_TIMEOUT", "15s")
|
||||
os.Setenv("ALERTMANAGER_PROXY", "true")
|
||||
os.Setenv("ALERTMANAGER_INTERVAL", "3m")
|
||||
Config.Read()
|
||||
mockConfigRead()
|
||||
if len(Config.Alertmanager.Servers) != 1 {
|
||||
t.Errorf("Expected 1 Alertmanager server, got %d", len(Config.Alertmanager.Servers))
|
||||
} else {
|
||||
@@ -262,7 +269,7 @@ func TestUrlSecretTest(t *testing.T) {
|
||||
|
||||
// FIXME check logged values
|
||||
func TestLogValues(t *testing.T) {
|
||||
Config.Read()
|
||||
mockConfigRead()
|
||||
Config.LogValues()
|
||||
}
|
||||
|
||||
@@ -275,7 +282,7 @@ func TestInvalidSilenceFormRegex(t *testing.T) {
|
||||
var wasFatal bool
|
||||
log.StandardLogger().ExitFunc = func(int) { wasFatal = true }
|
||||
|
||||
Config.Read()
|
||||
mockConfigRead()
|
||||
|
||||
if !wasFatal {
|
||||
t.Error("Invalid silence form regex didn't cause log.Fatal()")
|
||||
@@ -291,7 +298,7 @@ func TestInvalidGridSortingOrder(t *testing.T) {
|
||||
var wasFatal bool
|
||||
log.StandardLogger().ExitFunc = func(int) { wasFatal = true }
|
||||
|
||||
Config.Read()
|
||||
mockConfigRead()
|
||||
|
||||
if !wasFatal {
|
||||
t.Error("Invalid grid.sorting.order value didn't cause log.Fatal()")
|
||||
@@ -307,7 +314,7 @@ func TestInvalidUICollapseGroups(t *testing.T) {
|
||||
var wasFatal bool
|
||||
log.StandardLogger().ExitFunc = func(int) { wasFatal = true }
|
||||
|
||||
Config.Read()
|
||||
mockConfigRead()
|
||||
|
||||
if !wasFatal {
|
||||
t.Error("Invalid ui.collapseGroups value didn't cause log.Fatal()")
|
||||
@@ -323,7 +330,7 @@ func TestInvalidUITheme(t *testing.T) {
|
||||
var wasFatal bool
|
||||
log.StandardLogger().ExitFunc = func(int) { wasFatal = true }
|
||||
|
||||
Config.Read()
|
||||
mockConfigRead()
|
||||
|
||||
if !wasFatal {
|
||||
t.Error("Invalid ui.theme value didn't cause log.Fatal()")
|
||||
|
||||
Reference in New Issue
Block a user