// Copyright 2013 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package notifier import ( "fmt" "net/url" "path" "github.com/prometheus/common/model" "github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/discovery/targetgroup" "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/relabel" ) // Alertmanager holds Alertmanager endpoint information. type alertmanager interface { url() *url.URL } type alertmanagerLabels struct{ labels.Labels } const pathLabel = "__alerts_path__" func (a alertmanagerLabels) url() *url.URL { return &url.URL{ Scheme: a.Get(model.SchemeLabel), Host: a.Get(model.AddressLabel), Path: a.Get(pathLabel), } } // AlertmanagerFromGroup extracts a list of alertmanagers from a target group // and an associated AlertmanagerConfig. func AlertmanagerFromGroup(tg *targetgroup.Group, cfg *config.AlertmanagerConfig) ([]alertmanager, []alertmanager, error) { var res []alertmanager var droppedAlertManagers []alertmanager lb := labels.NewBuilder(labels.EmptyLabels()) for _, tlset := range tg.Targets { lb.Reset(labels.EmptyLabels()) for ln, lv := range tlset { lb.Set(string(ln), string(lv)) } // Set configured scheme as the initial scheme label for overwrite. lb.Set(model.SchemeLabel, cfg.Scheme) lb.Set(pathLabel, postPath(cfg.PathPrefix, cfg.APIVersion)) // Combine target labels with target group labels. for ln, lv := range tg.Labels { if _, ok := tlset[ln]; !ok { lb.Set(string(ln), string(lv)) } } preRelabel := lb.Labels() keep := relabel.ProcessBuilder(lb, cfg.RelabelConfigs...) if !keep { droppedAlertManagers = append(droppedAlertManagers, alertmanagerLabels{preRelabel}) continue } addr := lb.Get(model.AddressLabel) if err := config.CheckTargetAddress(model.LabelValue(addr)); err != nil { return nil, nil, err } res = append(res, alertmanagerLabels{lb.Labels()}) } return res, droppedAlertManagers, nil } func postPath(pre string, v config.AlertmanagerAPIVersion) string { alertPushEndpoint := fmt.Sprintf("/api/%v/alerts", string(v)) return path.Join("/", pre, alertPushEndpoint) }