This repository has been archived by the owner on Aug 16, 2022. It is now read-only.
/
accounts.go
133 lines (128 loc) · 4.33 KB
/
accounts.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package organizations
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/aws/smithy-go"
"github.com/cloudquery/cq-provider-aws/client"
"github.com/cloudquery/cq-provider-sdk/provider/diag"
"github.com/cloudquery/cq-provider-sdk/provider/schema"
)
//go:generate cq-gen --resource accounts --config gen.hcl --output .
func Accounts() *schema.Table {
return &schema.Table{
Name: "aws_organizations_accounts",
Description: "Contains information about an AWS account that is a member of an organization",
Resolver: fetchOrganizationsAccounts,
Multiplex: client.AccountMultiplex,
DeleteFilter: client.DeleteAccountFilter,
IgnoreError: client.IgnoreAccessDeniedServiceDisabled,
IgnoreInTests: true,
Options: schema.TableCreationOptions{PrimaryKeys: []string{"account_id", "id"}},
Columns: []schema.Column{
{
Name: "account_id",
Description: "The AWS Account ID of the resource.",
Type: schema.TypeString,
Resolver: client.ResolveAWSAccount,
},
{
Name: "tags",
Description: "The AWS tags of the resource.",
Type: schema.TypeJSON,
Resolver: ResolveOrganizationsAccountTags,
},
{
Name: "arn",
Description: "The Amazon Resource Name (ARN) of the account",
Type: schema.TypeString,
},
{
Name: "email",
Description: "The email address associated with the AWS account",
Type: schema.TypeString,
},
{
Name: "id",
Description: "The unique identifier (ID) of the account",
Type: schema.TypeString,
},
{
Name: "joined_method",
Description: "The method by which the account joined the organization",
Type: schema.TypeString,
},
{
Name: "joined_timestamp",
Description: "The date the account became a part of the organization",
Type: schema.TypeTimestamp,
},
{
Name: "name",
Description: "The friendly name of the account",
Type: schema.TypeString,
},
{
Name: "status",
Description: "The status of the account in the organization",
Type: schema.TypeString,
},
},
}
}
// ====================================================================================================================
// Table Resolver Functions
// ====================================================================================================================
func fetchOrganizationsAccounts(ctx context.Context, meta schema.ClientMeta, _ *schema.Resource, res chan<- interface{}) error {
c := meta.(*client.Client)
svc := c.Services().Organizations
var input organizations.ListAccountsInput
for {
response, err := svc.ListAccounts(ctx, &input)
var ae smithy.APIError
if errors.As(err, &ae) {
switch ae.ErrorCode() {
case "AWSOrganizationsNotInUseException", "AccessDeniedException":
// This is going to happen most probably due to account not being the root organizational account
// so it's better to ignore it completely as it happens basically on every account
// otherwise it screws up with dev experience and with our tests
meta.Logger().Warn("account is probably not the root organization account https://docs.aws.amazon.com/organizations/latest/APIReference/API_ListAccounts.html")
return nil
}
}
if err != nil {
return diag.WrapError(err)
}
res <- response.Accounts
if aws.ToString(response.NextToken) == "" {
break
}
input.NextToken = response.NextToken
}
return nil
}
func ResolveOrganizationsAccountTags(ctx context.Context, meta schema.ClientMeta, resource *schema.Resource, _ schema.Column) error {
cl := meta.(*client.Client)
account := resource.Item.(types.Account)
allTags := make(map[string]*string)
input := organizations.ListTagsForResourceInput{
ResourceId: account.Id,
NextToken: nil,
}
for {
response, err := cl.Services().Organizations.ListTagsForResource(ctx, &input)
if err != nil {
return diag.WrapError(err)
}
for _, t := range response.Tags {
allTags[*t.Key] = t.Value
}
if response.NextToken == nil {
break
}
input.NextToken = response.NextToken
}
return diag.WrapError(resource.Set("tags", allTags))
}