Skip to content

Commit

Permalink
Merge pull request #19957 from hashicorp/f-caller-id-base-role
Browse files Browse the repository at this point in the history
d/aws_iam_session_context: New data source
  • Loading branch information
YakDriver committed Jun 28, 2021
2 parents 4dc4476 + 4252de0 commit 6c348dd
Show file tree
Hide file tree
Showing 8 changed files with 475 additions and 5 deletions.
3 changes: 3 additions & 0 deletions .changelog/19957.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-data-source
aws_iam_session_context
```
2 changes: 1 addition & 1 deletion aws/data_source_aws_caller_identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func dataSourceAwsCallerIdentityRead(d *schema.ResourceData, meta interface{}) e
res, err := client.GetCallerIdentity(&sts.GetCallerIdentityInput{})

if err != nil {
return fmt.Errorf("Error getting Caller Identity: %w", err)
return fmt.Errorf("getting Caller Identity: %w", err)
}

log.Printf("[DEBUG] Received Caller Identity: %s", res)
Expand Down
128 changes: 128 additions & 0 deletions aws/data_source_aws_iam_session_context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package aws

import (
"fmt"
"regexp"
"strings"

"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/iam/finder"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/iam/waiter"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource"
)

func dataSourceAwsIAMSessionContext() *schema.Resource {
return &schema.Resource{
Read: dataSourceAwsIAMSessionContextRead,

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateArn,
},
"issuer_arn": {
Type: schema.TypeString,
Computed: true,
},
"issuer_id": {
Type: schema.TypeString,
Computed: true,
},
"issuer_name": {
Type: schema.TypeString,
Computed: true,
},
"session_name": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func dataSourceAwsIAMSessionContextRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).iamconn

arn := d.Get("arn").(string)

d.SetId(arn)

roleName := ""
sessionName := ""
var err error

if roleName, sessionName = roleNameSessionFromARN(arn); roleName == "" {
d.Set("issuer_arn", arn)
d.Set("issuer_id", "")
d.Set("issuer_name", "")
d.Set("session_name", "")

return nil
}

var role *iam.Role

err = resource.Retry(waiter.PropagationTimeout, func() *resource.RetryError {
var err error

role, err = finder.Role(conn, roleName)

if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, iam.ErrCodeNoSuchEntityException) {
return resource.RetryableError(err)
}

if err != nil {
return resource.NonRetryableError(err)
}

return nil
})

if tfresource.TimedOut(err) {
role, err = finder.Role(conn, roleName)
}

if err != nil {
return fmt.Errorf("unable to get role (%s): %w", roleName, err)
}

if role == nil || role.Arn == nil {
return fmt.Errorf("empty role returned (%s)", roleName)
}

d.Set("issuer_arn", role.Arn)
d.Set("issuer_id", role.RoleId)
d.Set("issuer_name", roleName)
d.Set("session_name", sessionName)

return nil
}

// roleNameSessionFromARN returns the role and session names in an ARN if any.
// Otherwise, it returns empty strings.
func roleNameSessionFromARN(rawARN string) (string, string) {
parsedARN, err := arn.Parse(rawARN)

if err != nil {
return "", ""
}

reAssume := regexp.MustCompile(`^assumed-role/.{1,}/.{2,}`)

if !reAssume.MatchString(parsedARN.Resource) || parsedARN.Service != "sts" {
return "", ""
}

parts := strings.Split(parsedARN.Resource, "/")

if len(parts) < 3 {
return "", ""
}

return parts[len(parts)-2], parts[len(parts)-1]
}

0 comments on commit 6c348dd

Please sign in to comment.