diff --git a/pkg/expr/graph.go b/pkg/expr/graph.go index 260af692e92..6f02526d104 100644 --- a/pkg/expr/graph.go +++ b/pkg/expr/graph.go @@ -157,7 +157,7 @@ func (s *Service) buildGraph(req *Request) (*simple.DirectedGraph, error) { case dsName == DatasourceName || dsUID == DatasourceUID: node, err = buildCMDNode(dp, rn) default: // If it's not an expression query, it's a data source query. - node, err = s.buildDSNode(dp, rn, req.OrgId) + node, err = s.buildDSNode(dp, rn, req) } if err != nil { return nil, err diff --git a/pkg/expr/nodes.go b/pkg/expr/nodes.go index 616015aace3..f88d054e0a9 100644 --- a/pkg/expr/nodes.go +++ b/pkg/expr/nodes.go @@ -142,6 +142,7 @@ type DSNode struct { timeRange TimeRange intervalMS int64 maxDP int64 + request Request } // NodeType returns the data pipeline node type. @@ -149,7 +150,7 @@ func (dn *DSNode) NodeType() NodeType { return TypeDatasourceNode } -func (s *Service) buildDSNode(dp *simple.DirectedGraph, rn *rawNode, orgID int64) (*DSNode, error) { +func (s *Service) buildDSNode(dp *simple.DirectedGraph, rn *rawNode, req *Request) (*DSNode, error) { encodedQuery, err := json.Marshal(rn.Query) if err != nil { return nil, err @@ -160,12 +161,13 @@ func (s *Service) buildDSNode(dp *simple.DirectedGraph, rn *rawNode, orgID int64 id: dp.NewNode().ID(), refID: rn.RefID, }, - orgID: orgID, + orgID: req.OrgId, query: json.RawMessage(encodedQuery), queryType: rn.QueryType, intervalMS: defaultIntervalMS, maxDP: defaultMaxDP, timeRange: rn.TimeRange, + request: *req, } rawDsID, ok := rn.Query["datasourceId"] @@ -231,6 +233,7 @@ func (dn *DSNode) Execute(ctx context.Context, vars mathexp.Vars, s *Service) (m resp, err := s.queryData(ctx, &backend.QueryDataRequest{ PluginContext: pc, Queries: q, + Headers: dn.request.Headers, }) if err != nil { diff --git a/pkg/expr/transform.go b/pkg/expr/transform.go index c5d31560862..11416b7e4ac 100644 --- a/pkg/expr/transform.go +++ b/pkg/expr/transform.go @@ -206,6 +206,7 @@ func (s *Service) queryData(ctx context.Context, req *backend.QueryDataRequest) tQ := plugins.DataQuery{ TimeRange: &timeRange, Queries: queries, + Headers: req.Headers, } // Execute the converted queries diff --git a/pkg/services/ngalert/eval/eval.go b/pkg/services/ngalert/eval/eval.go index 475cd442153..c7fd9cf2373 100644 --- a/pkg/services/ngalert/eval/eval.go +++ b/pkg/services/ngalert/eval/eval.go @@ -117,6 +117,10 @@ type AlertExecCtx struct { func GetExprRequest(ctx AlertExecCtx, data []models.AlertQuery, now time.Time) (*expr.Request, error) { req := &expr.Request{ OrgId: ctx.OrgID, + Headers: map[string]string{ + // Some data sources check this in query method as sometimes alerting needs special considerations. + "FromAlert": "true", + }, } for i := range data { diff --git a/pkg/tsdb/cloudwatch/annotation_query.go b/pkg/tsdb/cloudwatch/annotation_query.go index 1a427afaaeb..81dd9ccb72e 100644 --- a/pkg/tsdb/cloudwatch/annotation_query.go +++ b/pkg/tsdb/cloudwatch/annotation_query.go @@ -21,10 +21,7 @@ func (e *cloudWatchExecutor) executeAnnotationQuery(ctx context.Context, model * namespace := model.Get("namespace").MustString("") metricName := model.Get("metricName").MustString("") dimensions := model.Get("dimensions").MustMap() - statistics, err := parseStatistics(model) - if err != nil { - return nil, err - } + statistics := parseStatistics(model) period := int64(model.Get("period").MustInt(0)) if period == 0 && !usePrefixMatch { period = 300 diff --git a/pkg/tsdb/cloudwatch/request_parser.go b/pkg/tsdb/cloudwatch/request_parser.go index 8a9f10a368e..d27410b653c 100644 --- a/pkg/tsdb/cloudwatch/request_parser.go +++ b/pkg/tsdb/cloudwatch/request_parser.go @@ -2,6 +2,7 @@ package cloudwatch import ( "errors" + "fmt" "math" "regexp" "sort" @@ -52,20 +53,17 @@ func parseRequestQuery(model *simplejson.Json, refId string, startTime time.Time } namespace, err := model.Get("namespace").String() if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get namespace: %v", err) } metricName, err := model.Get("metricName").String() if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get metricName: %v", err) } dimensions, err := parseDimensions(model) if err != nil { - return nil, err - } - statistics, err := parseStatistics(model) - if err != nil { - return nil, err + return nil, fmt.Errorf("failed to parse dimensions: %v", err) } + statistics := parseStatistics(model) p := model.Get("period").MustString("") var period int @@ -84,12 +82,12 @@ func parseRequestQuery(model *simplejson.Json, refId string, startTime time.Time if reNumber.Match([]byte(p)) { period, err = strconv.Atoi(p) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to parse period as integer: %v", err) } } else { d, err := time.ParseDuration(p) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to parse period as duration: %v", err) } period = int(d.Seconds()) } @@ -125,13 +123,13 @@ func parseRequestQuery(model *simplejson.Json, refId string, startTime time.Time }, nil } -func parseStatistics(model *simplejson.Json) ([]string, error) { +func parseStatistics(model *simplejson.Json) []string { var statistics []string for _, s := range model.Get("statistics").MustArray() { statistics = append(statistics, s.(string)) } - return statistics, nil + return statistics } func parseDimensions(model *simplejson.Json) (map[string][]string, error) { @@ -145,7 +143,7 @@ func parseDimensions(model *simplejson.Json) (map[string][]string, error) { parsedDimensions[k] = append(parsedDimensions[k], value.(string)) } } else { - return nil, errors.New("failed to parse dimensions") + return nil, errors.New("unknown type as dimension value") } }