Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions notify/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,11 @@ func GetTemplateData(ctx context.Context, tmpl *template.Template, alerts []*typ
notificationReason = ReasonUnknown
}
data := tmpl.Data(recv, groupLabels, routeLabels, notificationReason.String(), alerts...)
// Group key is optional for some callers (e.g. tests); populate when present
// so templates and webhook-style consumers can access .GroupKey.
if groupKey, ok := GroupKey(ctx); ok {
data.GroupKey = groupKey
}
// Route labels are pre-rendered by the dispatcher; don't execute them again.
template.MarkRouteLabelsRendered(data)
return data
Expand Down
29 changes: 29 additions & 0 deletions notify/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ func TestGetTemplateDataWithRouteLabels(t *testing.T) {

data := GetTemplateData(ctx, tmpl, nil, promslog.NewNopLogger())

require.Equal(t, "test-key", data.GroupKey)
require.Equal(t, "ops", data.RouteLabels["team"])
require.Equal(t, "value is {{ $value }}", data.RouteLabels["desc"])

Expand All @@ -253,6 +254,34 @@ func TestGetTemplateDataWithRouteLabels(t *testing.T) {
require.Equal(t, "ops|value is {{ $value }}", got)
}

func TestGetTemplateDataGroupKey(t *testing.T) {
tmpl, err := template.New()
require.NoError(t, err)
tmpl.ExternalURL = &url.URL{Scheme: "http", Host: "example.com"}

groupKey := `{}:{alertname="HighErrorRate"}`
ctx := context.Background()
ctx = WithReceiverName(ctx, "webhook")
ctx = WithGroupKey(ctx, groupKey)
ctx = WithGroupLabels(ctx, model.LabelSet{"alertname": "HighErrorRate"})
ctx = WithNotificationReason(ctx, ReasonFirstNotification)

data := GetTemplateData(ctx, tmpl, nil, promslog.NewNopLogger())
require.Equal(t, groupKey, data.GroupKey)

// Templates can reference .GroupKey like other Data fields.
got, err := tmpl.ExecuteTextString(`{{ .GroupKey }}`, data)
require.NoError(t, err)
require.Equal(t, groupKey, got)

// Missing group key leaves GroupKey empty without failing.
ctxNoKey := WithReceiverName(context.Background(), "webhook")
ctxNoKey = WithGroupLabels(ctxNoKey, model.LabelSet{"alertname": "HighErrorRate"})
ctxNoKey = WithNotificationReason(ctxNoKey, ReasonFirstNotification)
dataNoKey := GetTemplateData(ctxNoKey, tmpl, nil, promslog.NewNopLogger())
require.Empty(t, dataNoKey.GroupKey)
}

func TestGetFailureReasonFromStatusCode(t *testing.T) {
for _, tc := range []struct {
statusCode int
Expand Down
4 changes: 4 additions & 0 deletions template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,10 @@ type Data struct {
Status string `json:"status"`
Alerts Alerts `json:"alerts"`

// GroupKey is the grouping key of the alert group, matching the webhook
// payload field of the same name.
GroupKey string `json:"groupKey"`

NotificationReason string `json:"notification_reason"`

GroupLabels KV `json:"groupLabels"`
Expand Down