Cloudwatch: Use new log group picker also for non cross-account queries (#60913)
* use new log group picker also for non cross-account queries * cleanup and add comment * remove not used code * remove not used test * add error message when trying to set log groups before saving * fix bugs from pr feedback * add more tests * fix broken test
This commit is contained in:
@@ -403,142 +403,6 @@ func TestQuery_ResourceRequest_DescribeAllLogGroups(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
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) {
|
||||
return DataSource{Settings: models.CloudWatchSettings{}}, nil
|
||||
})
|
||||
|
||||
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)
|
||||
|
||||
assert.Equal(t, stringsToSuggestData([]string{"group_a", "group_b", "group_c"}), suggestDataResponse)
|
||||
})
|
||||
|
||||
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) {
|
||||
return DataSource{Settings: models.CloudWatchSettings{}}, nil
|
||||
})
|
||||
|
||||
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) {
|
||||
return DataSource{Settings: models.CloudWatchSettings{}}, nil
|
||||
})
|
||||
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
||||
func TestQuery_ResourceRequest_DescribeLogGroups_with_CrossAccountQuerying(t *testing.T) {
|
||||
sender := &mockedCallResourceResponseSenderForOauth{}
|
||||
origNewMetricsAPI := NewMetricsAPI
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
||||
)
|
||||
|
||||
@@ -213,19 +212,16 @@ func (e *cloudWatchExecutor) executeStartQuery(ctx context.Context, logsClient c
|
||||
QueryString: aws.String(modifiedQueryString),
|
||||
}
|
||||
|
||||
if e.features.IsEnabled(featuremgmt.FlagCloudWatchCrossAccountQuerying) {
|
||||
if logsQuery.LogGroups != nil && len(logsQuery.LogGroups) > 0 {
|
||||
var logGroupIdentifiers []string
|
||||
for _, lg := range logsQuery.LogGroups {
|
||||
arn := lg.ARN
|
||||
// due to a bug in the startQuery api, we remove * from the arn, otherwise it throws an error
|
||||
logGroupIdentifiers = append(logGroupIdentifiers, strings.TrimSuffix(arn, "*"))
|
||||
}
|
||||
startQueryInput.LogGroupIdentifiers = aws.StringSlice(logGroupIdentifiers)
|
||||
if logsQuery.LogGroups != nil && len(logsQuery.LogGroups) > 0 {
|
||||
var logGroupIdentifiers []string
|
||||
for _, lg := range logsQuery.LogGroups {
|
||||
arn := lg.ARN
|
||||
// due to a bug in the startQuery api, we remove * from the arn, otherwise it throws an error
|
||||
logGroupIdentifiers = append(logGroupIdentifiers, strings.TrimSuffix(arn, "*"))
|
||||
}
|
||||
}
|
||||
|
||||
if startQueryInput.LogGroupIdentifiers == nil {
|
||||
startQueryInput.LogGroupIdentifiers = aws.StringSlice(logGroupIdentifiers)
|
||||
} else {
|
||||
// even though log group names are being phased out, we still need to support them for backwards compatibility and alert queries
|
||||
startQueryInput.LogGroupNames = aws.StringSlice(logsQuery.LogGroupNames)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"net/url"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -290,39 +289,6 @@ func (e *cloudWatchExecutor) resourceGroupsGetResources(pluginCtx backend.Plugin
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (e *cloudWatchExecutor) handleGetLogGroups(pluginCtx backend.PluginContext, parameters url.Values) ([]suggestData, error) {
|
||||
region := parameters.Get("region")
|
||||
limit := parameters.Get("limit")
|
||||
logGroupNamePrefix := parameters.Get("logGroupNamePrefix")
|
||||
|
||||
logsClient, err := e.getCWLogsClient(pluginCtx, region)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logGroupLimit := defaultLogGroupLimit
|
||||
intLimit, err := strconv.ParseInt(limit, 10, 64)
|
||||
if err == nil && intLimit > 0 {
|
||||
logGroupLimit = intLimit
|
||||
}
|
||||
|
||||
var response *cloudwatchlogs.DescribeLogGroupsOutput = nil
|
||||
input := &cloudwatchlogs.DescribeLogGroupsInput{Limit: aws.Int64(logGroupLimit)}
|
||||
if len(logGroupNamePrefix) > 0 {
|
||||
input.LogGroupNamePrefix = aws.String(logGroupNamePrefix)
|
||||
}
|
||||
response, err = logsClient.DescribeLogGroups(input)
|
||||
if err != nil || response == nil {
|
||||
return nil, err
|
||||
}
|
||||
result := make([]suggestData, 0)
|
||||
for _, logGroup := range response.LogGroups {
|
||||
logGroupName := *logGroup.LogGroupName
|
||||
result = append(result, suggestData{Text: logGroupName, Value: logGroupName, Label: logGroupName})
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
func (e *cloudWatchExecutor) handleGetAllLogGroups(pluginCtx backend.PluginContext, parameters url.Values) ([]suggestData, error) {
|
||||
var nextToken *string
|
||||
|
||||
|
||||
@@ -18,8 +18,7 @@ func (e *cloudWatchExecutor) newResourceMux() *http.ServeMux {
|
||||
mux.HandleFunc("/ebs-volume-ids", handleResourceReq(e.handleGetEbsVolumeIds))
|
||||
mux.HandleFunc("/ec2-instance-attribute", handleResourceReq(e.handleGetEc2InstanceAttribute))
|
||||
mux.HandleFunc("/resource-arns", handleResourceReq(e.handleGetResourceArns))
|
||||
mux.HandleFunc("/log-groups", handleResourceReq(e.handleGetLogGroups))
|
||||
mux.HandleFunc("/describe-log-groups", routes.ResourceRequestMiddleware(routes.LogGroupsHandler, logger, e.getRequestContext)) // supports CrossAccountQuerying
|
||||
mux.HandleFunc("/describe-log-groups", routes.ResourceRequestMiddleware(routes.LogGroupsHandler, logger, e.getRequestContext))
|
||||
mux.HandleFunc("/all-log-groups", handleResourceReq(e.handleGetAllLogGroups))
|
||||
mux.HandleFunc("/metrics", routes.ResourceRequestMiddleware(routes.MetricsHandler, logger, e.getRequestContext))
|
||||
mux.HandleFunc("/dimension-values", routes.ResourceRequestMiddleware(routes.DimensionValuesHandler, logger, e.getRequestContext))
|
||||
|
||||
Reference in New Issue
Block a user