Cloudwatch: Refactor dimension values resource request (#57346)

* refactor dimension values backend

* fix test file name
This commit is contained in:
Erik Sundell
2022-10-24 15:04:25 +02:00
committed by GitHub
parent 9ebed91eed
commit 017da781cf
23 changed files with 587 additions and 277 deletions
+47 -10
View File
@@ -2,11 +2,13 @@ package services
import (
"fmt"
"sort"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cloudwatch"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/constants"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/request"
)
type ListMetricsService struct {
@@ -26,7 +28,7 @@ func (*ListMetricsService) GetHardCodedDimensionKeysByNamespace(namespace string
return dimensionKeys, nil
}
func (l *ListMetricsService) GetDimensionKeysByDimensionFilter(r *models.DimensionKeysRequest) ([]string, error) {
func (l *ListMetricsService) GetDimensionKeysByDimensionFilter(r *request.DimensionKeysRequest) ([]string, error) {
input := &cloudwatch.ListMetricsInput{}
if r.Namespace != "" {
input.Namespace = aws.String(r.Namespace)
@@ -34,15 +36,7 @@ func (l *ListMetricsService) GetDimensionKeysByDimensionFilter(r *models.Dimensi
if r.MetricName != "" {
input.MetricName = aws.String(r.MetricName)
}
for _, dimension := range r.DimensionFilter {
df := &cloudwatch.DimensionFilter{
Name: aws.String(dimension.Name),
}
if dimension.Value != "" {
df.Value = aws.String(dimension.Value)
}
input.Dimensions = append(input.Dimensions, df)
}
setDimensionFilter(input, r.DimensionFilter)
metrics, err := l.ListMetricsWithPageLimit(input)
if err != nil {
@@ -79,6 +73,37 @@ func (l *ListMetricsService) GetDimensionKeysByDimensionFilter(r *models.Dimensi
return dimensionKeys, nil
}
func (l *ListMetricsService) GetDimensionValuesByDimensionFilter(r *request.DimensionValuesRequest) ([]string, error) {
input := &cloudwatch.ListMetricsInput{
Namespace: aws.String(r.Namespace),
MetricName: aws.String(r.MetricName),
}
setDimensionFilter(input, r.DimensionFilter)
metrics, err := l.ListMetricsWithPageLimit(input)
if err != nil {
return nil, fmt.Errorf("%v: %w", "unable to call AWS API", err)
}
var dimensionValues []string
dupCheck := make(map[string]bool)
for _, metric := range metrics {
for _, dim := range metric.Dimensions {
if *dim.Name == r.DimensionKey {
if _, exists := dupCheck[*dim.Value]; exists {
continue
}
dupCheck[*dim.Value] = true
dimensionValues = append(dimensionValues, *dim.Value)
}
}
}
sort.Strings(dimensionValues)
return dimensionValues, nil
}
func (l *ListMetricsService) GetDimensionKeysByNamespace(namespace string) ([]string, error) {
metrics, err := l.ListMetricsWithPageLimit(&cloudwatch.ListMetricsInput{Namespace: aws.String(namespace)})
if err != nil {
@@ -100,3 +125,15 @@ func (l *ListMetricsService) GetDimensionKeysByNamespace(namespace string) ([]st
return dimensionKeys, nil
}
func setDimensionFilter(input *cloudwatch.ListMetricsInput, dimensionFilter []*request.Dimension) {
for _, dimension := range dimensionFilter {
df := &cloudwatch.DimensionFilter{
Name: aws.String(dimension.Name),
}
if dimension.Value != "" {
df.Value = aws.String(dimension.Value)
}
input.Dimensions = append(input.Dimensions, df)
}
}
@@ -6,7 +6,7 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cloudwatch"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/request"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
@@ -64,11 +64,11 @@ func TestListMetricsService_GetDimensionKeysByDimensionFilter(t *testing.T) {
fakeMetricsClient.On("ListMetricsWithPageLimit", mock.Anything).Return(metricResponse, nil)
listMetricsService := NewListMetricsService(fakeMetricsClient)
resp, err := listMetricsService.GetDimensionKeysByDimensionFilter(&models.DimensionKeysRequest{
Region: "us-east-1",
Namespace: "AWS/EC2",
MetricName: "CPUUtilization",
DimensionFilter: []*models.Dimension{
resp, err := listMetricsService.GetDimensionKeysByDimensionFilter(&request.DimensionKeysRequest{
ResourceRequest: &request.ResourceRequest{Region: "us-east-1"},
Namespace: "AWS/EC2",
MetricName: "CPUUtilization",
DimensionFilter: []*request.Dimension{
{Name: "InstanceId", Value: ""},
},
})
@@ -90,3 +90,24 @@ func TestListMetricsService_GetDimensionKeysByNamespace(t *testing.T) {
assert.Equal(t, []string{"InstanceId", "InstanceType", "AutoScalingGroupName"}, resp)
})
}
func TestListMetricsService_GetDimensionValuesByDimensionFilter(t *testing.T) {
t.Run("Should filter out duplicates and keys matching dimension filter keys", func(t *testing.T) {
fakeMetricsClient := &mocks.FakeMetricsClient{}
fakeMetricsClient.On("ListMetricsWithPageLimit", mock.Anything).Return(metricResponse, nil)
listMetricsService := NewListMetricsService(fakeMetricsClient)
resp, err := listMetricsService.GetDimensionValuesByDimensionFilter(&request.DimensionValuesRequest{
ResourceRequest: &request.ResourceRequest{Region: "us-east-1"},
Namespace: "AWS/EC2",
MetricName: "CPUUtilization",
DimensionKey: "InstanceId",
DimensionFilter: []*request.Dimension{
{Name: "InstanceId", Value: ""},
},
})
require.NoError(t, err)
assert.Equal(t, []string{"i-1234567890abcdef0", "i-5234567890abcdef0", "i-64234567890abcdef0"}, resp)
})
}