| 
									
										
										
										
											2021-06-09 17:19:43 +02:00
										 |  |  | package cloudwatch | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2022-03-04 11:15:36 +01:00
										 |  |  | 	"encoding/json" | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2022-09-21 10:55:54 +02:00
										 |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2021-06-09 17:19:43 +02:00
										 |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2022-03-04 11:15:36 +01:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2021-06-09 17:19:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 	"github.com/aws/aws-sdk-go/aws" | 
					
						
							|  |  |  | 	"github.com/aws/aws-sdk-go/aws/session" | 
					
						
							|  |  |  | 	"github.com/aws/aws-sdk-go/service/cloudwatch" | 
					
						
							|  |  |  | 	"github.com/aws/aws-sdk-go/service/cloudwatchlogs" | 
					
						
							|  |  |  | 	"github.com/aws/aws-sdk-go/service/cloudwatchlogs/cloudwatchlogsiface" | 
					
						
							| 
									
										
										
										
											2021-06-09 17:19:43 +02:00
										 |  |  | 	"github.com/google/go-cmp/cmp" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana-aws-sdk/pkg/awsds" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana-plugin-sdk-go/backend" | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 	"github.com/grafana/grafana-plugin-sdk-go/backend/datasource" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" | 
					
						
							| 
									
										
										
										
											2022-01-18 09:34:12 +01:00
										 |  |  | 	"github.com/grafana/grafana/pkg/infra/httpclient" | 
					
						
							| 
									
										
										
										
											2022-04-29 17:47:46 +02:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/featuremgmt" | 
					
						
							| 
									
										
										
										
											2022-10-20 12:53:28 +02:00
										 |  |  | 	"github.com/grafana/grafana/pkg/setting" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/tsdb/cloudwatch/mocks" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models" | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 	"github.com/stretchr/testify/assert" | 
					
						
							| 
									
										
										
										
											2021-06-09 17:19:43 +02:00
										 |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestNewInstanceSettings(t *testing.T) { | 
					
						
							|  |  |  | 	tests := []struct { | 
					
						
							|  |  |  | 		name       string | 
					
						
							|  |  |  | 		settings   backend.DataSourceInstanceSettings | 
					
						
							| 
									
										
										
										
											2022-10-25 09:52:12 +02:00
										 |  |  | 		expectedDS DataSource | 
					
						
							| 
									
										
										
										
											2021-06-09 17:19:43 +02:00
										 |  |  | 		Err        require.ErrorAssertionFunc | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "creates a request", | 
					
						
							|  |  |  | 			settings: backend.DataSourceInstanceSettings{ | 
					
						
							|  |  |  | 				JSONData: []byte(`{ | 
					
						
							|  |  |  | 					"profile": "foo", | 
					
						
							|  |  |  | 					"defaultRegion": "us-east2", | 
					
						
							|  |  |  | 					"assumeRoleArn": "role", | 
					
						
							|  |  |  | 					"externalId": "id", | 
					
						
							|  |  |  | 					"endpoint": "bar", | 
					
						
							|  |  |  | 					"customMetricsNamespaces": "ns", | 
					
						
							|  |  |  | 					"authType": "keys" | 
					
						
							|  |  |  | 				}`), | 
					
						
							|  |  |  | 				DecryptedSecureJSONData: map[string]string{ | 
					
						
							|  |  |  | 					"accessKey": "A123", | 
					
						
							|  |  |  | 					"secretKey": "secret", | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-10-25 09:52:12 +02:00
										 |  |  | 			expectedDS: DataSource{ | 
					
						
							|  |  |  | 				Settings: &models.CloudWatchSettings{ | 
					
						
							|  |  |  | 					AWSDatasourceSettings: awsds.AWSDatasourceSettings{ | 
					
						
							|  |  |  | 						Profile:       "foo", | 
					
						
							|  |  |  | 						Region:        "us-east2", | 
					
						
							|  |  |  | 						AssumeRoleARN: "role", | 
					
						
							|  |  |  | 						ExternalID:    "id", | 
					
						
							|  |  |  | 						Endpoint:      "bar", | 
					
						
							|  |  |  | 						AuthType:      awsds.AuthTypeKeys, | 
					
						
							|  |  |  | 						AccessKey:     "A123", | 
					
						
							|  |  |  | 						SecretKey:     "secret", | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					Namespace: "ns", | 
					
						
							|  |  |  | 				}, | 
					
						
							| 
									
										
										
										
											2021-06-09 17:19:43 +02:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			Err: require.NoError, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, tt := range tests { | 
					
						
							|  |  |  | 		t.Run(tt.name, func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-01-18 09:34:12 +01:00
										 |  |  | 			f := NewInstanceSettings(httpclient.NewProvider()) | 
					
						
							| 
									
										
										
										
											2021-06-09 17:19:43 +02:00
										 |  |  | 			model, err := f(tt.settings) | 
					
						
							|  |  |  | 			tt.Err(t, err) | 
					
						
							| 
									
										
										
										
											2022-10-25 09:52:12 +02:00
										 |  |  | 			datasourceComparer := cmp.Comparer(func(d1 DataSource, d2 DataSource) bool { | 
					
						
							|  |  |  | 				return d1.Settings.Profile == d2.Settings.Profile && | 
					
						
							|  |  |  | 					d1.Settings.Region == d2.Settings.Region && | 
					
						
							|  |  |  | 					d1.Settings.AuthType == d2.Settings.AuthType && | 
					
						
							|  |  |  | 					d1.Settings.AssumeRoleARN == d2.Settings.AssumeRoleARN && | 
					
						
							|  |  |  | 					d1.Settings.ExternalID == d2.Settings.ExternalID && | 
					
						
							|  |  |  | 					d1.Settings.Namespace == d2.Settings.Namespace && | 
					
						
							|  |  |  | 					d1.Settings.Endpoint == d2.Settings.Endpoint && | 
					
						
							|  |  |  | 					d1.Settings.AccessKey == d2.Settings.AccessKey && | 
					
						
							|  |  |  | 					d1.Settings.SecretKey == d2.Settings.SecretKey | 
					
						
							| 
									
										
										
										
											2021-06-09 17:19:43 +02:00
										 |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2022-10-25 09:52:12 +02:00
										 |  |  | 			if !cmp.Equal(model.(DataSource), tt.expectedDS, datasourceComparer) { | 
					
						
							| 
									
										
										
										
											2021-06-09 17:19:43 +02:00
										 |  |  | 				t.Errorf("Unexpected result. Expecting\n%v \nGot:\n%v", model, tt.expectedDS) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | func Test_CheckHealth(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-10-25 15:03:51 +02:00
										 |  |  | 	origNewMetricsAPI := NewMetricsAPI | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 	origNewCWLogsClient := NewCWLogsClient | 
					
						
							|  |  |  | 	t.Cleanup(func() { | 
					
						
							| 
									
										
										
										
											2022-10-25 15:03:51 +02:00
										 |  |  | 		NewMetricsAPI = origNewMetricsAPI | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 		NewCWLogsClient = origNewCWLogsClient | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var client fakeCheckHealthClient | 
					
						
							| 
									
										
										
										
											2022-10-25 15:03:51 +02:00
										 |  |  | 	NewMetricsAPI = func(sess *session.Session) models.CloudWatchMetricsAPIProvider { | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 		return client | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	NewCWLogsClient = func(sess *session.Session) cloudwatchlogsiface.CloudWatchLogsAPI { | 
					
						
							|  |  |  | 		return client | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("successfully query metrics and logs", func(t *testing.T) { | 
					
						
							|  |  |  | 		client = fakeCheckHealthClient{} | 
					
						
							|  |  |  | 		im := datasource.NewInstanceManager(func(s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { | 
					
						
							| 
									
										
										
										
											2022-10-25 09:52:12 +02:00
										 |  |  | 			return DataSource{Settings: &models.CloudWatchSettings{}}, nil | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-04-29 17:47:46 +02:00
										 |  |  | 		executor := newExecutor(im, newTestConfig(), &fakeSessionCache{}, featuremgmt.WithFeatures()) | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		resp, err := executor.CheckHealth(context.Background(), &backend.CheckHealthRequest{ | 
					
						
							|  |  |  | 			PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		assert.NoError(t, err) | 
					
						
							|  |  |  | 		assert.Equal(t, &backend.CheckHealthResult{ | 
					
						
							|  |  |  | 			Status:  backend.HealthStatusOk, | 
					
						
							|  |  |  | 			Message: "1. Successfully queried the CloudWatch metrics API.\n2. Successfully queried the CloudWatch logs API.", | 
					
						
							|  |  |  | 		}, resp) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("successfully queries metrics, fails during logs query", func(t *testing.T) { | 
					
						
							|  |  |  | 		client = fakeCheckHealthClient{ | 
					
						
							| 
									
										
										
										
											2022-09-21 10:55:54 +02:00
										 |  |  | 			describeLogGroups: func(input *cloudwatchlogs.DescribeLogGroupsInput) (*cloudwatchlogs.DescribeLogGroupsOutput, error) { | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 				return nil, fmt.Errorf("some logs query error") | 
					
						
							|  |  |  | 			}} | 
					
						
							|  |  |  | 		im := datasource.NewInstanceManager(func(s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { | 
					
						
							| 
									
										
										
										
											2022-10-25 09:52:12 +02:00
										 |  |  | 			return DataSource{Settings: &models.CloudWatchSettings{}}, nil | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-04-29 17:47:46 +02:00
										 |  |  | 		executor := newExecutor(im, newTestConfig(), &fakeSessionCache{}, featuremgmt.WithFeatures()) | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		resp, err := executor.CheckHealth(context.Background(), &backend.CheckHealthRequest{ | 
					
						
							|  |  |  | 			PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		assert.NoError(t, err) | 
					
						
							|  |  |  | 		assert.Equal(t, &backend.CheckHealthResult{ | 
					
						
							|  |  |  | 			Status:  backend.HealthStatusError, | 
					
						
							|  |  |  | 			Message: "1. Successfully queried the CloudWatch metrics API.\n2. CloudWatch logs query failed: some logs query error", | 
					
						
							|  |  |  | 		}, resp) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("successfully queries logs, fails during metrics query", func(t *testing.T) { | 
					
						
							|  |  |  | 		client = fakeCheckHealthClient{ | 
					
						
							|  |  |  | 			listMetricsPages: func(input *cloudwatch.ListMetricsInput, fn func(*cloudwatch.ListMetricsOutput, bool) bool) error { | 
					
						
							|  |  |  | 				return fmt.Errorf("some list metrics error") | 
					
						
							|  |  |  | 			}} | 
					
						
							|  |  |  | 		im := datasource.NewInstanceManager(func(s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { | 
					
						
							| 
									
										
										
										
											2022-10-25 09:52:12 +02:00
										 |  |  | 			return DataSource{Settings: &models.CloudWatchSettings{}}, nil | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-04-29 17:47:46 +02:00
										 |  |  | 		executor := newExecutor(im, newTestConfig(), &fakeSessionCache{}, featuremgmt.WithFeatures()) | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		resp, err := executor.CheckHealth(context.Background(), &backend.CheckHealthRequest{ | 
					
						
							|  |  |  | 			PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		assert.NoError(t, err) | 
					
						
							|  |  |  | 		assert.Equal(t, &backend.CheckHealthResult{ | 
					
						
							|  |  |  | 			Status:  backend.HealthStatusError, | 
					
						
							|  |  |  | 			Message: "1. CloudWatch metrics query failed: some list metrics error\n2. Successfully queried the CloudWatch logs API.", | 
					
						
							|  |  |  | 		}, resp) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("fail to get clients", func(t *testing.T) { | 
					
						
							|  |  |  | 		client = fakeCheckHealthClient{} | 
					
						
							|  |  |  | 		im := datasource.NewInstanceManager(func(s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { | 
					
						
							| 
									
										
										
										
											2022-10-25 09:52:12 +02:00
										 |  |  | 			return DataSource{Settings: &models.CloudWatchSettings{}}, nil | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-03-04 11:15:36 +01:00
										 |  |  | 		executor := newExecutor(im, newTestConfig(), &fakeSessionCache{getSession: func(c awsds.SessionConfig) (*session.Session, error) { | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 			return nil, fmt.Errorf("some sessions error") | 
					
						
							| 
									
										
										
										
											2022-04-29 17:47:46 +02:00
										 |  |  | 		}}, featuremgmt.WithFeatures()) | 
					
						
							| 
									
										
										
										
											2022-03-02 08:48:51 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		resp, err := executor.CheckHealth(context.Background(), &backend.CheckHealthRequest{ | 
					
						
							|  |  |  | 			PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		assert.NoError(t, err) | 
					
						
							|  |  |  | 		assert.Equal(t, &backend.CheckHealthResult{ | 
					
						
							|  |  |  | 			Status:  backend.HealthStatusError, | 
					
						
							|  |  |  | 			Message: "1. CloudWatch metrics query failed: some sessions error\n2. CloudWatch logs query failed: some sessions error", | 
					
						
							|  |  |  | 		}, resp) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-03-04 11:15:36 +01:00
										 |  |  | func Test_executeLogAlertQuery(t *testing.T) { | 
					
						
							|  |  |  | 	origNewCWClient := NewCWClient | 
					
						
							|  |  |  | 	t.Cleanup(func() { | 
					
						
							|  |  |  | 		NewCWClient = origNewCWClient | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var cli fakeCWLogsClient | 
					
						
							|  |  |  | 	NewCWLogsClient = func(sess *session.Session) cloudwatchlogsiface.CloudWatchLogsAPI { | 
					
						
							|  |  |  | 		return &cli | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("getCWLogsClient is called with region from input JSON", func(t *testing.T) { | 
					
						
							|  |  |  | 		cli = fakeCWLogsClient{queryResults: cloudwatchlogs.GetQueryResultsOutput{Status: aws.String("Complete")}} | 
					
						
							|  |  |  | 		im := datasource.NewInstanceManager(func(s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { | 
					
						
							| 
									
										
										
										
											2022-10-25 09:52:12 +02:00
										 |  |  | 			return DataSource{Settings: &models.CloudWatchSettings{}}, nil | 
					
						
							| 
									
										
										
										
											2022-03-04 11:15:36 +01:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 		sess := fakeSessionCache{} | 
					
						
							| 
									
										
										
										
											2022-04-29 17:47:46 +02:00
										 |  |  | 		executor := newExecutor(im, newTestConfig(), &sess, featuremgmt.WithFeatures()) | 
					
						
							| 
									
										
										
										
											2022-03-04 11:15:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		_, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ | 
					
						
							|  |  |  | 			Headers:       map[string]string{"FromAlert": "some value"}, | 
					
						
							|  |  |  | 			PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, | 
					
						
							|  |  |  | 			Queries: []backend.DataQuery{ | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					TimeRange: backend.TimeRange{From: time.Unix(0, 0), To: time.Unix(1, 0)}, | 
					
						
							|  |  |  | 					JSON: json.RawMessage(`{ | 
					
						
							|  |  |  | 						"queryMode":    "Logs", | 
					
						
							|  |  |  | 						"region": "some region" | 
					
						
							|  |  |  | 					}`), | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		assert.NoError(t, err) | 
					
						
							|  |  |  | 		assert.Equal(t, []string{"some region"}, sess.calledRegions) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("getCWLogsClient is called with region from instance manager when region is default", func(t *testing.T) { | 
					
						
							|  |  |  | 		cli = fakeCWLogsClient{queryResults: cloudwatchlogs.GetQueryResultsOutput{Status: aws.String("Complete")}} | 
					
						
							|  |  |  | 		im := datasource.NewInstanceManager(func(s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { | 
					
						
							| 
									
										
										
										
											2022-10-25 09:52:12 +02:00
										 |  |  | 			return DataSource{Settings: &models.CloudWatchSettings{AWSDatasourceSettings: awsds.AWSDatasourceSettings{Region: "instance manager's region"}}}, nil | 
					
						
							| 
									
										
										
										
											2022-03-04 11:15:36 +01:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 		sess := fakeSessionCache{} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-29 17:47:46 +02:00
										 |  |  | 		executor := newExecutor(im, newTestConfig(), &sess, featuremgmt.WithFeatures()) | 
					
						
							| 
									
										
										
										
											2022-03-04 11:15:36 +01:00
										 |  |  | 		_, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ | 
					
						
							|  |  |  | 			Headers:       map[string]string{"FromAlert": "some value"}, | 
					
						
							|  |  |  | 			PluginContext: backend.PluginContext{DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}}, | 
					
						
							|  |  |  | 			Queries: []backend.DataQuery{ | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					TimeRange: backend.TimeRange{From: time.Unix(0, 0), To: time.Unix(1, 0)}, | 
					
						
							|  |  |  | 					JSON: json.RawMessage(`{ | 
					
						
							|  |  |  | 						"queryMode":    "Logs", | 
					
						
							|  |  |  | 						"region": "default" | 
					
						
							|  |  |  | 					}`), | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		assert.NoError(t, err) | 
					
						
							|  |  |  | 		assert.Equal(t, []string{"instance manager's region"}, sess.calledRegions) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-09-21 10:55:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-22 10:32:05 +02:00
										 |  |  | func TestQuery_ResourceRequest_DescribeAllLogGroups(t *testing.T) { | 
					
						
							|  |  |  | 	origNewCWLogsClient := NewCWLogsClient | 
					
						
							|  |  |  | 	t.Cleanup(func() { | 
					
						
							|  |  |  | 		NewCWLogsClient = origNewCWLogsClient | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var cli fakeCWLogsClient | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	NewCWLogsClient = func(sess *session.Session) cloudwatchlogsiface.CloudWatchLogsAPI { | 
					
						
							|  |  |  | 		return &cli | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	im := datasource.NewInstanceManager(func(s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { | 
					
						
							| 
									
										
										
										
											2022-10-25 09:52:12 +02:00
										 |  |  | 		return DataSource{Settings: &models.CloudWatchSettings{}}, nil | 
					
						
							| 
									
										
										
										
											2022-09-22 10:32:05 +02:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	executor := newExecutor(im, newTestConfig(), &fakeSessionCache{}, featuremgmt.WithFeatures()) | 
					
						
							|  |  |  | 	sender := &mockedCallResourceResponseSenderForOauth{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("multiple batches", func(t *testing.T) { | 
					
						
							|  |  |  | 		token := "foo" | 
					
						
							|  |  |  | 		cli = fakeCWLogsClient{ | 
					
						
							|  |  |  | 			logGroups: []cloudwatchlogs.DescribeLogGroupsOutput{ | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					LogGroups: []*cloudwatchlogs.LogGroup{ | 
					
						
							|  |  |  | 						{ | 
					
						
							|  |  |  | 							LogGroupName: aws.String("group_a"), | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 						{ | 
					
						
							|  |  |  | 							LogGroupName: aws.String("group_b"), | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 						{ | 
					
						
							|  |  |  | 							LogGroupName: aws.String("group_c"), | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					NextToken: &token, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					LogGroups: []*cloudwatchlogs.LogGroup{ | 
					
						
							|  |  |  | 						{ | 
					
						
							|  |  |  | 							LogGroupName: aws.String("group_x"), | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 						{ | 
					
						
							|  |  |  | 							LogGroupName: aws.String("group_y"), | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 						{ | 
					
						
							|  |  |  | 							LogGroupName: aws.String("group_z"), | 
					
						
							|  |  |  | 						}, | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		req := &backend.CallResourceRequest{ | 
					
						
							|  |  |  | 			Method: "GET", | 
					
						
							|  |  |  | 			Path:   "/all-log-groups?limit=50", | 
					
						
							|  |  |  | 			PluginContext: backend.PluginContext{ | 
					
						
							|  |  |  | 				DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ | 
					
						
							|  |  |  | 					ID: 0, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				PluginID: "cloudwatch", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		err := executor.CallResource(context.Background(), req, sender) | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		sent := sender.Response | 
					
						
							|  |  |  | 		require.NotNil(t, sent) | 
					
						
							|  |  |  | 		require.Equal(t, http.StatusOK, sent.Status) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		suggestDataResponse := []suggestData{} | 
					
						
							|  |  |  | 		err = json.Unmarshal(sent.Body, &suggestDataResponse) | 
					
						
							|  |  |  | 		require.Nil(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		assert.Equal(t, stringsToSuggestData([]string{ | 
					
						
							|  |  |  | 			"group_a", "group_b", "group_c", "group_x", "group_y", "group_z", | 
					
						
							|  |  |  | 		}), suggestDataResponse) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-21 10:55:54 +02:00
										 |  |  | func TestQuery_ResourceRequest_DescribeLogGroups(t *testing.T) { | 
					
						
							|  |  |  | 	origNewCWLogsClient := NewCWLogsClient | 
					
						
							|  |  |  | 	t.Cleanup(func() { | 
					
						
							|  |  |  | 		NewCWLogsClient = origNewCWLogsClient | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var cli fakeCWLogsClient | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	NewCWLogsClient = func(sess *session.Session) cloudwatchlogsiface.CloudWatchLogsAPI { | 
					
						
							|  |  |  | 		return &cli | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	im := datasource.NewInstanceManager(func(s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { | 
					
						
							| 
									
										
										
										
											2022-10-25 09:52:12 +02:00
										 |  |  | 		return DataSource{Settings: &models.CloudWatchSettings{}}, nil | 
					
						
							| 
									
										
										
										
											2022-09-21 10:55:54 +02:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	executor := newExecutor(im, newTestConfig(), &fakeSessionCache{}, featuremgmt.WithFeatures()) | 
					
						
							|  |  |  | 	sender := &mockedCallResourceResponseSenderForOauth{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("Should map log groups to SuggestData response", func(t *testing.T) { | 
					
						
							|  |  |  | 		cli = fakeCWLogsClient{ | 
					
						
							|  |  |  | 			logGroups: []cloudwatchlogs.DescribeLogGroupsOutput{ | 
					
						
							|  |  |  | 				{LogGroups: []*cloudwatchlogs.LogGroup{ | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						LogGroupName: aws.String("group_a"), | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						LogGroupName: aws.String("group_b"), | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						LogGroupName: aws.String("group_c"), | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		req := &backend.CallResourceRequest{ | 
					
						
							|  |  |  | 			Method: "GET", | 
					
						
							|  |  |  | 			Path:   "/log-groups", | 
					
						
							|  |  |  | 			PluginContext: backend.PluginContext{ | 
					
						
							|  |  |  | 				DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ | 
					
						
							|  |  |  | 					ID: 0, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				PluginID: "cloudwatch", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		err := executor.CallResource(context.Background(), req, sender) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		sent := sender.Response | 
					
						
							|  |  |  | 		require.NotNil(t, sent) | 
					
						
							|  |  |  | 		require.Equal(t, http.StatusOK, sent.Status) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		suggestDataResponse := []suggestData{} | 
					
						
							|  |  |  | 		err = json.Unmarshal(sent.Body, &suggestDataResponse) | 
					
						
							|  |  |  | 		require.Nil(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-22 10:32:05 +02:00
										 |  |  | 		assert.Equal(t, stringsToSuggestData([]string{"group_a", "group_b", "group_c"}), suggestDataResponse) | 
					
						
							| 
									
										
										
										
											2022-09-21 10:55:54 +02:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("Should call api with LogGroupNamePrefix if passed in resource call", func(t *testing.T) { | 
					
						
							|  |  |  | 		cli = fakeCWLogsClient{ | 
					
						
							|  |  |  | 			logGroups: []cloudwatchlogs.DescribeLogGroupsOutput{ | 
					
						
							|  |  |  | 				{LogGroups: []*cloudwatchlogs.LogGroup{}}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		im := datasource.NewInstanceManager(func(s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { | 
					
						
							| 
									
										
										
										
											2022-10-25 09:52:12 +02:00
										 |  |  | 			return DataSource{Settings: &models.CloudWatchSettings{}}, nil | 
					
						
							| 
									
										
										
										
											2022-09-21 10:55:54 +02:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		executor := newExecutor(im, newTestConfig(), &fakeSessionCache{}, featuremgmt.WithFeatures()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		req := &backend.CallResourceRequest{ | 
					
						
							|  |  |  | 			Method: "GET", | 
					
						
							|  |  |  | 			Path:   "/log-groups?logGroupNamePrefix=test", | 
					
						
							|  |  |  | 			PluginContext: backend.PluginContext{ | 
					
						
							|  |  |  | 				DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ | 
					
						
							|  |  |  | 					ID: 0, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				PluginID: "cloudwatch", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		err := executor.CallResource(context.Background(), req, sender) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		sent := sender.Response | 
					
						
							|  |  |  | 		require.NotNil(t, sent) | 
					
						
							|  |  |  | 		require.Equal(t, http.StatusOK, sent.Status) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		assert.Equal(t, []*cloudwatchlogs.DescribeLogGroupsInput{ | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				Limit:              aws.Int64(defaultLogGroupLimit), | 
					
						
							|  |  |  | 				LogGroupNamePrefix: aws.String("test"), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, cli.calls.describeLogGroups) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("Should call api without LogGroupNamePrefix if not passed in resource call", func(t *testing.T) { | 
					
						
							|  |  |  | 		cli = fakeCWLogsClient{ | 
					
						
							|  |  |  | 			logGroups: []cloudwatchlogs.DescribeLogGroupsOutput{ | 
					
						
							|  |  |  | 				{LogGroups: []*cloudwatchlogs.LogGroup{}}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		im := datasource.NewInstanceManager(func(s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { | 
					
						
							| 
									
										
										
										
											2022-10-25 09:52:12 +02:00
										 |  |  | 			return DataSource{Settings: &models.CloudWatchSettings{}}, nil | 
					
						
							| 
									
										
										
										
											2022-09-21 10:55:54 +02:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		executor := newExecutor(im, newTestConfig(), &fakeSessionCache{}, featuremgmt.WithFeatures()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		req := &backend.CallResourceRequest{ | 
					
						
							|  |  |  | 			Method: "GET", | 
					
						
							|  |  |  | 			Path:   "/log-groups?limit=100", | 
					
						
							|  |  |  | 			PluginContext: backend.PluginContext{ | 
					
						
							|  |  |  | 				DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ | 
					
						
							|  |  |  | 					ID: 0, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				PluginID: "cloudwatch", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		err := executor.CallResource(context.Background(), req, sender) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		sent := sender.Response | 
					
						
							|  |  |  | 		require.NotNil(t, sent) | 
					
						
							|  |  |  | 		require.Equal(t, http.StatusOK, sent.Status) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		assert.Equal(t, []*cloudwatchlogs.DescribeLogGroupsInput{ | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				Limit: aws.Int64(100), | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, cli.calls.describeLogGroups) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-09-22 10:32:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-20 12:53:28 +02:00
										 |  |  | func Test_CloudWatch_CallResource_Integration_Test(t *testing.T) { | 
					
						
							|  |  |  | 	sender := &mockedCallResourceResponseSenderForOauth{} | 
					
						
							|  |  |  | 	origNewMetricsAPI := NewMetricsAPI | 
					
						
							|  |  |  | 	t.Cleanup(func() { | 
					
						
							|  |  |  | 		NewMetricsAPI = origNewMetricsAPI | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	var api mocks.FakeMetricsAPI | 
					
						
							|  |  |  | 	NewMetricsAPI = func(sess *session.Session) models.CloudWatchMetricsAPIProvider { | 
					
						
							|  |  |  | 		return &api | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	im := datasource.NewInstanceManager(func(s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { | 
					
						
							| 
									
										
										
										
											2022-10-25 09:52:12 +02:00
										 |  |  | 		return DataSource{Settings: &models.CloudWatchSettings{}}, nil | 
					
						
							| 
									
										
										
										
											2022-10-20 12:53:28 +02:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-24 15:04:25 +02:00
										 |  |  | 	t.Run("Should handle dimension value request and return values from the api", func(t *testing.T) { | 
					
						
							|  |  |  | 		pageLimit := 100 | 
					
						
							|  |  |  | 		api = mocks.FakeMetricsAPI{Metrics: []*cloudwatch.Metric{ | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName1"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1"), Value: aws.String("Value1")}, {Name: aws.String("Test_DimensionName2"), Value: aws.String("Value2")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName2"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1"), Value: aws.String("Value3")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName3"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName2"), Value: aws.String("Value1")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName10"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName4"), Value: aws.String("Value2")}, {Name: aws.String("Test_DimensionName5")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName4"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName2"), Value: aws.String("Value3")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName5"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1"), Value: aws.String("Value4")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName6"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1"), Value: aws.String("Value6")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName7"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName4"), Value: aws.String("Value7")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName8"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName4"), Value: aws.String("Value1")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName9"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1"), Value: aws.String("Value2")}}}, | 
					
						
							|  |  |  | 		}, MetricsPerPage: 100} | 
					
						
							|  |  |  | 		executor := newExecutor(im, &setting.Cfg{AWSListMetricsPageLimit: pageLimit}, &fakeSessionCache{}, featuremgmt.WithFeatures()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		req := &backend.CallResourceRequest{ | 
					
						
							|  |  |  | 			Method: "GET", | 
					
						
							|  |  |  | 			Path:   `/dimension-values?region=us-east-2&dimensionKey=Test_DimensionName4&namespace=AWS/EC2&metricName=CPUUtilization`, | 
					
						
							|  |  |  | 			PluginContext: backend.PluginContext{ | 
					
						
							|  |  |  | 				DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ID: 0}, | 
					
						
							|  |  |  | 				PluginID:                   "cloudwatch", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		err := executor.CallResource(context.Background(), req, sender) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		sent := sender.Response | 
					
						
							|  |  |  | 		require.NotNil(t, sent) | 
					
						
							|  |  |  | 		require.Equal(t, http.StatusOK, sent.Status) | 
					
						
							|  |  |  | 		res := []string{} | 
					
						
							|  |  |  | 		err = json.Unmarshal(sent.Body, &res) | 
					
						
							|  |  |  | 		require.Nil(t, err) | 
					
						
							|  |  |  | 		assert.Equal(t, []string{"Value1", "Value2", "Value7"}, res) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-20 12:53:28 +02:00
										 |  |  | 	t.Run("Should handle dimension key filter query and return keys from the api", func(t *testing.T) { | 
					
						
							|  |  |  | 		pageLimit := 3 | 
					
						
							|  |  |  | 		api = mocks.FakeMetricsAPI{Metrics: []*cloudwatch.Metric{ | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName1"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1")}, {Name: aws.String("Test_DimensionName2")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName2"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName3"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName2")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName10"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName4")}, {Name: aws.String("Test_DimensionName5")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName4"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName2")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName5"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName6"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName7"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName4")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName8"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName4")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName9"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1")}}}, | 
					
						
							|  |  |  | 		}, MetricsPerPage: 2} | 
					
						
							|  |  |  | 		executor := newExecutor(im, &setting.Cfg{AWSListMetricsPageLimit: pageLimit}, &fakeSessionCache{}, featuremgmt.WithFeatures()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		req := &backend.CallResourceRequest{ | 
					
						
							|  |  |  | 			Method: "GET", | 
					
						
							|  |  |  | 			Path:   `/dimension-keys?region=us-east-2&namespace=AWS/EC2&metricName=CPUUtilization&dimensionFilters={"NodeID":["Shared"],"stage":["QueryCommit"]}`, | 
					
						
							|  |  |  | 			PluginContext: backend.PluginContext{ | 
					
						
							|  |  |  | 				DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ID: 0}, | 
					
						
							|  |  |  | 				PluginID:                   "cloudwatch", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		err := executor.CallResource(context.Background(), req, sender) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		sent := sender.Response | 
					
						
							|  |  |  | 		require.NotNil(t, sent) | 
					
						
							|  |  |  | 		require.Equal(t, http.StatusOK, sent.Status) | 
					
						
							|  |  |  | 		res := []string{} | 
					
						
							|  |  |  | 		err = json.Unmarshal(sent.Body, &res) | 
					
						
							|  |  |  | 		require.Nil(t, err) | 
					
						
							|  |  |  | 		assert.Equal(t, []string{"Test_DimensionName1", "Test_DimensionName2", "Test_DimensionName4", "Test_DimensionName5"}, res) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("Should handle standard dimension key query and return hard coded keys", func(t *testing.T) { | 
					
						
							|  |  |  | 		api = mocks.FakeMetricsAPI{} | 
					
						
							|  |  |  | 		executor := newExecutor(im, newTestConfig(), &fakeSessionCache{}, featuremgmt.WithFeatures()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		req := &backend.CallResourceRequest{ | 
					
						
							|  |  |  | 			Method: "GET", | 
					
						
							|  |  |  | 			Path:   `/dimension-keys?region=us-east-2&namespace=AWS/CloudSearch&metricName=CPUUtilization`, | 
					
						
							|  |  |  | 			PluginContext: backend.PluginContext{ | 
					
						
							|  |  |  | 				DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ID: 0}, | 
					
						
							|  |  |  | 				PluginID:                   "cloudwatch", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		err := executor.CallResource(context.Background(), req, sender) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		sent := sender.Response | 
					
						
							|  |  |  | 		require.NotNil(t, sent) | 
					
						
							|  |  |  | 		require.Equal(t, http.StatusOK, sent.Status) | 
					
						
							|  |  |  | 		res := []string{} | 
					
						
							|  |  |  | 		err = json.Unmarshal(sent.Body, &res) | 
					
						
							|  |  |  | 		require.Nil(t, err) | 
					
						
							|  |  |  | 		assert.Equal(t, []string{"ClientId", "DomainName"}, res) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("Should handle custom namespace dimension key query and return hard coded keys", func(t *testing.T) { | 
					
						
							|  |  |  | 		api = mocks.FakeMetricsAPI{} | 
					
						
							|  |  |  | 		executor := newExecutor(im, newTestConfig(), &fakeSessionCache{}, featuremgmt.WithFeatures()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		req := &backend.CallResourceRequest{ | 
					
						
							|  |  |  | 			Method: "GET", | 
					
						
							|  |  |  | 			Path:   `/dimension-keys?region=us-east-2&namespace=AWS/CloudSearch&metricName=CPUUtilization`, | 
					
						
							|  |  |  | 			PluginContext: backend.PluginContext{ | 
					
						
							|  |  |  | 				DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ID: 0}, | 
					
						
							|  |  |  | 				PluginID:                   "cloudwatch", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		err := executor.CallResource(context.Background(), req, sender) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		sent := sender.Response | 
					
						
							|  |  |  | 		require.NotNil(t, sent) | 
					
						
							|  |  |  | 		require.Equal(t, http.StatusOK, sent.Status) | 
					
						
							|  |  |  | 		res := []string{} | 
					
						
							|  |  |  | 		err = json.Unmarshal(sent.Body, &res) | 
					
						
							|  |  |  | 		require.Nil(t, err) | 
					
						
							|  |  |  | 		assert.Equal(t, []string{"ClientId", "DomainName"}, res) | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2022-10-25 14:00:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("Should handle custom namespace metrics query and return metrics from api", func(t *testing.T) { | 
					
						
							|  |  |  | 		pageLimit := 3 | 
					
						
							|  |  |  | 		api = mocks.FakeMetricsAPI{Metrics: []*cloudwatch.Metric{ | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName1"), Namespace: aws.String("AWS/EC2"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1")}, {Name: aws.String("Test_DimensionName2")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName2"), Namespace: aws.String("AWS/EC2"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName3"), Namespace: aws.String("AWS/ECS"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName2")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName10"), Namespace: aws.String("AWS/ECS"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName4")}, {Name: aws.String("Test_DimensionName5")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName4"), Namespace: aws.String("AWS/ECS"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName2")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName5"), Namespace: aws.String("AWS/Redshift"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName6"), Namespace: aws.String("AWS/Redshift"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName7"), Namespace: aws.String("AWS/EC2"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName4")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName8"), Namespace: aws.String("AWS/EC2"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName4")}}}, | 
					
						
							|  |  |  | 			{MetricName: aws.String("Test_MetricName9"), Namespace: aws.String("AWS/EC2"), Dimensions: []*cloudwatch.Dimension{{Name: aws.String("Test_DimensionName1")}}}, | 
					
						
							|  |  |  | 		}, MetricsPerPage: 2} | 
					
						
							|  |  |  | 		executor := newExecutor(im, &setting.Cfg{AWSListMetricsPageLimit: pageLimit}, &fakeSessionCache{}, featuremgmt.WithFeatures()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		req := &backend.CallResourceRequest{ | 
					
						
							|  |  |  | 			Method: "GET", | 
					
						
							|  |  |  | 			Path:   `/metrics?region=us-east-2&namespace=custom-namespace`, | 
					
						
							|  |  |  | 			PluginContext: backend.PluginContext{ | 
					
						
							|  |  |  | 				DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ID: 0}, | 
					
						
							|  |  |  | 				PluginID:                   "cloudwatch", | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		err := executor.CallResource(context.Background(), req, sender) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		sent := sender.Response | 
					
						
							|  |  |  | 		require.NotNil(t, sent) | 
					
						
							|  |  |  | 		require.Equal(t, http.StatusOK, sent.Status) | 
					
						
							|  |  |  | 		res := []models.Metric{} | 
					
						
							|  |  |  | 		err = json.Unmarshal(sent.Body, &res) | 
					
						
							|  |  |  | 		require.Nil(t, err) | 
					
						
							|  |  |  | 		assert.Equal(t, []models.Metric{{Name: "Test_MetricName1", Namespace: "AWS/EC2"}, {Name: "Test_MetricName2", Namespace: "AWS/EC2"}, {Name: "Test_MetricName3", Namespace: "AWS/ECS"}, {Name: "Test_MetricName10", Namespace: "AWS/ECS"}, {Name: "Test_MetricName4", Namespace: "AWS/ECS"}, {Name: "Test_MetricName5", Namespace: "AWS/Redshift"}}, res) | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2022-10-20 12:53:28 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-22 10:32:05 +02:00
										 |  |  | func stringsToSuggestData(values []string) []suggestData { | 
					
						
							|  |  |  | 	suggestDataArray := make([]suggestData, 0) | 
					
						
							|  |  |  | 	for _, v := range values { | 
					
						
							|  |  |  | 		suggestDataArray = append(suggestDataArray, suggestData{Text: v, Value: v, Label: v}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return suggestDataArray | 
					
						
							|  |  |  | } |