Skip to content
This repository was archived by the owner on Jan 15, 2024. It is now read-only.

Commit ac1c246

Browse files
committed
Add string-based For field and convert from ForDuration
1 parent 4467425 commit ac1c246

File tree

2 files changed

+57
-5
lines changed

2 files changed

+57
-5
lines changed

alerting_alert_rule.go

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ type AlertRule struct {
2222
Title string `json:"title"`
2323
UID string `json:"uid,omitempty"`
2424
Updated time.Time `json:"updated"`
25-
ForDuration time.Duration `json:"for"`
25+
For string `json:"for"`
26+
ForDuration time.Duration `json:"-"`
2627
Provenance string `json:"provenance"`
2728
}
2829

@@ -82,6 +83,7 @@ func (c *Client) AlertRuleGroup(folderUID string, name string) (RuleGroup, error
8283

8384
// SetAlertRuleGroup overwrites an existing rule group on the server.
8485
func (c *Client) SetAlertRuleGroup(group RuleGroup) error {
86+
syncCalculatedRuleGroupFields(&group)
8587
folderUID := group.FolderUID
8688
name := group.Title
8789
req, err := json.Marshal(group)
@@ -95,6 +97,7 @@ func (c *Client) SetAlertRuleGroup(group RuleGroup) error {
9597

9698
// NewAlertRule creates a new alert rule and returns its UID.
9799
func (c *Client) NewAlertRule(ar *AlertRule) (string, error) {
100+
syncCalculatedRuleFields(ar)
98101
req, err := json.Marshal(ar)
99102
if err != nil {
100103
return "", err
@@ -109,6 +112,7 @@ func (c *Client) NewAlertRule(ar *AlertRule) (string, error) {
109112

110113
// UpdateAlertRule replaces an alert rule, identified by the alert rule's UID.
111114
func (c *Client) UpdateAlertRule(ar *AlertRule) error {
115+
syncCalculatedRuleFields(ar)
112116
uri := fmt.Sprintf("/api/v1/provisioning/alert-rules/%s", ar.UID)
113117
req, err := json.Marshal(ar)
114118
if err != nil {
@@ -123,3 +127,50 @@ func (c *Client) DeleteAlertRule(uid string) error {
123127
uri := fmt.Sprintf("/api/v1/provisioning/alert-rules/%s", uid)
124128
return c.request("DELETE", uri, nil, nil, nil)
125129
}
130+
131+
func syncCalculatedRuleGroupFields(group *RuleGroup) {
132+
for i := range group.Rules {
133+
syncCalculatedRuleFields(&group.Rules[i])
134+
}
135+
}
136+
137+
func syncCalculatedRuleFields(rule *AlertRule) {
138+
// rule.For is the newer field. Older systems may not provide the value.
139+
// If the user provided a For, prefer that over whatever we might calculate.
140+
// Otherwise, translate the time.Duration-based field to the format that the rule API expects.
141+
if rule.For == "" {
142+
rule.For = timeDurationToRuleDuration(rule.ForDuration)
143+
}
144+
}
145+
146+
// timeDurationToRuleDuration converts a typical time.Duration to the string-based format that alert rules expect.
147+
func timeDurationToRuleDuration(d time.Duration) string {
148+
ms := int64(d / time.Millisecond)
149+
if ms == 0 {
150+
return "0s"
151+
}
152+
153+
r := ""
154+
f := func(unit string, mult int64, exact bool) {
155+
if exact && ms%mult != 0 {
156+
return
157+
}
158+
if v := ms / mult; v > 0 {
159+
r += fmt.Sprintf("%d%s", v, unit)
160+
ms -= v * mult
161+
}
162+
}
163+
164+
// Only format years and weeks if the remainder is zero, as it is often
165+
// easier to read 90d than 12w6d.
166+
f("y", 1000*60*60*24*365, true)
167+
f("w", 1000*60*60*24*7, true)
168+
169+
f("d", 1000*60*60*24, false)
170+
f("h", 1000*60*60, false)
171+
f("m", 1000*60, false)
172+
f("s", 1000, false)
173+
f("ms", 1, false)
174+
175+
return r
176+
}

alerting_alert_rule_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package gapi
33
import (
44
"encoding/json"
55
"testing"
6+
"time"
67

78
"github.com/gobs/pretty"
89
)
@@ -138,7 +139,7 @@ func createAlertRule() AlertRule {
138139
OrgID: 1,
139140
RuleGroup: "eval_group_1",
140141
Title: "Always in alarm",
141-
ForDuration: 0,
142+
ForDuration: 60 * time.Second,
142143
}
143144
}
144145

@@ -165,7 +166,7 @@ const writeAlertRuleJSON = `
165166
"orgId": 1,
166167
"ruleGroup": "eval_group_1",
167168
"title": "Always in alarm",
168-
"for": 0
169+
"for": "1m"
169170
}
170171
`
171172

@@ -180,7 +181,7 @@ const getAlertRuleJSON = `
180181
"uid": "123abcd",
181182
"ruleGroup": "eval_group_1",
182183
"title": "Always in alarm",
183-
"for": 0
184+
"for": "1m"
184185
}
185186
`
186187

@@ -266,7 +267,7 @@ const getAlertRuleGroupJSON = `
266267
"RuleGroupIndex": 1,
267268
"NoDataState": "NoData",
268269
"ExecErrState": "Alerting",
269-
"For": 300000000000,
270+
"For": "1m",
270271
"Annotations": {},
271272
"Labels": {}
272273
}

0 commit comments

Comments
 (0)