a9fa7e4b23
By default alerts will no longer be split apart and any caching functionality will be disabled. With this the behaviour will be closer to what the user has configured in Alertmanger/Prometheus itself.
401 lines
8.3 KiB
Go
401 lines
8.3 KiB
Go
// Package config defines the configuration file.
|
|
package config
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.sr.ht/~emersion/go-scfg"
|
|
)
|
|
|
|
// AlertMode determines if alerts grouped by Alertmanager are being kept together.
|
|
type AlertMode int
|
|
|
|
// The different modes for AlertMode.
|
|
const (
|
|
Single AlertMode = iota
|
|
Multi
|
|
)
|
|
|
|
// Config is the configuration of the bridge.
|
|
type Config struct {
|
|
BaseURL string
|
|
HTTPAddress string
|
|
LogLevel string
|
|
AlertMode AlertMode
|
|
User string
|
|
Password string
|
|
Ntfy ntfyConfig
|
|
Labels labels
|
|
Cache CacheConfig
|
|
Am alertmanagerConfig
|
|
Resolved resolvedConfig
|
|
}
|
|
|
|
type ntfyConfig struct {
|
|
Topic string
|
|
User string
|
|
Password string
|
|
AccessToken string
|
|
EmailAddress string
|
|
Call string
|
|
}
|
|
|
|
type labels struct {
|
|
Order []string
|
|
Label map[string]labelConfig
|
|
}
|
|
|
|
type labelConfig struct {
|
|
Priority string
|
|
Tags []string
|
|
Icon string
|
|
EmailAddress string
|
|
Call string
|
|
}
|
|
|
|
// CacheConfig is the configuration of the cache.
|
|
type CacheConfig struct {
|
|
// shared settings
|
|
Type string
|
|
Duration time.Duration
|
|
// memory settings
|
|
CleanupInterval time.Duration
|
|
// redis settings
|
|
RedisURL string
|
|
}
|
|
|
|
type alertmanagerConfig struct {
|
|
User string
|
|
Password string
|
|
SilenceDuration time.Duration
|
|
URL string
|
|
}
|
|
|
|
type resolvedConfig struct {
|
|
Tags []string
|
|
Icon string
|
|
}
|
|
|
|
// ReadConfig reads an scfg formatted file and returns the configuration struct.
|
|
func ReadConfig(path string) (*Config, error) {
|
|
cfg, err := scfg.Load(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
config := new(Config)
|
|
// Set default values
|
|
config.HTTPAddress = "127.0.0.1:8080"
|
|
config.LogLevel = "info"
|
|
config.AlertMode = Multi
|
|
|
|
config.Cache.Type = "disabled"
|
|
config.Cache.Duration = time.Hour * 24
|
|
// memory
|
|
config.Cache.CleanupInterval = time.Hour
|
|
// redis
|
|
config.Cache.RedisURL = "redis://localhost:6379"
|
|
|
|
d := cfg.Get("log-level")
|
|
if d != nil {
|
|
if err := d.ParseParams(&config.LogLevel); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
d = cfg.Get("http-address")
|
|
if d != nil {
|
|
if err := d.ParseParams(&config.HTTPAddress); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
d = cfg.Get("base-url")
|
|
if d != nil {
|
|
if err := d.ParseParams(&config.BaseURL); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
d = cfg.Get("alert-mode")
|
|
if d != nil {
|
|
var mode string
|
|
if err := d.ParseParams(&mode); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
switch strings.ToLower(mode) {
|
|
case "single":
|
|
config.AlertMode = Single
|
|
|
|
case "multi":
|
|
config.AlertMode = Multi
|
|
|
|
default:
|
|
return nil, fmt.Errorf("%q directive: illegal mode %q", d.Name, mode)
|
|
}
|
|
}
|
|
|
|
d = cfg.Get("user")
|
|
if d != nil {
|
|
if err := d.ParseParams(&config.User); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
d = cfg.Get("password")
|
|
if d != nil {
|
|
if err := d.ParseParams(&config.Password); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if (config.Password != "" && config.User == "") ||
|
|
(config.Password == "" && config.User != "") {
|
|
return nil, errors.New("user and password have to be set together")
|
|
}
|
|
|
|
labelsDir := cfg.Get("labels")
|
|
if labelsDir != nil {
|
|
d = labelsDir.Children.Get("order")
|
|
if d != nil {
|
|
var order string
|
|
if err := d.ParseParams(&order); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
config.Labels.Order = strings.Split(order, ",")
|
|
}
|
|
|
|
labels := make(map[string]labelConfig)
|
|
for _, labelName := range config.Labels.Order {
|
|
for _, labelDir := range labelsDir.Children.GetAll(labelName) {
|
|
labelConfig := new(labelConfig)
|
|
var name string
|
|
|
|
if err := labelDir.ParseParams(&name); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
d = labelDir.Children.Get("priority")
|
|
if d != nil {
|
|
if err := d.ParseParams(&labelConfig.Priority); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
d = labelDir.Children.Get("tags")
|
|
if d != nil {
|
|
var tags string
|
|
if err := d.ParseParams(&tags); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
labelConfig.Tags = strings.Split(tags, ",")
|
|
}
|
|
|
|
d = labelDir.Children.Get("icon")
|
|
if d != nil {
|
|
if err := d.ParseParams(&labelConfig.Icon); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
d = labelDir.Children.Get("email-address")
|
|
if d != nil {
|
|
if err := d.ParseParams(&labelConfig.EmailAddress); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
d = labelDir.Children.Get("call")
|
|
if d != nil {
|
|
if err := d.ParseParams(&labelConfig.Call); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
labels[fmt.Sprintf("%s:%s", labelName, name)] = *labelConfig
|
|
}
|
|
}
|
|
|
|
config.Labels.Label = labels
|
|
}
|
|
|
|
ntfyDir := cfg.Get("ntfy")
|
|
if ntfyDir == nil {
|
|
return nil, fmt.Errorf("%q directive missing", "ntfy")
|
|
}
|
|
|
|
d = ntfyDir.Children.Get("topic")
|
|
if d == nil {
|
|
return nil, fmt.Errorf("%q missing from %q directive", "topic", "ntfy")
|
|
}
|
|
if err := d.ParseParams(&config.Ntfy.Topic); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
d = ntfyDir.Children.Get("user")
|
|
if d != nil {
|
|
if err := d.ParseParams(&config.Ntfy.User); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
d = ntfyDir.Children.Get("password")
|
|
if d != nil {
|
|
if err := d.ParseParams(&config.Ntfy.Password); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if (config.Ntfy.Password != "" && config.Ntfy.User == "") ||
|
|
(config.Ntfy.Password == "" && config.Ntfy.User != "") {
|
|
return nil, errors.New("ntfy: user and password have to be set together")
|
|
}
|
|
|
|
d = ntfyDir.Children.Get("access-token")
|
|
if d != nil {
|
|
if err := d.ParseParams(&config.Ntfy.AccessToken); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if config.Ntfy.User != "" && config.Ntfy.AccessToken != "" {
|
|
return nil, errors.New("ntfy: cannot use both an access-token and a user/password at the same time")
|
|
}
|
|
|
|
d = ntfyDir.Children.Get("email-address")
|
|
if d != nil {
|
|
if err := d.ParseParams(&config.Ntfy.EmailAddress); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
d = ntfyDir.Children.Get("call")
|
|
if d != nil {
|
|
if err := d.ParseParams(&config.Ntfy.Call); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
cacheDir := cfg.Get("cache")
|
|
|
|
if cacheDir != nil {
|
|
d = cacheDir.Children.Get("type")
|
|
if d != nil {
|
|
if err := d.ParseParams(&config.Cache.Type); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
var durationString string
|
|
d = cacheDir.Children.Get("duration")
|
|
if d != nil {
|
|
if err := d.ParseParams(&durationString); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
duration, err := time.ParseDuration(durationString)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
config.Cache.Duration = duration
|
|
}
|
|
|
|
// memory
|
|
var cleanupIntervalString string
|
|
d = cacheDir.Children.Get("cleanup-interval")
|
|
if d != nil {
|
|
if err := d.ParseParams(&cleanupIntervalString); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
interval, err := time.ParseDuration(cleanupIntervalString)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
config.Cache.CleanupInterval = interval
|
|
}
|
|
|
|
// redis
|
|
d = cacheDir.Children.Get("redis-url")
|
|
if d != nil {
|
|
if err := d.ParseParams(&config.Cache.RedisURL); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
}
|
|
|
|
amDir := cfg.Get("alertmanager")
|
|
|
|
if amDir != nil {
|
|
var durationString string
|
|
d = amDir.Children.Get("silence-duration")
|
|
if d != nil {
|
|
if err := d.ParseParams(&durationString); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
duration, err := time.ParseDuration(durationString)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
config.Am.SilenceDuration = duration
|
|
}
|
|
|
|
d = amDir.Children.Get("user")
|
|
if d != nil {
|
|
if err := d.ParseParams(&config.Am.User); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
d = amDir.Children.Get("password")
|
|
if d != nil {
|
|
if err := d.ParseParams(&config.Am.Password); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if (config.Am.Password != "" && config.Am.User == "") ||
|
|
(config.Am.Password == "" && config.Am.User != "") {
|
|
return nil, errors.New("alertmanager: user and password have to be set together")
|
|
}
|
|
|
|
d = amDir.Children.Get("url")
|
|
if d != nil {
|
|
if err := d.ParseParams(&config.Am.URL); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
}
|
|
|
|
resolvedDir := cfg.Get("resolved")
|
|
if resolvedDir != nil {
|
|
d = resolvedDir.Children.Get("tags")
|
|
if d != nil {
|
|
var tags string
|
|
if err := d.ParseParams(&tags); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
config.Resolved.Tags = strings.Split(tags, ",")
|
|
}
|
|
|
|
d = resolvedDir.Children.Get("icon")
|
|
if d != nil {
|
|
if err := d.ParseParams(&config.Resolved.Icon); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
}
|
|
|
|
return config, nil
|
|
}
|