瀏覽代碼

Merge pull request #14151 from grafana/14150_cloudwatch

Fix invalid time range causes panic in Cloudwatch datasources
Marcus Efraimsson 7 年之前
父節點
當前提交
40a38552a9
共有 2 個文件被更改,包括 47 次插入2 次删除
  1. 25 2
      pkg/tsdb/cloudwatch/cloudwatch.go
  2. 22 0
      pkg/tsdb/cloudwatch/cloudwatch_test.go

+ 25 - 2
pkg/tsdb/cloudwatch/cloudwatch.go

@@ -126,6 +126,18 @@ func (e *CloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, queryCo
 		}
 
 		eg.Go(func() error {
+			defer func() {
+				if err := recover(); err != nil {
+					plog.Error("Execute Query Panic", "error", err, "stack", log.Stack(1))
+					if theErr, ok := err.(error); ok {
+						resultChan <- &tsdb.QueryResult{
+							RefId: query.RefId,
+							Error: theErr,
+						}
+					}
+				}
+			}()
+
 			queryRes, err := e.executeQuery(ectx, query, queryContext)
 			if ae, ok := err.(awserr.Error); ok && ae.Code() == "500" {
 				return err
@@ -146,6 +158,17 @@ func (e *CloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, queryCo
 		for region, getMetricDataQuery := range getMetricDataQueries {
 			q := getMetricDataQuery
 			eg.Go(func() error {
+				defer func() {
+					if err := recover(); err != nil {
+						plog.Error("Execute Get Metric Data Query Panic", "error", err, "stack", log.Stack(1))
+						if theErr, ok := err.(error); ok {
+							resultChan <- &tsdb.QueryResult{
+								Error: theErr,
+							}
+						}
+					}
+				}()
+
 				queryResponses, err := e.executeGetMetricDataQuery(ectx, region, q, queryContext)
 				if ae, ok := err.(awserr.Error); ok && ae.Code() == "500" {
 					return err
@@ -188,8 +211,8 @@ func (e *CloudWatchExecutor) executeQuery(ctx context.Context, query *CloudWatch
 		return nil, err
 	}
 
-	if endTime.Before(startTime) {
-		return nil, fmt.Errorf("Invalid time range: End time can't be before start time")
+	if !startTime.Before(endTime) {
+		return nil, fmt.Errorf("Invalid time range: Start time must be before end time")
 	}
 
 	params := &cloudwatch.GetMetricStatisticsInput{

+ 22 - 0
pkg/tsdb/cloudwatch/cloudwatch_test.go

@@ -1,9 +1,13 @@
 package cloudwatch
 
 import (
+	"context"
 	"testing"
 	"time"
 
+	"github.com/grafana/grafana/pkg/models"
+	"github.com/grafana/grafana/pkg/tsdb"
+
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/service/cloudwatch"
 	"github.com/grafana/grafana/pkg/components/null"
@@ -14,6 +18,24 @@ import (
 func TestCloudWatch(t *testing.T) {
 	Convey("CloudWatch", t, func() {
 
+		Convey("executeQuery", func() {
+			e := &CloudWatchExecutor{
+				DataSource: &models.DataSource{
+					JsonData: simplejson.New(),
+				},
+			}
+
+			Convey("End time before start time should result in error", func() {
+				_, err := e.executeQuery(context.Background(), &CloudWatchQuery{}, &tsdb.TsdbQuery{TimeRange: tsdb.NewTimeRange("now-1h", "now-2h")})
+				So(err.Error(), ShouldEqual, "Invalid time range: Start time must be before end time")
+			})
+
+			Convey("End time equals start time should result in error", func() {
+				_, err := e.executeQuery(context.Background(), &CloudWatchQuery{}, &tsdb.TsdbQuery{TimeRange: tsdb.NewTimeRange("now-1h", "now-1h")})
+				So(err.Error(), ShouldEqual, "Invalid time range: Start time must be before end time")
+			})
+		})
+
 		Convey("can parse cloudwatch json model", func() {
 			json := `
 				{