From 0aa87fd1d45054944d68b7d334daa5115dc6a5d0 Mon Sep 17 00:00:00 2001 From: Matthew Jacobson Date: Thu, 12 Sep 2024 13:44:03 -0400 Subject: [PATCH] Alerting: Fix DashboardUID typo in json provisioning api (#65143) * Alerting: Fix dasboardUid typo in json provisioning api The json tag for DashboardUID was incorrectly set to dasboardUid in the provisioning api. This change fixes the typo while keeping backwards compatibility for the typo. * Add alerting-squad as CODEOWNER for services/provisioning/alerting --- .github/CODEOWNERS | 1 + .../alerting/config_reader_test.go | 29 +++++++++++ .../provisioning/alerting/rules_types.go | 13 ++++- .../dasboard-typo-support/rules.json | 49 +++++++++++++++++++ .../dasboard-typo-support/rules.yml | 28 +++++++++++ 5 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 pkg/services/provisioning/alerting/testdata/alert_rules/dasboard-typo-support/rules.json create mode 100644 pkg/services/provisioning/alerting/testdata/alert_rules/dasboard-typo-support/rules.yml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 60e4bc67e68..4492c36d77b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -133,6 +133,7 @@ /pkg/services/playlist/ @grafana/grafana-app-platform-squad /pkg/services/preference/ @grafana/grafana-backend-group /pkg/services/provisioning/ @grafana/grafana-search-and-storage +/pkg/services/provisioning/alerting/ @grafana/alerting-backend /pkg/services/query/ @grafana/grafana-app-platform-squad /pkg/services/queryhistory/ @grafana/explore-squad /pkg/services/quota/ @grafana/grafana-search-and-storage diff --git a/pkg/services/provisioning/alerting/config_reader_test.go b/pkg/services/provisioning/alerting/config_reader_test.go index edcf431e690..c13780633c3 100644 --- a/pkg/services/provisioning/alerting/config_reader_test.go +++ b/pkg/services/provisioning/alerting/config_reader_test.go @@ -16,6 +16,7 @@ const ( testFileSupportedFiletypes = "./testdata/common/supported-filetypes" testFileCorrectProperties = "./testdata/alert_rules/correct-properties" testFileCorrectPropertiesWithOrg = "./testdata/alert_rules/correct-properties-with-org" + testFileDasboardTypoSupport = "./testdata/alert_rules/dasboard-typo-support" testFileMultipleRules = "./testdata/alert_rules/multiple-rules" testFileMultipleFiles = "./testdata/alert_rules/multiple-files" testFileCorrectProperties_cp = "./testdata/contact_points/correct-properties" @@ -159,4 +160,32 @@ func TestConfigReader(t *testing.T) { require.NoError(t, err) require.Len(t, file[0].Templates, 2) }) + t.Run("a rule file with dasboard typo", func(t *testing.T) { + ruleFiles, err := configReader.readConfig(ctx, testFileDasboardTypoSupport) + require.NoError(t, err) + t.Run("only dasboard present", func(t *testing.T) { + for _, ruleFile := range ruleFiles { + group := ruleFile.Groups[0] + t.Run(group.Title, func(t *testing.T) { + require.Equal(t, "dasboardUid", *group.Rules[0].DashboardUID) + }) + } + }) + t.Run("only dashboard present", func(t *testing.T) { + for _, ruleFile := range ruleFiles { + group := ruleFile.Groups[0] + t.Run(group.Title, func(t *testing.T) { + require.Equal(t, "dashboardUid", *group.Rules[1].DashboardUID) + }) + } + }) + t.Run("both dasboard and dashboard present", func(t *testing.T) { + for _, ruleFile := range ruleFiles { + group := ruleFile.Groups[0] + t.Run(group.Title, func(t *testing.T) { + require.Equal(t, "dashboardUid", *group.Rules[2].DashboardUID) + }) + } + }) + }) } diff --git a/pkg/services/provisioning/alerting/rules_types.go b/pkg/services/provisioning/alerting/rules_types.go index cce86eedba4..805ca5b1506 100644 --- a/pkg/services/provisioning/alerting/rules_types.go +++ b/pkg/services/provisioning/alerting/rules_types.go @@ -66,7 +66,8 @@ type AlertRuleV1 struct { Title values.StringValue `json:"title" yaml:"title"` Condition values.StringValue `json:"condition" yaml:"condition"` Data []QueryV1 `json:"data" yaml:"data"` - DashboardUID values.StringValue `json:"dasboardUid" yaml:"dashboardUid"` + DasboardUID values.StringValue `json:"dasboardUid" yaml:"dasboardUid"` // TODO: Grandfathered typo support. TODO: This should be removed in V2. + DashboardUID values.StringValue `json:"dashboardUid" yaml:"dashboardUid"` PanelID values.Int64Value `json:"panelId" yaml:"panelId"` NoDataState values.StringValue `json:"noDataState" yaml:"noDataState"` ExecErrState values.StringValue `json:"execErrState" yaml:"execErrState"` @@ -78,6 +79,13 @@ type AlertRuleV1 struct { Record *RecordV1 `json:"record" yaml:"record"` } +func withFallback(value, fallback string) *string { + if value == "" { + return &fallback + } + return &value +} + func (rule *AlertRuleV1) mapToModel(orgID int64) (models.AlertRule, error) { alertRule := models.AlertRule{} alertRule.Title = rule.Title.Value() @@ -94,8 +102,9 @@ func (rule *AlertRuleV1) mapToModel(orgID int64) (models.AlertRule, error) { return models.AlertRule{}, fmt.Errorf("rule '%s' failed to parse: %w", alertRule.Title, err) } alertRule.For = time.Duration(duration) + dasboardUID := rule.DasboardUID.Value() dashboardUID := rule.DashboardUID.Value() - alertRule.DashboardUID = &dashboardUID + alertRule.DashboardUID = withFallback(dashboardUID, dasboardUID) // Use correct spelling over supported typo. panelID := rule.PanelID.Value() alertRule.PanelID = &panelID execErrStateValue := strings.TrimSpace(rule.ExecErrState.Value()) diff --git a/pkg/services/provisioning/alerting/testdata/alert_rules/dasboard-typo-support/rules.json b/pkg/services/provisioning/alerting/testdata/alert_rules/dasboard-typo-support/rules.json new file mode 100644 index 00000000000..2e2b35d9cd4 --- /dev/null +++ b/pkg/services/provisioning/alerting/testdata/alert_rules/dasboard-typo-support/rules.json @@ -0,0 +1,49 @@ +{ + "apiVersion": 1, + "groups": [ + { + "name": "json_group", + "folder": "my_folder", + "interval": "10s", + "rules": [ + { + "title": "with_typo", + "uid": "with_typo", + "dasboardUid": "dasboardUid", + "condition": "A", + "for": "1m", + "data": [ + { + "refId": "A" + } + ] + }, + { + "title": "without_typo", + "uid": "without_typo", + "dashboardUid": "dashboardUid", + "condition": "A", + "for": "1m", + "data": [ + { + "refId": "A" + } + ] + }, + { + "title": "with_both", + "uid": "with_both", + "dashboardUid": "dashboardUid", + "dasboardUid": "dasboardUid", + "condition": "A", + "for": "1m", + "data": [ + { + "refId": "A" + } + ] + } + ] + } + ] +} diff --git a/pkg/services/provisioning/alerting/testdata/alert_rules/dasboard-typo-support/rules.yml b/pkg/services/provisioning/alerting/testdata/alert_rules/dasboard-typo-support/rules.yml new file mode 100644 index 00000000000..1936e33619c --- /dev/null +++ b/pkg/services/provisioning/alerting/testdata/alert_rules/dasboard-typo-support/rules.yml @@ -0,0 +1,28 @@ +apiVersion: 1 +groups: + - name: yaml_group + folder: my_folder + interval: 10s + rules: + - title: with_typo + uid: with_typo + dasboardUid: dasboardUid + condition: A + for: 1m + data: + - refId: A + - title: without_typo + uid: without_typo + dashboardUid: dashboardUid + condition: A + for: 1m + data: + - refId: A + - title: with_both + uid: with_both + dashboardUid: dashboardUid + dasboardUid: dasboardUid + condition: A + for: 1m + data: + - refId: A