alertmanager/config/config.go (134 lines of code) (raw):

/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ package config import ( "fmt" "time" "github.com/facebookincubator/prometheus-configmanager/alertmanager/common" "github.com/thoas/go-funk" amconfig "github.com/prometheus/alertmanager/config" "github.com/prometheus/common/model" "gopkg.in/yaml.v2" ) const ( TenantBaseRoutePostfix = "tenant_base_route" ) // Config uses a custom receiver struct to avoid scrubbing of 'secrets' during // marshaling type Config struct { Global *GlobalConfig `yaml:"global,omitempty" json:"global,omitempty"` Route *Route `yaml:"route,omitempty" json:"route,omitempty"` InhibitRules []*amconfig.InhibitRule `yaml:"inhibit_rules,omitempty" json:"inhibit_rules,omitempty"` Receivers []*Receiver `yaml:"receivers,omitempty" json:"receivers,omitempty"` Templates []string `yaml:"templates" json:"templates"` } // GetReceiver returns the receiver config with the given name func (c *Config) GetReceiver(name string) *Receiver { for _, rec := range c.Receivers { if rec.Name == name { return rec } } return nil } func (c *Config) GetRouteIdx(name string) int { for idx, route := range c.Route.Routes { if route.Receiver == name { return idx } } return -1 } func (c *Config) InitializeNetworkBaseRoute(route *Route, matcherLabel, tenantID string) error { baseRouteName := MakeBaseRouteName(tenantID) if c.GetReceiver(baseRouteName) != nil { return fmt.Errorf("Base route for tenant %s already exists", tenantID) } c.Receivers = append(c.Receivers, &Receiver{Name: baseRouteName}) route.Receiver = baseRouteName if matcherLabel != "" { route.Match = map[string]string{matcherLabel: tenantID} } c.Route.Routes = append(c.Route.Routes, route) return c.Validate() } // Validate makes sure that the config is properly formed. Unmarshal the yaml // data into an alertmanager Config struct to ensure that it is properly formed func (c *Config) Validate() error { yamlData, err := yaml.Marshal(c) if err != nil { return err } err = yaml.Unmarshal(yamlData, &amconfig.Config{}) if err != nil { return err } return nil } func (c *Config) SearchRoutesForReceiver(receiver string) bool { if c.Route.Receiver == receiver { return true } for _, route := range c.Route.Routes { if searchRoutesForReceiverImpl(receiver, route) { return true } } return false } func searchRoutesForReceiverImpl(receiver string, route *Route) bool { if route.Receiver == receiver { return true } for _, route := range route.Routes { if searchRoutesForReceiverImpl(receiver, route) { return true } } return false } func (c *Config) RemoveReceiverFromRoute(receiver string) { for i, route := range c.Route.Routes { c.Route.Routes[i] = removeReceiverFromRouteImpl(receiver, route) } prunedRoutes := funk.Filter(c.Route.Routes, func(x *Route) bool { return x != nil }) c.Route.Routes = prunedRoutes.([]*Route) } func removeReceiverFromRouteImpl(receiver string, route *Route) *Route { if route.Receiver == receiver { return nil } for i, childRoute := range route.Routes { route.Routes[i] = removeReceiverFromRouteImpl(receiver, childRoute) } // Remove nil routes from array prunedRoutes := funk.Filter(route.Routes, func(x *Route) bool { return x != nil }) route.Routes = prunedRoutes.([]*Route) return route } // GlobalConfig is a copy of prometheus/alertmanager/config.GlobalConfig with // `Secret` fields replaced with strings to enable marshaling without obfuscation type GlobalConfig struct { // ResolveTimeout is the time after which an alert is declared resolved // if it has not been updated. ResolveTimeout string `yaml:"resolve_timeout" json:"resolve_timeout"` HTTPConfig *common.HTTPConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` SMTPFrom string `yaml:"smtp_from,omitempty" json:"smtp_from,omitempty"` SMTPHello string `yaml:"smtp_hello,omitempty" json:"smtp_hello,omitempty"` SMTPSmarthost string `yaml:"smtp_smarthost,omitempty" json:"smtp_smarthost,omitempty"` SMTPAuthUsername string `yaml:"smtp_auth_username,omitempty" json:"smtp_auth_username,omitempty"` SMTPAuthPassword string `yaml:"smtp_auth_password,omitempty" json:"smtp_auth_password,omitempty"` SMTPAuthSecret string `yaml:"smtp_auth_secret,omitempty" json:"smtp_auth_secret,omitempty"` SMTPAuthIdentity string `yaml:"smtp_auth_identity,omitempty" json:"smtp_auth_identity,omitempty"` SMTPRequireTLS bool `yaml:"smtp_require_tls,omitempty" json:"smtp_require_tls,omitempty"` SlackAPIURL *amconfig.URL `yaml:"slack_api_url,omitempty" json:"slack_api_url,omitempty"` PagerdutyURL *amconfig.URL `yaml:"pagerduty_url,omitempty" json:"pagerduty_url,omitempty"` HipchatAPIURL *amconfig.URL `yaml:"hipchat_api_url,omitempty" json:"hipchat_api_url,omitempty"` HipchatAuthToken string `yaml:"hipchat_auth_token,omitempty" json:"hipchat_auth_token,omitempty"` OpsGenieAPIURL *amconfig.URL `yaml:"opsgenie_api_url,omitempty" json:"opsgenie_api_url,omitempty"` OpsGenieAPIKey string `yaml:"opsgenie_api_key,omitempty" json:"opsgenie_api_key,omitempty"` WeChatAPIURL *amconfig.URL `yaml:"wechat_api_url,omitempty" json:"wechat_api_url,omitempty"` WeChatAPISecret string `yaml:"wechat_api_secret,omitempty" json:"wechat_api_secret,omitempty"` WeChatAPICorpID string `yaml:"wechat_api_corp_id,omitempty" json:"wechat_api_corp_id,omitempty"` VictorOpsAPIURL *amconfig.URL `yaml:"victorops_api_url,omitempty" json:"victorops_api_url,omitempty"` VictorOpsAPIKey string `yaml:"victorops_api_key,omitempty" json:"victorops_api_key,omitempty"` } func DefaultGlobalConfig() GlobalConfig { return GlobalConfig{ ResolveTimeout: model.Duration(5 * time.Minute).String(), HTTPConfig: &common.HTTPConfig{}, SMTPHello: "localhost", SMTPRequireTLS: false, } } func MakeBaseRouteName(tenantID string) string { return fmt.Sprintf("%s_%s", tenantID, TenantBaseRoutePostfix) }