2020-07-23 11:52:22 -05:00
|
|
|
package cloudwatch
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
|
|
"github.com/aws/aws-sdk-go/aws/request"
|
2021-03-12 07:30:21 -06:00
|
|
|
"github.com/aws/aws-sdk-go/aws/session"
|
2020-07-23 11:52:22 -05:00
|
|
|
"github.com/aws/aws-sdk-go/service/cloudwatch"
|
|
|
|
"github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface"
|
|
|
|
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
|
|
|
|
"github.com/aws/aws-sdk-go/service/cloudwatchlogs/cloudwatchlogsiface"
|
|
|
|
"github.com/aws/aws-sdk-go/service/ec2"
|
|
|
|
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
|
|
|
|
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi"
|
|
|
|
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi/resourcegroupstaggingapiiface"
|
2021-03-12 07:30:21 -06:00
|
|
|
"github.com/grafana/grafana-aws-sdk/pkg/awsds"
|
2021-03-09 14:20:59 -06:00
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
2020-07-23 11:52:22 -05:00
|
|
|
)
|
|
|
|
|
2022-03-03 02:42:51 -06:00
|
|
|
type fakeCWLogsClient struct {
|
2020-07-23 11:52:22 -05:00
|
|
|
cloudwatchlogsiface.CloudWatchLogsAPI
|
2022-02-25 07:14:59 -06:00
|
|
|
|
|
|
|
calls logsQueryCalls
|
|
|
|
|
2020-07-23 11:52:22 -05:00
|
|
|
logGroups cloudwatchlogs.DescribeLogGroupsOutput
|
|
|
|
logGroupFields cloudwatchlogs.GetLogGroupFieldsOutput
|
|
|
|
queryResults cloudwatchlogs.GetQueryResultsOutput
|
|
|
|
}
|
|
|
|
|
2022-02-25 07:14:59 -06:00
|
|
|
type logsQueryCalls struct {
|
|
|
|
startQueryWithContext []*cloudwatchlogs.StartQueryInput
|
2022-07-19 12:59:30 -05:00
|
|
|
getEventsWithContext []*cloudwatchlogs.GetLogEventsInput
|
2022-02-25 07:14:59 -06:00
|
|
|
}
|
|
|
|
|
2022-03-03 02:42:51 -06:00
|
|
|
func (m *fakeCWLogsClient) GetQueryResultsWithContext(ctx context.Context, input *cloudwatchlogs.GetQueryResultsInput, option ...request.Option) (*cloudwatchlogs.GetQueryResultsOutput, error) {
|
2020-07-23 11:52:22 -05:00
|
|
|
return &m.queryResults, nil
|
|
|
|
}
|
|
|
|
|
2022-03-03 02:42:51 -06:00
|
|
|
func (m *fakeCWLogsClient) StartQueryWithContext(ctx context.Context, input *cloudwatchlogs.StartQueryInput, option ...request.Option) (*cloudwatchlogs.StartQueryOutput, error) {
|
2022-02-25 07:14:59 -06:00
|
|
|
m.calls.startQueryWithContext = append(m.calls.startQueryWithContext, input)
|
|
|
|
|
2020-07-23 11:52:22 -05:00
|
|
|
return &cloudwatchlogs.StartQueryOutput{
|
|
|
|
QueryId: aws.String("abcd-efgh-ijkl-mnop"),
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2022-03-03 02:42:51 -06:00
|
|
|
func (m *fakeCWLogsClient) StopQueryWithContext(ctx context.Context, input *cloudwatchlogs.StopQueryInput, option ...request.Option) (*cloudwatchlogs.StopQueryOutput, error) {
|
2020-07-23 11:52:22 -05:00
|
|
|
return &cloudwatchlogs.StopQueryOutput{
|
|
|
|
Success: aws.Bool(true),
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2022-03-03 02:42:51 -06:00
|
|
|
func (m *fakeCWLogsClient) DescribeLogGroupsWithContext(ctx context.Context, input *cloudwatchlogs.DescribeLogGroupsInput, option ...request.Option) (*cloudwatchlogs.DescribeLogGroupsOutput, error) {
|
2020-07-23 11:52:22 -05:00
|
|
|
return &m.logGroups, nil
|
|
|
|
}
|
|
|
|
|
2022-03-03 02:42:51 -06:00
|
|
|
func (m *fakeCWLogsClient) GetLogGroupFieldsWithContext(ctx context.Context, input *cloudwatchlogs.GetLogGroupFieldsInput, option ...request.Option) (*cloudwatchlogs.GetLogGroupFieldsOutput, error) {
|
2020-07-23 11:52:22 -05:00
|
|
|
return &m.logGroupFields, nil
|
|
|
|
}
|
|
|
|
|
2022-07-19 12:59:30 -05:00
|
|
|
func (m *fakeCWLogsClient) GetLogEventsWithContext(ctx context.Context, input *cloudwatchlogs.GetLogEventsInput, option ...request.Option) (*cloudwatchlogs.GetLogEventsOutput, error) {
|
|
|
|
m.calls.getEventsWithContext = append(m.calls.getEventsWithContext, input)
|
|
|
|
|
|
|
|
return &cloudwatchlogs.GetLogEventsOutput{
|
|
|
|
Events: []*cloudwatchlogs.OutputLogEvent{},
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2022-03-03 02:42:51 -06:00
|
|
|
type fakeCWClient struct {
|
2020-07-23 11:52:22 -05:00
|
|
|
cloudwatchiface.CloudWatchAPI
|
2021-06-10 03:23:17 -05:00
|
|
|
cloudwatch.GetMetricDataOutput
|
2020-07-23 11:52:22 -05:00
|
|
|
|
2022-05-05 06:59:23 -05:00
|
|
|
Metrics []*cloudwatch.Metric
|
2021-03-10 00:41:22 -06:00
|
|
|
MetricsPerPage int
|
2022-05-05 06:59:23 -05:00
|
|
|
|
|
|
|
callsGetMetricDataWithContext []*cloudwatch.GetMetricDataInput
|
2020-07-23 11:52:22 -05:00
|
|
|
}
|
|
|
|
|
2022-05-05 06:59:23 -05:00
|
|
|
func (c *fakeCWClient) GetMetricDataWithContext(ctx aws.Context, input *cloudwatch.GetMetricDataInput, opts ...request.Option) (*cloudwatch.GetMetricDataOutput, error) {
|
|
|
|
c.callsGetMetricDataWithContext = append(c.callsGetMetricDataWithContext, input)
|
|
|
|
|
2021-06-10 03:23:17 -05:00
|
|
|
return &c.GetMetricDataOutput, nil
|
|
|
|
}
|
|
|
|
|
2022-04-12 09:22:28 -05:00
|
|
|
func (c *fakeCWClient) ListMetricsPages(input *cloudwatch.ListMetricsInput, fn func(*cloudwatch.ListMetricsOutput, bool) bool) error {
|
2021-03-10 00:41:22 -06:00
|
|
|
if c.MetricsPerPage == 0 {
|
|
|
|
c.MetricsPerPage = 1000
|
|
|
|
}
|
|
|
|
chunks := chunkSlice(c.Metrics, c.MetricsPerPage)
|
|
|
|
|
|
|
|
for i, metrics := range chunks {
|
|
|
|
response := fn(&cloudwatch.ListMetricsOutput{
|
|
|
|
Metrics: metrics,
|
|
|
|
}, i+1 == len(chunks))
|
|
|
|
if !response {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2020-07-23 11:52:22 -05:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-03-03 02:42:51 -06:00
|
|
|
type fakeCWAnnotationsClient struct {
|
2022-02-15 05:45:50 -06:00
|
|
|
cloudwatchiface.CloudWatchAPI
|
|
|
|
calls annontationsQueryCalls
|
|
|
|
|
|
|
|
describeAlarmsForMetricOutput *cloudwatch.DescribeAlarmsForMetricOutput
|
|
|
|
describeAlarmsOutput *cloudwatch.DescribeAlarmsOutput
|
|
|
|
}
|
|
|
|
|
|
|
|
type annontationsQueryCalls struct {
|
|
|
|
describeAlarmsForMetric []*cloudwatch.DescribeAlarmsForMetricInput
|
|
|
|
describeAlarms []*cloudwatch.DescribeAlarmsInput
|
|
|
|
}
|
|
|
|
|
2022-03-03 02:42:51 -06:00
|
|
|
func (c *fakeCWAnnotationsClient) DescribeAlarmsForMetric(params *cloudwatch.DescribeAlarmsForMetricInput) (*cloudwatch.DescribeAlarmsForMetricOutput, error) {
|
2022-02-15 05:45:50 -06:00
|
|
|
c.calls.describeAlarmsForMetric = append(c.calls.describeAlarmsForMetric, params)
|
|
|
|
|
|
|
|
return c.describeAlarmsForMetricOutput, nil
|
|
|
|
}
|
|
|
|
|
2022-03-03 02:42:51 -06:00
|
|
|
func (c *fakeCWAnnotationsClient) DescribeAlarms(params *cloudwatch.DescribeAlarmsInput) (*cloudwatch.DescribeAlarmsOutput, error) {
|
2022-02-15 05:45:50 -06:00
|
|
|
c.calls.describeAlarms = append(c.calls.describeAlarms, params)
|
|
|
|
|
|
|
|
return c.describeAlarmsOutput, nil
|
|
|
|
}
|
|
|
|
|
2020-07-23 11:52:22 -05:00
|
|
|
type fakeEC2Client struct {
|
|
|
|
ec2iface.EC2API
|
|
|
|
|
|
|
|
regions []string
|
|
|
|
reservations []*ec2.Reservation
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c fakeEC2Client) DescribeRegions(*ec2.DescribeRegionsInput) (*ec2.DescribeRegionsOutput, error) {
|
|
|
|
regions := []*ec2.Region{}
|
|
|
|
for _, region := range c.regions {
|
|
|
|
regions = append(regions, &ec2.Region{
|
|
|
|
RegionName: aws.String(region),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return &ec2.DescribeRegionsOutput{
|
|
|
|
Regions: regions,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c fakeEC2Client) DescribeInstancesPages(in *ec2.DescribeInstancesInput,
|
|
|
|
fn func(*ec2.DescribeInstancesOutput, bool) bool) error {
|
|
|
|
reservations := []*ec2.Reservation{}
|
|
|
|
for _, r := range c.reservations {
|
|
|
|
instances := []*ec2.Instance{}
|
|
|
|
for _, inst := range r.Instances {
|
|
|
|
if len(in.InstanceIds) == 0 {
|
|
|
|
instances = append(instances, inst)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, id := range in.InstanceIds {
|
|
|
|
if *inst.InstanceId == *id {
|
|
|
|
instances = append(instances, inst)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
reservation := &ec2.Reservation{Instances: instances}
|
|
|
|
reservations = append(reservations, reservation)
|
|
|
|
}
|
|
|
|
fn(&ec2.DescribeInstancesOutput{
|
|
|
|
Reservations: reservations,
|
|
|
|
}, true)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type fakeRGTAClient struct {
|
|
|
|
resourcegroupstaggingapiiface.ResourceGroupsTaggingAPIAPI
|
|
|
|
|
|
|
|
tagMapping []*resourcegroupstaggingapi.ResourceTagMapping
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c fakeRGTAClient) GetResourcesPages(in *resourcegroupstaggingapi.GetResourcesInput,
|
|
|
|
fn func(*resourcegroupstaggingapi.GetResourcesOutput, bool) bool) error {
|
|
|
|
fn(&resourcegroupstaggingapi.GetResourcesOutput{
|
|
|
|
ResourceTagMappingList: c.tagMapping,
|
|
|
|
}, true)
|
|
|
|
return nil
|
|
|
|
}
|
2021-03-09 14:20:59 -06:00
|
|
|
|
2022-03-02 07:48:51 -06:00
|
|
|
type fakeCheckHealthClient struct {
|
|
|
|
cloudwatchiface.CloudWatchAPI
|
|
|
|
cloudwatchlogsiface.CloudWatchLogsAPI
|
|
|
|
|
|
|
|
listMetricsPages func(input *cloudwatch.ListMetricsInput, fn func(*cloudwatch.ListMetricsOutput, bool) bool) error
|
|
|
|
describeLogGroupsWithContext func(ctx aws.Context, input *cloudwatchlogs.DescribeLogGroupsInput,
|
|
|
|
options ...request.Option) (*cloudwatchlogs.DescribeLogGroupsOutput, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c fakeCheckHealthClient) ListMetricsPages(input *cloudwatch.ListMetricsInput, fn func(*cloudwatch.ListMetricsOutput, bool) bool) error {
|
|
|
|
if c.listMetricsPages != nil {
|
|
|
|
return c.listMetricsPages(input, fn)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c fakeCheckHealthClient) DescribeLogGroupsWithContext(ctx aws.Context, input *cloudwatchlogs.DescribeLogGroupsInput, options ...request.Option) (*cloudwatchlogs.DescribeLogGroupsOutput, error) {
|
|
|
|
if c.describeLogGroupsWithContext != nil {
|
|
|
|
return c.describeLogGroupsWithContext(ctx, input, options...)
|
|
|
|
}
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
2021-03-10 00:41:22 -06:00
|
|
|
func chunkSlice(slice []*cloudwatch.Metric, chunkSize int) [][]*cloudwatch.Metric {
|
|
|
|
var chunks [][]*cloudwatch.Metric
|
|
|
|
for {
|
|
|
|
if len(slice) == 0 {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if len(slice) < chunkSize {
|
|
|
|
chunkSize = len(slice)
|
|
|
|
}
|
|
|
|
|
|
|
|
chunks = append(chunks, slice[0:chunkSize])
|
|
|
|
slice = slice[chunkSize:]
|
|
|
|
}
|
|
|
|
|
|
|
|
return chunks
|
|
|
|
}
|
|
|
|
|
2021-03-09 14:20:59 -06:00
|
|
|
func newTestConfig() *setting.Cfg {
|
2021-03-10 00:41:22 -06:00
|
|
|
return &setting.Cfg{AWSAllowedAuthProviders: []string{"default"}, AWSAssumeRoleEnabled: true, AWSListMetricsPageLimit: 1000}
|
2021-03-09 14:20:59 -06:00
|
|
|
}
|
2021-03-12 07:30:21 -06:00
|
|
|
|
|
|
|
type fakeSessionCache struct {
|
2022-03-04 04:15:36 -06:00
|
|
|
getSession func(c awsds.SessionConfig) (*session.Session, error)
|
|
|
|
calledRegions []string
|
2021-03-12 07:30:21 -06:00
|
|
|
}
|
|
|
|
|
2022-03-04 04:15:36 -06:00
|
|
|
func (s *fakeSessionCache) GetSession(c awsds.SessionConfig) (*session.Session, error) {
|
|
|
|
s.calledRegions = append(s.calledRegions, c.Settings.Region)
|
|
|
|
|
2022-03-02 07:48:51 -06:00
|
|
|
if s.getSession != nil {
|
|
|
|
return s.getSession(c)
|
|
|
|
}
|
2021-03-12 07:30:21 -06:00
|
|
|
return &session.Session{
|
|
|
|
Config: &aws.Config{},
|
|
|
|
}, nil
|
|
|
|
}
|