Procházet zdrojové kódy

Cloudwatch: add support for multi instances (#10570)

* cloudwatch: fix ebs_volume_ids by create a client-session before call ec2:DescribeInstances.

* cloudwatch: add support for multi instanceIds on call ebs_volume_ids.
hannes před 8 roky
rodič
revize
43e6ea95e0

+ 22 - 3
pkg/tsdb/cloudwatch/metric_find_query.go

@@ -215,6 +215,21 @@ func transformToTable(data []suggestData, result *tsdb.QueryResult) {
 	result.Meta.Set("rowCount", len(data))
 	result.Meta.Set("rowCount", len(data))
 }
 }
 
 
+func parseMultiSelectValue(input string) []string {
+	trimmedInput := strings.TrimSpace(input)
+
+	if strings.HasPrefix(trimmedInput, "{") {
+		values := strings.Split(strings.TrimRight(strings.TrimLeft(trimmedInput, "{"), "}"), ",")
+		trimValues := make([]string, len(values))
+		for i, v := range values {
+			trimValues[i] = strings.TrimSpace(v)
+		}
+		return trimValues
+	} else {
+		return []string{trimmedInput}
+	}
+}
+
 // Whenever this list is updated, frontend list should also be updated.
 // Whenever this list is updated, frontend list should also be updated.
 // Please update the region list in public/app/plugins/datasource/cloudwatch/partials/config.html
 // Please update the region list in public/app/plugins/datasource/cloudwatch/partials/config.html
 func (e *CloudWatchExecutor) handleGetRegions(ctx context.Context, parameters *simplejson.Json, queryContext *tsdb.TsdbQuery) ([]suggestData, error) {
 func (e *CloudWatchExecutor) handleGetRegions(ctx context.Context, parameters *simplejson.Json, queryContext *tsdb.TsdbQuery) ([]suggestData, error) {
@@ -378,15 +393,19 @@ func (e *CloudWatchExecutor) handleGetEbsVolumeIds(ctx context.Context, paramete
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	instanceIds := []*string{aws.String(instanceId)}
+	instanceIds := aws.StringSlice(parseMultiSelectValue(instanceId))
 	instances, err := e.ec2DescribeInstances(region, nil, instanceIds)
 	instances, err := e.ec2DescribeInstances(region, nil, instanceIds)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
 	result := make([]suggestData, 0)
 	result := make([]suggestData, 0)
-	for _, mapping := range instances.Reservations[0].Instances[0].BlockDeviceMappings {
-		result = append(result, suggestData{Text: *mapping.Ebs.VolumeId, Value: *mapping.Ebs.VolumeId})
+	for _, reservation := range instances.Reservations {
+		for _, instance := range reservation.Instances {
+			for _, mapping := range instance.BlockDeviceMappings {
+				result = append(result, suggestData{Text: *mapping.Ebs.VolumeId, Value: *mapping.Ebs.VolumeId})
+			}
+		}
 	}
 	}
 
 
 	return result, nil
 	return result, nil

+ 82 - 0
pkg/tsdb/cloudwatch/metric_find_query_test.go

@@ -8,6 +8,7 @@ import (
 	"github.com/aws/aws-sdk-go/service/cloudwatch"
 	"github.com/aws/aws-sdk-go/service/cloudwatch"
 	"github.com/aws/aws-sdk-go/service/ec2"
 	"github.com/aws/aws-sdk-go/service/ec2"
 	"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
 	"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
+	"github.com/bmizerany/assert"
 	"github.com/grafana/grafana/pkg/components/simplejson"
 	"github.com/grafana/grafana/pkg/components/simplejson"
 	"github.com/grafana/grafana/pkg/tsdb"
 	"github.com/grafana/grafana/pkg/tsdb"
 	. "github.com/smartystreets/goconvey/convey"
 	. "github.com/smartystreets/goconvey/convey"
@@ -114,4 +115,85 @@ func TestCloudWatchMetrics(t *testing.T) {
 			So(result[0].Text, ShouldEqual, "i-12345678")
 			So(result[0].Text, ShouldEqual, "i-12345678")
 		})
 		})
 	})
 	})
+
+	Convey("When calling handleGetEbsVolumeIds", t, func() {
+
+		executor := &CloudWatchExecutor{
+			ec2Svc: mockedEc2{Resp: ec2.DescribeInstancesOutput{
+				Reservations: []*ec2.Reservation{
+					{
+						Instances: []*ec2.Instance{
+							{
+								InstanceId: aws.String("i-1"),
+								BlockDeviceMappings: []*ec2.InstanceBlockDeviceMapping{
+									{Ebs: &ec2.EbsInstanceBlockDevice{VolumeId: aws.String("vol-1-1")}},
+									{Ebs: &ec2.EbsInstanceBlockDevice{VolumeId: aws.String("vol-1-2")}},
+								},
+							},
+							{
+								InstanceId: aws.String("i-2"),
+								BlockDeviceMappings: []*ec2.InstanceBlockDeviceMapping{
+									{Ebs: &ec2.EbsInstanceBlockDevice{VolumeId: aws.String("vol-2-1")}},
+									{Ebs: &ec2.EbsInstanceBlockDevice{VolumeId: aws.String("vol-2-2")}},
+								},
+							},
+						},
+					},
+					{
+						Instances: []*ec2.Instance{
+							{
+								InstanceId: aws.String("i-3"),
+								BlockDeviceMappings: []*ec2.InstanceBlockDeviceMapping{
+									{Ebs: &ec2.EbsInstanceBlockDevice{VolumeId: aws.String("vol-3-1")}},
+									{Ebs: &ec2.EbsInstanceBlockDevice{VolumeId: aws.String("vol-3-2")}},
+								},
+							},
+							{
+								InstanceId: aws.String("i-4"),
+								BlockDeviceMappings: []*ec2.InstanceBlockDeviceMapping{
+									{Ebs: &ec2.EbsInstanceBlockDevice{VolumeId: aws.String("vol-4-1")}},
+									{Ebs: &ec2.EbsInstanceBlockDevice{VolumeId: aws.String("vol-4-2")}},
+								},
+							},
+						},
+					},
+				},
+			}},
+		}
+
+		json := simplejson.New()
+		json.Set("region", "us-east-1")
+		json.Set("instanceId", "{i-1, i-2, i-3, i-4}")
+		result, _ := executor.handleGetEbsVolumeIds(context.Background(), json, &tsdb.TsdbQuery{})
+
+		Convey("Should return all 8 VolumeIds", func() {
+			So(len(result), ShouldEqual, 8)
+			So(result[0].Text, ShouldEqual, "vol-1-1")
+			So(result[1].Text, ShouldEqual, "vol-1-2")
+			So(result[2].Text, ShouldEqual, "vol-2-1")
+			So(result[3].Text, ShouldEqual, "vol-2-2")
+			So(result[4].Text, ShouldEqual, "vol-3-1")
+			So(result[5].Text, ShouldEqual, "vol-3-2")
+			So(result[6].Text, ShouldEqual, "vol-4-1")
+			So(result[7].Text, ShouldEqual, "vol-4-2")
+		})
+	})
+}
+
+func TestParseMultiSelectValue(t *testing.T) {
+
+	var values []string
+
+	values = parseMultiSelectValue(" i-someInstance ")
+	assert.Equal(t, []string{"i-someInstance"}, values)
+
+	values = parseMultiSelectValue("{i-05}")
+	assert.Equal(t, []string{"i-05"}, values)
+
+	values = parseMultiSelectValue(" {i-01, i-03, i-04} ")
+	assert.Equal(t, []string{"i-01", "i-03", "i-04"}, values)
+
+	values = parseMultiSelectValue("i-{01}")
+	assert.Equal(t, []string{"i-{01}"}, values)
+
 }
 }