Skip to content

Commit

Permalink
Merge pull request #2276 from ricoberger/pass-labels-to-opsgenie-details
Browse files Browse the repository at this point in the history
Propagate labels to Opsgenie details
  • Loading branch information
bwplotka committed Jun 9, 2020
2 parents 12da9d6 + 4b59db0 commit 6d77929
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 75 deletions.
7 changes: 6 additions & 1 deletion notify/opsgenie/opsgenie.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,12 @@ func (n *Notifier) createRequest(ctx context.Context, as ...*types.Alert) (*http

tmpl := notify.TmplText(n.tmpl, data, &err)

details := make(map[string]string, len(n.conf.Details))
details := make(map[string]string)

for k, v := range data.CommonLabels {
details[k] = v
}

for k, v := range n.conf.Details {
details[k] = tmpl(v)
}
Expand Down
198 changes: 124 additions & 74 deletions notify/opsgenie/opsgenie_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,85 +76,135 @@ func TestOpsGenie(t *testing.T) {
}
logger := log.NewNopLogger()
tmpl := test.CreateTmpl(t)
conf := &config.OpsGenieConfig{
NotifierConfig: config.NotifierConfig{
VSendResolved: true,
},
Message: `{{ .CommonLabels.Message }}`,
Description: `{{ .CommonLabels.Description }}`,
Source: `{{ .CommonLabels.Source }}`,
Responders: []config.OpsGenieConfigResponder{
{
Name: `{{ .CommonLabels.ResponderName1 }}`,
Type: `{{ .CommonLabels.ResponderType1 }}`,
},
{
Name: `{{ .CommonLabels.ResponderName2 }}`,
Type: `{{ .CommonLabels.ResponderType2 }}`,
},
},
Tags: `{{ .CommonLabels.Tags }}`,
Note: `{{ .CommonLabels.Note }}`,
Priority: `{{ .CommonLabels.Priority }}`,
APIKey: `{{ .ExternalURL }}`,
APIURL: &config.URL{URL: u},
HTTPConfig: &commoncfg.HTTPClientConfig{},
}
notifier, err := New(conf, tmpl, logger)
require.NoError(t, err)

ctx := context.Background()
ctx = notify.WithGroupKey(ctx, "1")

expectedURL, _ := url.Parse("https://opsgenie/apiv2/alerts")

// Empty alert.
alert1 := &types.Alert{
Alert: model.Alert{
StartsAt: time.Now(),
EndsAt: time.Now().Add(time.Hour),
for _, tc := range []struct {
title string
cfg *config.OpsGenieConfig

expectedEmptyAlertBody string
expectedBody string
}{
{
title: "config without details",
cfg: &config.OpsGenieConfig{
NotifierConfig: config.NotifierConfig{
VSendResolved: true,
},
Message: `{{ .CommonLabels.Message }}`,
Description: `{{ .CommonLabels.Description }}`,
Source: `{{ .CommonLabels.Source }}`,
Responders: []config.OpsGenieConfigResponder{
{
Name: `{{ .CommonLabels.ResponderName1 }}`,
Type: `{{ .CommonLabels.ResponderType1 }}`,
},
{
Name: `{{ .CommonLabels.ResponderName2 }}`,
Type: `{{ .CommonLabels.ResponderType2 }}`,
},
},
Tags: `{{ .CommonLabels.Tags }}`,
Note: `{{ .CommonLabels.Note }}`,
Priority: `{{ .CommonLabels.Priority }}`,
APIKey: `{{ .ExternalURL }}`,
APIURL: &config.URL{URL: u},
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
expectedEmptyAlertBody: `{"alias":"6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b","message":"","details":{},"source":""}
`,
expectedBody: `{"alias":"6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b","message":"message","description":"description","details":{"Description":"description","Message":"message","Note":"this is a note","Priority":"P1","ResponderName1":"TeamA","ResponderName2":"EscalationA","ResponderType1":"team","ResponderType2":"escalation","Source":"http://prometheus","Tags":"tag1,tag2"},"source":"http://prometheus","responders":[{"name":"TeamA","type":"team"},{"name":"EscalationA","type":"escalation"}],"tags":["tag1","tag2"],"note":"this is a note","priority":"P1"}
`,
},
}
expectedBody := `{"alias":"6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b","message":"","details":{},"source":""}
`
req, retry, err := notifier.createRequest(ctx, alert1)
require.NoError(t, err)
require.Equal(t, true, retry)
require.Equal(t, expectedURL, req.URL)
require.Equal(t, "GenieKey http://am", req.Header.Get("Authorization"))
require.Equal(t, expectedBody, readBody(t, req))

// Fully defined alert.
alert2 := &types.Alert{
Alert: model.Alert{
Labels: model.LabelSet{
"Message": "message",
"Description": "description",
"Source": "http://prometheus",
"ResponderName1": "TeamA",
"ResponderType1": "team",
"ResponderName2": "EscalationA",
"ResponderType2": "escalation",
"Tags": "tag1,tag2",
"Note": "this is a note",
"Priority": "P1",
{
title: "config with details",
cfg: &config.OpsGenieConfig{
NotifierConfig: config.NotifierConfig{
VSendResolved: true,
},
Message: `{{ .CommonLabels.Message }}`,
Description: `{{ .CommonLabels.Description }}`,
Source: `{{ .CommonLabels.Source }}`,
Details: map[string]string{
"Description": `adjusted {{ .CommonLabels.Description }}`,
},
Responders: []config.OpsGenieConfigResponder{
{
Name: `{{ .CommonLabels.ResponderName1 }}`,
Type: `{{ .CommonLabels.ResponderType1 }}`,
},
{
Name: `{{ .CommonLabels.ResponderName2 }}`,
Type: `{{ .CommonLabels.ResponderType2 }}`,
},
},
Tags: `{{ .CommonLabels.Tags }}`,
Note: `{{ .CommonLabels.Note }}`,
Priority: `{{ .CommonLabels.Priority }}`,
APIKey: `{{ .ExternalURL }}`,
APIURL: &config.URL{URL: u},
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
StartsAt: time.Now(),
EndsAt: time.Now().Add(time.Hour),
expectedEmptyAlertBody: `{"alias":"6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b","message":"","details":{"Description":"adjusted "},"source":""}
`,
expectedBody: `{"alias":"6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b","message":"message","description":"description","details":{"Description":"adjusted description","Message":"message","Note":"this is a note","Priority":"P1","ResponderName1":"TeamA","ResponderName2":"EscalationA","ResponderType1":"team","ResponderType2":"escalation","Source":"http://prometheus","Tags":"tag1,tag2"},"source":"http://prometheus","responders":[{"name":"TeamA","type":"team"},{"name":"EscalationA","type":"escalation"}],"tags":["tag1","tag2"],"note":"this is a note","priority":"P1"}
`,
},
} {
t.Run(tc.title, func(t *testing.T) {
notifier, err := New(tc.cfg, tmpl, logger)
require.NoError(t, err)

ctx := context.Background()
ctx = notify.WithGroupKey(ctx, "1")

expectedURL, _ := url.Parse("https://opsgenie/apiv2/alerts")

// Empty alert.
alert1 := &types.Alert{
Alert: model.Alert{
StartsAt: time.Now(),
EndsAt: time.Now().Add(time.Hour),
},
}

req, retry, err := notifier.createRequest(ctx, alert1)
require.NoError(t, err)
require.Equal(t, true, retry)
require.Equal(t, expectedURL, req.URL)
require.Equal(t, "GenieKey http://am", req.Header.Get("Authorization"))
require.Equal(t, tc.expectedEmptyAlertBody, readBody(t, req))

// Fully defined alert.
alert2 := &types.Alert{
Alert: model.Alert{
Labels: model.LabelSet{
"Message": "message",
"Description": "description",
"Source": "http://prometheus",
"ResponderName1": "TeamA",
"ResponderType1": "team",
"ResponderName2": "EscalationA",
"ResponderType2": "escalation",
"Tags": "tag1,tag2",
"Note": "this is a note",
"Priority": "P1",
},
StartsAt: time.Now(),
EndsAt: time.Now().Add(time.Hour),
},
}
req, retry, err = notifier.createRequest(ctx, alert2)
require.NoError(t, err)
require.Equal(t, true, retry)
require.Equal(t, tc.expectedBody, readBody(t, req))

// Broken API Key Template.
tc.cfg.APIKey = "{{ kaput "
_, _, err = notifier.createRequest(ctx, alert2)
require.Error(t, err)
require.Equal(t, err.Error(), "templating error: template: :1: function \"kaput\" not defined")
})
}
expectedBody = `{"alias":"6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b","message":"message","description":"description","details":{},"source":"http://prometheus","responders":[{"name":"TeamA","type":"team"},{"name":"EscalationA","type":"escalation"}],"tags":["tag1","tag2"],"note":"this is a note","priority":"P1"}
`
req, retry, err = notifier.createRequest(ctx, alert2)
require.NoError(t, err)
require.Equal(t, true, retry)
require.Equal(t, expectedBody, readBody(t, req))

// Broken API Key Template.
conf.APIKey = "{{ kaput "
_, _, err = notifier.createRequest(ctx, alert2)
require.Error(t, err)
require.Equal(t, err.Error(), "templating error: template: :1: function \"kaput\" not defined")
}

func readBody(t *testing.T, r *http.Request) string {
Expand Down

0 comments on commit 6d77929

Please sign in to comment.