From a1f938e5eb202ae2da7dd48c10a3f8573477bd71 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 29 Sep 2022 11:14:13 -0400 Subject: [PATCH] Add and use 'FindTrafficMirrorTarget' and friends. --- internal/service/ec2/errors.go | 1 + internal/service/ec2/find.go | 70 +++++++++++++++ .../service/ec2/vpc_traffic_mirror_target.go | 89 ++++++++----------- .../ec2/vpc_traffic_mirror_target_test.go | 37 +++----- 4 files changed, 121 insertions(+), 76 deletions(-) diff --git a/internal/service/ec2/errors.go b/internal/service/ec2/errors.go index 6b0abe6f909..2cb1b4d291e 100644 --- a/internal/service/ec2/errors.go +++ b/internal/service/ec2/errors.go @@ -73,6 +73,7 @@ const ( errCodeInvalidSubnetCIDRReservationIDNotFound = "InvalidSubnetCidrReservationID.NotFound" errCodeInvalidSubnetIDNotFound = "InvalidSubnetID.NotFound" errCodeInvalidSubnetIdNotFound = "InvalidSubnetId.NotFound" + errCodeInvalidTrafficMirrorTargetIdNotFound = "InvalidTrafficMirrorTargetId.NotFound" errCodeInvalidTransitGatewayAttachmentIDNotFound = "InvalidTransitGatewayAttachmentID.NotFound" errCodeInvalidTransitGatewayConnectPeerIDNotFound = "InvalidTransitGatewayConnectPeerID.NotFound" errCodeInvalidTransitGatewayIDNotFound = "InvalidTransitGatewayID.NotFound" diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index aa510f820ab..6c35fef2d78 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -3147,6 +3147,76 @@ func FindVPNConnectionRouteByVPNConnectionIDAndCIDR(conn *ec2.EC2, vpnConnection } } +func FindTrafficMirrorTarget(conn *ec2.EC2, input *ec2.DescribeTrafficMirrorTargetsInput) (*ec2.TrafficMirrorTarget, error) { + output, err := FindTrafficMirrorTargets(conn, input) + + if err != nil { + return nil, err + } + + if len(output) == 0 || output[0] == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } + + return output[0], nil +} + +func FindTrafficMirrorTargets(conn *ec2.EC2, input *ec2.DescribeTrafficMirrorTargetsInput) ([]*ec2.TrafficMirrorTarget, error) { + var output []*ec2.TrafficMirrorTarget + + err := conn.DescribeTrafficMirrorTargetsPages(input, func(page *ec2.DescribeTrafficMirrorTargetsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.TrafficMirrorTargets { + if v != nil { + output = append(output, v) + } + } + + return !lastPage + }) + + if tfawserr.ErrCodeEquals(err, errCodeInvalidTrafficMirrorTargetIdNotFound) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + return output, nil +} + +func FindTrafficMirrorTargetByID(conn *ec2.EC2, id string) (*ec2.TrafficMirrorTarget, error) { + input := &ec2.DescribeTrafficMirrorTargetsInput{ + TrafficMirrorTargetIds: aws.StringSlice([]string{id}), + } + + output, err := FindTrafficMirrorTarget(conn, input) + + if err != nil { + return nil, err + } + + // Eventual consistency check. + if aws.StringValue(output.TrafficMirrorTargetId) != id { + return nil, &resource.NotFoundError{ + LastRequest: input, + } + } + + return output, nil +} + func FindTransitGateway(conn *ec2.EC2, input *ec2.DescribeTransitGatewaysInput) (*ec2.TransitGateway, error) { output, err := FindTransitGateways(conn, input) diff --git a/internal/service/ec2/vpc_traffic_mirror_target.go b/internal/service/ec2/vpc_traffic_mirror_target.go index c510e659b55..4b8b4436873 100644 --- a/internal/service/ec2/vpc_traffic_mirror_target.go +++ b/internal/service/ec2/vpc_traffic_mirror_target.go @@ -7,10 +7,10 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/ec2" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/internal/verify" ) @@ -104,26 +104,13 @@ func resourceTrafficMirrorTargetCreate(d *schema.ResourceData, meta interface{}) input.TagSpecifications = tagSpecificationsFromKeyValueTags(tags, ec2.ResourceTypeTrafficMirrorTarget) } - out, err := conn.CreateTrafficMirrorTarget(input) + output, err := conn.CreateTrafficMirrorTarget(input) + if err != nil { - return fmt.Errorf("Error creating traffic mirror target %v", err) + return fmt.Errorf("creating EC2 Traffic Mirror Target: %w", err) } - d.SetId(aws.StringValue(out.TrafficMirrorTarget.TrafficMirrorTargetId)) - - return resourceTrafficMirrorTargetRead(d, meta) -} - -func resourceTrafficMirrorTargetUpdate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*conns.AWSClient).EC2Conn - - if d.HasChange("tags_all") { - o, n := d.GetChange("tags_all") - - if err := UpdateTags(conn, d.Id(), o, n); err != nil { - return fmt.Errorf("error updating EC2 Traffic Mirror Target (%s) tags: %s", d.Id(), err) - } - } + d.SetId(aws.StringValue(output.TrafficMirrorTarget.TrafficMirrorTargetId)) return resourceTrafficMirrorTargetRead(d, meta) } @@ -133,71 +120,71 @@ func resourceTrafficMirrorTargetRead(d *schema.ResourceData, meta interface{}) e defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig - targetId := d.Id() - input := &ec2.DescribeTrafficMirrorTargetsInput{ - TrafficMirrorTargetIds: []*string{&targetId}, - } + target, err := FindTrafficMirrorTargetByID(conn, d.Id()) - out, err := conn.DescribeTrafficMirrorTargets(input) - if tfawserr.ErrCodeEquals(err, "InvalidTrafficMirrorTargetId.NotFound") { - log.Printf("[WARN] EC2 Traffic Mirror Target (%s) not found, removing from state", d.Id()) + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] EC2 Traffic Mirror Target %s not found, removing from state", d.Id()) d.SetId("") return nil } if err != nil { - return fmt.Errorf("error describing EC2 Traffic Mirror Target (%s): %w", targetId, err) + return fmt.Errorf("reading EC2 Traffic Mirror Target (%s): %w", d.Id(), err) } - if out == nil || len(out.TrafficMirrorTargets) == 0 { - log.Printf("[WARN] EC2 Traffic Mirror Target (%s) not found, removing from state", d.Id()) - d.SetId("") - return nil - } - - target := out.TrafficMirrorTargets[0] + ownerID := aws.StringValue(target.OwnerId) + arn := arn.ARN{ + Partition: meta.(*conns.AWSClient).Partition, + Service: ec2.ServiceName, + Region: meta.(*conns.AWSClient).Region, + AccountID: ownerID, + Resource: fmt.Sprintf("traffic-mirror-target/%s", d.Id()), + }.String() + d.Set("arn", arn) d.Set("description", target.Description) d.Set("gateway_load_balancer_endpoint_id", target.GatewayLoadBalancerEndpointId) d.Set("network_interface_id", target.NetworkInterfaceId) d.Set("network_load_balancer_arn", target.NetworkLoadBalancerArn) + d.Set("owner_id", ownerID) tags := KeyValueTags(target.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) //lintignore:AWSR002 if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %w", err) + return fmt.Errorf("setting tags: %w", err) } if err := d.Set("tags_all", tags.Map()); err != nil { - return fmt.Errorf("error setting tags_all: %w", err) + return fmt.Errorf("setting tags_all: %w", err) } - d.Set("owner_id", target.OwnerId) + return nil +} - arn := arn.ARN{ - Partition: meta.(*conns.AWSClient).Partition, - Service: ec2.ServiceName, - Region: meta.(*conns.AWSClient).Region, - AccountID: aws.StringValue(target.OwnerId), - Resource: fmt.Sprintf("traffic-mirror-target/%s", d.Id()), - }.String() +func resourceTrafficMirrorTargetUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).EC2Conn - d.Set("arn", arn) + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") - return nil + if err := UpdateTags(conn, d.Id(), o, n); err != nil { + return fmt.Errorf("updating EC2 Traffic Mirror Target (%s) tags: %w", d.Id(), err) + } + } + + return resourceTrafficMirrorTargetRead(d, meta) } func resourceTrafficMirrorTargetDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - targetId := d.Id() - input := &ec2.DeleteTrafficMirrorTargetInput{ - TrafficMirrorTargetId: &targetId, - } + log.Printf("[DEBUG] Deleting EC2 Traffic Mirror Target: %s", d.Id()) + _, err := conn.DeleteTrafficMirrorTarget(&ec2.DeleteTrafficMirrorTargetInput{ + TrafficMirrorTargetId: aws.String(d.Id()), + }) - _, err := conn.DeleteTrafficMirrorTarget(input) if nil != err { - return fmt.Errorf("error deleting EC2 Traffic Mirror Target (%s): %w", targetId, err) + return fmt.Errorf("deleting EC2 Traffic Mirror Target (%s): %w", d.Id(), err) } return nil diff --git a/internal/service/ec2/vpc_traffic_mirror_target_test.go b/internal/service/ec2/vpc_traffic_mirror_target_test.go index feaea1b84b7..edeeb2d6a3c 100644 --- a/internal/service/ec2/vpc_traffic_mirror_target_test.go +++ b/internal/service/ec2/vpc_traffic_mirror_target_test.go @@ -5,15 +5,14 @@ import ( "regexp" "testing" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" tfec2 "github.com/hashicorp/terraform-provider-aws/internal/service/ec2" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) func TestAccVPCTrafficMirrorTarget_nlb(t *testing.T) { @@ -198,13 +197,9 @@ func testAccCheckTrafficMirrorTargetDestroy(s *terraform.State) error { continue } - out, err := conn.DescribeTrafficMirrorTargets(&ec2.DescribeTrafficMirrorTargetsInput{ - TrafficMirrorTargetIds: []*string{ - aws.String(rs.Primary.ID), - }, - }) + _, err := tfec2.FindTrafficMirrorTargetByID(conn, rs.Primary.ID) - if tfawserr.ErrCodeEquals(err, "InvalidTrafficMirrorTargetId.NotFound") { + if tfresource.NotFound(err) { continue } @@ -212,40 +207,32 @@ func testAccCheckTrafficMirrorTargetDestroy(s *terraform.State) error { return err } - if len(out.TrafficMirrorTargets) != 0 { - return fmt.Errorf("Traffic mirror target %s still not destroyed", rs.Primary.ID) - } + return fmt.Errorf("EC2 Traffic Mirror Target %s still exists", rs.Primary.ID) } return nil } -func testAccCheckTrafficMirrorTargetExists(name string, target *ec2.TrafficMirrorTarget) resource.TestCheckFunc { +func testAccCheckTrafficMirrorTargetExists(n string, v *ec2.TrafficMirrorTarget) resource.TestCheckFunc { return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[name] + rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not found: %s", name) + return fmt.Errorf("Not found: %s", n) } + if rs.Primary.ID == "" { - return fmt.Errorf("No ID set for %s", name) + return fmt.Errorf("No EC2 Traffic Mirror Target ID is set") } conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn - out, err := conn.DescribeTrafficMirrorTargets(&ec2.DescribeTrafficMirrorTargetsInput{ - TrafficMirrorTargetIds: []*string{ - aws.String(rs.Primary.ID), - }, - }) + + output, err := tfec2.FindTrafficMirrorTargetByID(conn, rs.Primary.ID) if err != nil { return err } - if len(out.TrafficMirrorTargets) == 0 { - return fmt.Errorf("Traffic mirror target %s not found", rs.Primary.ID) - } - - *target = *out.TrafficMirrorTargets[0] + *v = *output return nil }