Skip to content

Commit 270c9f3

Browse files
authored
Add aws_rolesanywhere_profile and aws_rolesanywhere_trust_anchor tables (#2475)
1 parent 43ffba7 commit 270c9f3

8 files changed

+676
-0
lines changed

aws/plugin.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,8 @@ func Plugin(ctx context.Context) *plugin.Plugin {
457457
"aws_resource_explorer_index": tableAWSResourceExplorerIndex(ctx),
458458
"aws_resource_explorer_search": tableAWSResourceExplorerSearch(ctx),
459459
"aws_resource_explorer_supported_resource_type": tableAWSResourceExplorerSupportedResourceType(ctx),
460+
"aws_rolesanywhere_profile": tableAwsRolesAnywhereProfile(ctx),
461+
"aws_rolesanywhere_trust_anchor": tableAwsRolesAnywhereTrustAnchor(ctx),
460462
"aws_route53_domain": tableAwsRoute53Domain(ctx),
461463
"aws_route53_health_check": tableAwsRoute53HealthCheck(ctx),
462464
"aws_route53_query_log": tableAwsRoute53QueryLog(ctx),

aws/service.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ import (
114114
"github.com/aws/aws-sdk-go-v2/service/redshiftserverless"
115115
"github.com/aws/aws-sdk-go-v2/service/resourceexplorer2"
116116
"github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi"
117+
"github.com/aws/aws-sdk-go-v2/service/rolesanywhere"
117118
"github.com/aws/aws-sdk-go-v2/service/route53"
118119
"github.com/aws/aws-sdk-go-v2/service/route53domains"
119120
"github.com/aws/aws-sdk-go-v2/service/route53resolver"
@@ -1355,6 +1356,14 @@ func ResourceGroupsTaggingClient(ctx context.Context, d *plugin.QueryData) (*res
13551356
return resourcegroupstaggingapi.NewFromConfig(*cfg), nil
13561357
}
13571358

1359+
func RolesAnywhereClient(ctx context.Context, d *plugin.QueryData) (*rolesanywhere.Client, error) {
1360+
cfg, err := getClientForQueryRegion(ctx, d)
1361+
if err != nil {
1362+
return nil, err
1363+
}
1364+
return rolesanywhere.NewFromConfig(*cfg), nil
1365+
}
1366+
13581367
func Route53Client(ctx context.Context, d *plugin.QueryData) (*route53.Client, error) {
13591368
// Route53 is a global service with a single DNS endpoint
13601369
// (route53.amazonaws.com).
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
package aws
2+
3+
import (
4+
"context"
5+
6+
"github.com/aws/aws-sdk-go-v2/aws"
7+
"github.com/aws/aws-sdk-go-v2/service/rolesanywhere"
8+
"github.com/aws/aws-sdk-go-v2/service/rolesanywhere/types"
9+
10+
"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
11+
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
12+
"github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform"
13+
)
14+
15+
//// TABLE DEFINITION
16+
17+
func tableAwsRolesAnywhereProfile(ctx context.Context) *plugin.Table {
18+
return &plugin.Table{
19+
Name: "aws_rolesanywhere_profile",
20+
Description: "AWS Roles Anywhere Profile",
21+
Get: &plugin.GetConfig{
22+
KeyColumns: plugin.AnyColumn([]string{"profile_id"}),
23+
IgnoreConfig: &plugin.IgnoreConfig{
24+
ShouldIgnoreErrorFunc: shouldIgnoreErrors([]string{"ResourceNotFoundException"}),
25+
},
26+
Hydrate: getProfile,
27+
Tags: map[string]string{"service": "rolesanywhere", "action": "GetProfile"},
28+
},
29+
List: &plugin.ListConfig{
30+
Hydrate: listProfiles,
31+
Tags: map[string]string{"service": "rolesanywhere", "action": "ListProfiles"},
32+
},
33+
HydrateConfig: []plugin.HydrateConfig{
34+
{
35+
Func: listTagsForProfile,
36+
Tags: map[string]string{"service": "rolesanywhere", "action": "ListTagsForResource"},
37+
},
38+
},
39+
GetMatrixItemFunc: SupportedRegionMatrix(AWS_ROLESANYWHERE_SERVICE_ID),
40+
Columns: awsRegionalColumns([]*plugin.Column{
41+
{
42+
Name: "profile_id",
43+
Description: "The unique identifier of the profile.",
44+
Type: proto.ColumnType_STRING,
45+
},
46+
{
47+
Name: "arn",
48+
Description: "The Amazon Resource Name (ARN) specifying the profile.",
49+
Type: proto.ColumnType_STRING,
50+
Transform: transform.FromField("ProfileArn"),
51+
},
52+
{
53+
Name: "name",
54+
Description: "The name of the profile.",
55+
Type: proto.ColumnType_STRING,
56+
},
57+
{
58+
Name: "accept_role_session_name",
59+
Description: "Used to determine if a custom role session name will be accepted in a temporary credential request.",
60+
Type: proto.ColumnType_BOOL,
61+
},
62+
{
63+
Name: "updated_at",
64+
Description: "The date and time when the profile was updated.",
65+
Type: proto.ColumnType_TIMESTAMP,
66+
},
67+
{
68+
Name: "created_at",
69+
Description: "The date and time when the profile was created.",
70+
Type: proto.ColumnType_TIMESTAMP,
71+
},
72+
{
73+
Name: "created_by",
74+
Description: "The account that created the profile.",
75+
Type: proto.ColumnType_STRING,
76+
},
77+
{
78+
Name: "duration_seconds",
79+
Description: "Used to determine how long sessions vended using this profile are valid for.",
80+
Type: proto.ColumnType_INT,
81+
},
82+
{
83+
Name: "enabled",
84+
Description: "If the profile is enabled or not.",
85+
Type: proto.ColumnType_BOOL,
86+
},
87+
{
88+
Name: "require_instance_properties",
89+
Description: "Specifies whether instance properties are required in temporary credential requests with this profile.",
90+
Type: proto.ColumnType_BOOL,
91+
},
92+
{
93+
Name: "attribute_mappings",
94+
Description: "A mapping applied to the authenticating end-entity certificate.",
95+
Type: proto.ColumnType_JSON,
96+
},
97+
{
98+
Name: "managed_policy_arns",
99+
Description: "A list of managed policy ARNs that apply to the vended session credentials.",
100+
Type: proto.ColumnType_JSON,
101+
},
102+
{
103+
Name: "role_arns",
104+
Description: "A list of IAM roles that this profile can assume in a temporary credential request.",
105+
Type: proto.ColumnType_JSON,
106+
},
107+
{
108+
Name: "session_policy",
109+
Description: "A session policy that applies to the trust boundary of the vended session credentials.",
110+
Type: proto.ColumnType_JSON,
111+
Transform: transform.FromField("SessionPolicy").Transform(transform.UnmarshalYAML),
112+
},
113+
{
114+
Name: "session_policy_std",
115+
Description: "Contains the session policy in a canonical form for easier searching.",
116+
Type: proto.ColumnType_JSON,
117+
Transform: transform.FromField("SessionPolicy").Transform(unescape).Transform(policyToCanonical),
118+
},
119+
{
120+
Name: "tags_src",
121+
Description: "A list of tags associated with the profile",
122+
Type: proto.ColumnType_JSON,
123+
Hydrate: listTagsForProfile,
124+
Transform: transform.FromField("Tags"),
125+
},
126+
127+
// Steampipe standard columns
128+
{
129+
Name: "title",
130+
Description: resourceInterfaceDescription("title"),
131+
Type: proto.ColumnType_STRING,
132+
Transform: transform.FromField("Name"),
133+
},
134+
{
135+
Name: "tags",
136+
Description: resourceInterfaceDescription("tags"),
137+
Type: proto.ColumnType_JSON,
138+
Hydrate: listTagsForProfile,
139+
Transform: transform.From(profileTurbotTags),
140+
},
141+
{
142+
Name: "akas",
143+
Description: resourceInterfaceDescription("akas"),
144+
Type: proto.ColumnType_JSON,
145+
Transform: transform.FromField("ProfileArn").Transform(transform.EnsureStringArray),
146+
},
147+
}),
148+
}
149+
}
150+
151+
//// LIST FUNCTION
152+
153+
func listProfiles(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) {
154+
svc, err := RolesAnywhereClient(ctx, d)
155+
if err != nil {
156+
plugin.Logger(ctx).Error("aws_rolesanywhere_profile.listProfiles", "client_error", err)
157+
return nil, err
158+
}
159+
if svc == nil {
160+
return nil, nil
161+
}
162+
163+
input := rolesanywhere.ListProfilesInput{}
164+
paginator := rolesanywhere.NewListProfilesPaginator(svc, &input, func(o *rolesanywhere.ListProfilesPaginatorOptions) {
165+
o.StopOnDuplicateToken = true
166+
})
167+
168+
for paginator.HasMorePages() {
169+
d.WaitForListRateLimit(ctx)
170+
171+
output, err := paginator.NextPage(ctx)
172+
if err != nil {
173+
plugin.Logger(ctx).Error("aws_rolesanywhere_profile.listProfiles", "api_error", err)
174+
return nil, err
175+
}
176+
177+
for _, profile := range output.Profiles {
178+
d.StreamListItem(ctx, profile)
179+
180+
// Context may get cancelled due to manual cancellation or if the limit has been reached
181+
if d.RowsRemaining(ctx) == 0 {
182+
return nil, nil
183+
}
184+
}
185+
}
186+
187+
return nil, nil
188+
189+
}
190+
191+
//// HYDRATE FUNCTIONS
192+
193+
func getProfile(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) {
194+
profile_id := d.EqualsQuals["id"].GetStringValue()
195+
196+
svc, err := RolesAnywhereClient(ctx, d)
197+
if err != nil {
198+
plugin.Logger(ctx).Error("aws_rolesanywhere_profile.getProfile", "client_error", err)
199+
return nil, err
200+
}
201+
if svc == nil {
202+
return nil, nil
203+
}
204+
205+
params := &rolesanywhere.GetProfileInput{
206+
ProfileId: aws.String(profile_id),
207+
}
208+
op, err := svc.GetProfile(ctx, params)
209+
if err != nil {
210+
plugin.Logger(ctx).Error("aws_rolesanywhere_profile.getProfile", "api_error", err)
211+
return nil, err
212+
}
213+
return *op.Profile, nil
214+
}
215+
216+
func listTagsForProfile(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
217+
profile_arn := h.Item.(types.ProfileDetail).ProfileArn
218+
219+
svc, err := RolesAnywhereClient(ctx, d)
220+
if err != nil {
221+
plugin.Logger(ctx).Error("aws_rolesanywhere_profile.listTagsForProfile", "client_error", err)
222+
return nil, err
223+
}
224+
if svc == nil {
225+
return nil, nil
226+
}
227+
228+
params := &rolesanywhere.ListTagsForResourceInput{
229+
ResourceArn: profile_arn,
230+
}
231+
op, err := svc.ListTagsForResource(ctx, params)
232+
if err != nil {
233+
plugin.Logger(ctx).Error("aws_rolesanywhere_profile.listTagsForProfile", "api_error", err)
234+
return nil, err
235+
}
236+
237+
return op, nil
238+
}
239+
240+
//// TRANSFORM FUNCTION
241+
242+
func profileTurbotTags(_ context.Context, d *transform.TransformData) (interface{}, error) {
243+
tags := d.HydrateItem.(*rolesanywhere.ListTagsForResourceOutput)
244+
var turbotTagsMap map[string]string
245+
if tags.Tags != nil {
246+
turbotTagsMap = map[string]string{}
247+
for _, i := range tags.Tags {
248+
turbotTagsMap[*i.Key] = *i.Value
249+
}
250+
}
251+
return turbotTagsMap, nil
252+
}

0 commit comments

Comments
 (0)