Skip to content

Commit

Permalink
Adjust for better code
Browse files Browse the repository at this point in the history
  • Loading branch information
YakDriver committed Aug 14, 2019
1 parent f3dbef3 commit 1226a0a
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 116 deletions.
178 changes: 84 additions & 94 deletions aws/resource_aws_ram_resource_share_accepter.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/ram"

"github.com/hashicorp/terraform/helper/resource"
Expand Down Expand Up @@ -85,36 +84,42 @@ func resourceAwsRamResourceShareAccepter() *schema.Resource {
func resourceAwsRamResourceShareAccepterCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ramconn

in := &ram.AcceptResourceShareInvitationInput{
input := &ram.AcceptResourceShareInvitationInput{
ClientToken: aws.String(resource.UniqueId()),
}

if v, ok := d.GetOk("invitation_arn"); ok {
in.ResourceShareInvitationArn = aws.String(v.(string))
} else if v, ok := d.GetOk("share_arn"); ok {
// need to find invitation arn
invitationARN, err := resourceAwsRamResourceShareGetInvitationARN(conn, v.(string))
if v, ok := d.GetOk("invitation_arn"); ok && v.(string) != "" {
input.ResourceShareInvitationArn = aws.String(v.(string))
} else if v, ok := d.GetOk("share_arn"); ok && v.(string) != "" {
// need invitation arn
invitation, err := resourceAwsRamResourceShareGetInvitation(d, meta, v.(string), ram.ResourceShareInvitationStatusPending)
if err != nil {
return err
}
if invitation == nil || aws.StringValue(invitation.ResourceShareInvitationArn) == "" {
return fmt.Errorf("No RAM resource share invitation by ARN (%s) found", v.(string))
}

in.ResourceShareInvitationArn = aws.String(invitationARN)
input.ResourceShareInvitationArn = invitation.ResourceShareInvitationArn
} else {
return fmt.Errorf("Either an invitation ARN or share ARN are required")
}

log.Printf("[DEBUG] Accept RAM resource share invitation request: %s", in)
out, err := conn.AcceptResourceShareInvitation(in)
log.Printf("[DEBUG] Accept RAM resource share invitation request: %s", input)
output, err := conn.AcceptResourceShareInvitation(input)
if err != nil {
return fmt.Errorf("Error accepting RAM resource share invitation: %s", err)
}

d.SetId(aws.StringValue(out.ResourceShareInvitation.ResourceShareInvitationArn))
d.SetId(aws.StringValue(output.ResourceShareInvitation.ResourceShareArn))
d.Set("invitation_arn", output.ResourceShareInvitation.ResourceShareInvitationArn)

stateConf := &resource.StateChangeConf{
Pending: []string{ram.ResourceShareInvitationStatusPending},
Target: []string{ram.ResourceShareInvitationStatusAccepted},
Refresh: resourceAwsRamResourceShareAccepterStateRefreshFunc(conn, d.Id()),
Refresh: resourceAwsRamResourceShareAccepterStateRefreshFunc(
conn,
aws.StringValue(output.ResourceShareInvitation.ResourceShareInvitationArn)),
Timeout: d.Timeout(schema.TimeoutCreate),
}

Expand All @@ -129,61 +134,44 @@ func resourceAwsRamResourceShareAccepterCreate(d *schema.ResourceData, meta inte
func resourceAwsRamResourceShareAccepterRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ramconn

request := &ram.GetResourceShareInvitationsInput{
ResourceShareInvitationArns: []*string{aws.String(d.Id())},
}
invitation, err := resourceAwsRamResourceShareGetInvitation(d, meta, d.Id(), ram.ResourceShareInvitationStatusAccepted)

out, err := conn.GetResourceShareInvitations(request)
if err != nil {
if isAWSErr(err, ram.ErrCodeUnknownResourceException, "") {
log.Printf("[WARN] No RAM resource share invitation by ARN (%s) found, removing from state", d.Id())
d.SetId("")
return nil
}
return fmt.Errorf("Error reading RAM resource share invitation %s: %s", d.Id(), err)
}

if len(out.ResourceShareInvitations) == 0 {
if err == nil && invitation == nil {
log.Printf("[WARN] No RAM resource share invitation by ARN (%s) found, removing from state", d.Id())
d.SetId("")
return nil
}

invitation := out.ResourceShareInvitations[0]
if err != nil {
return err
}

d.Set("status", invitation.Status)
d.Set("receiver_account_id", invitation.ReceiverAccountId)
d.Set("sender_account_id", invitation.SenderAccountId)
d.Set("share_arn", invitation.ResourceShareArn)
d.Set("invitation_arn", invitation.ResourceShareInvitationArn)
d.Set("share_id", resourceAwsRamResourceShareGetIDFromARN(aws.StringValue(invitation.ResourceShareArn)))
d.Set("share_id", resourceAwsRamResourceShareGetIDFromARN(d.Id()))
d.Set("share_name", invitation.ResourceShareName)

var nextToken string
var resourceARNs []*string
for {
listInput := &ram.ListResourcesInput{
MaxResults: aws.Int64(int64(500)),
ResourceOwner: aws.String(ram.ResourceOwnerOtherAccounts),
ResourceShareArns: aws.StringSlice([]string{aws.StringValue(invitation.ResourceShareArn)}),
Principal: invitation.SenderAccountId,
}
listInput := &ram.ListResourcesInput{
MaxResults: aws.Int64(int64(500)),
ResourceOwner: aws.String(ram.ResourceOwnerOtherAccounts),
ResourceShareArns: aws.StringSlice([]string{d.Id()}),
Principal: invitation.SenderAccountId,
}

if nextToken != "" {
listInput.NextToken = aws.String(nextToken)
}
out, err := conn.ListResources(listInput)
if err != nil {
return fmt.Errorf("could not list share resources: %s", err)
}
for _, resource := range out.Resources {
var resourceARNs []*string
err = conn.ListResourcesPages(listInput, func(page *ram.ListResourcesOutput, lastPage bool) bool {
for _, resource := range page.Resources {
resourceARNs = append(resourceARNs, resource.Arn)
}

if out.NextToken == nil {
break
}
nextToken = aws.StringValue(out.NextToken)
return !lastPage
})

if err != nil {
return fmt.Errorf("Error reading RAM resource share resources %s: %s", d.Id(), err)
}

if err := d.Set("resources", flattenStringList(resourceARNs)); err != nil {
Expand All @@ -196,78 +184,80 @@ func resourceAwsRamResourceShareAccepterRead(d *schema.ResourceData, meta interf
func resourceAwsRamResourceShareAccepterDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ramconn

v, ok := d.GetOk("share_arn")
if !ok {
return fmt.Errorf("The share ARN is required to leave a resource share")
}
shareARN := v.(string)

v, ok = d.GetOk("receiver_account_id")
v, ok := d.GetOk("receiver_account_id")
if !ok {
return fmt.Errorf("The receiver account ID is required to leave a resource share")
}
receiverID := v.(string)

in := &ram.DisassociateResourceShareInput{
input := &ram.DisassociateResourceShareInput{
ClientToken: aws.String(resource.UniqueId()),
ResourceShareArn: aws.String(shareARN),
ResourceShareArn: aws.String(d.Id()),
Principals: []*string{aws.String(receiverID)},
}
log.Printf("[DEBUG] Leaving RAM resource share request: %s", in)
_, err := conn.DisassociateResourceShare(in)
log.Printf("[DEBUG] Leaving RAM resource share request: %s", input)
_, err := conn.DisassociateResourceShare(input)
if err != nil {
return fmt.Errorf("Error leaving RAM resource share: %s", err)
}

stateConf := &resource.StateChangeConf{
Pending: []string{ram.ResourceShareAssociationStatusAssociated},
Target: []string{ram.ResourceShareAssociationStatusDisassociated},
Refresh: resourceAwsRamResourceShareStateRefreshFunc(conn, shareARN),
Timeout: d.Timeout(schema.TimeoutCreate),
Refresh: resourceAwsRamResourceShareStateRefreshFunc(conn, d.Id()),
Timeout: d.Timeout(schema.TimeoutDelete),
}

if _, err := stateConf.WaitForState(); err != nil {
if awserr, ok := err.(awserr.Error); ok {
switch awserr.Code() {
case ram.ErrCodeUnknownResourceException:
// what we want
d.SetId("")
return nil
}
if isAWSErr(err, ram.ErrCodeUnknownResourceException, "") {
// what we want
return nil
}
return fmt.Errorf("Error waiting for RAM resource share (%s) state: %s", d.Id(), err)
}

return nil
}

func resourceAwsRamResourceShareGetInvitationARN(conn *ram.RAM, resourceShareARN string) (string, error) {
var nextToken string
for {
input := &ram.GetResourceShareInvitationsInput{
MaxResults: aws.Int64(int64(500)),
ResourceShareArns: aws.StringSlice([]string{resourceShareARN}),
}
if nextToken != "" {
input.NextToken = aws.String(nextToken)
}
out, err := conn.GetResourceShareInvitations(input)
if err != nil {
return "", err
}
for _, invitation := range out.ResourceShareInvitations {
if aws.StringValue(invitation.Status) == ram.ResourceShareInvitationStatusPending {
return aws.StringValue(invitation.ResourceShareInvitationArn), nil
func resourceAwsRamResourceShareGetInvitation(d *schema.ResourceData, meta interface{}, resourceShareARN, status string) (*ram.ResourceShareInvitation, error) {
conn := meta.(*AWSClient).ramconn

input := &ram.GetResourceShareInvitationsInput{
ResourceShareArns: []*string{aws.String(resourceShareARN)},
}

invitationARN := d.Get("invitation_arn").(string)
if invitationARN != "" {
input.ResourceShareInvitationArns = []*string{aws.String(invitationARN)}
}

var invitation *ram.ResourceShareInvitation
err := conn.GetResourceShareInvitationsPages(input, func(page *ram.GetResourceShareInvitationsOutput, lastPage bool) bool {
for _, rsi := range page.ResourceShareInvitations {
if aws.StringValue(rsi.Status) == status {
invitation = rsi
break
}
}

if out.NextToken == nil {
break
}
nextToken = aws.StringValue(out.NextToken)
return !lastPage
})

// if invitation not found with invitation ARN, try to find without
if invitation == nil && invitationARN != "" {
d.Set("invitation_arn", "")
return resourceAwsRamResourceShareGetInvitation(d, meta, resourceShareARN, status)
}

if invitation == nil {
return nil, nil
}

if err != nil {
return nil, fmt.Errorf("Error reading RAM resource share invitation %s: %s", resourceShareARN, err)
}

return "", fmt.Errorf("Unable to find a pending invitation for resource share %s", resourceShareARN)
return invitation, nil
}

func resourceAwsRamResourceShareAccepterStateRefreshFunc(conn *ram.RAM, invitationArn string) resource.StateRefreshFunc {
Expand All @@ -276,17 +266,17 @@ func resourceAwsRamResourceShareAccepterStateRefreshFunc(conn *ram.RAM, invitati
ResourceShareInvitationArns: []*string{aws.String(invitationArn)},
}

out, err := conn.GetResourceShareInvitations(request)
output, err := conn.GetResourceShareInvitations(request)

if err != nil {
return nil, "Unable to get resource share invitations", err
}

if len(out.ResourceShareInvitations) == 0 {
if len(output.ResourceShareInvitations) == 0 {
return nil, "Resource share invitation not found", nil
}

invitation := out.ResourceShareInvitations[0]
invitation := output.ResourceShareInvitations[0]

return invitation, aws.StringValue(invitation.Status), nil
}
Expand Down
48 changes: 26 additions & 22 deletions aws/resource_aws_ram_resource_share_accepter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"regexp"
"testing"

"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
Expand Down Expand Up @@ -60,35 +59,44 @@ func testAccCheckAwsRamResourceShareAccepterDestroy(s *terraform.State) error {
continue
}

request := &ram.GetResourceSharesInput{
input := &ram.GetResourceSharesInput{
ResourceShareArns: []*string{aws.String(rs.Primary.Attributes["share_arn"])},
ResourceOwner: aws.String(ram.ResourceOwnerOtherAccounts),
}

resp, err := conn.GetResourceShares(request)
output, err := conn.GetResourceShares(input)
if err != nil {
if awserr, ok := err.(awserr.Error); ok {
switch awserr.Code() {
case ram.ErrCodeUnknownResourceException:
// good - it's gone
return nil
}
if isAWSErr(err, ram.ErrCodeUnknownResourceException, "") {
return nil
}
return fmt.Errorf("Error deleting RAM resource share: %s", err)
}

if len(resp.ResourceShares) == 0 {
if len(output.ResourceShares) == 0 {
return nil
}
}
return fmt.Errorf("RAM resource share association found, should be destroyed")
return fmt.Errorf("RAM resource share invitation found, should be destroyed")
}

func testAccCheckAwsRamResourceShareAccepterExists(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
_, ok := s.RootModule().Resources[name]
if !ok {
return fmt.Errorf("Not found: %s", name)
rs, ok := s.RootModule().Resources[name]

if !ok || rs.Type != "aws_ram_resource_share_accepter" {
return fmt.Errorf("RAM resource share invitation not found: %s", name)
}

conn := testAccProvider.Meta().(*AWSClient).ramconn

input := &ram.GetResourceSharesInput{
ResourceShareArns: []*string{aws.String(rs.Primary.Attributes["share_arn"])},
ResourceOwner: aws.String(ram.ResourceOwnerOtherAccounts),
}

output, err := conn.GetResourceShares(input)
if err != nil || len(output.ResourceShares) == 0 {
return fmt.Errorf("Error finding RAM resource share: %s", err)
}

return nil
Expand All @@ -100,11 +108,11 @@ func testAccAwsRamResourceShareAccepterBasic(shareName string) string {
resource "aws_ram_resource_share" "test" {
provider = "aws.alternate"
name = %q
name = %[1]q
allow_external_principals = true
tags = {
Name = %q
Name = %[1]q
}
}
Expand All @@ -113,16 +121,12 @@ resource "aws_ram_principal_association" "test" {
principal = "${data.aws_caller_identity.receiver.account_id}"
resource_share_arn = "${aws_ram_resource_share.test.arn}"
depends_on = ["data.aws_caller_identity.receiver"]
}
data "aws_caller_identity" "receiver" {}
resource "aws_ram_resource_share_accepter" "test" {
share_arn = "${aws_ram_resource_share.test.arn}"
depends_on = ["aws_ram_resource_share.test", "aws_ram_principal_association.test"]
share_arn = "${aws_ram_principal_association.test.resource_share_arn}"
}
`, shareName, shareName)
`, shareName)
}

0 comments on commit 1226a0a

Please sign in to comment.