Commit 52e1c411 by Mitsuhiro Tanda Committed by Torkel Ödegaard

fix cloudwatch ec2_instance_attribute (#9718)

* fix cloudwatch ec2_instance_attribute

* add test

* minor fix
parent 685ee393
...@@ -17,6 +17,7 @@ import ( ...@@ -17,6 +17,7 @@ import (
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/cloudwatch" "github.com/aws/aws-sdk-go/service/cloudwatch"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/grafana/grafana/pkg/components/null" "github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/metrics" "github.com/grafana/grafana/pkg/metrics"
...@@ -24,6 +25,7 @@ import ( ...@@ -24,6 +25,7 @@ import (
type CloudWatchExecutor struct { type CloudWatchExecutor struct {
*models.DataSource *models.DataSource
ec2Svc ec2iface.EC2API
} }
type DatasourceInfo struct { type DatasourceInfo struct {
......
...@@ -185,6 +185,18 @@ func (e *CloudWatchExecutor) executeMetricFindQuery(ctx context.Context, queryCo ...@@ -185,6 +185,18 @@ func (e *CloudWatchExecutor) executeMetricFindQuery(ctx context.Context, queryCo
data, err = e.handleGetEbsVolumeIds(ctx, parameters, queryContext) data, err = e.handleGetEbsVolumeIds(ctx, parameters, queryContext)
break break
case "ec2_instance_attribute": case "ec2_instance_attribute":
region := parameters.Get("region").MustString()
dsInfo := e.getDsInfo(region)
cfg, err := e.getAwsConfig(dsInfo)
if err != nil {
return nil, errors.New("Failed to call ec2:DescribeInstances")
}
sess, err := session.NewSession(cfg)
if err != nil {
return nil, errors.New("Failed to call ec2:DescribeInstances")
}
e.ec2Svc = ec2.New(sess, cfg)
data, err = e.handleGetEc2InstanceAttribute(ctx, parameters, queryContext) data, err = e.handleGetEc2InstanceAttribute(ctx, parameters, queryContext)
break break
} }
...@@ -375,14 +387,16 @@ func (e *CloudWatchExecutor) handleGetEc2InstanceAttribute(ctx context.Context, ...@@ -375,14 +387,16 @@ func (e *CloudWatchExecutor) handleGetEc2InstanceAttribute(ctx context.Context,
var filters []*ec2.Filter var filters []*ec2.Filter
for k, v := range filterJson { for k, v := range filterJson {
if vv, ok := v.([]string); ok { if vv, ok := v.([]interface{}); ok {
var vvvv []*string var vvvvv []*string
for _, vvv := range vv { for _, vvv := range vv {
vvvv = append(vvvv, &vvv) if vvvv, ok := vvv.(string); ok {
vvvvv = append(vvvvv, &vvvv)
}
} }
filters = append(filters, &ec2.Filter{ filters = append(filters, &ec2.Filter{
Name: aws.String(k), Name: aws.String(k),
Values: vvvv, Values: vvvvv,
}) })
} }
} }
...@@ -469,24 +483,13 @@ func (e *CloudWatchExecutor) cloudwatchListMetrics(region string, namespace stri ...@@ -469,24 +483,13 @@ func (e *CloudWatchExecutor) cloudwatchListMetrics(region string, namespace stri
} }
func (e *CloudWatchExecutor) ec2DescribeInstances(region string, filters []*ec2.Filter, instanceIds []*string) (*ec2.DescribeInstancesOutput, error) { func (e *CloudWatchExecutor) ec2DescribeInstances(region string, filters []*ec2.Filter, instanceIds []*string) (*ec2.DescribeInstancesOutput, error) {
dsInfo := e.getDsInfo(region)
cfg, err := e.getAwsConfig(dsInfo)
if err != nil {
return nil, errors.New("Failed to call ec2:DescribeInstances")
}
sess, err := session.NewSession(cfg)
if err != nil {
return nil, errors.New("Failed to call ec2:DescribeInstances")
}
svc := ec2.New(sess, cfg)
params := &ec2.DescribeInstancesInput{ params := &ec2.DescribeInstancesInput{
Filters: filters, Filters: filters,
InstanceIds: instanceIds, InstanceIds: instanceIds,
} }
var resp ec2.DescribeInstancesOutput var resp ec2.DescribeInstancesOutput
err = svc.DescribeInstancesPages(params, err := e.ec2Svc.DescribeInstancesPages(params,
func(page *ec2.DescribeInstancesOutput, lastPage bool) bool { func(page *ec2.DescribeInstancesOutput, lastPage bool) bool {
reservations, _ := awsutil.ValuesAtPath(page, "Reservations") reservations, _ := awsutil.ValuesAtPath(page, "Reservations")
for _, reservation := range reservations { for _, reservation := range reservations {
......
package cloudwatch package cloudwatch
import ( import (
"context"
"testing" "testing"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"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/ec2iface"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/tsdb"
. "github.com/smartystreets/goconvey/convey" . "github.com/smartystreets/goconvey/convey"
) )
type mockedEc2 struct {
ec2iface.EC2API
Resp ec2.DescribeInstancesOutput
}
func (m mockedEc2) DescribeInstancesPages(in *ec2.DescribeInstancesInput, fn func(*ec2.DescribeInstancesOutput, bool) bool) error {
fn(&m.Resp, true)
return nil
}
func TestCloudWatchMetrics(t *testing.T) { func TestCloudWatchMetrics(t *testing.T) {
Convey("When calling getMetricsForCustomMetrics", t, func() { Convey("When calling getMetricsForCustomMetrics", t, func() {
...@@ -66,4 +81,37 @@ func TestCloudWatchMetrics(t *testing.T) { ...@@ -66,4 +81,37 @@ func TestCloudWatchMetrics(t *testing.T) {
}) })
}) })
Convey("When calling handleGetEc2InstanceAttribute", t, func() {
executor := &CloudWatchExecutor{
ec2Svc: mockedEc2{Resp: ec2.DescribeInstancesOutput{
Reservations: []*ec2.Reservation{
{
Instances: []*ec2.Instance{
{
InstanceId: aws.String("i-12345678"),
Tags: []*ec2.Tag{
{
Key: aws.String("Environment"),
Value: aws.String("production"),
},
},
},
},
},
},
}},
}
json := simplejson.New()
json.Set("region", "us-east-1")
json.Set("attributeName", "InstanceId")
filters := make(map[string]interface{})
filters["tag:Environment"] = []string{"production"}
json.Set("filters", filters)
result, _ := executor.handleGetEc2InstanceAttribute(context.Background(), json, &tsdb.TsdbQuery{})
Convey("Should equal production InstanceId", func() {
So(result[0].Text, ShouldEqual, "i-12345678")
})
})
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment