Repository: prometheus/alertmanager
Pull request #4159 (2024-12-06 18:55:07)

Enable templating for Jira project and issue_type
Update Jira notifications to support templating in `project` and `issue_type`.

I'd like to be able to open issues in multiple Jira projects with different priorities and issue types depending on the alert labels or annotations.

Some Jira fields, like `summary` and `priority`, already allow templating, but it's missing in these two.


Patch:
diff --git a/notify/jira/jira.go b/notify/jira/jira.go
index 00d67027..02c75295 100644
--- a/notify/jira/jira.go
+++ b/notify/jira/jira.go
@@ -124,6 +124,14 @@ func (n *Notifier) prepareIssueRequestBody(ctx context.Context, logger *slog.Log
 	if err != nil {
 		return issue{}, fmt.Errorf("summary template: %w", err)
 	}
+	project, err := tmplTextFunc(n.conf.Project)
+	if err != nil {
+		return issue{}, fmt.Errorf("project template: %w", err)
+	}
+	issueType, err := tmplTextFunc(n.conf.IssueType)
+	if err != nil {
+		return issue{}, fmt.Errorf("issue_type template: %w", err)
+	}
 
 	// Recursively convert any maps to map[string]interface{}, filtering out all non-string keys, so the json encoder
 	// doesn't blow up when marshaling JIRA requests.
@@ -138,8 +146,8 @@ func (n *Notifier) prepareIssueRequestBody(ctx context.Context, logger *slog.Log
 	}
 
 	requestBody := issue{Fields: &issueFields{
-		Project:   &issueProject{Key: n.conf.Project},
-		Issuetype: &idNameValue{Name: n.conf.IssueType},
+		Project:   &issueProject{Key: project},
+		Issuetype: &idNameValue{Name: issueType},
 		Summary:   summary,
 		Labels:    make([]string, 0, len(n.conf.Labels)+1),
 		Fields:    fieldsWithStringKeys,


Test patch:
diff --git a/notify/jira/jira_test.go b/notify/jira/jira_test.go
index fd2583a1..1c728b6c 100644
--- a/notify/jira/jira_test.go
+++ b/notify/jira/jira_test.go
@@ -95,6 +95,24 @@ func TestJiraTemplating(t *testing.T) {
 			},
 			retry: false,
 		},
+		{
+			title: "template project",
+			cfg: &config.JiraConfig{
+				Project:     `{{ .CommonLabels.lbl1 }}`,
+				Summary:     `{{ template "jira.default.summary" . }}`,
+				Description: `{{ template "jira.default.description" . }}`,
+			},
+			retry: false,
+		},
+		{
+			title: "template issue type",
+			cfg: &config.JiraConfig{
+				IssueType:   `{{ .CommonLabels.lbl1 }}`,
+				Summary:     `{{ template "jira.default.summary" . }}`,
+				Description: `{{ template "jira.default.description" . }}`,
+			},
+			retry: false,
+		},
 		{
 			title: "summary with templating errors",
 			cfg: &config.JiraConfig{
@@ -208,6 +226,51 @@ func TestJiraNotify(t *testing.T) {
 			customFieldAssetFn: func(t *testing.T, issue map[string]any) {},
 			errMsg:             "",
 		},
+		{
+			title: "create new issue with template project and issue type",
+			cfg: &config.JiraConfig{
+				Summary:           `{{ template "jira.default.summary" . }}`,
+				Description:       `{{ template "jira.default.description" . }}`,
+				IssueType:         "{{ .CommonLabels.issue_type }}",
+				Project:           "{{ .CommonLabels.project }}",
+				Priority:          `{{ template "jira.default.priority" . }}`,
+				Labels:            []string{"alertmanager", "{{ .GroupLabels.alertname }}"},
+				ReopenDuration:    model.Duration(1 * time.Hour),
+				ReopenTransition:  "REOPEN",
+				ResolveTransition: "CLOSE",
+				WontFixResolution: "WONTFIX",
+			},
+			alert: &types.Alert{
+				Alert: model.Alert{
+					Labels: model.LabelSet{
+						"alertname":  "test",
+						"instance":   "vm1",
+						"severity":   "critical",
+						"project":    "MONITORING",
+						"issue_type": "MINOR",
+					},
+					StartsAt: time.Now(),
+					EndsAt:   time.Now().Add(time.Hour),
+				},
+			},
+			searchResponse: issueSearchResult{
+				Total:  0,
+				Issues: []issue{},
+			},
+			issue: issue{
+				Key: "",
+				Fields: &issueFields{
+					Summary:     "[FIRING:1] test (vm1 MINOR MONITORING critical)",
+					Description: "\n\n# Alerts Firing:\n\nLabels:\n  - alertname = test\n  - instance = vm1\n  - issue_type = MINOR\n  - project = MONITORING\n  - severity = critical\n\nAnnotations:\n\nSource: \n\n\n\n\n",
+					Issuetype:   &idNameValue{Name: "MINOR"},
+					Labels:      []string{"ALERT{6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b}", "alertmanager", "test"},
+					Project:     &issueProject{Key: "MONITORING"},
+					Priority:    &idNameValue{Name: "High"},
+				},
+			},
+			customFieldAssetFn: func(t *testing.T, issue map[string]any) {},
+			errMsg:             "",
+		},
 		{
 			title: "create new issue with custom field and too long summary",
 			cfg: &config.JiraConfig{