mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
* Use context in aws ListSinks and ListAttachedLinks In the current way, ListSinks and ListAttachedLinks is used which doesn't allow cancelling the request if the context changes. Using ListSinksWithContext and ListAttachedLinksWithContext is the preferred way. Adding context for GetAccountsForCurrentUserOrRole is required to pass it to ListSinks method.
91 lines
2.3 KiB
Go
91 lines
2.3 KiB
Go
package services
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
"github.com/aws/aws-sdk-go/service/oam"
|
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models/resources"
|
|
)
|
|
|
|
var ErrAccessDeniedException = errors.New("access denied. please check your IAM policy")
|
|
|
|
type AccountsService struct {
|
|
models.OAMAPIProvider
|
|
}
|
|
|
|
func NewAccountsService(oamClient models.OAMAPIProvider) models.AccountsProvider {
|
|
return &AccountsService{oamClient}
|
|
}
|
|
|
|
func (a *AccountsService) GetAccountsForCurrentUserOrRole(ctx context.Context) ([]resources.ResourceResponse[resources.Account], error) {
|
|
var nextToken *string
|
|
sinks := []*oam.ListSinksItem{}
|
|
for {
|
|
response, err := a.ListSinksWithContext(ctx, &oam.ListSinksInput{NextToken: nextToken})
|
|
if err != nil {
|
|
var aerr awserr.Error
|
|
if errors.As(err, &aerr) {
|
|
switch aerr.Code() {
|
|
// unlike many other services, OAM doesn't define this error code. however, it's returned in case calling role/user has insufficient permissions
|
|
case "AccessDeniedException":
|
|
return nil, fmt.Errorf("%w: %s", ErrAccessDeniedException, aerr.Message())
|
|
}
|
|
}
|
|
}
|
|
if err != nil {
|
|
return nil, fmt.Errorf("ListSinks error: %w", err)
|
|
}
|
|
|
|
sinks = append(sinks, response.Items...)
|
|
|
|
if response.NextToken == nil {
|
|
break
|
|
}
|
|
nextToken = response.NextToken
|
|
}
|
|
|
|
if len(sinks) == 0 {
|
|
return nil, nil
|
|
}
|
|
|
|
sinkIdentifier := sinks[0].Arn
|
|
response := []resources.Account{{
|
|
Id: getAccountId(*sinkIdentifier),
|
|
Label: *sinks[0].Name,
|
|
Arn: *sinkIdentifier,
|
|
IsMonitoringAccount: true,
|
|
}}
|
|
|
|
nextToken = nil
|
|
for {
|
|
links, err := a.ListAttachedLinksWithContext(ctx, &oam.ListAttachedLinksInput{
|
|
SinkIdentifier: sinkIdentifier,
|
|
NextToken: nextToken,
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("ListAttachedLinks error: %w", err)
|
|
}
|
|
|
|
for _, link := range links.Items {
|
|
arn := *link.LinkArn
|
|
response = append(response, resources.Account{
|
|
Id: getAccountId(arn),
|
|
Label: *link.Label,
|
|
Arn: arn,
|
|
IsMonitoringAccount: false,
|
|
})
|
|
}
|
|
|
|
if links.NextToken == nil {
|
|
break
|
|
}
|
|
nextToken = links.NextToken
|
|
}
|
|
|
|
return valuesToListMetricRespone(response), nil
|
|
}
|