diff --git a/examples/jiralert.yml b/examples/jiralert.yml index da9b0b8..8776a71 100644 --- a/examples/jiralert.yml +++ b/examples/jiralert.yml @@ -56,7 +56,9 @@ receivers: # # Automatically resolve jira issues when alert is resolved. Optional. If declared, ensure state is not an empty string. auto_resolve: - state: 'Done' + state: 'Done' + # Include ticket update as comment. Optional (default: false). + update_in_comment: false # File containing template definitions. Required. template: jiralert.tmpl diff --git a/pkg/config/config.go b/pkg/config/config.go index 71ba2b8..2b8dd99 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -149,6 +149,9 @@ type ReceiverConfig struct { // Label copy settings AddGroupLabels bool `yaml:"add_group_labels" json:"add_group_labels"` + // Flag to enable updates in comments. + UpdateInComment bool `yaml:"update_in_comment" json:"update_in_comment"` + // Flag to auto-resolve opened issue when the alert is resolved. AutoResolve *AutoResolve `yaml:"auto_resolve" json:"auto_resolve"` diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index d851f72..222e148 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -56,6 +56,7 @@ receivers: project: AB # Copy all Prometheus labels into separate JIRA labels. Optional (default: false). add_group_labels: false + update_in_comment: false static_labels: ["somelabel"] - name: 'jira-xy' @@ -128,6 +129,7 @@ type receiverTestConfig struct { Description string `yaml:"description,omitempty"` WontFixResolution string `yaml:"wont_fix_resolution,omitempty"` AddGroupLabels bool `yaml:"add_group_labels,omitempty"` + UpdateInComment bool `yaml:"update_in_comment,omitempty"` StaticLabels []string `yaml:"static_labels" json:"static_labels"` AutoResolve *AutoResolve `yaml:"auto_resolve" json:"auto_resolve"` @@ -330,6 +332,8 @@ func TestReceiverOverrides(t *testing.T) { {"Description", "A nice description", "A nice description"}, {"WontFixResolution", "Won't Fix", "Won't Fix"}, {"AddGroupLabels", false, false}, + {"UpdateInComment", false, false}, + {"UpdateInComment", true, true}, {"AutoResolve", &AutoResolve{State: "Done"}, &autoResolve}, {"StaticLabels", []string{"somelabel"}, []string{"somelabel"}}, } { diff --git a/pkg/notify/notify.go b/pkg/notify/notify.go index 3f07a45..b24ab55 100644 --- a/pkg/notify/notify.go +++ b/pkg/notify/notify.go @@ -40,6 +40,7 @@ type jiraIssueService interface { Create(issue *jira.Issue) (*jira.Issue, *jira.Response, error) UpdateWithOptions(issue *jira.Issue, opts *jira.UpdateQueryOptions) (*jira.Issue, *jira.Response, error) + AddComment(issueID string, comment *jira.Comment) (*jira.Comment, *jira.Response, error) DoTransition(ticketID, transitionID string) (*jira.Response, error) } @@ -112,6 +113,13 @@ func (r *Receiver) Notify(data *alertmanager.Data, hashJiraLabel bool, updateSum } } + if r.conf.UpdateInComment { + retry, err := r.addComment(issue.Key, issueDesc) + if err != nil { + return retry, err + } + } + if len(data.Alerts.Firing()) == 0 { if r.conf.AutoResolve != nil { level.Debug(r.logger).Log("msg", "no firing alert; resolving issue", "key", issue.Key, "label", issueGroupLabel) @@ -370,6 +378,21 @@ func (r *Receiver) updateDescription(issueKey string, description string) (bool, return false, nil } +func (r *Receiver) addComment(issueKey string, content string) (bool, error) { + level.Debug(r.logger).Log("msg", "adding comment to existing issue", "key", issueKey, "content", content) + + commentDetails := &jira.Comment{ + Body: content, + } + + comment, resp, err := r.client.AddComment(issueKey, commentDetails) + if err != nil { + return handleJiraErrResponse("Issue.AddComment", resp, err, r.logger) + } + level.Debug(r.logger).Log("msg", "added comment to issue", "key", issueKey, "id", comment.ID) + return false, nil +} + func (r *Receiver) reopen(issueKey string) (bool, error) { return r.doTransition(issueKey, r.conf.ReopenState) } diff --git a/pkg/notify/notify_test.go b/pkg/notify/notify_test.go index 3390f56..bd3d022 100644 --- a/pkg/notify/notify_test.go +++ b/pkg/notify/notify_test.go @@ -134,6 +134,11 @@ func (f *fakeJira) UpdateWithOptions(old *jira.Issue, _ *jira.UpdateQueryOptions return issue, nil, nil } +func (f *fakeJira) AddComment(issueID string, comment *jira.Comment) (*jira.Comment, *jira.Response, error) { + // This is a placeholder to keep fakeJira compatible with the updated Interface + return nil, nil, nil +} + func (f *fakeJira) DoTransition(ticketID, transitionID string) (*jira.Response, error) { issue, ok := f.issuesByKey[ticketID] if !ok {