Alerting: Add MissingSeriesEvalsToResolve to the APIs (#102150)
What is this feature? A follow-up for #101184, adds AlertRule.MissingSeriesEvalsToResolve to the APIs. missing_series_evals_to_resolve must be specified too and it must be > 0. POST /api/ruler/grafana/api/v1/rules/{folderUID} works in the following way: If missing_series_evals_to_resolve is not sent or null, the rule keeps its existing value If missing_series_evals_to_resolve > 0: updates to that value If missing_series_evals_to_resolve = 0: resets to default (nil). AlertRule.MissingSeriesEvalsToResolve can't be 0, so I used it to reset In the Provisioning API, the value is just set if present and > 0. Otherwise it's reset: PUT to /api/v1/provisioning/alert-rules/{UID}: If missing_series_evals_to_resolve is nil, it's reset to the default value If missing_series_evals_to_resolve > 0, it's updated
This commit is contained in:
@@ -29,6 +29,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/tests/testinfra"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
func createRuleWithNotificationSettings(t *testing.T, client apiClient, folder string, nfSettings *definitions.AlertRuleNotificationSettings) (definitions.PostableRuleGroupConfig, string) {
|
||||
@@ -664,14 +665,24 @@ func TestIntegrationProvisioningRules(t *testing.T) {
|
||||
Model: json.RawMessage([]byte(`{"type":"math","expression":"2 + 3 \u003e 1"}`)),
|
||||
},
|
||||
},
|
||||
MissingSeriesEvalsToResolve: util.Pointer(3),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result, status, raw := apiClient.CreateOrUpdateRuleGroupProvisioning(t, originalRuleGroup)
|
||||
|
||||
t.Run("should create a new rule group with UIDs specified", func(t *testing.T) {
|
||||
requireStatusCode(t, http.StatusOK, status, raw)
|
||||
require.Equal(t, originalRuleGroup, result)
|
||||
|
||||
require.Len(t, result.Rules, 3)
|
||||
for _, rule := range result.Rules {
|
||||
require.NotEmpty(t, rule.UID)
|
||||
if rule.UID == "rule3" {
|
||||
require.Equal(t, 3, *rule.MissingSeriesEvalsToResolve)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should remove a rule when updating group with a rule removed", func(t *testing.T) {
|
||||
|
||||
@@ -1753,6 +1753,94 @@ func TestIntegrationRuleUpdate(t *testing.T) {
|
||||
require.Equal(t, newKeepFiringFor, *getGroup.Rules[0].ApiRuleNode.KeepFiringFor)
|
||||
})
|
||||
|
||||
t.Run("missing_series_evals_to_resolve", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
initialValue *int
|
||||
updatedValue *int
|
||||
expectedValue *int
|
||||
expectedStatus int
|
||||
}{
|
||||
{
|
||||
name: "should be able to set missing_series_evals_to_resolve to 5",
|
||||
initialValue: nil,
|
||||
updatedValue: util.Pointer(5),
|
||||
expectedValue: util.Pointer(5),
|
||||
expectedStatus: http.StatusAccepted,
|
||||
},
|
||||
{
|
||||
name: "should be able to update missing_series_evals_to_resolve",
|
||||
initialValue: util.Pointer(1),
|
||||
updatedValue: util.Pointer(2),
|
||||
expectedValue: util.Pointer(2),
|
||||
expectedStatus: http.StatusAccepted,
|
||||
},
|
||||
{
|
||||
name: "should preserve missing_series_evals_to_resolve when it's set nil",
|
||||
initialValue: util.Pointer(5),
|
||||
updatedValue: nil,
|
||||
expectedValue: util.Pointer(5),
|
||||
expectedStatus: http.StatusAccepted,
|
||||
},
|
||||
{
|
||||
name: "should reject missing_series_evals_to_resolve < 0",
|
||||
initialValue: util.Pointer(1),
|
||||
updatedValue: util.Pointer(-1),
|
||||
expectedStatus: http.StatusBadRequest,
|
||||
},
|
||||
{
|
||||
name: "should be able to reset missing_series_evals_to_resolve by setting it to 0",
|
||||
initialValue: util.Pointer(1),
|
||||
updatedValue: util.Pointer(0),
|
||||
expectedValue: nil,
|
||||
expectedStatus: http.StatusAccepted,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// Create a new rule
|
||||
group := generateAlertRuleGroup(1, alertRuleGen())
|
||||
group.Rules[0].GrafanaManagedAlert.MissingSeriesEvalsToResolve = tc.initialValue
|
||||
|
||||
// Post the rule group with our alert rule
|
||||
_, status, body := client.PostRulesGroupWithStatus(t, folderUID, &group, false)
|
||||
require.Equalf(t, http.StatusAccepted, status, "failed to post rule group. Response: %s", body)
|
||||
|
||||
// and the value of the missing_series_evals_to_resolve
|
||||
getGroup, status := client.GetRulesGroup(t, folderUID, group.Name)
|
||||
require.Equal(t, http.StatusAccepted, status)
|
||||
if tc.initialValue == nil {
|
||||
require.Nil(t, getGroup.Rules[0].GrafanaManagedAlert.MissingSeriesEvalsToResolve)
|
||||
} else {
|
||||
require.Equal(t, *tc.initialValue, *getGroup.Rules[0].GrafanaManagedAlert.MissingSeriesEvalsToResolve)
|
||||
}
|
||||
|
||||
// Now let's update the initial value with the updated value
|
||||
group = convertGettableRuleGroupToPostable(getGroup.GettableRuleGroupConfig)
|
||||
group.Rules[0].GrafanaManagedAlert.MissingSeriesEvalsToResolve = tc.updatedValue
|
||||
_, status, body = client.PostRulesGroupWithStatus(t, folderUID, &group, false)
|
||||
require.Equalf(t, tc.expectedStatus, status, "failed to post rule group. Response: %s", body)
|
||||
// Check the response status
|
||||
require.Equal(t, tc.expectedStatus, status)
|
||||
if tc.expectedStatus != http.StatusAccepted {
|
||||
// If the status is not accepted, we don't need to check the response body
|
||||
return
|
||||
}
|
||||
|
||||
// Get the group again and check that the value is updated to updatedValue
|
||||
getGroup, status = client.GetRulesGroup(t, folderUID, group.Name)
|
||||
require.Equal(t, http.StatusAccepted, status)
|
||||
|
||||
if tc.expectedValue == nil {
|
||||
require.Nil(t, getGroup.Rules[0].GrafanaManagedAlert.MissingSeriesEvalsToResolve)
|
||||
} else {
|
||||
require.Equal(t, *tc.expectedValue, *getGroup.Rules[0].GrafanaManagedAlert.MissingSeriesEvalsToResolve)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("when data source missing", func(t *testing.T) {
|
||||
var groupName string
|
||||
{
|
||||
@@ -3362,16 +3450,17 @@ func TestIntegrationAlertRuleCRUD(t *testing.T) {
|
||||
}`),
|
||||
},
|
||||
},
|
||||
NoDataState: apimodels.NoDataState(ngmodels.Alerting),
|
||||
ExecErrState: apimodels.ExecutionErrorState(ngmodels.AlertingErrState),
|
||||
NoDataState: apimodels.NoDataState(ngmodels.Alerting),
|
||||
ExecErrState: apimodels.ExecutionErrorState(ngmodels.AlertingErrState),
|
||||
MissingSeriesEvalsToResolve: util.Pointer(2), // If UID is specified, this field is required
|
||||
},
|
||||
},
|
||||
},
|
||||
Interval: interval,
|
||||
}
|
||||
|
||||
response, status, _ := apiClient.PostRulesGroupWithStatus(t, "default", &rules, false)
|
||||
assert.Equal(t, http.StatusAccepted, status)
|
||||
response, status, body := apiClient.PostRulesGroupWithStatus(t, "default", &rules, false)
|
||||
assert.Equal(t, http.StatusAccepted, status, body)
|
||||
|
||||
require.Len(t, response.Created, 1)
|
||||
require.Len(t, response.Updated, 2)
|
||||
|
||||
@@ -36,7 +36,8 @@
|
||||
"labels": {
|
||||
"label1": "test-label"
|
||||
},
|
||||
"isPaused": false
|
||||
"isPaused": false,
|
||||
"missing_series_evals_to_resolve": 1
|
||||
},
|
||||
{
|
||||
"uid": "<dynamic>",
|
||||
@@ -67,9 +68,10 @@
|
||||
"labels": {
|
||||
"label1": "test-label"
|
||||
},
|
||||
"isPaused": false
|
||||
"isPaused": false,
|
||||
"missing_series_evals_to_resolve": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
"simplified_query_and_expressions_section": false,
|
||||
"simplified_notifications_section": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"missing_series_evals_to_resolve": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -93,7 +94,8 @@
|
||||
"simplified_query_and_expressions_section": false,
|
||||
"simplified_notifications_section": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"missing_series_evals_to_resolve": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
}
|
||||
],
|
||||
"no_data_state": "NoData",
|
||||
"exec_err_state": "Alerting"
|
||||
"exec_err_state": "Alerting",
|
||||
"missing_series_evals_to_resolve": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -49,7 +50,8 @@
|
||||
}
|
||||
],
|
||||
"no_data_state": "NoData",
|
||||
"exec_err_state": "Alerting"
|
||||
"exec_err_state": "Alerting",
|
||||
"missing_series_evals_to_resolve": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user