Split the notifier package into smaller source files. Signed-off-by: Siavash Safi <siavash@cloudflare.com>pull/16398/head
parent
8ad21d0659
commit
ef48e4cb9f
@ -0,0 +1,91 @@ |
|||||||
|
// 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" |
||||||
|
"time" |
||||||
|
|
||||||
|
"github.com/prometheus/prometheus/model/labels" |
||||||
|
"github.com/prometheus/prometheus/model/relabel" |
||||||
|
) |
||||||
|
|
||||||
|
// Alert is a generic representation of an alert in the Prometheus eco-system.
|
||||||
|
type Alert struct { |
||||||
|
// Label value pairs for purpose of aggregation, matching, and disposition
|
||||||
|
// dispatching. This must minimally include an "alertname" label.
|
||||||
|
Labels labels.Labels `json:"labels"` |
||||||
|
|
||||||
|
// Extra key/value information which does not define alert identity.
|
||||||
|
Annotations labels.Labels `json:"annotations"` |
||||||
|
|
||||||
|
// The known time range for this alert. Both ends are optional.
|
||||||
|
StartsAt time.Time `json:"startsAt,omitempty"` |
||||||
|
EndsAt time.Time `json:"endsAt,omitempty"` |
||||||
|
GeneratorURL string `json:"generatorURL,omitempty"` |
||||||
|
} |
||||||
|
|
||||||
|
// Name returns the name of the alert. It is equivalent to the "alertname" label.
|
||||||
|
func (a *Alert) Name() string { |
||||||
|
return a.Labels.Get(labels.AlertName) |
||||||
|
} |
||||||
|
|
||||||
|
// Hash returns a hash over the alert. It is equivalent to the alert labels hash.
|
||||||
|
func (a *Alert) Hash() uint64 { |
||||||
|
return a.Labels.Hash() |
||||||
|
} |
||||||
|
|
||||||
|
func (a *Alert) String() string { |
||||||
|
s := fmt.Sprintf("%s[%s]", a.Name(), fmt.Sprintf("%016x", a.Hash())[:7]) |
||||||
|
if a.Resolved() { |
||||||
|
return s + "[resolved]" |
||||||
|
} |
||||||
|
return s + "[active]" |
||||||
|
} |
||||||
|
|
||||||
|
// Resolved returns true iff the activity interval ended in the past.
|
||||||
|
func (a *Alert) Resolved() bool { |
||||||
|
return a.ResolvedAt(time.Now()) |
||||||
|
} |
||||||
|
|
||||||
|
// ResolvedAt returns true iff the activity interval ended before
|
||||||
|
// the given timestamp.
|
||||||
|
func (a *Alert) ResolvedAt(ts time.Time) bool { |
||||||
|
if a.EndsAt.IsZero() { |
||||||
|
return false |
||||||
|
} |
||||||
|
return !a.EndsAt.After(ts) |
||||||
|
} |
||||||
|
|
||||||
|
func relabelAlerts(relabelConfigs []*relabel.Config, externalLabels labels.Labels, alerts []*Alert) []*Alert { |
||||||
|
lb := labels.NewBuilder(labels.EmptyLabels()) |
||||||
|
var relabeledAlerts []*Alert |
||||||
|
|
||||||
|
for _, a := range alerts { |
||||||
|
lb.Reset(a.Labels) |
||||||
|
externalLabels.Range(func(l labels.Label) { |
||||||
|
if a.Labels.Get(l.Name) == "" { |
||||||
|
lb.Set(l.Name, l.Value) |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
keep := relabel.ProcessBuilder(lb, relabelConfigs...) |
||||||
|
if !keep { |
||||||
|
continue |
||||||
|
} |
||||||
|
a.Labels = lb.Labels() |
||||||
|
relabeledAlerts = append(relabeledAlerts, a) |
||||||
|
} |
||||||
|
return relabeledAlerts |
||||||
|
} |
@ -0,0 +1,90 @@ |
|||||||
|
// 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) |
||||||
|
} |
@ -0,0 +1,62 @@ |
|||||||
|
// 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 ( |
||||||
|
"testing" |
||||||
|
|
||||||
|
"github.com/stretchr/testify/require" |
||||||
|
|
||||||
|
"github.com/prometheus/prometheus/config" |
||||||
|
) |
||||||
|
|
||||||
|
func TestPostPath(t *testing.T) { |
||||||
|
cases := []struct { |
||||||
|
in, out string |
||||||
|
}{ |
||||||
|
{ |
||||||
|
in: "", |
||||||
|
out: "/api/v2/alerts", |
||||||
|
}, |
||||||
|
{ |
||||||
|
in: "/", |
||||||
|
out: "/api/v2/alerts", |
||||||
|
}, |
||||||
|
{ |
||||||
|
in: "/prefix", |
||||||
|
out: "/prefix/api/v2/alerts", |
||||||
|
}, |
||||||
|
{ |
||||||
|
in: "/prefix//", |
||||||
|
out: "/prefix/api/v2/alerts", |
||||||
|
}, |
||||||
|
{ |
||||||
|
in: "prefix//", |
||||||
|
out: "/prefix/api/v2/alerts", |
||||||
|
}, |
||||||
|
} |
||||||
|
for _, c := range cases { |
||||||
|
require.Equal(t, c.out, postPath(c.in, config.AlertmanagerAPIVersionV2)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func TestLabelSetNotReused(t *testing.T) { |
||||||
|
tg := makeInputTargetGroup() |
||||||
|
_, _, err := AlertmanagerFromGroup(tg, &config.AlertmanagerConfig{}) |
||||||
|
|
||||||
|
require.NoError(t, err) |
||||||
|
|
||||||
|
// Target modified during alertmanager extraction
|
||||||
|
require.Equal(t, tg, makeInputTargetGroup()) |
||||||
|
} |
@ -0,0 +1,128 @@ |
|||||||
|
// 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 ( |
||||||
|
"crypto/md5" |
||||||
|
"encoding/hex" |
||||||
|
"log/slog" |
||||||
|
"net/http" |
||||||
|
"sync" |
||||||
|
|
||||||
|
config_util "github.com/prometheus/common/config" |
||||||
|
"github.com/prometheus/sigv4" |
||||||
|
"gopkg.in/yaml.v2" |
||||||
|
|
||||||
|
"github.com/prometheus/prometheus/config" |
||||||
|
"github.com/prometheus/prometheus/discovery/targetgroup" |
||||||
|
) |
||||||
|
|
||||||
|
// alertmanagerSet contains a set of Alertmanagers discovered via a group of service
|
||||||
|
// discovery definitions that have a common configuration on how alerts should be sent.
|
||||||
|
type alertmanagerSet struct { |
||||||
|
cfg *config.AlertmanagerConfig |
||||||
|
client *http.Client |
||||||
|
|
||||||
|
metrics *alertMetrics |
||||||
|
|
||||||
|
mtx sync.RWMutex |
||||||
|
ams []alertmanager |
||||||
|
droppedAms []alertmanager |
||||||
|
logger *slog.Logger |
||||||
|
} |
||||||
|
|
||||||
|
func newAlertmanagerSet(cfg *config.AlertmanagerConfig, logger *slog.Logger, metrics *alertMetrics) (*alertmanagerSet, error) { |
||||||
|
client, err := config_util.NewClientFromConfig(cfg.HTTPClientConfig, "alertmanager") |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
t := client.Transport |
||||||
|
|
||||||
|
if cfg.SigV4Config != nil { |
||||||
|
t, err = sigv4.NewSigV4RoundTripper(cfg.SigV4Config, client.Transport) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
client.Transport = t |
||||||
|
|
||||||
|
s := &alertmanagerSet{ |
||||||
|
client: client, |
||||||
|
cfg: cfg, |
||||||
|
logger: logger, |
||||||
|
metrics: metrics, |
||||||
|
} |
||||||
|
return s, nil |
||||||
|
} |
||||||
|
|
||||||
|
// sync extracts a deduplicated set of Alertmanager endpoints from a list
|
||||||
|
// of target groups definitions.
|
||||||
|
func (s *alertmanagerSet) sync(tgs []*targetgroup.Group) { |
||||||
|
allAms := []alertmanager{} |
||||||
|
allDroppedAms := []alertmanager{} |
||||||
|
|
||||||
|
for _, tg := range tgs { |
||||||
|
ams, droppedAms, err := AlertmanagerFromGroup(tg, s.cfg) |
||||||
|
if err != nil { |
||||||
|
s.logger.Error("Creating discovered Alertmanagers failed", "err", err) |
||||||
|
continue |
||||||
|
} |
||||||
|
allAms = append(allAms, ams...) |
||||||
|
allDroppedAms = append(allDroppedAms, droppedAms...) |
||||||
|
} |
||||||
|
|
||||||
|
s.mtx.Lock() |
||||||
|
defer s.mtx.Unlock() |
||||||
|
previousAms := s.ams |
||||||
|
// Set new Alertmanagers and deduplicate them along their unique URL.
|
||||||
|
s.ams = []alertmanager{} |
||||||
|
s.droppedAms = []alertmanager{} |
||||||
|
s.droppedAms = append(s.droppedAms, allDroppedAms...) |
||||||
|
seen := map[string]struct{}{} |
||||||
|
|
||||||
|
for _, am := range allAms { |
||||||
|
us := am.url().String() |
||||||
|
if _, ok := seen[us]; ok { |
||||||
|
continue |
||||||
|
} |
||||||
|
|
||||||
|
// This will initialize the Counters for the AM to 0.
|
||||||
|
s.metrics.sent.WithLabelValues(us) |
||||||
|
s.metrics.errors.WithLabelValues(us) |
||||||
|
|
||||||
|
seen[us] = struct{}{} |
||||||
|
s.ams = append(s.ams, am) |
||||||
|
} |
||||||
|
// Now remove counters for any removed Alertmanagers.
|
||||||
|
for _, am := range previousAms { |
||||||
|
us := am.url().String() |
||||||
|
if _, ok := seen[us]; ok { |
||||||
|
continue |
||||||
|
} |
||||||
|
s.metrics.latency.DeleteLabelValues(us) |
||||||
|
s.metrics.sent.DeleteLabelValues(us) |
||||||
|
s.metrics.errors.DeleteLabelValues(us) |
||||||
|
seen[us] = struct{}{} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (s *alertmanagerSet) configHash() (string, error) { |
||||||
|
b, err := yaml.Marshal(s.cfg) |
||||||
|
if err != nil { |
||||||
|
return "", err |
||||||
|
} |
||||||
|
hash := md5.Sum(b) |
||||||
|
return hex.EncodeToString(hash[:]), nil |
||||||
|
} |
@ -0,0 +1,94 @@ |
|||||||
|
// 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 "github.com/prometheus/client_golang/prometheus" |
||||||
|
|
||||||
|
type alertMetrics struct { |
||||||
|
latency *prometheus.SummaryVec |
||||||
|
errors *prometheus.CounterVec |
||||||
|
sent *prometheus.CounterVec |
||||||
|
dropped prometheus.Counter |
||||||
|
queueLength prometheus.GaugeFunc |
||||||
|
queueCapacity prometheus.Gauge |
||||||
|
alertmanagersDiscovered prometheus.GaugeFunc |
||||||
|
} |
||||||
|
|
||||||
|
func newAlertMetrics(r prometheus.Registerer, queueCap int, queueLen, alertmanagersDiscovered func() float64) *alertMetrics { |
||||||
|
m := &alertMetrics{ |
||||||
|
latency: prometheus.NewSummaryVec(prometheus.SummaryOpts{ |
||||||
|
Namespace: namespace, |
||||||
|
Subsystem: subsystem, |
||||||
|
Name: "latency_seconds", |
||||||
|
Help: "Latency quantiles for sending alert notifications.", |
||||||
|
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, |
||||||
|
}, |
||||||
|
[]string{alertmanagerLabel}, |
||||||
|
), |
||||||
|
errors: prometheus.NewCounterVec(prometheus.CounterOpts{ |
||||||
|
Namespace: namespace, |
||||||
|
Subsystem: subsystem, |
||||||
|
Name: "errors_total", |
||||||
|
Help: "Total number of sent alerts affected by errors.", |
||||||
|
}, |
||||||
|
[]string{alertmanagerLabel}, |
||||||
|
), |
||||||
|
sent: prometheus.NewCounterVec(prometheus.CounterOpts{ |
||||||
|
Namespace: namespace, |
||||||
|
Subsystem: subsystem, |
||||||
|
Name: "sent_total", |
||||||
|
Help: "Total number of alerts sent.", |
||||||
|
}, |
||||||
|
[]string{alertmanagerLabel}, |
||||||
|
), |
||||||
|
dropped: prometheus.NewCounter(prometheus.CounterOpts{ |
||||||
|
Namespace: namespace, |
||||||
|
Subsystem: subsystem, |
||||||
|
Name: "dropped_total", |
||||||
|
Help: "Total number of alerts dropped due to errors when sending to Alertmanager.", |
||||||
|
}), |
||||||
|
queueLength: prometheus.NewGaugeFunc(prometheus.GaugeOpts{ |
||||||
|
Namespace: namespace, |
||||||
|
Subsystem: subsystem, |
||||||
|
Name: "queue_length", |
||||||
|
Help: "The number of alert notifications in the queue.", |
||||||
|
}, queueLen), |
||||||
|
queueCapacity: prometheus.NewGauge(prometheus.GaugeOpts{ |
||||||
|
Namespace: namespace, |
||||||
|
Subsystem: subsystem, |
||||||
|
Name: "queue_capacity", |
||||||
|
Help: "The capacity of the alert notifications queue.", |
||||||
|
}), |
||||||
|
alertmanagersDiscovered: prometheus.NewGaugeFunc(prometheus.GaugeOpts{ |
||||||
|
Name: "prometheus_notifications_alertmanagers_discovered", |
||||||
|
Help: "The number of alertmanagers discovered and active.", |
||||||
|
}, alertmanagersDiscovered), |
||||||
|
} |
||||||
|
|
||||||
|
m.queueCapacity.Set(float64(queueCap)) |
||||||
|
|
||||||
|
if r != nil { |
||||||
|
r.MustRegister( |
||||||
|
m.latency, |
||||||
|
m.errors, |
||||||
|
m.sent, |
||||||
|
m.dropped, |
||||||
|
m.queueLength, |
||||||
|
m.queueCapacity, |
||||||
|
m.alertmanagersDiscovered, |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
return m |
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
// 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 ( |
||||||
|
"github.com/go-openapi/strfmt" |
||||||
|
"github.com/prometheus/alertmanager/api/v2/models" |
||||||
|
|
||||||
|
"github.com/prometheus/prometheus/model/labels" |
||||||
|
) |
||||||
|
|
||||||
|
func alertsToOpenAPIAlerts(alerts []*Alert) models.PostableAlerts { |
||||||
|
openAPIAlerts := models.PostableAlerts{} |
||||||
|
for _, a := range alerts { |
||||||
|
start := strfmt.DateTime(a.StartsAt) |
||||||
|
end := strfmt.DateTime(a.EndsAt) |
||||||
|
openAPIAlerts = append(openAPIAlerts, &models.PostableAlert{ |
||||||
|
Annotations: labelsToOpenAPILabelSet(a.Annotations), |
||||||
|
EndsAt: end, |
||||||
|
StartsAt: start, |
||||||
|
Alert: models.Alert{ |
||||||
|
GeneratorURL: strfmt.URI(a.GeneratorURL), |
||||||
|
Labels: labelsToOpenAPILabelSet(a.Labels), |
||||||
|
}, |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return openAPIAlerts |
||||||
|
} |
||||||
|
|
||||||
|
func labelsToOpenAPILabelSet(modelLabelSet labels.Labels) models.LabelSet { |
||||||
|
apiLabelSet := models.LabelSet{} |
||||||
|
modelLabelSet.Range(func(label labels.Label) { |
||||||
|
apiLabelSet[label.Name] = label.Value |
||||||
|
}) |
||||||
|
|
||||||
|
return apiLabelSet |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
// 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 ( |
||||||
|
"testing" |
||||||
|
|
||||||
|
"github.com/prometheus/alertmanager/api/v2/models" |
||||||
|
"github.com/stretchr/testify/require" |
||||||
|
|
||||||
|
"github.com/prometheus/prometheus/model/labels" |
||||||
|
) |
||||||
|
|
||||||
|
func TestLabelsToOpenAPILabelSet(t *testing.T) { |
||||||
|
require.Equal(t, models.LabelSet{"aaa": "111", "bbb": "222"}, labelsToOpenAPILabelSet(labels.FromStrings("aaa", "111", "bbb", "222"))) |
||||||
|
} |
Loading…
Reference in new issue