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
|
|
}
|