Skip to content

Commit faae439

Browse files
Alerting: Add support for setting target_datasource_uid for recording rules (#2164)
1 parent 8b815e2 commit faae439

File tree

4 files changed

+89
-1
lines changed

4 files changed

+89
-1
lines changed

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ services:
3131
- GF_SERVER_ROOT_URL=${GRAFANA_URL}
3232
- GF_ENTERPRISE_LICENSE_TEXT=${GF_ENTERPRISE_LICENSE_TEXT:-}
3333
- GF_SERVER_SERVE_FROM_SUB_PATH=${GF_SERVER_SERVE_FROM_SUB_PATH:-}
34-
- GF_FEATURE_TOGGLES_ENABLE=nestedFolders,ssoSettingsApi,ssoSettingsSAML,ssoSettingsLDAP
34+
- GF_FEATURE_TOGGLES_ENABLE=nestedFolders,ssoSettingsApi,ssoSettingsSAML,ssoSettingsLDAP,grafanaManagedRecordingRulesDatasources
3535
healthcheck:
3636
test: wget --no-verbose --tries=1 --spider http://0.0.0.0:3000/api/health || exit 1 # Use wget because older versions of Grafana don't have curl
3737
interval: 10s

docs/resources/rule_group.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,10 @@ Required:
197197
- `from` (String) The ref id of the query node in the data field to use as the source of the metric.
198198
- `metric` (String) The name of the metric to write to.
199199

200+
Optional:
201+
202+
- `target_datasource_uid` (String) The UID of the datasource to write the metric to.
203+
200204
## Import
201205

202206
Import is supported using the following syntax:

internal/resources/grafana/resource_alerting_rule_group.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,11 @@ This resource requires Grafana 9.1.0 or later.
285285
Required: true,
286286
Description: "The ref id of the query node in the data field to use as the source of the metric.",
287287
},
288+
"target_datasource_uid": {
289+
Type: schema.TypeString,
290+
Optional: true,
291+
Description: "The UID of the datasource to write the metric to.",
292+
},
288293
},
289294
},
290295
},
@@ -825,6 +830,9 @@ func packRecord(r *models.Record) interface{} {
825830
if r.From != nil {
826831
res["from"] = *r.From
827832
}
833+
if r.TargetDatasourceUID != "" {
834+
res["target_datasource_uid"] = r.TargetDatasourceUID
835+
}
828836
return []interface{}{res}
829837
}
830838

@@ -844,5 +852,8 @@ func unpackRecord(p interface{}) *models.Record {
844852
if v, ok := jsonData["from"]; ok && v != nil {
845853
res.From = common.Ref(v.(string))
846854
}
855+
if v, ok := jsonData["target_datasource_uid"]; ok && v != nil {
856+
res.TargetDatasourceUID = v.(string)
857+
}
847858
return res
848859
}

internal/resources/grafana/resource_alerting_rule_group_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,35 @@ func TestAccAlertRule_keepFiringFor(t *testing.T) {
762762
})
763763
}
764764

765+
func TestAccAlertRule_RecordingRules_TargetDatasourceUID(t *testing.T) {
766+
testutils.CheckOSSTestsEnabled(t, ">=12.0.0")
767+
768+
var group models.AlertRuleGroup
769+
var name = acctest.RandString(10)
770+
var metric = "valid_metric"
771+
var targetDatasourceUID = "some_datasource_uid"
772+
773+
resource.ParallelTest(t, resource.TestCase{
774+
ProtoV5ProviderFactories: testutils.ProtoV5ProviderFactories,
775+
CheckDestroy: alertingRuleGroupCheckExists.destroyed(&group, nil),
776+
Steps: []resource.TestStep{
777+
{
778+
Config: testAccRecordingRuleWithTargetDatasourceUID(name, metric, "A", targetDatasourceUID),
779+
Check: resource.ComposeTestCheckFunc(
780+
alertingRuleGroupCheckExists.exists("grafana_rule_group.my_rule_group", &group),
781+
resource.TestCheckResourceAttr("grafana_rule_group.my_rule_group", "name", name),
782+
resource.TestCheckResourceAttr("grafana_rule_group.my_rule_group", "rule.#", "1"),
783+
resource.TestCheckResourceAttr("grafana_rule_group.my_rule_group", "rule.0.name", "My Random Walk Alert"),
784+
resource.TestCheckResourceAttr("grafana_rule_group.my_rule_group", "rule.0.data.0.model", "{\"refId\":\"A\"}"),
785+
resource.TestCheckResourceAttr("grafana_rule_group.my_rule_group", "rule.0.record.0.metric", metric),
786+
resource.TestCheckResourceAttr("grafana_rule_group.my_rule_group", "rule.0.record.0.from", "A"),
787+
resource.TestCheckResourceAttr("grafana_rule_group.my_rule_group", "rule.0.record.0.target_datasource_uid", targetDatasourceUID),
788+
),
789+
},
790+
},
791+
})
792+
}
793+
765794
func TestAccAlertRule_NotificationSettings(t *testing.T) {
766795
testutils.CheckOSSTestsEnabled(t, ">=10.4.0")
767796

@@ -1037,6 +1066,50 @@ resource "grafana_rule_group" "my_rule_group" {
10371066
}`, name, metric, refID)
10381067
}
10391068

1069+
func testAccRecordingRuleWithTargetDatasourceUID(name, metric, refID, datasourceUID string) string {
1070+
return fmt.Sprintf(`
1071+
resource "grafana_folder" "rule_folder" {
1072+
title = "%[1]s"
1073+
}
1074+
1075+
resource "grafana_data_source" "testdata_datasource" {
1076+
name = "%[1]s"
1077+
type = "grafana-testdata-datasource"
1078+
url = "http://localhost:3333"
1079+
uid = "%[4]s"
1080+
}
1081+
1082+
resource "grafana_rule_group" "my_rule_group" {
1083+
name = "%[1]s"
1084+
folder_uid = grafana_folder.rule_folder.uid
1085+
interval_seconds = 60
1086+
1087+
rule {
1088+
name = "My Random Walk Alert"
1089+
1090+
// Query the datasource.
1091+
data {
1092+
ref_id = "A"
1093+
relative_time_range {
1094+
from = 600
1095+
to = 0
1096+
}
1097+
datasource_uid = grafana_data_source.testdata_datasource.uid
1098+
model = jsonencode({
1099+
intervalMs = 1000
1100+
maxDataPoints = 43200
1101+
refId = "A"
1102+
})
1103+
}
1104+
record {
1105+
metric = "%[2]s"
1106+
from = "%[3]s"
1107+
target_datasource_uid = grafana_data_source.testdata_datasource.uid
1108+
}
1109+
}
1110+
}`, name, metric, refID, datasourceUID)
1111+
}
1112+
10401113
func testAccRecordingRuleInvalid(name string, metric string, refID string) string {
10411114
return fmt.Sprintf(`
10421115
resource "grafana_folder" "rule_folder" {

0 commit comments

Comments
 (0)