Add a 'simplified mode' for configuration that can be used with only one Alertmanager instance

This commit is contained in:
Łukasz Mierzwa
2018-01-14 21:13:03 -08:00
parent 63a0799263
commit 36178ee1ba
3 changed files with 125 additions and 29 deletions

View File

@@ -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
```

View File

@@ -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"),
},
}
}

View File

@@ -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