grafana/pkg/tsdb/cloudwatch/services/log_groups.go

93 lines
3.0 KiB
Go

package services
import (
"context"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/resources"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/utils"
)
type LogGroupsService struct {
logGroupsAPI models.CloudWatchLogsAPIProvider
isCrossAccountEnabled bool
}
func NewLogGroupsService(logsClient models.CloudWatchLogsAPIProvider, isCrossAccountEnabled bool) models.LogGroupsProvider {
return &LogGroupsService{logGroupsAPI: logsClient, isCrossAccountEnabled: isCrossAccountEnabled}
}
func (s *LogGroupsService) GetLogGroupsWithContext(ctx context.Context, req resources.LogGroupsRequest) ([]resources.ResourceResponse[resources.LogGroup], error) {
input := &cloudwatchlogs.DescribeLogGroupsInput{
Limit: aws.Int64(req.Limit),
LogGroupNamePrefix: req.LogGroupNamePrefix,
}
if s.isCrossAccountEnabled && req.AccountId != nil {
input.IncludeLinkedAccounts = aws.Bool(true)
if req.LogGroupNamePattern != nil {
input.LogGroupNamePrefix = req.LogGroupNamePattern
}
if !req.IsTargetingAllAccounts() {
// TODO: accept more than one account id in search
input.AccountIdentifiers = []*string{req.AccountId}
}
}
result := []resources.ResourceResponse[resources.LogGroup]{}
for {
response, err := s.logGroupsAPI.DescribeLogGroupsWithContext(ctx, input)
if err != nil || response == nil {
return nil, err
}
for _, logGroup := range response.LogGroups {
result = append(result, resources.ResourceResponse[resources.LogGroup]{
Value: resources.LogGroup{
Arn: *logGroup.Arn,
Name: *logGroup.LogGroupName,
},
AccountId: utils.Pointer(getAccountId(*logGroup.Arn)),
})
}
if !req.ListAllLogGroups || response.NextToken == nil {
break
}
input.NextToken = response.NextToken
}
return result, nil
}
func (s *LogGroupsService) GetLogGroupFieldsWithContext(ctx context.Context, request resources.LogGroupFieldsRequest, option ...request.Option) ([]resources.ResourceResponse[resources.LogGroupField], error) {
input := &cloudwatchlogs.GetLogGroupFieldsInput{
LogGroupName: aws.String(request.LogGroupName),
}
// we should use LogGroupIdentifier instead of LogGroupName, but currently the api doesn't accept LogGroupIdentifier. need to check if it's a bug or not.
// if request.LogGroupARN != "" {
// input.LogGroupIdentifier = aws.String(strings.TrimSuffix(request.LogGroupARN, ":*"))
// input.LogGroupName = nil
// }
getLogGroupFieldsOutput, err := s.logGroupsAPI.GetLogGroupFieldsWithContext(ctx, input)
if err != nil {
return nil, err
}
result := make([]resources.ResourceResponse[resources.LogGroupField], 0)
for _, logGroupField := range getLogGroupFieldsOutput.LogGroupFields {
result = append(result, resources.ResourceResponse[resources.LogGroupField]{
Value: resources.LogGroupField{
Name: *logGroupField.Name,
Percent: *logGroupField.Percent,
},
})
}
return result, nil
}