mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Panel ID annotation cannot be set without Dashboard UID (#40019)
This commit is contained in:
parent
2f731d42f3
commit
935bd34a30
@ -503,6 +503,10 @@ func (st DBstore) validateAlertRule(alertRule ngmodels.AlertRule) error {
|
|||||||
return fmt.Errorf("%w: no organisation is found", ngmodels.ErrAlertRuleFailedValidation)
|
return fmt.Errorf("%w: no organisation is found", ngmodels.ErrAlertRuleFailedValidation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if alertRule.DashboardUID == nil && alertRule.PanelID != nil {
|
||||||
|
return fmt.Errorf("%w: cannot have Panel ID without a Dashboard UID", ngmodels.ErrAlertRuleFailedValidation)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,6 +158,11 @@ func (m *updateDashboardUIDPanelIDMigration) Exec(sess *xorm.Session, mg *migrat
|
|||||||
}
|
}
|
||||||
panelID = &i
|
panelID = &i
|
||||||
}
|
}
|
||||||
|
// We do not want to set panel_id to a non-nil value when dashboard_uid is nil
|
||||||
|
// as panel_id is not unique and so cannot be queried without its dashboard_uid.
|
||||||
|
// This can happen where users have deleted the dashboard_uid annotation but kept
|
||||||
|
// the panel_id annotation.
|
||||||
|
if dashboardUID != nil {
|
||||||
if _, err := sess.Exec(`UPDATE alert_rule SET dashboard_uid = ?, panel_id = ? WHERE id = ?`,
|
if _, err := sess.Exec(`UPDATE alert_rule SET dashboard_uid = ?, panel_id = ? WHERE id = ?`,
|
||||||
dashboardUID,
|
dashboardUID,
|
||||||
panelID,
|
panelID,
|
||||||
@ -165,6 +170,7 @@ func (m *updateDashboardUIDPanelIDMigration) Exec(sess *xorm.Session, mg *migrat
|
|||||||
return fmt.Errorf("failed to set dashboard_uid and panel_id for alert rule: %w", err)
|
return fmt.Errorf("failed to set dashboard_uid and panel_id for alert rule: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,6 +150,60 @@ func TestPrometheusRules(t *testing.T) {
|
|||||||
require.JSONEq(t, `{"message":"rule group updated successfully"}`, string(b))
|
require.JSONEq(t, `{"message":"rule group updated successfully"}`, string(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that we cannot create a rule that has a panel_id and no dashboard_uid
|
||||||
|
{
|
||||||
|
rules := apimodels.PostableRuleGroupConfig{
|
||||||
|
Name: "anotherrulegroup",
|
||||||
|
Rules: []apimodels.PostableExtendedRuleNode{
|
||||||
|
{
|
||||||
|
ApiRuleNode: &apimodels.ApiRuleNode{
|
||||||
|
For: interval,
|
||||||
|
Labels: map[string]string{},
|
||||||
|
Annotations: map[string]string{"__panelId__": "1"},
|
||||||
|
},
|
||||||
|
// this rule does not explicitly set no data and error states
|
||||||
|
// therefore it should get the default values
|
||||||
|
GrafanaManagedAlert: &apimodels.PostableGrafanaRule{
|
||||||
|
Title: "NeverCreated",
|
||||||
|
Condition: "A",
|
||||||
|
Data: []ngmodels.AlertQuery{
|
||||||
|
{
|
||||||
|
RefID: "A",
|
||||||
|
RelativeTimeRange: ngmodels.RelativeTimeRange{
|
||||||
|
From: ngmodels.Duration(time.Duration(5) * time.Hour),
|
||||||
|
To: ngmodels.Duration(time.Duration(3) * time.Hour),
|
||||||
|
},
|
||||||
|
DatasourceUID: "-100",
|
||||||
|
Model: json.RawMessage(`{
|
||||||
|
"type": "math",
|
||||||
|
"expression": "2 + 3 > 1"
|
||||||
|
}`),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
buf := bytes.Buffer{}
|
||||||
|
enc := json.NewEncoder(&buf)
|
||||||
|
err := enc.Encode(&rules)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
u := fmt.Sprintf("http://grafana:password@%s/api/ruler/grafana/api/v1/rules/default", grafanaListedAddr)
|
||||||
|
// nolint:gosec
|
||||||
|
resp, err := http.Post(u, "application/json", &buf)
|
||||||
|
require.NoError(t, err)
|
||||||
|
t.Cleanup(func() {
|
||||||
|
err := resp.Body.Close()
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
b, err := ioutil.ReadAll(resp.Body)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, 400, resp.StatusCode)
|
||||||
|
require.JSONEq(t, `{"message":"failed to update rule group: invalid alert rule: cannot have Panel ID without a Dashboard UID"}`, string(b))
|
||||||
|
}
|
||||||
|
|
||||||
// Now, let's see how this looks like.
|
// Now, let's see how this looks like.
|
||||||
{
|
{
|
||||||
promRulesURL := fmt.Sprintf("http://grafana:password@%s/api/prometheus/grafana/api/v1/rules", grafanaListedAddr)
|
promRulesURL := fmt.Sprintf("http://grafana:password@%s/api/prometheus/grafana/api/v1/rules", grafanaListedAddr)
|
||||||
|
Loading…
Reference in New Issue
Block a user