Alerting: Fix recording rule export (#91405)

* Fix HCL export

* Update rule export struct to support new optional fields

* Omit `for` field in export API if empty
This commit is contained in:
William Wernert 2024-08-22 09:04:21 -04:00 committed by GitHub
parent 00381711a4
commit dfbddd8262
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 242 additions and 16 deletions

View File

@ -653,7 +653,7 @@ func createService(store *fakes.RuleStore) *RulerSrv {
authz: accesscontrol.NewRuleService(acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient())),
amConfigStore: &fakeAMRefresher{},
amRefresher: &fakeAMRefresher{},
featureManager: featuremgmt.WithFeatures(),
featureManager: featuremgmt.WithFeatures(featuremgmt.FlagGrafanaManagedRecordingRules),
}
}

View File

@ -179,16 +179,32 @@ func AlertRuleExportFromAlertRule(rule models.AlertRule) (definitions.AlertRuleE
data = append(data, query)
}
cPtr := &rule.Condition
if rule.Condition == "" {
cPtr = nil
}
noDataState := definitions.NoDataState(rule.NoDataState)
ndsPtr := &noDataState
if noDataState == "" {
ndsPtr = nil
}
execErrorState := definitions.ExecutionErrorState(rule.ExecErrState)
eesPtr := &execErrorState
if execErrorState == "" {
eesPtr = nil
}
result := definitions.AlertRuleExport{
UID: rule.UID,
Title: rule.Title,
For: model.Duration(rule.For),
Condition: rule.Condition,
Condition: cPtr,
Data: data,
DashboardUID: rule.DashboardUID,
PanelID: rule.PanelID,
NoDataState: definitions.NoDataState(rule.NoDataState),
ExecErrState: definitions.ExecutionErrorState(rule.ExecErrState),
NoDataState: ndsPtr,
ExecErrState: eesPtr,
IsPaused: rule.IsPaused,
NotificationSettings: AlertRuleNotificationSettingsExportFromNotificationSettings(rule.NotificationSettings),
Record: AlertRuleRecordExportFromRecord(rule.Record),

View File

@ -87,4 +87,48 @@ resource "grafana_rule_group" "rule_group_d3e8424bfbf66bc3" {
mute_timings = ["test-mute"]
}
}
rule {
name = "recording rule"
data {
ref_id = "query"
relative_time_range {
from = 18000
to = 10800
}
datasource_uid = "000000002"
model = "{\"expr\":\"http_request_duration_microseconds_count\",\"hide\":false,\"interval\":\"\",\"intervalMs\":1000,\"legendFormat\":\"\",\"maxDataPoints\":100,\"refId\":\"query\"}"
}
data {
ref_id = "reduced"
relative_time_range {
from = 18000
to = 10800
}
datasource_uid = "__expr__"
model = "{\"expression\":\"query\",\"hide\":false,\"intervalMs\":1000,\"maxDataPoints\":100,\"reducer\":\"mean\",\"refId\":\"reduced\",\"type\":\"reduce\"}"
}
data {
ref_id = "condition"
relative_time_range {
from = 18000
to = 10800
}
datasource_uid = "__expr__"
model = "{\"expression\":\"$reduced > 10\",\"hide\":false,\"intervalMs\":1000,\"maxDataPoints\":100,\"refId\":\"condition\",\"type\":\"math\"}"
}
is_paused = false
record {
metric = "test_metric"
from = "condition"
}
}
}

View File

@ -108,7 +108,6 @@
],
"noDataState": "NoData",
"execErrState": "Alerting",
"for": "0s",
"isPaused": false,
"notification_settings":{
"receiver":"Test-Receiver",
@ -118,6 +117,66 @@
"repeat_interval":"5m",
"mute_time_intervals":["test-mute"]
}
},
{
"title": "recording rule",
"data": [
{
"refId": "query",
"relativeTimeRange": {
"from": 18000,
"to": 10800
},
"datasourceUid": "000000002",
"model": {
"expr": "http_request_duration_microseconds_count",
"hide": false,
"interval": "",
"intervalMs": 1000,
"legendFormat": "",
"maxDataPoints": 100,
"refId": "query"
}
},
{
"refId": "reduced",
"relativeTimeRange": {
"from": 18000,
"to": 10800
},
"datasourceUid": "__expr__",
"model": {
"expression": "query",
"hide": false,
"intervalMs": 1000,
"maxDataPoints": 100,
"reducer": "mean",
"refId": "reduced",
"type": "reduce"
}
},
{
"refId": "condition",
"relativeTimeRange": {
"from": 18000,
"to": 10800
},
"datasourceUid": "__expr__",
"model": {
"expression": "$reduced \u003e 10",
"hide": false,
"intervalMs": 1000,
"maxDataPoints": 100,
"refId": "condition",
"type": "math"
}
}
],
"isPaused": false,
"record": {
"metric": "test_metric",
"from": "condition"
}
}
]
}

View File

@ -81,7 +81,6 @@ groups:
type: reduce
noDataState: NoData
execErrState: Alerting
for: 0s
isPaused: false
notification_settings:
receiver: Test-Receiver
@ -94,3 +93,47 @@ groups:
repeat_interval: 5m
mute_time_intervals:
- test-mute
- title: recording rule
data:
- refId: query
relativeTimeRange:
from: 18000
to: 10800
datasourceUid: "000000002"
model:
expr: http_request_duration_microseconds_count
hide: false
interval: ""
intervalMs: 1000
legendFormat: ""
maxDataPoints: 100
refId: query
- refId: reduced
relativeTimeRange:
from: 18000
to: 10800
datasourceUid: __expr__
model:
expression: query
hide: false
intervalMs: 1000
maxDataPoints: 100
reducer: mean
refId: reduced
type: reduce
- refId: condition
relativeTimeRange:
from: 18000
to: 10800
datasourceUid: __expr__
model:
expression: $reduced > 10
hide: false
intervalMs: 1000
maxDataPoints: 100
refId: condition
type: math
isPaused: false
record:
metric: test_metric
from: condition

View File

@ -119,6 +119,70 @@
"mute_time_intervals":["test-mute"]
}
}
},
{
"grafana_alert": {
"title": "recording rule",
"data": [
{
"refId": "query",
"queryType": "",
"relativeTimeRange": {
"from": 18000,
"to": 10800
},
"datasourceUid": "000000002",
"model": {
"expr": "http_request_duration_microseconds_count",
"hide": false,
"interval": "",
"intervalMs": 1000,
"legendFormat": "",
"maxDataPoints": 100,
"refId": "query"
}
},
{
"refId": "reduced",
"queryType": "",
"relativeTimeRange": {
"from": 18000,
"to": 10800
},
"datasourceUid": "__expr__",
"model": {
"expression": "query",
"hide": false,
"intervalMs": 1000,
"maxDataPoints": 100,
"reducer": "mean",
"refId": "reduced",
"type": "reduce"
}
},
{
"refId": "condition",
"queryType": "",
"relativeTimeRange": {
"from": 18000,
"to": 10800
},
"datasourceUid": "__expr__",
"model": {
"expression": "$reduced > 10",
"hide": false,
"intervalMs": 1000,
"maxDataPoints": 100,
"refId": "condition",
"type": "math"
}
}
],
"record": {
"metric": "test_metric",
"from": "condition"
}
}
}
]
}

View File

@ -258,15 +258,15 @@ type AlertRuleGroupExport struct {
// AlertRuleExport is the provisioned file export of models.AlertRule.
type AlertRuleExport struct {
UID string `json:"uid,omitempty" yaml:"uid,omitempty"`
Title string `json:"title" yaml:"title" hcl:"name"`
Condition string `json:"condition" yaml:"condition" hcl:"condition"`
Data []AlertQueryExport `json:"data" yaml:"data" hcl:"data,block"`
DashboardUID *string `json:"dashboardUid,omitempty" yaml:"dashboardUid,omitempty"`
PanelID *int64 `json:"panelId,omitempty" yaml:"panelId,omitempty"`
NoDataState NoDataState `json:"noDataState" yaml:"noDataState" hcl:"no_data_state"`
ExecErrState ExecutionErrorState `json:"execErrState" yaml:"execErrState" hcl:"exec_err_state"`
For model.Duration `json:"for" yaml:"for"`
UID string `json:"uid,omitempty" yaml:"uid,omitempty"`
Title string `json:"title" yaml:"title" hcl:"name"`
Condition *string `json:"condition,omitempty" yaml:"condition,omitempty" hcl:"condition"`
Data []AlertQueryExport `json:"data" yaml:"data" hcl:"data,block"`
DashboardUID *string `json:"dashboardUid,omitempty" yaml:"dashboardUid,omitempty"`
PanelID *int64 `json:"panelId,omitempty" yaml:"panelId,omitempty"`
NoDataState *NoDataState `json:"noDataState,omitempty" yaml:"noDataState,omitempty" hcl:"no_data_state"`
ExecErrState *ExecutionErrorState `json:"execErrState,omitempty" yaml:"execErrState,omitempty" hcl:"exec_err_state"`
For model.Duration `json:"for,omitempty" yaml:"for,omitempty"`
// ForString is used to:
// - Only export the for field for HCL if it is non-zero.
// - Format the Prometheus model.Duration type properly for HCL.
@ -275,7 +275,7 @@ type AlertRuleExport struct {
Labels *map[string]string `json:"labels,omitempty" yaml:"labels,omitempty" hcl:"labels"`
IsPaused bool `json:"isPaused" yaml:"isPaused" hcl:"is_paused"`
NotificationSettings *AlertRuleNotificationSettingsExport `json:"notification_settings,omitempty" yaml:"notification_settings,omitempty" hcl:"notification_settings,block"`
Record *AlertRuleRecordExport `json:"record,omitempty" yaml:"record,omitempty" hcl:"record"`
Record *AlertRuleRecordExport `json:"record,omitempty" yaml:"record,omitempty" hcl:"record,block"`
}
// AlertQueryExport is the provisioned export of models.AlertQuery.