diff --git a/client/client.go b/client/client.go index 6cdc8a142..54e446fdd 100644 --- a/client/client.go +++ b/client/client.go @@ -62,8 +62,9 @@ import ( "github.com/aws/aws-sdk-go-v2/service/sts" "github.com/aws/aws-sdk-go-v2/service/waf" "github.com/aws/aws-sdk-go-v2/service/wafv2" - "github.com/cloudquery/cq-provider-sdk/provider/schema" "github.com/hashicorp/go-hclog" + + "github.com/cloudquery/cq-provider-sdk/provider/schema" ) // Provider Client passed as meta to all table fetchers @@ -175,7 +176,7 @@ func (s *ServicesManager) InitServicesForAccountAndRegion(accountId string, regi type Client struct { // Those are already normalized values after configure and this is why we don't want to hold // config directly. - accounts []Account + Accounts []Account regions []string logLevel *string maxRetries int @@ -212,12 +213,12 @@ func NewAwsClient(logger hclog.Logger, accounts []Account, regions []string) Cli services: ServicesAccountRegionMap{}, }, logger: logger, - accounts: accounts, + Accounts: accounts, regions: regions, } } func (c *Client) Logger() hclog.Logger { - return &awsLogger{c.logger, c.accounts} + return &awsLogger{c.logger, c.Accounts} } func (c *Client) Services() *Services { @@ -226,7 +227,7 @@ func (c *Client) Services() *Services { func (c *Client) withAccountID(accountID string) *Client { return &Client{ - accounts: c.accounts, + Accounts: c.Accounts, regions: c.regions, logLevel: c.logLevel, maxRetries: c.maxRetries, @@ -241,7 +242,7 @@ func (c *Client) withAccountID(accountID string) *Client { func (c *Client) withAccountIDAndRegion(accountID, region string) *Client { return &Client{ - accounts: c.accounts, + Accounts: c.Accounts, regions: c.regions, logLevel: c.logLevel, maxRetries: c.maxRetries, @@ -256,7 +257,7 @@ func (c *Client) withAccountIDAndRegion(accountID, region string) *Client { func (c *Client) withAccountIDRegionAndNamespace(accountID, region, namespace string) *Client { return &Client{ - accounts: c.accounts, + Accounts: c.Accounts, regions: c.regions, logLevel: c.logLevel, maxRetries: c.maxRetries, @@ -369,7 +370,7 @@ func Configure(logger hclog.Logger, providerConfig interface{}) (schema.ClientMe // set default client.AccountID = *output.Account client.Region = client.regions[0] - client.accounts = append(client.accounts, Account{ID: *output.Account, RoleARN: *output.Arn}) + client.Accounts = append(client.Accounts, Account{ID: *output.Account, RoleARN: *output.Arn}) } for _, region := range client.regions { client.ServicesManager.InitServicesForAccountAndRegion(*output.Account, region, initServices(region, awsCfg)) diff --git a/client/errors.go b/client/errors.go index bd3e6e38f..50a71355d 100644 --- a/client/errors.go +++ b/client/errors.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/aws/smithy-go" + "github.com/cloudquery/cq-provider-sdk/provider/schema" "github.com/cloudquery/cq-provider-sdk/provider/schema/diag" ) @@ -16,22 +17,22 @@ func ErrorClassifier(meta schema.ClientMeta, resourceName string, err error) []d switch ae.ErrorCode() { case "AccessDenied", "AccessDeniedException", "UnauthorizedOperation", "AuthorizationError": return []diag.Diagnostic{ - diag.FromError(err, diag.WARNING, diag.ACCESS, resourceName, parseSummaryMessage(client.accounts, err, ae), errorCodeDescriptions[ae.ErrorCode()]), + diag.FromError(err, diag.WARNING, diag.ACCESS, resourceName, ParseSummaryMessage(client.Accounts, err, ae), errorCodeDescriptions[ae.ErrorCode()]), } case "OptInRequired", "SubscriptionRequiredException", "InvalidClientTokenId": return []diag.Diagnostic{ - diag.FromError(err, diag.WARNING, diag.ACCESS, resourceName, parseSummaryMessage(client.accounts, err, ae), errorCodeDescriptions[ae.ErrorCode()]), + diag.FromError(err, diag.WARNING, diag.ACCESS, resourceName, ParseSummaryMessage(client.Accounts, err, ae), errorCodeDescriptions[ae.ErrorCode()]), } case "InvalidAction": return []diag.Diagnostic{ - diag.FromError(err, diag.IGNORE, diag.RESOLVING, resourceName, parseSummaryMessage(client.accounts, err, ae), + diag.FromError(err, diag.IGNORE, diag.RESOLVING, resourceName, ParseSummaryMessage(client.Accounts, err, ae), "The action is invalid for the service."), } } } if IsErrorThrottle(err) { return []diag.Diagnostic{ - diag.FromError(err, diag.WARNING, diag.THROTTLE, resourceName, parseSummaryMessage(client.accounts, err, ae), + diag.FromError(err, diag.WARNING, diag.THROTTLE, resourceName, ParseSummaryMessage(client.Accounts, err, ae), "CloudQuery AWS provider has been throttled, increase max_retries/retry_timeout in provider configuration."), } } @@ -39,7 +40,7 @@ func ErrorClassifier(meta schema.ClientMeta, resourceName string, err error) []d return nil } -func parseSummaryMessage(aa []Account, err error, apiErr smithy.APIError) string { +func ParseSummaryMessage(aa []Account, err error, apiErr smithy.APIError) string { for { if op, ok := err.(*smithy.OperationError); ok { return fmt.Sprintf("%s: %s - %s", op.Service(), op.Operation(), accountObfusactor(aa, apiErr.ErrorMessage())) diff --git a/resources/organizations_accounts.go b/resources/organizations_accounts.go index a0e0225b0..a36ea969f 100644 --- a/resources/organizations_accounts.go +++ b/resources/organizations_accounts.go @@ -2,11 +2,16 @@ package resources import ( "context" + "errors" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/organizations" + "github.com/aws/aws-sdk-go-v2/service/organizations/types" + "github.com/cloudquery/cq-provider-aws/client" + "github.com/cloudquery/cq-provider-sdk/provider/schema" + "github.com/cloudquery/cq-provider-sdk/provider/schema/diag" ) func OrganizationsAccounts() *schema.Table { @@ -74,8 +79,11 @@ func fetchOrganizationsAccounts(ctx context.Context, meta schema.ClientMeta, par var input organizations.ListAccountsInput for { response, err := svc.ListAccounts(ctx, &input) + var ade *types.AccessDeniedException + if errors.As(err, &ade) { + return diag.FromError(err, diag.IGNORE, diag.ACCESS, OrganizationsAccounts().Name, client.ParseSummaryMessage(c.Accounts, err, ade), "Missing permissions or account might not be root/organizational unit.") + } if err != nil { - meta.Logger().Warn("missing permissions or account might not be root/organizational unit", "account", c.AccountID) return err } res <- response.Accounts