mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
AlertingNG: Add For+Annotations to Grafana_Alert (#32793)
* add db columns * Fix deserialisation issue of AlertRule For field (#32848) * Update to latest alerting-api Co-authored-by: Sofia Papagiannaki <papagian@users.noreply.github.com>
This commit is contained in:
parent
fa45fc1833
commit
80dfa83380
4
go.mod
4
go.mod
@ -41,7 +41,7 @@ require (
|
|||||||
github.com/google/go-cmp v0.5.5
|
github.com/google/go-cmp v0.5.5
|
||||||
github.com/google/uuid v1.2.0
|
github.com/google/uuid v1.2.0
|
||||||
github.com/gosimple/slug v1.9.0
|
github.com/gosimple/slug v1.9.0
|
||||||
github.com/grafana/alerting-api v0.0.0-20210407150830-64bd267999d1
|
github.com/grafana/alerting-api v0.0.0-20210409134845-c36ac1eae41b
|
||||||
github.com/grafana/grafana-aws-sdk v0.4.0
|
github.com/grafana/grafana-aws-sdk v0.4.0
|
||||||
github.com/grafana/grafana-live-sdk v0.0.4
|
github.com/grafana/grafana-live-sdk v0.0.4
|
||||||
github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4
|
github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4
|
||||||
@ -103,4 +103,4 @@ require (
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||||
xorm.io/core v0.7.3
|
xorm.io/core v0.7.3
|
||||||
xorm.io/xorm v0.8.2
|
xorm.io/xorm v0.8.2
|
||||||
)
|
)
|
10
go.sum
10
go.sum
@ -816,8 +816,18 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U
|
|||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/gosimple/slug v1.9.0 h1:r5vDcYrFz9BmfIAMC829un9hq7hKM4cHUrsv36LbEqs=
|
github.com/gosimple/slug v1.9.0 h1:r5vDcYrFz9BmfIAMC829un9hq7hKM4cHUrsv36LbEqs=
|
||||||
github.com/gosimple/slug v1.9.0/go.mod h1:AMZ+sOVe65uByN3kgEyf9WEBKBCSS+dJjMX9x4vDJbg=
|
github.com/gosimple/slug v1.9.0/go.mod h1:AMZ+sOVe65uByN3kgEyf9WEBKBCSS+dJjMX9x4vDJbg=
|
||||||
|
github.com/grafana/alerting-api v0.0.0-20210331135037-3294563b51bb h1:Hj25Whc/TRv0hSLm5VN0FJ5R4yZ6M4ycRcBgu7bsEAc=
|
||||||
|
github.com/grafana/alerting-api v0.0.0-20210331135037-3294563b51bb/go.mod h1:5IppnPguSHcCbVLGCVzVjBvuQZNbYgVJ4KyXXjhCyWY=
|
||||||
|
github.com/grafana/alerting-api v0.0.0-20210405171311-97906879c771 h1:CTmKHUu2n0O9fPTSXb+s5FO8Em9Atw57Z7mvw7lt6IM=
|
||||||
|
github.com/grafana/alerting-api v0.0.0-20210405171311-97906879c771/go.mod h1:5IppnPguSHcCbVLGCVzVjBvuQZNbYgVJ4KyXXjhCyWY=
|
||||||
github.com/grafana/alerting-api v0.0.0-20210407150830-64bd267999d1 h1:pbG8BsRHezUvUjMxwq+uZsx1ZMEQsfSj26KSd/H3A9g=
|
github.com/grafana/alerting-api v0.0.0-20210407150830-64bd267999d1 h1:pbG8BsRHezUvUjMxwq+uZsx1ZMEQsfSj26KSd/H3A9g=
|
||||||
github.com/grafana/alerting-api v0.0.0-20210407150830-64bd267999d1/go.mod h1:Ce2PwraBlFMa+P0ArBzubfB/BXZV35mfYWQjM8C/BSE=
|
github.com/grafana/alerting-api v0.0.0-20210407150830-64bd267999d1/go.mod h1:Ce2PwraBlFMa+P0ArBzubfB/BXZV35mfYWQjM8C/BSE=
|
||||||
|
github.com/grafana/alerting-api v0.0.0-20210408130544-2969b61275a5 h1:r33Ruhf3TNvT4Y+acR8R0zBtNULnThnJRlAje2AFt6c=
|
||||||
|
github.com/grafana/alerting-api v0.0.0-20210408130544-2969b61275a5/go.mod h1:Ce2PwraBlFMa+P0ArBzubfB/BXZV35mfYWQjM8C/BSE=
|
||||||
|
github.com/grafana/alerting-api v0.0.0-20210408135630-bc10f737ceff h1:3l/P+TIOXJy1zX/kZB6dFAMPQrpwpiN3cLMVr8B8u4Q=
|
||||||
|
github.com/grafana/alerting-api v0.0.0-20210408135630-bc10f737ceff/go.mod h1:Ce2PwraBlFMa+P0ArBzubfB/BXZV35mfYWQjM8C/BSE=
|
||||||
|
github.com/grafana/alerting-api v0.0.0-20210409134845-c36ac1eae41b h1:QG52Et3EVCxPoYZifm91bRPVknccfjQURcpi7zXVut8=
|
||||||
|
github.com/grafana/alerting-api v0.0.0-20210409134845-c36ac1eae41b/go.mod h1:Ce2PwraBlFMa+P0ArBzubfB/BXZV35mfYWQjM8C/BSE=
|
||||||
github.com/grafana/go-mssqldb v0.0.0-20210326084033-d0ce3c521036 h1:GplhUk6Xes5JIhUUrggPcPBhOn+eT8+WsHiebvq7GgA=
|
github.com/grafana/go-mssqldb v0.0.0-20210326084033-d0ce3c521036 h1:GplhUk6Xes5JIhUUrggPcPBhOn+eT8+WsHiebvq7GgA=
|
||||||
github.com/grafana/go-mssqldb v0.0.0-20210326084033-d0ce3c521036/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
github.com/grafana/go-mssqldb v0.0.0-20210326084033-d0ce3c521036/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
github.com/grafana/grafana v1.9.2-0.20210308201921-4ce0a49eac03/go.mod h1:AHRRvd4utJGY25J5nW8aL7wZzn/LcJ0z2za9oOp14j4=
|
github.com/grafana/grafana v1.9.2-0.20210308201921-4ce0a49eac03/go.mod h1:AHRRvd4utJGY25J5nW8aL7wZzn/LcJ0z2za9oOp14j4=
|
||||||
|
@ -211,6 +211,8 @@ func toGettableExtendedRuleNode(r ngmodels.AlertRule) apimodels.GettableExtended
|
|||||||
RuleGroup: r.RuleGroup,
|
RuleGroup: r.RuleGroup,
|
||||||
NoDataState: apimodels.NoDataState(r.NoDataState),
|
NoDataState: apimodels.NoDataState(r.NoDataState),
|
||||||
ExecErrState: apimodels.ExecutionErrorState(r.ExecErrState),
|
ExecErrState: apimodels.ExecutionErrorState(r.ExecErrState),
|
||||||
|
For: r.For,
|
||||||
|
Annotations: r.Annotations,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,6 +227,8 @@ func toPostableExtendedRuleNode(r ngmodels.AlertRule) apimodels.PostableExtended
|
|||||||
UID: r.UID,
|
UID: r.UID,
|
||||||
NoDataState: apimodels.NoDataState(r.NoDataState),
|
NoDataState: apimodels.NoDataState(r.NoDataState),
|
||||||
ExecErrState: apimodels.ExecutionErrorState(r.ExecErrState),
|
ExecErrState: apimodels.ExecutionErrorState(r.ExecErrState),
|
||||||
|
For: r.For,
|
||||||
|
Annotations: r.Annotations,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,23 +158,26 @@ func (api *API) ruleGroupByOldID(c *models.ReqContext) response.Response {
|
|||||||
return response.Error(400, "unable to translate nodata/exec error settings",
|
return response.Error(400, "unable to translate nodata/exec error settings",
|
||||||
fmt.Errorf("unable to translate nodata/exec error settings for alert id %v: %w", id, err))
|
fmt.Errorf("unable to translate nodata/exec error settings for alert id %v: %w", id, err))
|
||||||
}
|
}
|
||||||
// TODO: What to do with Rule Tags
|
|
||||||
// ruleTags := map[string]string{}
|
ruleTags := map[string]string{}
|
||||||
// for k, v := range oldAlert.Settings.Get("alertRuleTags").MustMap() {
|
|
||||||
// sV, ok := v.(string)
|
for k, v := range oldAlert.Settings.Get("alertRuleTags").MustMap() {
|
||||||
// if !ok {
|
sV, ok := v.(string)
|
||||||
// return response.Error(400, "unable to unmarshal rule tags",
|
if !ok {
|
||||||
// fmt.Errorf("unexpected type %T for tag %v", v, k))
|
return response.Error(400, "unable to unmarshal rule tags",
|
||||||
// }
|
fmt.Errorf("unexpected type %T for tag %v", v, k))
|
||||||
// ruleTags[k] = sV
|
}
|
||||||
// }
|
ruleTags[k] = sV
|
||||||
// TODO: Need place to put FOR duration
|
}
|
||||||
|
|
||||||
rule := ngmodels.AlertRule{
|
rule := ngmodels.AlertRule{
|
||||||
Title: oldAlert.Name,
|
Title: oldAlert.Name,
|
||||||
Data: sseCond.Data,
|
Data: sseCond.Data,
|
||||||
Condition: sseCond.Condition,
|
Condition: sseCond.Condition,
|
||||||
NoDataState: *noDataSetting,
|
NoDataState: *noDataSetting,
|
||||||
ExecErrState: *execErrSetting,
|
ExecErrState: *execErrSetting,
|
||||||
|
For: ngmodels.Duration(oldAlert.For),
|
||||||
|
Annotations: ruleTags,
|
||||||
}
|
}
|
||||||
rgc := apimodels.PostableRuleGroupConfig{
|
rgc := apimodels.PostableRuleGroupConfig{
|
||||||
// TODO? Generate new name on conflict?
|
// TODO? Generate new name on conflict?
|
||||||
@ -204,6 +207,7 @@ func (api *API) ruleGroupByOldID(c *models.ReqContext) response.Response {
|
|||||||
}
|
}
|
||||||
return response.JSON(200, cmd)
|
return response.JSON(200, cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func transAdjustInterval(freq int64) model.Duration {
|
func transAdjustInterval(freq int64) model.Duration {
|
||||||
// 10 corresponds to the SchedulerCfg, but TODO not worrying about fetching for now.
|
// 10 corresponds to the SchedulerCfg, but TODO not worrying about fetching for now.
|
||||||
var baseFreq int64 = 10
|
var baseFreq int64 = 10
|
||||||
@ -212,6 +216,7 @@ func transAdjustInterval(freq int64) model.Duration {
|
|||||||
}
|
}
|
||||||
return model.Duration(time.Duration((freq - (freq % baseFreq))) * time.Second)
|
return model.Duration(time.Duration((freq - (freq % baseFreq))) * time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
func transGetAlertById(id int64, user models.SignedInUser) (*models.Alert, int, error) {
|
func transGetAlertById(id int64, user models.SignedInUser) (*models.Alert, int, error) {
|
||||||
getAlert := &models.GetAlertByIdQuery{
|
getAlert := &models.GetAlertByIdQuery{
|
||||||
Id: id,
|
Id: id,
|
||||||
@ -224,6 +229,7 @@ func transGetAlertById(id int64, user models.SignedInUser) (*models.Alert, int,
|
|||||||
}
|
}
|
||||||
return getAlert.Result, 0, nil
|
return getAlert.Result, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func transGetAlertsDashById(dashboardId int64, user models.SignedInUser) (*models.Dashboard, int, error) {
|
func transGetAlertsDashById(dashboardId int64, user models.SignedInUser) (*models.Dashboard, int, error) {
|
||||||
getDash := &models.GetDashboardQuery{
|
getDash := &models.GetDashboardQuery{
|
||||||
Id: dashboardId,
|
Id: dashboardId,
|
||||||
@ -234,6 +240,7 @@ func transGetAlertsDashById(dashboardId int64, user models.SignedInUser) (*model
|
|||||||
}
|
}
|
||||||
return getDash.Result, 0, nil
|
return getDash.Result, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func transToSSECondition(m *models.Alert, user models.SignedInUser) (*ngmodels.Condition, error) {
|
func transToSSECondition(m *models.Alert, user models.SignedInUser) (*ngmodels.Condition, error) {
|
||||||
sb, err := m.Settings.ToDB()
|
sb, err := m.Settings.ToDB()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -245,6 +252,7 @@ func transToSSECondition(m *models.Alert, user models.SignedInUser) (*ngmodels.C
|
|||||||
}
|
}
|
||||||
return evalCond, nil
|
return evalCond, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func transNoDataExecSettings(m *models.Alert, user models.SignedInUser) (*ngmodels.NoDataState, *ngmodels.ExecutionErrorState, error) {
|
func transNoDataExecSettings(m *models.Alert, user models.SignedInUser) (*ngmodels.NoDataState, *ngmodels.ExecutionErrorState, error) {
|
||||||
oldNoData := m.Settings.Get("noDataState").MustString()
|
oldNoData := m.Settings.Get("noDataState").MustString()
|
||||||
noDataSetting, err := transNoData(oldNoData)
|
noDataSetting, err := transNoData(oldNoData)
|
||||||
@ -258,6 +266,7 @@ func transNoDataExecSettings(m *models.Alert, user models.SignedInUser) (*ngmode
|
|||||||
}
|
}
|
||||||
return &noDataSetting, &execErrSetting, nil
|
return &noDataSetting, &execErrSetting, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func transNoData(s string) (ngmodels.NoDataState, error) {
|
func transNoData(s string) (ngmodels.NoDataState, error) {
|
||||||
switch s {
|
switch s {
|
||||||
case "ok":
|
case "ok":
|
||||||
@ -271,6 +280,7 @@ func transNoData(s string) (ngmodels.NoDataState, error) {
|
|||||||
}
|
}
|
||||||
return ngmodels.NoData, fmt.Errorf("unrecognized No Data setting %v", s)
|
return ngmodels.NoData, fmt.Errorf("unrecognized No Data setting %v", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func transExecErr(s string) (ngmodels.ExecutionErrorState, error) {
|
func transExecErr(s string) (ngmodels.ExecutionErrorState, error) {
|
||||||
switch s {
|
switch s {
|
||||||
case "alerting":
|
case "alerting":
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
"grafana_alert": {
|
"grafana_alert": {
|
||||||
"title": "prom query with SSE",
|
"title": "prom query with SSE",
|
||||||
"condition": "condition",
|
"condition": "condition",
|
||||||
|
"for": 5,
|
||||||
|
"annotations": {
|
||||||
|
"foo": "bar"
|
||||||
|
},
|
||||||
"data": [
|
"data": [
|
||||||
{
|
{
|
||||||
"refId": "query",
|
"refId": "query",
|
||||||
|
@ -52,6 +52,8 @@ type AlertRule struct {
|
|||||||
RuleGroup string
|
RuleGroup string
|
||||||
NoDataState NoDataState
|
NoDataState NoDataState
|
||||||
ExecErrState ExecutionErrorState
|
ExecErrState ExecutionErrorState
|
||||||
|
For Duration
|
||||||
|
Annotations map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// AlertRuleKey is the alert definition identifier
|
// AlertRuleKey is the alert definition identifier
|
||||||
@ -100,6 +102,8 @@ type AlertRuleVersion struct {
|
|||||||
IntervalSeconds int64
|
IntervalSeconds int64
|
||||||
NoDataState NoDataState
|
NoDataState NoDataState
|
||||||
ExecErrState ExecutionErrorState
|
ExecErrState ExecutionErrorState
|
||||||
|
For Duration
|
||||||
|
Annotations map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAlertRuleByUIDQuery is the query for retrieving/deleting an alert rule by UID and organisation ID.
|
// GetAlertRuleByUIDQuery is the query for retrieving/deleting an alert rule by UID and organisation ID.
|
||||||
|
@ -211,6 +211,9 @@ func (st DBstore) UpsertAlertRules(rules []UpsertRule) error {
|
|||||||
r.New.RuleGroup = r.Existing.RuleGroup
|
r.New.RuleGroup = r.Existing.RuleGroup
|
||||||
r.New.Version = r.Existing.Version + 1
|
r.New.Version = r.Existing.Version + 1
|
||||||
|
|
||||||
|
r.New.For = r.Existing.For
|
||||||
|
r.New.Annotations = r.Existing.Annotations
|
||||||
|
|
||||||
if err := st.ValidateAlertRule(r.New, true); err != nil {
|
if err := st.ValidateAlertRule(r.New, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -241,6 +244,8 @@ func (st DBstore) UpsertAlertRules(rules []UpsertRule) error {
|
|||||||
IntervalSeconds: r.New.IntervalSeconds,
|
IntervalSeconds: r.New.IntervalSeconds,
|
||||||
NoDataState: r.New.NoDataState,
|
NoDataState: r.New.NoDataState,
|
||||||
ExecErrState: r.New.ExecErrState,
|
ExecErrState: r.New.ExecErrState,
|
||||||
|
For: r.New.For,
|
||||||
|
Annotations: r.New.Annotations,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,6 +427,8 @@ func (st DBstore) UpdateRuleGroup(cmd UpdateRuleGroupCmd) error {
|
|||||||
IntervalSeconds: int64(time.Duration(cmd.RuleGroupConfig.Interval).Seconds()),
|
IntervalSeconds: int64(time.Duration(cmd.RuleGroupConfig.Interval).Seconds()),
|
||||||
NamespaceUID: cmd.NamespaceUID,
|
NamespaceUID: cmd.NamespaceUID,
|
||||||
RuleGroup: ruleGroup,
|
RuleGroup: ruleGroup,
|
||||||
|
For: r.GrafanaManagedAlert.For,
|
||||||
|
Annotations: r.GrafanaManagedAlert.Annotations,
|
||||||
NoDataState: ngmodels.NoDataState(r.GrafanaManagedAlert.NoDataState),
|
NoDataState: ngmodels.NoDataState(r.GrafanaManagedAlert.NoDataState),
|
||||||
ExecErrState: ngmodels.ExecutionErrorState(r.GrafanaManagedAlert.ExecErrState),
|
ExecErrState: ngmodels.ExecutionErrorState(r.GrafanaManagedAlert.ExecErrState),
|
||||||
},
|
},
|
||||||
|
@ -147,6 +147,12 @@ func AddAlertRuleMigrations(mg *migrator.Migrator, defaultIntervalSeconds int64)
|
|||||||
|
|
||||||
mg.AddMigration("alter alert_rule table data column to mediumtext in mysql", migrator.NewRawSQLMigration("").
|
mg.AddMigration("alter alert_rule table data column to mediumtext in mysql", migrator.NewRawSQLMigration("").
|
||||||
Mysql("ALTER TABLE alert_rule MODIFY data MEDIUMTEXT;"))
|
Mysql("ALTER TABLE alert_rule MODIFY data MEDIUMTEXT;"))
|
||||||
|
|
||||||
|
// add for column
|
||||||
|
mg.AddMigration("add column for to alert_rule", migrator.NewAddColumnMigration(alertRule, &migrator.Column{Name: "for", Type: migrator.DB_BigInt, Nullable: false, Default: "0"}))
|
||||||
|
|
||||||
|
// add annotations column
|
||||||
|
mg.AddMigration("add column annotations to alert_rule", migrator.NewAddColumnMigration(alertRule, &migrator.Column{Name: "annotations", Type: migrator.DB_Text, Nullable: true}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddAlertRuleVersionMigrations(mg *migrator.Migrator) {
|
func AddAlertRuleVersionMigrations(mg *migrator.Migrator) {
|
||||||
@ -181,4 +187,10 @@ func AddAlertRuleVersionMigrations(mg *migrator.Migrator) {
|
|||||||
|
|
||||||
mg.AddMigration("alter alert_rule_version table data column to mediumtext in mysql", migrator.NewRawSQLMigration("").
|
mg.AddMigration("alter alert_rule_version table data column to mediumtext in mysql", migrator.NewRawSQLMigration("").
|
||||||
Mysql("ALTER TABLE alert_rule_version MODIFY data MEDIUMTEXT;"))
|
Mysql("ALTER TABLE alert_rule_version MODIFY data MEDIUMTEXT;"))
|
||||||
|
|
||||||
|
// add for column
|
||||||
|
mg.AddMigration("add column for to alert_rule_version", migrator.NewAddColumnMigration(alertRuleVersion, &migrator.Column{Name: "for", Type: migrator.DB_BigInt, Nullable: false, Default: "0"}))
|
||||||
|
|
||||||
|
// add annotations column
|
||||||
|
mg.AddMigration("add column annotations to alert_rule_version", migrator.NewAddColumnMigration(alertRuleVersion, &migrator.Column{Name: "annotations", Type: migrator.DB_Text, Nullable: true}))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user