-
Notifications
You must be signed in to change notification settings - Fork 9.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
131 additions
and
122 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
```release-note:new-data-source | ||
aws_iam_roles | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,118 +1,94 @@ | ||
package aws | ||
|
||
import ( // nosemgrep: aws-sdk-go-multiple-service-imports | ||
import ( | ||
"fmt" | ||
"log" | ||
"path/filepath" // filepath for glob matching | ||
"regexp" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/ec2" | ||
"github.com/aws/aws-sdk-go/service/iam" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" | ||
) | ||
|
||
func dataSourceAwsIAMRoles() *schema.Resource { | ||
return &schema.Resource{ | ||
Read: dataSourceAwsIAMRolesRead, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"filter": dataSourceFiltersSchema(), | ||
"path_prefix": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
"arns": { | ||
Type: schema.TypeSet, | ||
Computed: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
Set: schema.HashString, | ||
}, | ||
"name_regex": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
ValidateFunc: validation.StringIsValidRegExp, | ||
}, | ||
"names": { | ||
Type: schema.TypeSet, | ||
Computed: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
Set: schema.HashString, | ||
}, | ||
"path_prefix": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func dataSourceAwsIAMRolesRead(d *schema.ResourceData, meta interface{}) error { | ||
iamconn := meta.(*AWSClient).iamconn | ||
req := &iam.ListRolesInput{} | ||
conn := meta.(*AWSClient).iamconn | ||
|
||
if pathPrefix, hasPathPrefix := d.GetOk("path_prefix"); hasPathPrefix { | ||
req.PathPrefix = aws.String(pathPrefix.(string)) | ||
input := &iam.ListRolesInput{} | ||
|
||
if v, ok := d.GetOk("path_prefix"); ok { | ||
input.PathPrefix = aws.String(v.(string)) | ||
} | ||
|
||
filters, hasFilters := d.GetOk("filter") | ||
filtersSet := []*ec2.Filter{} | ||
var results []*iam.Role | ||
|
||
if hasFilters { | ||
filtersSet = buildAwsDataSourceFilters(filters.(*schema.Set)) | ||
log.Printf("[DEBUG] Has filters : %s", filtersSet) | ||
// Only filters using the name "role-name" are currently supported | ||
for _, f := range filtersSet { | ||
if "role-name" != aws.StringValue(f.Name) { | ||
return fmt.Errorf("Provided filters does not match supported names. See the documentation of this data source for supported filters.") | ||
} | ||
err := conn.ListRolesPages(input, func(page *iam.ListRolesOutput, lastPage bool) bool { | ||
if page == nil { | ||
return !lastPage | ||
} | ||
} else { | ||
log.Printf("[DEBUG] No filter") | ||
} | ||
|
||
roles := []*iam.Role{} | ||
|
||
err := iamconn.ListRolesPages( | ||
req, | ||
func(page *iam.ListRolesOutput, lastPage bool) bool { | ||
for _, role := range page.Roles { | ||
if hasFilters { | ||
log.Printf("[DEBUG] Found Role '%s' to be checked against filters", *role.RoleName) | ||
matchAllFilters := true | ||
for _, f := range filtersSet { | ||
for _, filterValue := range f.Values { | ||
// must match all values | ||
if matched, _ := filepath.Match(*filterValue, *role.RoleName); !matched { | ||
log.Printf("[DEBUG] RoleName '%s' does not match filter '%s'", *role.RoleName, *filterValue) | ||
matchAllFilters = false | ||
} | ||
} | ||
} | ||
if matchAllFilters { | ||
roles = append(roles, role) | ||
} | ||
} else { | ||
log.Printf("[DEBUG] Found Role '%s'", *role.RoleName) | ||
roles = append(roles, role) | ||
} | ||
for _, role := range page.Roles { | ||
if role == nil { | ||
continue | ||
} | ||
return !lastPage | ||
}, | ||
) | ||
|
||
if v, ok := d.GetOk("name_regex"); ok && !regexp.MustCompile(v.(string)).MatchString(aws.StringValue(role.RoleName)) { | ||
continue | ||
} | ||
|
||
results = append(results, role) | ||
} | ||
|
||
return !lastPage | ||
}) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error reading IAM roles : %w", err) | ||
return fmt.Errorf("error reading IAM roles: %w", err) | ||
} | ||
|
||
if len(roles) == 0 { | ||
log.Printf("[WARN] couldn't find any IAM role matching the provided parameters") | ||
} | ||
d.SetId(meta.(*AWSClient).region) | ||
|
||
var arns, names []string | ||
|
||
arns := []string{} | ||
names := []string{} | ||
for _, v := range roles { | ||
arns = append(arns, aws.StringValue(v.Arn)) | ||
names = append(names, aws.StringValue(v.RoleName)) | ||
for _, r := range results { | ||
arns = append(arns, aws.StringValue(r.Arn)) | ||
names = append(names, aws.StringValue(r.RoleName)) | ||
} | ||
|
||
if err := d.Set("arns", arns); err != nil { | ||
return fmt.Errorf("error setting arns: %w", err) | ||
} | ||
|
||
if err := d.Set("names", names); err != nil { | ||
return fmt.Errorf("error setting names: %w", err) | ||
} | ||
|
||
d.SetId(meta.(*AWSClient).region) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.