2020-11-12 15:11:30 +02:00
package ngalert
import (
2021-01-19 19:11:11 +02:00
"errors"
2020-11-12 15:11:30 +02:00
"fmt"
2020-12-17 16:00:09 +02:00
"time"
2020-11-12 15:11:30 +02:00
"github.com/grafana/grafana/pkg/models"
2020-12-17 16:00:09 +02:00
"github.com/grafana/grafana/pkg/services/ngalert/eval"
2020-11-12 15:11:30 +02:00
)
2021-01-19 19:11:11 +02:00
const alertDefinitionMaxTitleLength = 190
var errEmptyTitleError = errors . New ( "title is empty" )
2020-12-17 16:00:09 +02:00
// validateAlertDefinition validates the alert definition interval and organisation.
// If requireData is true checks that it contains at least one alert query
2021-03-03 17:52:19 +02:00
func ( st storeImpl ) validateAlertDefinition ( alertDefinition * AlertDefinition , requireData bool ) error {
2020-12-17 16:00:09 +02:00
if ! requireData && len ( alertDefinition . Data ) == 0 {
2020-11-12 15:11:30 +02:00
return fmt . Errorf ( "no queries or expressions are found" )
}
2021-01-19 19:11:11 +02:00
if alertDefinition . Title == "" {
return errEmptyTitleError
}
2021-03-03 17:52:19 +02:00
if alertDefinition . IntervalSeconds % int64 ( st . baseInterval . Seconds ( ) ) != 0 {
return fmt . Errorf ( "invalid interval: %v: interval should be divided exactly by scheduler interval: %v" , time . Duration ( alertDefinition . IntervalSeconds ) * time . Second , st . baseInterval )
2020-12-17 16:00:09 +02:00
}
// enfore max name length in SQLite
2021-01-19 19:11:11 +02:00
if len ( alertDefinition . Title ) > alertDefinitionMaxTitleLength {
return fmt . Errorf ( "name length should not be greater than %d" , alertDefinitionMaxTitleLength )
2020-12-17 16:00:09 +02:00
}
if alertDefinition . OrgID == 0 {
return fmt . Errorf ( "no organisation is found" )
}
return nil
}
// validateCondition validates that condition queries refer to existing datasources
2021-03-03 17:52:19 +02:00
func ( api * apiImpl ) validateCondition ( c eval . Condition , user * models . SignedInUser , skipCache bool ) error {
2020-12-17 16:00:09 +02:00
var refID string
if len ( c . QueriesAndExpressions ) == 0 {
return nil
}
for _ , query := range c . QueriesAndExpressions {
if c . RefID == query . RefID {
refID = c . RefID
}
2021-01-15 18:33:50 +02:00
datasourceUID , err := query . GetDatasource ( )
2020-11-12 15:11:30 +02:00
if err != nil {
return err
}
2021-01-15 18:33:50 +02:00
isExpression , err := query . IsExpression ( )
if err != nil {
return err
}
if isExpression {
2020-12-17 16:00:09 +02:00
continue
2020-11-12 15:11:30 +02:00
}
2021-03-03 17:52:19 +02:00
_ , err = api . DatasourceCache . GetDatasourceByUID ( datasourceUID , user , skipCache )
2020-11-12 15:11:30 +02:00
if err != nil {
2021-01-15 18:33:50 +02:00
return fmt . Errorf ( "failed to get datasource: %s: %w" , datasourceUID , err )
2020-11-12 15:11:30 +02:00
}
}
2020-12-17 16:00:09 +02:00
if refID == "" {
return fmt . Errorf ( "condition %s not found in any query or expression" , c . RefID )
}
2020-11-12 15:11:30 +02:00
return nil
}