Skip to content

Commit f3b1845

Browse files
Alerting Rule Groups: Fix provisioning in non-default org (#1124)
Closes #1120 Use the same pattern as other org-scoped resources to create the client
1 parent 0f123f7 commit f3b1845

File tree

3 files changed

+111
-19
lines changed

3 files changed

+111
-19
lines changed

docs/resources/rule_group.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,12 @@ EOT
116116
- `folder_uid` (String) The UID of the folder that the group belongs to.
117117
- `interval_seconds` (Number) The interval, in seconds, at which all rules in the group are evaluated. If a group contains many rules, the rules are evaluated sequentially.
118118
- `name` (String) The name of the rule group.
119-
- `org_id` (String) The ID of the org to which the group belongs.
120119
- `rule` (Block List, Min: 1) The rules within the group. (see [below for nested schema](#nestedblock--rule))
121120

121+
### Optional
122+
123+
- `org_id` (String) The Organization ID. If not set, the Org ID defined in the provider block will be used.
124+
122125
### Read-Only
123126

124127
- `id` (String) The ID of this resource.

internal/resources/grafana/resource_alerting_rule_group.go

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ This resource requires Grafana 9.1.0 or later.
3737

3838
SchemaVersion: 0,
3939
Schema: map[string]*schema.Schema{
40+
"org_id": orgIDAttribute(),
4041
"name": {
4142
Type: schema.TypeString,
4243
Required: true,
@@ -54,12 +55,6 @@ This resource requires Grafana 9.1.0 or later.
5455
Required: true,
5556
Description: "The interval, in seconds, at which all rules in the group are evaluated. If a group contains many rules, the rules are evaluated sequentially.",
5657
},
57-
"org_id": {
58-
Type: schema.TypeString,
59-
Required: true,
60-
ForceNew: true,
61-
Description: "The ID of the org to which the group belongs.",
62-
},
6358
"rule": {
6459
Type: schema.TypeList,
6560
Required: true,
@@ -192,9 +187,9 @@ This resource requires Grafana 9.1.0 or later.
192187
}
193188

194189
func readAlertRuleGroup(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {
195-
client := meta.(*common.Client).GrafanaAPI
190+
client, orgID, idStr := ClientFromExistingOrgResource(meta, data.Id())
196191

197-
key := UnpackGroupID(data.Id())
192+
key := UnpackGroupID(idStr)
198193

199194
group, err := client.AlertRuleGroup(key.FolderUID, key.Name)
200195
if err, shouldReturn := common.CheckReadError("rule group", data, err); shouldReturn {
@@ -204,13 +199,13 @@ func readAlertRuleGroup(ctx context.Context, data *schema.ResourceData, meta int
204199
if err := packRuleGroup(group, data); err != nil {
205200
return diag.FromErr(err)
206201
}
207-
data.SetId(packGroupID(ruleKeyFromGroup(group)))
202+
data.SetId(MakeOrgResourceID(orgID, packGroupID(ruleKeyFromGroup(group))))
208203

209204
return nil
210205
}
211206

212207
func createAlertRuleGroup(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {
213-
client := meta.(*common.Client).GrafanaAPI
208+
client, orgID := ClientFromNewOrgResource(meta, data)
214209

215210
group, err := unpackRuleGroup(data)
216211
if err != nil {
@@ -222,31 +217,29 @@ func createAlertRuleGroup(ctx context.Context, data *schema.ResourceData, meta i
222217
return diag.FromErr(err)
223218
}
224219

225-
data.SetId(packGroupID(key))
220+
data.SetId(MakeOrgResourceID(orgID, packGroupID(key)))
226221
return readAlertRuleGroup(ctx, data, meta)
227222
}
228223

229224
func updateAlertRuleGroup(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {
230-
client := meta.(*common.Client).GrafanaAPI
225+
client, _, _ := ClientFromExistingOrgResource(meta, data.Id())
231226

232227
group, err := unpackRuleGroup(data)
233228
if err != nil {
234229
return diag.FromErr(err)
235230
}
236-
key := ruleKeyFromGroup(group)
237231

238232
if err = client.SetAlertRuleGroup(group); err != nil {
239233
return diag.FromErr(err)
240234
}
241235

242-
data.SetId(packGroupID(key))
243236
return readAlertRuleGroup(ctx, data, meta)
244237
}
245238

246239
func deleteAlertRuleGroup(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {
247-
client := meta.(*common.Client).GrafanaAPI
240+
client, _, idStr := ClientFromExistingOrgResource(meta, data.Id())
248241

249-
key := UnpackGroupID(data.Id())
242+
key := UnpackGroupID(idStr)
250243

251244
group, err := client.AlertRuleGroup(key.FolderUID, key.Name)
252245
if err != nil {

internal/resources/grafana/resource_alerting_rule_group_test.go

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/grafana/terraform-provider-grafana/internal/common"
1010
"github.com/grafana/terraform-provider-grafana/internal/resources/grafana"
1111
"github.com/grafana/terraform-provider-grafana/internal/testutils"
12+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
1213
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
1314
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
1415
)
@@ -212,6 +213,54 @@ func TestAccAlertRule_compound(t *testing.T) {
212213
})
213214
}
214215

216+
func TestAccAlertRule_inOrg(t *testing.T) {
217+
testutils.CheckOSSTestsEnabled(t, ">=9.1.0")
218+
219+
var group gapi.RuleGroup
220+
var org gapi.Org
221+
name := acctest.RandString(10)
222+
223+
resource.ParallelTest(t, resource.TestCase{
224+
ProviderFactories: testutils.ProviderFactories,
225+
// Implicitly tests deletion.
226+
CheckDestroy: testAlertRuleCheckDestroy(&group),
227+
Steps: []resource.TestStep{
228+
// Test creation.
229+
{
230+
Config: testAccAlertRuleGroupInOrgConfig(name, 240),
231+
Check: resource.ComposeTestCheckFunc(
232+
testRuleGroupCheckExists("grafana_rule_group.test", &group),
233+
testAccOrganizationCheckExists("grafana_organization.test", &org),
234+
checkResourceIsInOrg("grafana_rule_group.test", "grafana_organization.test"),
235+
resource.TestCheckResourceAttr("grafana_rule_group.test", "name", name),
236+
resource.TestCheckResourceAttr("grafana_rule_group.test", "interval_seconds", "240"),
237+
resource.TestCheckResourceAttr("grafana_rule_group.test", "rule.#", "1"),
238+
resource.TestCheckResourceAttr("grafana_rule_group.test", "rule.0.data.0.model", "{\"hide\":false,\"refId\":\"A\"}"),
239+
),
240+
},
241+
// Test update content.
242+
{
243+
Config: testAccAlertRuleGroupInOrgConfig(name, 360),
244+
Check: resource.ComposeTestCheckFunc(
245+
testRuleGroupCheckExists("grafana_rule_group.test", &group),
246+
testAccOrganizationCheckExists("grafana_organization.test", &org),
247+
checkResourceIsInOrg("grafana_rule_group.test", "grafana_organization.test"),
248+
resource.TestCheckResourceAttr("grafana_rule_group.test", "name", name),
249+
resource.TestCheckResourceAttr("grafana_rule_group.test", "interval_seconds", "360"),
250+
resource.TestCheckResourceAttr("grafana_rule_group.test", "rule.#", "1"),
251+
resource.TestCheckResourceAttr("grafana_rule_group.test", "rule.0.data.0.model", "{\"hide\":false,\"refId\":\"A\"}"),
252+
),
253+
},
254+
// Test import.
255+
{
256+
ResourceName: "grafana_rule_group.test",
257+
ImportState: true,
258+
ImportStateVerify: true,
259+
},
260+
},
261+
})
262+
}
263+
215264
func testRuleGroupCheckExists(rname string, g *gapi.RuleGroup) resource.TestCheckFunc {
216265
return func(s *terraform.State) error {
217266
resource, ok := s.RootModule().Resources[rname]
@@ -223,8 +272,9 @@ func testRuleGroupCheckExists(rname string, g *gapi.RuleGroup) resource.TestChec
223272
return fmt.Errorf("resource id not set")
224273
}
225274

226-
client := testutils.Provider.Meta().(*common.Client).GrafanaAPI
227-
key := grafana.UnpackGroupID(resource.Primary.ID)
275+
orgID, idStr := grafana.SplitOrgResourceID(resource.Primary.ID)
276+
key := grafana.UnpackGroupID(idStr)
277+
client := testutils.Provider.Meta().(*common.Client).GrafanaAPI.WithOrgID(orgID)
228278
grp, err := client.AlertRuleGroup(key.FolderUID, key.Name)
229279
if err != nil {
230280
return fmt.Errorf("error getting resource: %s", err)
@@ -238,10 +288,56 @@ func testRuleGroupCheckExists(rname string, g *gapi.RuleGroup) resource.TestChec
238288
func testAlertRuleCheckDestroy(group *gapi.RuleGroup) resource.TestCheckFunc {
239289
return func(s *terraform.State) error {
240290
client := testutils.Provider.Meta().(*common.Client).GrafanaAPI
291+
if len(group.Rules) > 0 {
292+
client = client.WithOrgID(group.Rules[0].OrgID)
293+
}
241294
_, err := client.AlertRuleGroup(group.FolderUID, group.Title)
242295
if err == nil && strings.HasPrefix(err.Error(), "status: 404") {
243296
return fmt.Errorf("rule group still exists on the server")
244297
}
245298
return nil
246299
}
247300
}
301+
302+
func testAccAlertRuleGroupInOrgConfig(name string, interval int) string {
303+
return fmt.Sprintf(`
304+
resource "grafana_organization" "test" {
305+
name = "%[1]s"
306+
}
307+
308+
resource "grafana_folder" "test" {
309+
org_id = grafana_organization.test.id
310+
title = "%[1]s"
311+
}
312+
313+
resource "grafana_rule_group" "test" {
314+
org_id = grafana_organization.test.id
315+
name = "%[1]s"
316+
folder_uid = grafana_folder.test.uid
317+
interval_seconds = %[2]d
318+
rule {
319+
name = "My Alert Rule 1"
320+
for = "2m"
321+
condition = "B"
322+
no_data_state = "NoData"
323+
exec_err_state = "Alerting"
324+
is_paused = false
325+
data {
326+
ref_id = "A"
327+
query_type = ""
328+
relative_time_range {
329+
from = 600
330+
to = 0
331+
}
332+
datasource_uid = "PD8C576611E62080A"
333+
model = jsonencode({
334+
hide = false
335+
intervalMs = 1000
336+
maxDataPoints = 43200
337+
refId = "A"
338+
})
339+
}
340+
}
341+
}
342+
`, name, interval)
343+
}

0 commit comments

Comments
 (0)