diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index da6912a00..7305dba23 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -4,12 +4,12 @@ By default unsee will try to read configuration file named `unsee.yaml` from current directory. Configuration file uses [YAML](http://yaml.org/) format and -it needs to have `.yaml` extention. +it needs to have `.yaml` extension. Custom filename and directory can be passed via command line flags or environment variables: * `--config.file` flag or `CONFIG_FILE` env variable - name of the config file - to load (without extention). + to load (without extension). * `--config.dir` flag or `CONFIG_DIR` env variable - directory where config file can be found. @@ -36,7 +36,7 @@ $ CONFIG_FILE="example" unsee --config.dir ./docs/ `alertmanager` section allows setting Alertmanager servers that should be queried for alerts. You can configure one or more Alertmanager servers, alerts -with identical label set will be deduplicated and labeld with each Alertmanager +with identical label set will be deduplicated and labeled with each Alertmanager server they were observed at. This allows using unsee to collect alerts from a pair of Alertmanager instances running in [HA mode](https://prometheus.io/docs/alerting/alertmanager/#high-availability). @@ -65,15 +65,15 @@ alertmanager: every alert in the UI and for filtering alerts using `@alertmanager=NAME` filter * `uri` - base URI of this Alertmanager server. Supported URI schemes are - `http://`, `https://` and `file://`. `file://` scheme is only useful for - testing with JSON files, see [mock](/internal/mock/) dir for examples, files - in this directory are used for running tests and when running demo instance - of unsee with `make run`. + `http://`, `https://` and `file://`. `file://` scheme is only useful for + testing with JSON files, see [mock](/internal/mock/) dir for examples, files + in this directory are used for running tests and when running demo instance + of unsee with `make run`. * `timeout` - timeout for requests send to this Alertmanager server, a string in [time.Duration](https://golang.org/pkg/time/#ParseDuration) format. * `proxy` - if enabled requests from user browsers to this Alertmanager will be - proxied via unsee. This applies to requests made when managing - silences via unsee (creating or expiring silences). + proxied via unsee. This applies to requests made when managing + silences via unsee (creating or expiring silences). Example with two production Alertmanager instances running in HA mode and a staging instance that is also proxied: @@ -104,11 +104,14 @@ alertmanager: servers: [] ``` -There is no default for `alertmanager.servers` and it's a required option. +There is no default for `alertmanager.servers` and it's a required option for +setting multiple Alertmanager servers. For cases where only a single server +needs to be configured without a config file see +[Simplified Configuration](#simplified-configuration). ### Annotations -`annotations` section allows configuring how alert annotation are displyed in +`annotations` section allows configuring how alert annotation are displayed in the UI. Syntax: @@ -173,7 +176,7 @@ filters: ``` * `default` - list of filters to use by default when user navigates to unsee - web UI. Visit `/help` page in unsee for details on avaiable filters. + web UI. Visit `/help` page in unsee for details on available filters. Note that if a string starts with `@` YAML requires to wrap it in quotes. Example: @@ -246,7 +249,7 @@ labels: - task_id ``` -Example where all but `instance` and `alertname` labels are alowed: +Example where all but `instance` and `alertname` labels are allowed: ```yaml labels: @@ -269,7 +272,7 @@ labels: ### Listen -`listen` section allows configuring unsee web server behaviour. +`listen` section allows configuring unsee web server behavior. Syntax: ```yaml @@ -422,23 +425,20 @@ sentry: Config file options are mapped to command line flags, so `alertmanager:interval` config file key is accessible as `--alertmanager.interval` flag, run `unsee --help` to see a full list. -Exaceptions: +Exceptions for passing flags: -* `alertmanager.servers` - this config files option is a list of maps, to - configure multiple Alertmanager servers config file needs to be used. - It's possible to pass a single Alertmanager server URI using - `--alertmanager.uri` flag or `ALERTMANAGER_URI` environment variable. If this - flag/env is used name of the Alertmanager instance will be always `default` - and the timeout will be set to `40s`, customizing those two options requires - config file. -* `jira` - this option is a list of maps and it's only avaiable when using +* `jira` - this option is a list of maps and it's only available when using config file. +There's no support for configuring multiple Alertmanager servers using +flags, but it's possible to configure a single Alertmanager instance this way, +see the [Simplified Configuration](#simplified-configuration) section. + ## Environment variables -Environment variables are mapped in a similiar way as command line flags, +Environment variables are mapped in a similar way as command line flags, `alertmanager:interval` is accessible as `ALERTMANAGER_INTERVAL` env. -Same exceptions apply as with command line flags. +Exceptions for passing flags: * `HOST` - used by gin webserver, same effect as setting `listen:address` config option @@ -446,3 +446,59 @@ Same exceptions apply as with command line flags. option * `SENTRY_DSN` - is used by Sentry itself, same effect as passing value to `sentry:private` config option. + +There's no support for configuring multiple alertmanager servers using +environment variables, but it's possible to configure a single Alertmanager +instance this way, see the [Simplified Configuration](#simplified-configuration) +section. + +## Simplified Configuration + +To configure multiple Alertmanager instances unsee requires a config file, but +for a single Alertmanager instance cases it's possible to configure all +Alertmanager server options that are set for `alertmanager.servers` config +section using only flags or environment variables. + +### Alertmanager URI + +To set the `uri` key from `alertmanager.servers` map `ALERTMANAGER_URI` env or +`--alertmanager.uri` flag can be used. +Example: + +``` +$ ALERTMANAGER_URI=https://alertmanager.example.com unsee +$ unsee --alertmanager.uri https://alertmanager.example.com +``` + +### Alertmanager name + +To set the `name` key from `alertmanager.servers` map `ALERTMANAGER_NAME` env or +`--alertmanager.name` flag can be used. +Example: + +``` +$ ALERTMANAGER_NAME=single unsee +$ unsee --alertmanager.name single +``` + +### Alertmanager timeout + +To set the `timeout` key from `alertmanager.servers` map `ALERTMANAGER_TIMEOUT` +env or `--alertmanager.timeout` flag can be used. +Example: + +``` +$ ALERTMANAGER_TIMEOUT=10s unsee +$ unsee --alertmanager.timeout 10s +``` + +### Alertmanager request proxy + +To set the `proxy` key from `alertmanager.servers` map `ALERTMANAGER_PROXY` +env or `--alertmanager.proxy` flag can be used. +Example: + +``` +$ ALERTMANAGER_PROXY=true unsee +$ unsee --alertmanager.proxy +``` diff --git a/internal/config/config.go b/internal/config/config.go index b15ef21f9..ec19231b9 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -21,9 +21,16 @@ var ( ) func init() { - pflag.String("alertmanager.uri", "", "Alertmanager server URI") - pflag.Duration("alertmanager.interval", time.Second*60, + pflag.Duration("alertmanager.interval", time.Minute, "Interval for fetching data from Alertmanager servers") + pflag.String("alertmanager.name", "default", + "Name for the Alertmanager server (only used with simplified config)") + pflag.String("alertmanager.uri", "", + "Alertmanager server URI (only used with simplified config)") + pflag.Duration("alertmanager.timeout", time.Second*40, + "Timeout for requests sent to the Alertmanager server (only used with simplified config)") + pflag.Bool("alertmanager.proxy", false, + "Proxy all client requests to Alertmanager via unsee (only used with simplified config)") pflag.Bool( "annotations.default.hidden", false, @@ -106,6 +113,7 @@ func (config *configSchema) Read() { log.Infof("Config file used: %s", v.ConfigFileUsed()) } + config.Alertmanager.Servers = []alertmanagerConfig{} config.Alertmanager.Interval = v.GetDuration("alertmanager.interval") config.Annotations.Default.Hidden = v.GetBool("annotations.default.hidden") config.Annotations.Hidden = v.GetStringSlice("annotations.hidden") @@ -141,11 +149,13 @@ func (config *configSchema) Read() { // accept single Alertmanager server from flag/env if nothing is set yet if len(config.Alertmanager.Servers) == 0 && v.GetString("alertmanager.uri") != "" { + log.Info("Using simple config with a single Alertmanager server") config.Alertmanager.Servers = []alertmanagerConfig{ alertmanagerConfig{ - Name: "default", + Name: v.GetString("alertmanager.name"), URI: v.GetString("alertmanager.uri"), - Timeout: time.Second * 40, + Timeout: v.GetDuration("alertmanager.timeout"), + Proxy: v.GetBool("alertmanager.proxy"), }, } } diff --git a/internal/config/config_test.go b/internal/config/config_test.go index ffdafe7a9..32e06c37b 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -3,6 +3,7 @@ package config import ( "os" "testing" + "time" "github.com/pmezard/go-difflib/difflib" @@ -16,6 +17,10 @@ func resetEnv() { unseeEnvVariables := []string{ "ALERTMANAGER_INTERVAL", "ALERTMANAGER_URI", + "ALERTMANAGER_URIS", + "ALERTMANAGER_NAME", + "ALERTMANAGET_TIMEOUT", + "ALERTMANAGER_TTL", "ANNOTATIONS_DEFAULT_HIDDEN", "ANNOTATIONS_HIDDEN", "ANNOTATIONS_VISIBLE", @@ -165,6 +170,31 @@ func TestReadConfig(t *testing.T) { testReadConfig(t) } +func TestReadSimpleConfig(t *testing.T) { + resetEnv() + log.SetLevel(log.ErrorLevel) + os.Setenv("ALERTMANAGER_URI", "http://localhost") + os.Setenv("ALERTMANAGER_NAME", "single") + os.Setenv("ALERTMANAGER_TIMEOUT", "15s") + os.Setenv("ALERTMANAGER_PROXY", "true") + os.Setenv("ALERTMANAGER_INTERVAL", "3m") + Config.Read() + if len(Config.Alertmanager.Servers) != 1 { + t.Errorf("Expected 1 Alertmanager server, got %d", len(Config.Alertmanager.Servers)) + } else { + am := Config.Alertmanager.Servers[0] + if am.Name != "single" { + t.Errorf("Expect Alertmanager name 'single' got '%s'", am.Name) + } + if am.Timeout != time.Second*15 { + t.Errorf("Expect Alertmanager timeout '%v' got '%v'", time.Second*15, am.Timeout) + } + if Config.Alertmanager.Interval != time.Minute*3 { + t.Errorf("Expect Alertmanager timeout '%v' got '%v'", time.Minute*3, Config.Alertmanager.Interval) + } + } +} + type urlSecretTest struct { raw string sanitized string