Skip to content

Commit

Permalink
r/aws_efs_file_system: Switch to 'WithoutTimeout' CRUD handlers (#15090
Browse files Browse the repository at this point in the history
…).

Acceptance test output:

% make testacc TESTARGS='-run=TestAccEFSFileSystem_' PKG=efs ACCTEST_PARALLELISM=2
==> Checking that code complies with gofmt requirements...
TF_ACC=1 go test ./internal/service/efs/... -v -count 1 -parallel 2  -run=TestAccEFSFileSystem_ -timeout 180m
=== RUN   TestAccEFSFileSystem_basic
=== PAUSE TestAccEFSFileSystem_basic
=== RUN   TestAccEFSFileSystem_disappears
=== PAUSE TestAccEFSFileSystem_disappears
=== RUN   TestAccEFSFileSystem_performanceMode
=== PAUSE TestAccEFSFileSystem_performanceMode
=== RUN   TestAccEFSFileSystem_availabilityZoneName
=== PAUSE TestAccEFSFileSystem_availabilityZoneName
=== RUN   TestAccEFSFileSystem_tags
=== PAUSE TestAccEFSFileSystem_tags
=== RUN   TestAccEFSFileSystem_kmsKey
=== PAUSE TestAccEFSFileSystem_kmsKey
=== RUN   TestAccEFSFileSystem_kmsWithoutEncryption
=== PAUSE TestAccEFSFileSystem_kmsWithoutEncryption
=== RUN   TestAccEFSFileSystem_provisionedThroughputInMibps
=== PAUSE TestAccEFSFileSystem_provisionedThroughputInMibps
=== RUN   TestAccEFSFileSystem_throughputMode
=== PAUSE TestAccEFSFileSystem_throughputMode
=== RUN   TestAccEFSFileSystem_lifecyclePolicy
=== PAUSE TestAccEFSFileSystem_lifecyclePolicy
=== CONT  TestAccEFSFileSystem_basic
=== CONT  TestAccEFSFileSystem_kmsKey
--- PASS: TestAccEFSFileSystem_basic (29.08s)
=== CONT  TestAccEFSFileSystem_throughputMode
--- PASS: TestAccEFSFileSystem_kmsKey (30.19s)
=== CONT  TestAccEFSFileSystem_lifecyclePolicy
--- PASS: TestAccEFSFileSystem_throughputMode (46.36s)
=== CONT  TestAccEFSFileSystem_provisionedThroughputInMibps
--- PASS: TestAccEFSFileSystem_lifecyclePolicy (73.86s)
=== CONT  TestAccEFSFileSystem_kmsWithoutEncryption
--- PASS: TestAccEFSFileSystem_kmsWithoutEncryption (10.34s)
=== CONT  TestAccEFSFileSystem_availabilityZoneName
--- PASS: TestAccEFSFileSystem_provisionedThroughputInMibps (46.52s)
=== CONT  TestAccEFSFileSystem_tags
--- PASS: TestAccEFSFileSystem_availabilityZoneName (30.14s)
=== CONT  TestAccEFSFileSystem_performanceMode
--- PASS: TestAccEFSFileSystem_performanceMode (23.37s)
=== CONT  TestAccEFSFileSystem_disappears
--- PASS: TestAccEFSFileSystem_disappears (21.22s)
--- PASS: TestAccEFSFileSystem_tags (81.64s)
PASS
ok  	github.com/hashicorp/terraform-provider-aws/internal/service/efs	208.223s
  • Loading branch information
ewbankkit committed Nov 28, 2022
1 parent 18e6b89 commit 0bc5198
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 73 deletions.
128 changes: 62 additions & 66 deletions internal/service/efs/file_system.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package efs

import (
"context"
"errors"
"fmt"
"log"
Expand All @@ -9,6 +10,7 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/efs"
"github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
Expand All @@ -20,10 +22,10 @@ import (

func ResourceFileSystem() *schema.Resource {
return &schema.Resource{
Create: resourceFileSystemCreate,
Read: resourceFileSystemRead,
Update: resourceFileSystemUpdate,
Delete: resourceFileSystemDelete,
CreateWithoutTimeout: resourceFileSystemCreate,
ReadWithoutTimeout: resourceFileSystemRead,
UpdateWithoutTimeout: resourceFileSystemUpdate,
DeleteWithoutTimeout: resourceFileSystemDelete,

Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
Expand Down Expand Up @@ -141,7 +143,7 @@ func ResourceFileSystem() *schema.Resource {
}
}

func resourceFileSystemCreate(d *schema.ResourceData, meta interface{}) error {
func resourceFileSystemCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).EFSConn
defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig
tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{})))
Expand All @@ -154,73 +156,71 @@ func resourceFileSystemCreate(d *schema.ResourceData, meta interface{}) error {
}
throughputMode := d.Get("throughput_mode").(string)

createOpts := &efs.CreateFileSystemInput{
input := &efs.CreateFileSystemInput{
CreationToken: aws.String(creationToken),
Tags: Tags(tags.IgnoreAWS()),
ThroughputMode: aws.String(throughputMode),
}

if v, ok := d.GetOk("availability_zone_name"); ok {
createOpts.AvailabilityZoneName = aws.String(v.(string))
input.AvailabilityZoneName = aws.String(v.(string))
}

if v, ok := d.GetOk("performance_mode"); ok {
createOpts.PerformanceMode = aws.String(v.(string))
input.PerformanceMode = aws.String(v.(string))
}

if throughputMode == efs.ThroughputModeProvisioned {
createOpts.ProvisionedThroughputInMibps = aws.Float64(d.Get("provisioned_throughput_in_mibps").(float64))
input.ProvisionedThroughputInMibps = aws.Float64(d.Get("provisioned_throughput_in_mibps").(float64))
}

encrypted, hasEncrypted := d.GetOk("encrypted")
kmsKeyId, hasKmsKeyId := d.GetOk("kms_key_id")

if hasEncrypted {
createOpts.Encrypted = aws.Bool(encrypted.(bool))
input.Encrypted = aws.Bool(encrypted.(bool))
}

if hasKmsKeyId {
createOpts.KmsKeyId = aws.String(kmsKeyId.(string))
input.KmsKeyId = aws.String(kmsKeyId.(string))
}

if encrypted == false && hasKmsKeyId {
return errors.New("encrypted must be set to true when kms_key_id is specified")
return diag.FromErr(errors.New("encrypted must be set to true when kms_key_id is specified"))
}

log.Printf("[DEBUG] Creating EFS file system: %s", createOpts)
fs, err := conn.CreateFileSystem(createOpts)
output, err := conn.CreateFileSystemWithContext(ctx, input)

if err != nil {
return fmt.Errorf("error creating EFS file system: %w", err)
return diag.Errorf("creating EFS file system: %s", err)
}

d.SetId(aws.StringValue(fs.FileSystemId))
d.SetId(aws.StringValue(output.FileSystemId))

if _, err := waitFileSystemAvailable(conn, d.Id()); err != nil {
return fmt.Errorf("error waiting for EFS file system (%s) to be available: %w", d.Id(), err)
if _, err := waitFileSystemAvailable(ctx, conn, d.Id()); err != nil {
return diag.Errorf("waiting for EFS file system (%s) create: %s", d.Id(), err)
}

_, hasLifecyclePolicy := d.GetOk("lifecycle_policy")
if hasLifecyclePolicy {
_, err := conn.PutLifecycleConfiguration(&efs.PutLifecycleConfigurationInput{
if v, ok := d.GetOk("lifecycle_policy"); ok {
_, err := conn.PutLifecycleConfigurationWithContext(ctx, &efs.PutLifecycleConfigurationInput{
FileSystemId: aws.String(d.Id()),
LifecyclePolicies: expandFileSystemLifecyclePolicies(d.Get("lifecycle_policy").([]interface{})),
LifecyclePolicies: expandFileSystemLifecyclePolicies(v.([]interface{})),
})

if err != nil {
return fmt.Errorf("error creating EFS file system (%s) lifecycle configuration: %w", d.Id(), err)
return diag.Errorf("putting EFS file system (%s) lifecycle configuration: %s", d.Id(), err)
}
}

return resourceFileSystemRead(d, meta)
return resourceFileSystemRead(ctx, d, meta)
}

func resourceFileSystemRead(d *schema.ResourceData, meta interface{}) error {
func resourceFileSystemRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).EFSConn
defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig
ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig

fs, err := FindFileSystemByID(conn, d.Id())
fs, err := FindFileSystemByID(ctx, conn, d.Id())

if !d.IsNewResource() && tfresource.NotFound(err) {
log.Printf("[WARN] EFS file system (%s) not found, removing from state", d.Id())
Expand All @@ -229,54 +229,53 @@ func resourceFileSystemRead(d *schema.ResourceData, meta interface{}) error {
}

if err != nil {
return fmt.Errorf("error reading EFS file system (%s): %w", d.Id(), err)
return diag.Errorf("reading EFS file system (%s): %s", d.Id(), err)
}

d.Set("arn", fs.FileSystemArn)
d.Set("availability_zone_id", fs.AvailabilityZoneId)
d.Set("availability_zone_name", fs.AvailabilityZoneName)
d.Set("creation_token", fs.CreationToken)
d.Set("dns_name", meta.(*conns.AWSClient).RegionalHostname(fmt.Sprintf("%s.efs", aws.StringValue(fs.FileSystemId))))
d.Set("encrypted", fs.Encrypted)
d.Set("kms_key_id", fs.KmsKeyId)
d.Set("number_of_mount_targets", fs.NumberOfMountTargets)
d.Set("owner_id", fs.OwnerId)
d.Set("performance_mode", fs.PerformanceMode)
d.Set("provisioned_throughput_in_mibps", fs.ProvisionedThroughputInMibps)
d.Set("throughput_mode", fs.ThroughputMode)
d.Set("owner_id", fs.OwnerId)
d.Set("number_of_mount_targets", fs.NumberOfMountTargets)

tags := KeyValueTags(fs.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 diag.Errorf("setting tags: %s", err)
}

if err := d.Set("tags_all", tags.Map()); err != nil {
return fmt.Errorf("error setting tags_all: %w", err)
return diag.Errorf("setting tags_all: %s", err)
}

if err := d.Set("size_in_bytes", flattenFileSystemSizeInBytes(fs.SizeInBytes)); err != nil {
return fmt.Errorf("error setting size_in_bytes: %w", err)
return diag.Errorf("setting size_in_bytes: %s", err)
}

d.Set("dns_name", meta.(*conns.AWSClient).RegionalHostname(fmt.Sprintf("%s.efs", aws.StringValue(fs.FileSystemId))))

res, err := conn.DescribeLifecycleConfiguration(&efs.DescribeLifecycleConfigurationInput{
output, err := conn.DescribeLifecycleConfigurationWithContext(ctx, &efs.DescribeLifecycleConfigurationInput{
FileSystemId: aws.String(d.Id()),
})

if err != nil {
return fmt.Errorf("error reading EFS file system (%s) lifecycle configuration: %w", d.Id(), err)
return diag.Errorf("reading EFS file system (%s) lifecycle configuration: %s", d.Id(), err)
}

if err := d.Set("lifecycle_policy", flattenFileSystemLifecyclePolicies(res.LifecyclePolicies)); err != nil {
return fmt.Errorf("error setting lifecycle_policy: %w", err)
if err := d.Set("lifecycle_policy", flattenFileSystemLifecyclePolicies(output.LifecyclePolicies)); err != nil {
return diag.Errorf("setting lifecycle_policy: %s", err)
}

return nil
}

func resourceFileSystemUpdate(d *schema.ResourceData, meta interface{}) error {
func resourceFileSystemUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).EFSConn

if d.HasChanges("provisioned_throughput_in_mibps", "throughput_mode") {
Expand All @@ -291,14 +290,14 @@ func resourceFileSystemUpdate(d *schema.ResourceData, meta interface{}) error {
input.ProvisionedThroughputInMibps = aws.Float64(d.Get("provisioned_throughput_in_mibps").(float64))
}

_, err := conn.UpdateFileSystem(input)
_, err := conn.UpdateFileSystemWithContext(ctx, input)

if err != nil {
return fmt.Errorf("error updating EFS file system (%s): %w", d.Id(), err)
return diag.Errorf("updating EFS file system (%s): %s", d.Id(), err)
}

if _, err := waitFileSystemAvailable(conn, d.Id()); err != nil {
return fmt.Errorf("error waiting for EFS file system (%s) to be available: %w", d.Id(), err)
if _, err := waitFileSystemAvailable(ctx, conn, d.Id()); err != nil {
return diag.Errorf("waiting for EFS file system (%s) update: %s", d.Id(), err)
}
}

Expand All @@ -315,29 +314,29 @@ func resourceFileSystemUpdate(d *schema.ResourceData, meta interface{}) error {
input.LifecyclePolicies = []*efs.LifecyclePolicy{}
}

_, err := conn.PutLifecycleConfiguration(input)
_, err := conn.PutLifecycleConfigurationWithContext(ctx, input)

if err != nil {
return fmt.Errorf("error updating EFS file system (%s) lifecycle configuration: %w", d.Id(), err)
return diag.Errorf("putting EFS file system (%s) lifecycle configuration: %s", d.Id(), err)
}
}

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 EFS file system (%s) tags: %w", d.Id(), err)
if err := UpdateTagsWithContext(ctx, conn, d.Id(), o, n); err != nil {
return diag.Errorf("updating EFS file system (%s) tags: %s", d.Id(), err)
}
}

return resourceFileSystemRead(d, meta)
return resourceFileSystemRead(ctx, d, meta)
}

func resourceFileSystemDelete(d *schema.ResourceData, meta interface{}) error {
func resourceFileSystemDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).EFSConn

log.Printf("[DEBUG] Deleting EFS file system: %s", d.Id())
_, err := conn.DeleteFileSystem(&efs.DeleteFileSystemInput{
_, err := conn.DeleteFileSystemWithContext(ctx, &efs.DeleteFileSystemInput{
FileSystemId: aws.String(d.Id()),
})

Expand All @@ -346,25 +345,22 @@ func resourceFileSystemDelete(d *schema.ResourceData, meta interface{}) error {
}

if err != nil {
return fmt.Errorf("error deleting EFS file system (%s): %w", d.Id(), err)
return diag.Errorf("deleting EFS file system (%s): %s", d.Id(), err)
}

if _, err := waitFileSystemDeleted(conn, d.Id()); err != nil {
if tfawserr.ErrCodeEquals(err, efs.ErrCodeFileSystemNotFound) {
return nil
}
return fmt.Errorf("error waiting for EFS file system (%s) deletion: %w", d.Id(), err)
if _, err := waitFileSystemDeleted(ctx, conn, d.Id()); err != nil {
return diag.Errorf("waiting for EFS file system (%s) delete: %s", d.Id(), err)
}

return nil
}

func FindFileSystemByID(conn *efs.EFS, id string) (*efs.FileSystemDescription, error) {
func FindFileSystemByID(ctx context.Context, conn *efs.EFS, id string) (*efs.FileSystemDescription, error) {
input := &efs.DescribeFileSystemsInput{
FileSystemId: aws.String(id),
}

output, err := conn.DescribeFileSystems(input)
output, err := conn.DescribeFileSystemsWithContext(ctx, input)

if tfawserr.ErrCodeEquals(err, efs.ErrCodeFileSystemNotFound) {
return nil, &resource.NotFoundError{
Expand All @@ -384,9 +380,9 @@ func FindFileSystemByID(conn *efs.EFS, id string) (*efs.FileSystemDescription, e
return output.FileSystems[0], nil
}

func statusFileSystemLifeCycleState(conn *efs.EFS, id string) resource.StateRefreshFunc {
func statusFileSystemLifeCycleState(ctx context.Context, conn *efs.EFS, id string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
output, err := FindFileSystemByID(conn, id)
output, err := FindFileSystemByID(ctx, conn, id)

if tfresource.NotFound(err) {
return nil, "", nil
Expand All @@ -409,17 +405,17 @@ const (
fileSystemDeletedMinTimeout = 3 * time.Second
)

func waitFileSystemAvailable(conn *efs.EFS, fileSystemID string) (*efs.FileSystemDescription, error) { //nolint:unparam
func waitFileSystemAvailable(ctx context.Context, conn *efs.EFS, fileSystemID string) (*efs.FileSystemDescription, error) { //nolint:unparam
stateConf := &resource.StateChangeConf{
Pending: []string{efs.LifeCycleStateCreating, efs.LifeCycleStateUpdating},
Target: []string{efs.LifeCycleStateAvailable},
Refresh: statusFileSystemLifeCycleState(conn, fileSystemID),
Refresh: statusFileSystemLifeCycleState(ctx, conn, fileSystemID),
Timeout: fileSystemAvailableTimeout,
Delay: fileSystemAvailableDelayTimeout,
MinTimeout: fileSystemAvailableMinTimeout,
}

outputRaw, err := stateConf.WaitForState()
outputRaw, err := stateConf.WaitForStateContext(ctx)

if output, ok := outputRaw.(*efs.FileSystemDescription); ok {
return output, err
Expand All @@ -428,17 +424,17 @@ func waitFileSystemAvailable(conn *efs.EFS, fileSystemID string) (*efs.FileSyste
return nil, err
}

func waitFileSystemDeleted(conn *efs.EFS, fileSystemID string) (*efs.FileSystemDescription, error) {
func waitFileSystemDeleted(ctx context.Context, conn *efs.EFS, fileSystemID string) (*efs.FileSystemDescription, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{efs.LifeCycleStateAvailable, efs.LifeCycleStateDeleting},
Target: []string{},
Refresh: statusFileSystemLifeCycleState(conn, fileSystemID),
Refresh: statusFileSystemLifeCycleState(ctx, conn, fileSystemID),
Timeout: fileSystemDeletedTimeout,
Delay: fileSystemDeletedDelayTimeout,
MinTimeout: fileSystemDeletedMinTimeout,
}

outputRaw, err := stateConf.WaitForState()
outputRaw, err := stateConf.WaitForStateContext(ctx)

if output, ok := outputRaw.(*efs.FileSystemDescription); ok {
return output, err
Expand Down
14 changes: 7 additions & 7 deletions internal/service/efs/file_system_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package efs_test

import (
"context"
"fmt"
"regexp"
"testing"
Expand Down Expand Up @@ -384,7 +385,7 @@ func testAccCheckFileSystemDestroy(s *terraform.State) error {
continue
}

_, err := tfefs.FindFileSystemByID(conn, rs.Primary.ID)
_, err := tfefs.FindFileSystemByID(context.Background(), conn, rs.Primary.ID)

if tfresource.NotFound(err) {
continue
Expand All @@ -400,26 +401,25 @@ func testAccCheckFileSystemDestroy(s *terraform.State) error {
return nil
}

func testAccCheckFileSystem(resourceID string, fDesc *efs.FileSystemDescription) resource.TestCheckFunc {
func testAccCheckFileSystem(n string, v *efs.FileSystemDescription) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[resourceID]
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", resourceID)
return fmt.Errorf("Not found: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("No EFS file system ID is set")
}

conn := acctest.Provider.Meta().(*conns.AWSClient).EFSConn

fs, err := tfefs.FindFileSystemByID(conn, rs.Primary.ID)
output, err := tfefs.FindFileSystemByID(context.Background(), conn, rs.Primary.ID)

if err != nil {
return err
}

*fDesc = *fs
*v = *output

return nil
}
Expand Down

0 comments on commit 0bc5198

Please sign in to comment.