From d38ac63f22e2b58f932e8373bce57e4fdf3901ea Mon Sep 17 00:00:00 2001 From: George Robinson Date: Mon, 7 Nov 2022 17:07:07 +0000 Subject: [PATCH] Alerting: Append org ID to alert notification URLs (#57123) (#58349) (cherry picked from commit db1fd10ff13d936665210e0c8a86c50ecae09998) Co-authored-by: Neel <47709856+neel1996@users.noreply.github.com> --- pkg/services/ngalert/models/alert_rule.go | 1 + .../channels/default_template_test.go | 30 +++++++++---------- .../notifier/channels/template_data.go | 27 +++++++++++++++++ pkg/services/ngalert/schedule/compat.go | 5 ++++ .../alerting/api_notification_channel_test.go | 5 ++-- 5 files changed, 51 insertions(+), 17 deletions(-) diff --git a/pkg/services/ngalert/models/alert_rule.go b/pkg/services/ngalert/models/alert_rule.go index 163503cc048..0cd7dedce9e 100644 --- a/pkg/services/ngalert/models/alert_rule.go +++ b/pkg/services/ngalert/models/alert_rule.go @@ -86,6 +86,7 @@ const ( // Annotations are actually a set of labels, so technically this is the label name of an annotation. DashboardUIDAnnotation = "__dashboardUid__" PanelIDAnnotation = "__panelId__" + OrgIDAnnotation = "__orgId__" // This isn't a hard-coded secret token, hence the nolint. //nolint:gosec diff --git a/pkg/services/ngalert/notifier/channels/default_template_test.go b/pkg/services/ngalert/notifier/channels/default_template_test.go index 6f2827c9076..b331ace96ec 100644 --- a/pkg/services/ngalert/notifier/channels/default_template_test.go +++ b/pkg/services/ngalert/notifier/channels/default_template_test.go @@ -20,11 +20,11 @@ func TestDefaultTemplateString(t *testing.T) { Alert: model.Alert{ Labels: model.LabelSet{"alertname": "alert1", "lbl1": "val1"}, Annotations: model.LabelSet{ - "ann1": "annv1", "__dashboardUid__": "dbuid123", "__panelId__": "puid123", "__value_string__": "1234", + "ann1": "annv1", "__orgId__": "1", "__dashboardUid__": "dbuid123", "__panelId__": "puid123", "__values__": "{\"A\": 1234}", "__value_string__": "1234", }, StartsAt: time.Now(), EndsAt: time.Now().Add(1 * time.Hour), - GeneratorURL: "http://localhost/alert1", + GeneratorURL: "http://localhost/alert1?orgId=1", }, }, { // Firing without dashboard and panel ID. Alert: model.Alert{ @@ -38,7 +38,7 @@ func TestDefaultTemplateString(t *testing.T) { Alert: model.Alert{ Labels: model.LabelSet{"alertname": "alert1", "lbl1": "val3"}, Annotations: model.LabelSet{ - "ann1": "annv3", "__dashboardUid__": "dbuid456", "__panelId__": "puid456", "__value_string__": "1234", + "ann1": "annv3", "__orgId__": "1", "__dashboardUid__": "dbuid456", "__panelId__": "puid456", "__values__": "{\"A\": 1234}", "__value_string__": "1234", }, StartsAt: time.Now().Add(-1 * time.Hour), EndsAt: time.Now().Add(-30 * time.Minute), @@ -97,10 +97,10 @@ Labels: - lbl1 = val1 Annotations: - ann1 = annv1 -Source: http://localhost/alert1 +Source: http://localhost/alert1?orgId=1 Silence: http://localhost/grafana/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval1 -Dashboard: http://localhost/grafana/d/dbuid123 -Panel: http://localhost/grafana/d/dbuid123?viewPanel=puid123 +Dashboard: http://localhost/grafana/d/dbuid123?orgId=1 +Panel: http://localhost/grafana/d/dbuid123?orgId=1&viewPanel=puid123 Value: 1234 Labels: @@ -120,10 +120,10 @@ Labels: - lbl1 = val3 Annotations: - ann1 = annv3 -Source: http://localhost/alert3 +Source: http://localhost/alert3?orgId=1 Silence: http://localhost/grafana/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval3 -Dashboard: http://localhost/grafana/d/dbuid456 -Panel: http://localhost/grafana/d/dbuid456?viewPanel=puid456 +Dashboard: http://localhost/grafana/d/dbuid456?orgId=1 +Panel: http://localhost/grafana/d/dbuid456?orgId=1&viewPanel=puid456 Value: 1234 Labels: @@ -147,13 +147,13 @@ Labels: Annotations: - ann1 = annv1 -Source: [http://localhost/alert1](http://localhost/alert1) +Source: [http://localhost/alert1?orgId=1](http://localhost/alert1?orgId=1) Silence: [http://localhost/grafana/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval1](http://localhost/grafana/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval1) -Dashboard: [http://localhost/grafana/d/dbuid123](http://localhost/grafana/d/dbuid123) +Dashboard: [http://localhost/grafana/d/dbuid123?orgId=1](http://localhost/grafana/d/dbuid123?orgId=1) -Panel: [http://localhost/grafana/d/dbuid123?viewPanel=puid123](http://localhost/grafana/d/dbuid123?viewPanel=puid123) +Panel: [http://localhost/grafana/d/dbuid123?orgId=1&viewPanel=puid123](http://localhost/grafana/d/dbuid123?orgId=1&viewPanel=puid123) @@ -182,13 +182,13 @@ Labels: Annotations: - ann1 = annv3 -Source: [http://localhost/alert3](http://localhost/alert3) +Source: [http://localhost/alert3?orgId=1](http://localhost/alert3?orgId=1) Silence: [http://localhost/grafana/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval3](http://localhost/grafana/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval3) -Dashboard: [http://localhost/grafana/d/dbuid456](http://localhost/grafana/d/dbuid456) +Dashboard: [http://localhost/grafana/d/dbuid456?orgId=1](http://localhost/grafana/d/dbuid456?orgId=1) -Panel: [http://localhost/grafana/d/dbuid456?viewPanel=puid456](http://localhost/grafana/d/dbuid456?viewPanel=puid456) +Panel: [http://localhost/grafana/d/dbuid456?orgId=1&viewPanel=puid456](http://localhost/grafana/d/dbuid456?orgId=1&viewPanel=puid456) diff --git a/pkg/services/ngalert/notifier/channels/template_data.go b/pkg/services/ngalert/notifier/channels/template_data.go index c021d8ecc37..8a14d606a4d 100644 --- a/pkg/services/ngalert/notifier/channels/template_data.go +++ b/pkg/services/ngalert/notifier/channels/template_data.go @@ -87,6 +87,25 @@ func extendAlert(alert template.Alert, externalURL string, logger log.Logger) *E u.RawQuery = "viewPanel=" + panelId extended.PanelURL = u.String() } + + generatorUrl, err := url.Parse(extended.GeneratorURL) + if err != nil { + logger.Debug("failed to parse generator URL while extending template data", "url", extended.GeneratorURL, "err", err.Error()) + return extended + } + + dashboardUrl, err := url.Parse(extended.DashboardURL) + if err != nil { + logger.Debug("failed to parse dashboard URL while extending template data", "url", extended.DashboardURL, "err", err.Error()) + return extended + } + + orgId := alert.Annotations[ngmodels.OrgIDAnnotation] + if len(orgId) > 0 { + extended.DashboardURL = setOrgIdQueryParam(dashboardUrl, orgId) + extended.PanelURL = setOrgIdQueryParam(u, orgId) + extended.GeneratorURL = setOrgIdQueryParam(generatorUrl, orgId) + } } if alert.Annotations != nil { @@ -115,6 +134,14 @@ func extendAlert(alert template.Alert, externalURL string, logger log.Logger) *E return extended } +func setOrgIdQueryParam(url *url.URL, orgId string) string { + q := url.Query() + q.Set("orgId", orgId) + url.RawQuery = q.Encode() + + return url.String() +} + func ExtendData(data *template.Data, logger log.Logger) *ExtendedData { alerts := []ExtendedAlert{} diff --git a/pkg/services/ngalert/schedule/compat.go b/pkg/services/ngalert/schedule/compat.go index 4aa597a9c28..99c325a4c29 100644 --- a/pkg/services/ngalert/schedule/compat.go +++ b/pkg/services/ngalert/schedule/compat.go @@ -4,6 +4,7 @@ import ( "fmt" "net/url" "path" + "strconv" "time" "github.com/benbjohnson/clock" @@ -47,6 +48,10 @@ func stateToPostableAlert(alertState *state.State, appURL *url.URL) *models.Post nA[ngModels.StateReasonAnnotation] = alertState.StateReason } + if alertState.OrgID != 0 { + nA[ngModels.OrgIDAnnotation] = strconv.FormatInt(alertState.OrgID, 10) + } + var urlStr string if uid := nL[ngModels.RuleUIDLabel]; len(uid) > 0 && appURL != nil { u := *appURL diff --git a/pkg/tests/api/alerting/api_notification_channel_test.go b/pkg/tests/api/alerting/api_notification_channel_test.go index f8bbef7d2fd..0beeca1875b 100644 --- a/pkg/tests/api/alerting/api_notification_channel_test.go +++ b/pkg/tests/api/alerting/api_notification_channel_test.go @@ -2634,8 +2634,9 @@ var expNonEmailNotifications = map[string][]string{ "grafana_folder": "default" }, "annotations": { - "__value_string__": "[ var='A' labels={} value=1 ]" - }, + "__orgId__":"1", + "__value_string__": "[ var='A' labels={} value=1 ]" + }, "startsAt": "%s", "endsAt": "0001-01-01T00:00:00Z", "generatorURL": "http://localhost:3000/alerting/grafana/UID_AlertmanagerAlert/view",