Skip to content

Commit 0e848dc

Browse files
committed
implementing changes recommended by owner for a new PR
implementing changes recommended by owner for a new PR implementing changes recommended by owner for a new PR
1 parent 7e58824 commit 0e848dc

File tree

3 files changed

+113
-19
lines changed

3 files changed

+113
-19
lines changed

cmd/jiralert/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ import (
99
"runtime"
1010
"strconv"
1111

12+
_ "net/http/pprof"
13+
1214
"github.com/free/jiralert"
1315
"github.com/free/jiralert/alertmanager"
1416
log "github.com/golang/glog"
1517
"github.com/prometheus/client_golang/prometheus/promhttp"
16-
_ "net/http/pprof"
1718
)
1819

1920
const (

config.go

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import (
55
"io/ioutil"
66
"net/url"
77
"path/filepath"
8+
"regexp"
9+
"strconv"
810
"strings"
11+
"time"
912

1013
log "github.com/golang/glog"
1114
"github.com/trivago/tgo/tcontainer"
@@ -93,7 +96,7 @@ type ReceiverConfig struct {
9396
WontFixResolution string `yaml:"wont_fix_resolution" json:"wont_fix_resolution"`
9497
Fields map[string]interface{} `yaml:"fields" json:"fields"`
9598
Components []string `yaml:"components" json:"components"`
96-
ReopenDuration string `yaml:"reopen_duration" json:"reopen_duration"`
99+
ReopenDuration *Duration `yaml:"reopen_duration" json:"reopen_duration"`
97100

98101
// Label copy settings
99102
AddGroupLabels bool `yaml:"add_group_labels" json:"add_group_labels"`
@@ -199,6 +202,12 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {
199202
}
200203
rc.ReopenState = c.Defaults.ReopenState
201204
}
205+
if rc.ReopenDuration == nil {
206+
if c.Defaults.ReopenDuration == nil {
207+
return fmt.Errorf("missing reopen_duration in receiver %q", rc.Name)
208+
}
209+
rc.ReopenDuration = c.Defaults.ReopenDuration
210+
}
202211

203212
// Populate optional issue fields, where necessary
204213
if rc.Priority == "" && c.Defaults.Priority != "" {
@@ -250,3 +259,91 @@ func checkOverflow(m map[string]interface{}, ctx string) error {
250259
}
251260
return nil
252261
}
262+
263+
type Duration time.Duration
264+
265+
var durationRE = regexp.MustCompile("^([0-9]+)(y|w|d|h|m|s|ms)$")
266+
267+
// ParseDuration parses a string into a time.Duration, assuming that a year
268+
// always has 365d, a week always has 7d, and a day always has 24h.
269+
func ParseDuration(durationStr string) (Duration, error) {
270+
matches := durationRE.FindStringSubmatch(durationStr)
271+
if len(matches) != 3 {
272+
return 0, fmt.Errorf("not a valid duration string: %q", durationStr)
273+
}
274+
var (
275+
n, _ = strconv.Atoi(matches[1])
276+
dur = time.Duration(n) * time.Millisecond
277+
)
278+
switch unit := matches[2]; unit {
279+
case "y":
280+
dur *= 1000 * 60 * 60 * 24 * 365
281+
case "w":
282+
dur *= 1000 * 60 * 60 * 24 * 7
283+
case "d":
284+
dur *= 1000 * 60 * 60 * 24
285+
case "h":
286+
dur *= 1000 * 60 * 60
287+
case "m":
288+
dur *= 1000 * 60
289+
case "s":
290+
dur *= 1000
291+
case "ms":
292+
// Value already correct
293+
default:
294+
return 0, fmt.Errorf("invalid time unit in duration string: %q", unit)
295+
}
296+
return Duration(dur), nil
297+
}
298+
299+
func (d Duration) String() string {
300+
var (
301+
ms = int64(time.Duration(d) / time.Millisecond)
302+
unit = "ms"
303+
)
304+
if ms == 0 {
305+
return "0s"
306+
}
307+
factors := map[string]int64{
308+
"y": 1000 * 60 * 60 * 24 * 365,
309+
"w": 1000 * 60 * 60 * 24 * 7,
310+
"d": 1000 * 60 * 60 * 24,
311+
"h": 1000 * 60 * 60,
312+
"m": 1000 * 60,
313+
"s": 1000,
314+
"ms": 1,
315+
}
316+
317+
switch int64(0) {
318+
case ms % factors["y"]:
319+
unit = "y"
320+
case ms % factors["w"]:
321+
unit = "w"
322+
case ms % factors["d"]:
323+
unit = "d"
324+
case ms % factors["h"]:
325+
unit = "h"
326+
case ms % factors["m"]:
327+
unit = "m"
328+
case ms % factors["s"]:
329+
unit = "s"
330+
}
331+
return fmt.Sprintf("%v%v", ms/factors[unit], unit)
332+
}
333+
334+
func (d Duration) MarshalYAML() (interface{}, error) {
335+
return d.String(), nil
336+
}
337+
338+
func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error {
339+
var s string
340+
if err := unmarshal(&s); err != nil {
341+
return err
342+
}
343+
dur, err := ParseDuration(s)
344+
if err != nil {
345+
return err
346+
}
347+
*d = Duration(dur)
348+
return nil
349+
}

notify.go

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"fmt"
66
"io/ioutil"
7-
"net/http"
87
"reflect"
98
"strings"
109
"time"
@@ -24,11 +23,14 @@ type Receiver struct {
2423

2524
// NewReceiver creates a Receiver using the provided configuration and template.
2625
func NewReceiver(c *ReceiverConfig, t *Template) (*Receiver, error) {
27-
client, err := jira.NewClient(http.DefaultClient, c.APIURL)
26+
tp := jira.BasicAuthTransport{
27+
Username: c.User,
28+
Password: string(c.Password),
29+
}
30+
client, err := jira.NewClient(tp.Client(), c.APIURL)
2831
if err != nil {
2932
return nil, err
3033
}
31-
client.Authentication.SetBasicAuth(c.User, string(c.Password))
3234

3335
return &Receiver{conf: c, tmpl: t, client: client}, nil
3436
}
@@ -62,14 +64,8 @@ func (r *Receiver) Notify(data *alertmanager.Data) (bool, error) {
6264
return false, nil
6365
}
6466

65-
reopenDuration, err := time.ParseDuration(r.conf.ReopenDuration)
66-
if err != nil {
67-
log.Errorf("Unable to parse reopen duration: %v", err)
68-
return false, err
69-
}
70-
7167
resolutionTime := time.Time(issue.Fields.Resolutiondate)
72-
if resolutionTime.Add(reopenDuration).After(time.Now()) {
68+
if resolutionTime.Add(time.Duration(*r.conf.ReopenDuration)).After(time.Now()) {
7369
log.Infof("Issue %s for %s was resolved on %s, reopening", issue.Key, issueLabel, resolutionTime.Format(time.UnixDate))
7470
return r.reopen(issue.Key)
7571
}
@@ -96,7 +92,7 @@ func (r *Receiver) Notify(data *alertmanager.Data) (bool, error) {
9692
if len(r.conf.Components) > 0 {
9793
issue.Fields.Components = make([]*jira.Component, 0, len(r.conf.Components))
9894
for _, component := range r.conf.Components {
99-
issue.Fields.Components = append(issue.Fields.Components, &jira.Component{Name: component})
95+
issue.Fields.Components = append(issue.Fields.Components, &jira.Component{Name: r.tmpl.Execute(component, data)})
10096
}
10197
}
10298

@@ -178,7 +174,7 @@ func (r *Receiver) search(project, issueLabel string) (*jira.Issue, bool, error)
178174
query := fmt.Sprintf("project=\"%s\" and labels=%q order by key", project, issueLabel)
179175
options := &jira.SearchOptions{
180176
Fields: []string{"summary", "status", "resolution", "resolutiondate"},
181-
MaxResults: 50,
177+
MaxResults: 2,
182178
}
183179
log.V(1).Infof("search: query=%v options=%+v", query, options)
184180
issues, resp, err := r.client.Issue.Search(query, options)
@@ -188,13 +184,12 @@ func (r *Receiver) search(project, issueLabel string) (*jira.Issue, bool, error)
188184
}
189185
if len(issues) > 0 {
190186
if len(issues) > 1 {
191-
// Swallow it, but log an error.
187+
// Swallow it, but log a message.
192188
log.Infof("More than one issue matched %s, will only update last issue: %+v", query, issues)
193189
}
194190

195-
lastIndex := len(issues) - 1
196-
log.V(1).Infof(" found: %+v", issues[lastIndex])
197-
return &issues[lastIndex], false, nil
191+
log.V(1).Infof(" found: %+v", issues[0])
192+
return &issues[0], false, nil
198193
}
199194
log.V(1).Infof(" no results")
200195
return nil, false, nil
@@ -221,10 +216,11 @@ func (r *Receiver) reopen(issueKey string) (bool, error) {
221216

222217
func (r *Receiver) create(issue *jira.Issue) (bool, error) {
223218
log.V(1).Infof("create: issue=%v", *issue)
224-
issue, resp, err := r.client.Issue.Create(issue)
219+
newIssue, resp, err := r.client.Issue.Create(issue)
225220
if err != nil {
226221
return handleJiraError("Issue.Create", resp, err)
227222
}
223+
*issue = *newIssue
228224

229225
log.V(1).Infof(" done: key=%s ID=%s", issue.Key, issue.ID)
230226
return false, nil

0 commit comments

Comments
 (0)