diff --git a/config/notifiers.go b/config/notifiers.go index b5cc6c7151..aec8e221c0 100644 --- a/config/notifiers.go +++ b/config/notifiers.go @@ -469,7 +469,7 @@ type OpsGenieConfig struct { UpdateAlerts bool `yaml:"update_alerts,omitempty" json:"update_alerts,omitempty"` } -const opsgenieValidTypesRe = `^(team|user|escalation|schedule)$` +const opsgenieValidTypesRe = `^(team|teams|user|escalation|schedule)$` var opsgenieTypeMatcher = regexp.MustCompile(opsgenieValidTypesRe) diff --git a/docs/configuration.md b/docs/configuration.md index 9272584916..62d6f9c7e7 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -556,7 +556,7 @@ responders: [ name: ] [ username: ] -# "team", "user", "escalation" or "schedule". +# "team", "teams, "user", "escalation" or "schedule". type: ``` diff --git a/notify/opsgenie/opsgenie.go b/notify/opsgenie/opsgenie.go index 19fb4c14b6..89ae217d32 100644 --- a/notify/opsgenie/opsgenie.go +++ b/notify/opsgenie/opsgenie.go @@ -192,6 +192,18 @@ func (n *Notifier) createRequests(ctx context.Context, as ...*types.Alert) ([]*h continue } + if responder.Type == "teams" { + teams := safeSplit(responder.Name, ",") + for _, team := range teams { + newResponder := opsGenieCreateMessageResponder{ + Name: tmpl(team), + Type: tmpl("team"), + } + responders = append(responders, newResponder) + } + continue + } + responders = append(responders, responder) } diff --git a/notify/opsgenie/opsgenie_test.go b/notify/opsgenie/opsgenie_test.go index 0532269c43..86955e5329 100644 --- a/notify/opsgenie/opsgenie_test.go +++ b/notify/opsgenie/opsgenie_test.go @@ -137,7 +137,7 @@ func TestOpsGenie(t *testing.T) { }, 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":"message","description":"description","details":{"Description":"description","Message":"message","Note":"this is a note","Priority":"P1","ResponderName1":"TeamA","ResponderName2":"EscalationA","ResponderName3":"TeamA,TeamB","ResponderType1":"team","ResponderType2":"escalation","ResponderType3":"teams","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"} `, }, { @@ -171,7 +171,37 @@ func TestOpsGenie(t *testing.T) { }, 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"} + expectedBody: `{"alias":"6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b","message":"message","description":"description","details":{"Description":"adjusted description","Message":"message","Note":"this is a note","Priority":"P1","ResponderName1":"TeamA","ResponderName2":"EscalationA","ResponderName3":"TeamA,TeamB","ResponderType1":"team","ResponderType2":"escalation","ResponderType3":"teams","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"} +`, + }, + { + title: "config with multiple teams", + 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.ResponderName3 }}`, + Type: `{{ .CommonLabels.ResponderType3 }}`, + }, + }, + Tags: `{{ .CommonLabels.Tags }}`, + Note: `{{ .CommonLabels.Note }}`, + Priority: `{{ .CommonLabels.Priority }}`, + APIKey: `{{ .ExternalURL }}`, + APIURL: &config.URL{URL: u}, + HTTPConfig: &commoncfg.HTTPClientConfig{}, + }, + 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","ResponderName3":"TeamA,TeamB","ResponderType1":"team","ResponderType2":"escalation","ResponderType3":"teams","Source":"http://prometheus","Tags":"tag1,tag2"},"source":"http://prometheus","responders":[{"name":"TeamA","type":"team"},{"name":"TeamB","type":"team"}],"tags":["tag1","tag2"],"note":"this is a note","priority":"P1"} `, }, } { @@ -211,6 +241,8 @@ func TestOpsGenie(t *testing.T) { "ResponderType1": "team", "ResponderName2": "EscalationA", "ResponderType2": "escalation", + "ResponderName3": "TeamA,TeamB", + "ResponderType3": "teams", "Tags": "tag1,tag2", "Note": "this is a note", "Priority": "P1",