Skip to content

Commit 1dfd29a

Browse files
Alerting Notification Policies: Use OpenAPI client (#1229)
TODO after this is merged: - Support org-specific policies - Add `disable_provenance` feature
1 parent 58cfdc8 commit 1dfd29a

File tree

1 file changed

+38
-76
lines changed

1 file changed

+38
-76
lines changed

internal/resources/grafana/resource_alerting_notification_policy.go

Lines changed: 38 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ package grafana
22

33
import (
44
"context"
5-
"fmt"
65

7-
gapi "github.com/grafana/grafana-api-golang-client"
6+
"github.com/grafana/grafana-openapi-client-go/client/provisioning"
7+
"github.com/grafana/grafana-openapi-client-go/models"
88
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
99
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1010
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
@@ -25,9 +25,9 @@ Sets the global notification policy for Grafana.
2525
This resource requires Grafana 9.1.0 or later.
2626
`,
2727

28-
CreateContext: createNotificationPolicy,
28+
CreateContext: putNotificationPolicy,
2929
ReadContext: readNotificationPolicy,
30-
UpdateContext: updateNotificationPolicy,
30+
UpdateContext: putNotificationPolicy,
3131
DeleteContext: deleteNotificationPolicy,
3232
Importer: &schema.ResourceImporter{
3333
StateContext: schema.ImportStatePassthroughContext,
@@ -116,9 +116,10 @@ func policySchema(depth uint) *schema.Resource {
116116
Description: "The name of the label to match against.",
117117
},
118118
"match": {
119-
Type: schema.TypeString,
120-
Required: true,
121-
Description: "The operator to apply when matching values of the given label. Allowed operators are `=` for equality, `!=` for negated equality, `=~` for regex equality, and `!~` for negated regex equality.",
119+
Type: schema.TypeString,
120+
Required: true,
121+
Description: "The operator to apply when matching values of the given label. Allowed operators are `=` for equality, `!=` for negated equality, `=~` for regex equality, and `!~` for negated regex equality.",
122+
ValidateFunc: validation.StringInSlice([]string{"=", "!=", "=~", "!~"}, false),
122123
},
123124
"value": {
124125
Type: schema.TypeString,
@@ -172,69 +173,52 @@ func policySchema(depth uint) *schema.Resource {
172173
}
173174

174175
func readNotificationPolicy(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {
175-
client := meta.(*common.Client).DeprecatedGrafanaAPI
176+
client := OAPIGlobalClient(meta) // TODO: Support org-scoped policies
176177

177-
npt, err := client.NotificationPolicyTree()
178+
resp, err := client.Provisioning.GetPolicyTree()
178179
if err != nil {
179180
return diag.FromErr(err)
180181
}
181182

182-
packNotifPolicy(npt, data)
183+
packNotifPolicy(resp.Payload, data)
183184
data.SetId(PolicySingletonID)
184185
return nil
185186
}
186187

187-
func createNotificationPolicy(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {
188+
func putNotificationPolicy(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {
188189
lock := &meta.(*common.Client).AlertingMutex
189-
client := meta.(*common.Client).DeprecatedGrafanaAPI
190-
191-
npt, err := unpackNotifPolicy(data)
192-
if err != nil {
193-
return diag.FromErr(err)
194-
}
195-
196190
lock.Lock()
197191
defer lock.Unlock()
198-
if err := client.SetNotificationPolicyTree(&npt); err != nil {
199-
return diag.FromErr(err)
200-
}
201-
202-
data.SetId(PolicySingletonID)
203-
return readNotificationPolicy(ctx, data, meta)
204-
}
205-
206-
func updateNotificationPolicy(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {
207-
lock := &meta.(*common.Client).AlertingMutex
208-
client := meta.(*common.Client).DeprecatedGrafanaAPI
192+
client := OAPIGlobalClient(meta) // TODO: Support org-scoped policies
209193

210194
npt, err := unpackNotifPolicy(data)
211195
if err != nil {
212196
return diag.FromErr(err)
213197
}
214198

215-
lock.Lock()
216-
defer lock.Unlock()
217-
if err := client.SetNotificationPolicyTree(&npt); err != nil {
199+
params := provisioning.NewPutPolicyTreeParams().WithBody(npt)
200+
if _, err := client.Provisioning.PutPolicyTree(params); err != nil {
218201
return diag.FromErr(err)
219202
}
220203

204+
data.SetId(PolicySingletonID)
221205
return readNotificationPolicy(ctx, data, meta)
222206
}
223207

224208
func deleteNotificationPolicy(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {
225209
lock := &meta.(*common.Client).AlertingMutex
226-
client := meta.(*common.Client).DeprecatedGrafanaAPI
227-
228210
lock.Lock()
229211
defer lock.Unlock()
230-
if err := client.ResetNotificationPolicyTree(); err != nil {
212+
client := OAPIGlobalClient(meta) // TODO: Support org-scoped policies
213+
214+
if _, err := client.Provisioning.ResetPolicyTree(); err != nil {
231215
return diag.FromErr(err)
232216
}
233217

234218
return diag.Diagnostics{}
235219
}
236220

237-
func packNotifPolicy(npt gapi.NotificationPolicyTree, data *schema.ResourceData) {
221+
func packNotifPolicy(npt *models.Route, data *schema.ResourceData) {
238222
data.Set("contact_point", npt.Receiver)
239223
data.Set("group_by", npt.GroupBy)
240224
data.Set("group_wait", npt.GroupWait)
@@ -250,7 +234,7 @@ func packNotifPolicy(npt gapi.NotificationPolicyTree, data *schema.ResourceData)
250234
}
251235
}
252236

253-
func packSpecificPolicy(p gapi.SpecificPolicy, depth uint) interface{} {
237+
func packSpecificPolicy(p *models.Route, depth uint) interface{} {
254238
result := map[string]interface{}{
255239
"contact_point": p.Receiver,
256240
"continue": p.Continue,
@@ -288,35 +272,35 @@ func packSpecificPolicy(p gapi.SpecificPolicy, depth uint) interface{} {
288272
return result
289273
}
290274

291-
func packPolicyMatcher(m gapi.Matcher) interface{} {
275+
func packPolicyMatcher(m models.ObjectMatcher) interface{} {
292276
return map[string]interface{}{
293-
"label": m.Name,
294-
"match": m.Type.String(),
295-
"value": m.Value,
277+
"label": m[0],
278+
"match": m[1],
279+
"value": m[2],
296280
}
297281
}
298282

299-
func unpackNotifPolicy(data *schema.ResourceData) (gapi.NotificationPolicyTree, error) {
283+
func unpackNotifPolicy(data *schema.ResourceData) (*models.Route, error) {
300284
groupBy := data.Get("group_by").([]interface{})
301285
groups := make([]string, 0, len(groupBy))
302286
for _, g := range groupBy {
303287
groups = append(groups, g.(string))
304288
}
305289

306-
var children []gapi.SpecificPolicy
290+
var children []*models.Route
307291
nested, ok := data.GetOk("policy")
308292
if ok {
309293
routes := nested.([]interface{})
310294
for _, r := range routes {
311295
unpacked, err := unpackSpecificPolicy(r)
312296
if err != nil {
313-
return gapi.NotificationPolicyTree{}, err
297+
return nil, err
314298
}
315299
children = append(children, unpacked)
316300
}
317301
}
318302

319-
return gapi.NotificationPolicyTree{
303+
return &models.Route{
320304
Receiver: data.Get("contact_point").(string),
321305
GroupBy: groups,
322306
GroupWait: data.Get("group_wait").(string),
@@ -326,29 +310,25 @@ func unpackNotifPolicy(data *schema.ResourceData) (gapi.NotificationPolicyTree,
326310
}, nil
327311
}
328312

329-
func unpackSpecificPolicy(p interface{}) (gapi.SpecificPolicy, error) {
313+
func unpackSpecificPolicy(p interface{}) (*models.Route, error) {
330314
json := p.(map[string]interface{})
331315

332316
var groupBy []string
333317
if g, ok := json["group_by"]; ok {
334318
groupBy = common.ListToStringSlice(g.([]interface{}))
335319
}
336320

337-
policy := gapi.SpecificPolicy{
321+
policy := models.Route{
338322
Receiver: json["contact_point"].(string),
339323
GroupBy: groupBy,
340324
Continue: json["continue"].(bool),
341325
}
342326

343327
if v, ok := json["matcher"]; ok && v != nil {
344328
ms := v.(*schema.Set).List()
345-
matchers := make([]gapi.Matcher, 0, len(ms))
329+
matchers := make(models.ObjectMatchers, 0, len(ms))
346330
for _, m := range ms {
347-
matcher, err := unpackPolicyMatcher(m)
348-
if err != nil {
349-
return gapi.SpecificPolicy{}, err
350-
}
351-
matchers = append(matchers, matcher)
331+
matchers = append(matchers, unpackPolicyMatcher(m))
352332
}
353333
policy.ObjectMatchers = matchers
354334
}
@@ -369,39 +349,21 @@ func unpackSpecificPolicy(p interface{}) (gapi.SpecificPolicy, error) {
369349
}
370350
if v, ok := json["policy"]; ok && v != nil {
371351
ps := v.([]interface{})
372-
policies := make([]gapi.SpecificPolicy, 0, len(ps))
352+
policies := make([]*models.Route, 0, len(ps))
373353
for _, p := range ps {
374354
unpacked, err := unpackSpecificPolicy(p)
375355
if err != nil {
376-
return gapi.SpecificPolicy{}, err
356+
return nil, err
377357
}
378358
policies = append(policies, unpacked)
379359
}
380360
policy.Routes = policies
381361
}
382362

383-
return policy, nil
363+
return &policy, nil
384364
}
385365

386-
func unpackPolicyMatcher(m interface{}) (gapi.Matcher, error) {
366+
func unpackPolicyMatcher(m interface{}) models.ObjectMatcher {
387367
json := m.(map[string]interface{})
388-
389-
var matchType gapi.MatchType
390-
switch json["match"].(string) {
391-
case "=":
392-
matchType = gapi.MatchEqual
393-
case "!=":
394-
matchType = gapi.MatchNotEqual
395-
case "=~":
396-
matchType = gapi.MatchRegexp
397-
case "!~":
398-
matchType = gapi.MatchNotRegexp
399-
default:
400-
return gapi.Matcher{}, fmt.Errorf("unknown match operator: %s", json["match"].(string))
401-
}
402-
return gapi.Matcher{
403-
Name: json["label"].(string),
404-
Type: matchType,
405-
Value: json["value"].(string),
406-
}, nil
368+
return models.ObjectMatcher{json["label"].(string), json["match"].(string), json["value"].(string)}
407369
}

0 commit comments

Comments
 (0)