Cloudwatch: Fix Unexpected error (#74420)
Fix unexpected error when creating a new cloudwatch datasource. Involves a fair amount of refactoring, so if this causes unexpected issues related to region fetching we can turn this off with the cloudwatchNewRegionsHandler feature toggle, although we do not predict it will so we are enabling it to default to true and hope to remove it shortly.
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/constants"
|
||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/resources"
|
||||
)
|
||||
|
||||
type RegionsService struct {
|
||||
models.EC2APIProvider
|
||||
}
|
||||
|
||||
func NewRegionsService(ec2client models.EC2APIProvider) models.RegionsAPIProvider {
|
||||
return &RegionsService{
|
||||
ec2client,
|
||||
}
|
||||
}
|
||||
|
||||
func mergeEC2RegionsAndConstantRegions(regions map[string]struct{}, ec2Regions []*ec2.Region) {
|
||||
for _, region := range ec2Regions {
|
||||
if _, ok := regions[*region.RegionName]; !ok {
|
||||
regions[*region.RegionName] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RegionsService) GetRegions() ([]resources.ResourceResponse[resources.Region], error) {
|
||||
regions := constants.Regions()
|
||||
|
||||
result := make([]resources.ResourceResponse[resources.Region], 0)
|
||||
|
||||
ec2Regions, err := r.DescribeRegions(&ec2.DescribeRegionsInput{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mergeEC2RegionsAndConstantRegions(regions, ec2Regions.Regions)
|
||||
|
||||
for region := range regions {
|
||||
result = append(result, resources.ResourceResponse[resources.Region]{
|
||||
Value: resources.Region{
|
||||
Name: region,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
return result[i].Value.Name < result[j].Value.Name
|
||||
})
|
||||
|
||||
return result, nil
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks"
|
||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/resources"
|
||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRegions(t *testing.T) {
|
||||
t.Run("returns regions from the api and merges them with default regions", func(t *testing.T) {
|
||||
mockRegions := &ec2.DescribeRegionsOutput{
|
||||
Regions: []*ec2.Region{
|
||||
{
|
||||
RegionName: utils.Pointer("earth-1"),
|
||||
},
|
||||
},
|
||||
}
|
||||
ec2Mock := &mocks.EC2Mock{}
|
||||
ec2Mock.On("DescribeRegions").Return(mockRegions, nil)
|
||||
regions, err := NewRegionsService(ec2Mock).GetRegions()
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, regions, resources.ResourceResponse[resources.Region]{
|
||||
Value: resources.Region{
|
||||
Name: "us-east-2",
|
||||
},
|
||||
})
|
||||
assert.Contains(t, regions, resources.ResourceResponse[resources.Region]{
|
||||
Value: resources.Region{
|
||||
Name: "earth-1",
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("forwards error if DescribeRegions errors out", func(t *testing.T) {
|
||||
ec2Mock := &mocks.EC2Mock{}
|
||||
ec2Mock.On("DescribeRegions").Return((*ec2.DescribeRegionsOutput)(nil), assert.AnError)
|
||||
_, err := NewRegionsService(ec2Mock).GetRegions()
|
||||
assert.Error(t, err)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user