Skip to content

Commit

Permalink
Merge pull request #33303 from hashicorp/f-aws_fsx_windows_file_syste…
Browse files Browse the repository at this point in the history
…m-additions

FSx Windows acceptance tests fixes and enhancements
  • Loading branch information
ewbankkit authored Sep 5, 2023
2 parents 675d33e + 3e179a3 commit f36f9df
Show file tree
Hide file tree
Showing 15 changed files with 618 additions and 406 deletions.
7 changes: 7 additions & 0 deletions .changelog/33303.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
resource/aws_fsx_windows_file_system: Add `disk_iops_configuration` configuration block
```

```release-note:enhancement
data-source/aws_fsx_windows_file_system: Add `disk_iops_configuration` attribute
```
21 changes: 0 additions & 21 deletions internal/service/fsx/find.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,6 @@ import (
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
)

func FindAdministrativeActionByFileSystemIDAndActionType(ctx context.Context, conn *fsx.FSx, fsID, actionType string) (*fsx.AdministrativeAction, error) {
fileSystem, err := FindFileSystemByID(ctx, conn, fsID)

if err != nil {
return nil, err
}

for _, administrativeAction := range fileSystem.AdministrativeActions {
if administrativeAction == nil {
continue
}

if aws.StringValue(administrativeAction.AdministrativeActionType) == actionType {
return administrativeAction, nil
}
}

// If the administrative action isn't found, assume it's complete.
return &fsx.AdministrativeAction{Status: aws.String(fsx.StatusCompleted)}, nil
}

func FindBackupByID(ctx context.Context, conn *fsx.FSx, id string) (*fsx.Backup, error) {
input := &fsx.DescribeBackupsInput{
BackupIds: aws.StringSlice([]string{id}),
Expand Down
165 changes: 163 additions & 2 deletions internal/service/fsx/lustre_file_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package fsx

import (
"context"
"errors"
"fmt"
"log"
"strings"
Expand Down Expand Up @@ -532,19 +533,20 @@ func resourceLustreFileSystemUpdate(ctx context.Context, d *schema.ResourceData,
input.LustreConfiguration.WeeklyMaintenanceStartTime = aws.String(d.Get("weekly_maintenance_start_time").(string))
}

startTime := time.Now()
_, err := conn.UpdateFileSystemWithContext(ctx, input)

if err != nil {
return sdkdiag.AppendErrorf(diags, "updating FSX for Lustre File System (%s): %s", d.Id(), err)
}

if _, err := waitFileSystemUpdated(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate)); err != nil {
if _, err := waitFileSystemUpdated(ctx, conn, d.Id(), startTime, d.Timeout(schema.TimeoutUpdate)); err != nil {
return sdkdiag.AppendErrorf(diags, "waiting for FSx for Lustre File System (%s) update: %s", d.Id(), err)
}

if waitAdminAction {
if _, err := waitAdministrativeActionCompleted(ctx, conn, d.Id(), fsx.AdministrativeActionTypeFileSystemUpdate, d.Timeout(schema.TimeoutUpdate)); err != nil {
return sdkdiag.AppendErrorf(diags, "waiting for FSx for Lustre File System (%s) administrative action complete: %s", d.Id(), err)
return sdkdiag.AppendErrorf(diags, "waiting for FSx for Lustre File System (%s) administrative action (%s) complete: %s", d.Id(), fsx.AdministrativeActionTypeFileSystemUpdate, err)
}
}
}
Expand Down Expand Up @@ -765,3 +767,162 @@ func findFileSystems(ctx context.Context, conn *fsx.FSx, input *fsx.DescribeFile

return output, nil
}

func statusFileSystem(ctx context.Context, conn *fsx.FSx, id string) retry.StateRefreshFunc {
return func() (interface{}, string, error) {
output, err := FindFileSystemByID(ctx, conn, id)

if tfresource.NotFound(err) {
return nil, "", nil
}

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

return output, aws.StringValue(output.Lifecycle), nil
}
}

func waitFileSystemCreated(ctx context.Context, conn *fsx.FSx, id string, timeout time.Duration) (*fsx.FileSystem, error) { //nolint:unparam
stateConf := &retry.StateChangeConf{
Pending: []string{fsx.FileSystemLifecycleCreating},
Target: []string{fsx.FileSystemLifecycleAvailable},
Refresh: statusFileSystem(ctx, conn, id),
Timeout: timeout,
Delay: 30 * time.Second,
}

outputRaw, err := stateConf.WaitForStateContext(ctx)

if output, ok := outputRaw.(*fsx.FileSystem); ok {
if status, details := aws.StringValue(output.Lifecycle), output.FailureDetails; status == fsx.FileSystemLifecycleFailed && details != nil {
tfresource.SetLastError(err, errors.New(aws.StringValue(output.FailureDetails.Message)))
}

return output, err
}

return nil, err
}

func waitFileSystemUpdated(ctx context.Context, conn *fsx.FSx, id string, startTime time.Time, timeout time.Duration) (*fsx.FileSystem, error) { //nolint:unparam
stateConf := &retry.StateChangeConf{
Pending: []string{fsx.FileSystemLifecycleUpdating},
Target: []string{fsx.FileSystemLifecycleAvailable},
Refresh: statusFileSystem(ctx, conn, id),
Timeout: timeout,
Delay: 30 * time.Second,
}

outputRaw, err := stateConf.WaitForStateContext(ctx)

if output, ok := outputRaw.(*fsx.FileSystem); ok {
switch status := aws.StringValue(output.Lifecycle); status {
case fsx.FileSystemLifecycleFailed, fsx.FileSystemLifecycleMisconfigured, fsx.FileSystemLifecycleMisconfiguredUnavailable:
// Report any failed non-FILE_SYSTEM_UPDATE administrative actions.
// See https://docs.aws.amazon.com/fsx/latest/APIReference/API_AdministrativeAction.html#FSx-Type-AdministrativeAction-AdministrativeActionType.
administrativeActions := tfslices.Filter(output.AdministrativeActions, func(v *fsx.AdministrativeAction) bool {
return v != nil && aws.StringValue(v.Status) == fsx.StatusFailed && aws.StringValue(v.AdministrativeActionType) != fsx.AdministrativeActionTypeFileSystemUpdate && v.FailureDetails != nil && startTime.Before(aws.TimeValue(v.RequestTime))
})
administrativeActionsError := errors.Join(tfslices.ApplyToAll(administrativeActions, func(v *fsx.AdministrativeAction) error {
return fmt.Errorf("%s: %s", aws.StringValue(v.AdministrativeActionType), aws.StringValue(v.FailureDetails.Message))
})...)

if details := output.FailureDetails; details != nil {
if message := aws.StringValue(details.Message); administrativeActionsError != nil {
tfresource.SetLastError(err, fmt.Errorf("%s: %w", message, administrativeActionsError))
} else {
tfresource.SetLastError(err, errors.New(message))
}
} else {
tfresource.SetLastError(err, administrativeActionsError)
}
}

return output, err
}

return nil, err
}

func waitFileSystemDeleted(ctx context.Context, conn *fsx.FSx, id string, timeout time.Duration) (*fsx.FileSystem, error) { //nolint:unparam
stateConf := &retry.StateChangeConf{
Pending: []string{fsx.FileSystemLifecycleAvailable, fsx.FileSystemLifecycleDeleting},
Target: []string{},
Refresh: statusFileSystem(ctx, conn, id),
Timeout: timeout,
Delay: 30 * time.Second,
}

outputRaw, err := stateConf.WaitForStateContext(ctx)

if output, ok := outputRaw.(*fsx.FileSystem); ok {
if status, details := aws.StringValue(output.Lifecycle), output.FailureDetails; status == fsx.FileSystemLifecycleFailed && details != nil {
tfresource.SetLastError(err, errors.New(aws.StringValue(output.FailureDetails.Message)))
}

return output, err
}

return nil, err
}

func findAdministrativeAction(ctx context.Context, conn *fsx.FSx, fsID, actionType string) (*fsx.AdministrativeAction, error) {
output, err := FindFileSystemByID(ctx, conn, fsID)

if err != nil {
return nil, err
}

for _, v := range output.AdministrativeActions {
if v == nil {
continue
}

if aws.StringValue(v.AdministrativeActionType) == actionType {
return v, nil
}
}

// If the administrative action isn't found, assume it's complete.
return &fsx.AdministrativeAction{Status: aws.String(fsx.StatusCompleted)}, nil
}

func statusAdministrativeAction(ctx context.Context, conn *fsx.FSx, fsID, actionType string) retry.StateRefreshFunc {
return func() (interface{}, string, error) {
output, err := findAdministrativeAction(ctx, conn, fsID, actionType)

if tfresource.NotFound(err) {
return nil, "", nil
}

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

return output, aws.StringValue(output.Status), nil
}
}

func waitAdministrativeActionCompleted(ctx context.Context, conn *fsx.FSx, fsID, actionType string, timeout time.Duration) (*fsx.AdministrativeAction, error) { //nolint:unparam
stateConf := &retry.StateChangeConf{
Pending: []string{fsx.StatusInProgress, fsx.StatusPending},
Target: []string{fsx.StatusCompleted, fsx.StatusUpdatedOptimizing},
Refresh: statusAdministrativeAction(ctx, conn, fsID, actionType),
Timeout: timeout,
Delay: 30 * time.Second,
}

outputRaw, err := stateConf.WaitForStateContext(ctx)

if output, ok := outputRaw.(*fsx.AdministrativeAction); ok {
if status, details := aws.StringValue(output.Status), output.FailureDetails; status == fsx.StatusFailed && details != nil {
tfresource.SetLastError(err, errors.New(aws.StringValue(output.FailureDetails.Message)))
}

return output, err
}

return nil, err
}
4 changes: 2 additions & 2 deletions internal/service/fsx/lustre_file_system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,7 @@ func testAccCheckLustreFileSystemDestroy(ctx context.Context) resource.TestCheck
func testAccCheckLustreFileSystemNotRecreated(i, j *fsx.FileSystem) resource.TestCheckFunc {
return func(s *terraform.State) error {
if aws.StringValue(i.FileSystemId) != aws.StringValue(j.FileSystemId) {
return fmt.Errorf("FSx for File System (%s) recreated", aws.StringValue(i.FileSystemId))
return fmt.Errorf("FSx for Lustre File System (%s) recreated", aws.StringValue(i.FileSystemId))
}

return nil
Expand All @@ -1015,7 +1015,7 @@ func testAccCheckLustreFileSystemNotRecreated(i, j *fsx.FileSystem) resource.Tes
func testAccCheckLustreFileSystemRecreated(i, j *fsx.FileSystem) resource.TestCheckFunc {
return func(s *terraform.State) error {
if aws.StringValue(i.FileSystemId) == aws.StringValue(j.FileSystemId) {
return fmt.Errorf("FSx for File System (%s) not recreated", aws.StringValue(i.FileSystemId))
return fmt.Errorf("FSx for Lustre File System (%s) not recreated", aws.StringValue(i.FileSystemId))
}

return nil
Expand Down
5 changes: 3 additions & 2 deletions internal/service/fsx/ontap_file_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,18 +416,19 @@ func resourceOntapFileSystemUpdate(ctx context.Context, d *schema.ResourceData,
}
}

startTime := time.Now()
_, err := conn.UpdateFileSystemWithContext(ctx, input)

if err != nil {
return sdkdiag.AppendErrorf(diags, "updating FSx ONTAP File System (%s): %s", d.Id(), err)
}

if _, err := waitFileSystemUpdated(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate)); err != nil {
if _, err := waitFileSystemUpdated(ctx, conn, d.Id(), startTime, d.Timeout(schema.TimeoutUpdate)); err != nil {
return sdkdiag.AppendErrorf(diags, "waiting for FSx ONTAP File System (%s) update: %s", d.Id(), err)
}

if _, err := waitAdministrativeActionCompleted(ctx, conn, d.Id(), fsx.AdministrativeActionTypeFileSystemUpdate, d.Timeout(schema.TimeoutUpdate)); err != nil {
return sdkdiag.AppendErrorf(diags, "waiting for FSx ONTAP File System (%s) update: %s", d.Id(), err)
return sdkdiag.AppendErrorf(diags, "waiting for FSx for NetApp ONTAP File System (%s) administrative action (%s) complete: %s", d.Id(), fsx.AdministrativeActionTypeFileSystemUpdate, err)
}
}

Expand Down
7 changes: 4 additions & 3 deletions internal/service/fsx/openzfs_file_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,18 +572,19 @@ func resourceOpenZFSFileSystemUpdate(ctx context.Context, d *schema.ResourceData
input.OpenZFSConfiguration.WeeklyMaintenanceStartTime = aws.String(d.Get("weekly_maintenance_start_time").(string))
}

startTime := time.Now()
_, err := conn.UpdateFileSystemWithContext(ctx, input)

if err != nil {
return sdkdiag.AppendErrorf(diags, "updating FSx for OpenZFS File System (%s): %s", d.Id(), err)
}

if _, err := waitFileSystemUpdated(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate)); err != nil {
if _, err := waitFileSystemUpdated(ctx, conn, d.Id(), startTime, d.Timeout(schema.TimeoutUpdate)); err != nil {
return sdkdiag.AppendErrorf(diags, "waiting for FSx for OpenZFS File System (%s) update: %s", d.Id(), err)
}

if _, err := waitAdministrativeActionCompleted(ctx, conn, d.Id(), fsx.AdministrativeActionTypeFileSystemUpdate, d.Timeout(schema.TimeoutUpdate)); err != nil {
return sdkdiag.AppendErrorf(diags, "waiting for FSx for OpenZFS File System (%s) administrative action complete: %s", d.Id(), err)
return sdkdiag.AppendErrorf(diags, "waiting for FSx for OpenZFS File System (%s) administrative action (%s) complete: %s", d.Id(), fsx.AdministrativeActionTypeFileSystemUpdate, err)
}

if d.HasChange("root_volume_configuration") {
Expand All @@ -605,7 +606,7 @@ func resourceOpenZFSFileSystemUpdate(ctx context.Context, d *schema.ResourceData
}

if _, err := waitAdministrativeActionCompleted(ctx, conn, d.Id(), fsx.AdministrativeActionTypeVolumeUpdate, d.Timeout(schema.TimeoutUpdate)); err != nil {
return sdkdiag.AppendErrorf(diags, "waiting for FSx for OpenZFS File System (%s) administrative action complete: %s", d.Id(), err)
return sdkdiag.AppendErrorf(diags, "waiting for FSx for OpenZFS File System (%s) administrative action (%s) complete: %s", d.Id(), fsx.AdministrativeActionTypeVolumeUpdate, err)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions internal/service/fsx/openzfs_file_system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -959,7 +959,7 @@ func testAccCheckOpenZFSFileSystemDestroy(ctx context.Context) resource.TestChec
func testAccCheckOpenZFSFileSystemNotRecreated(i, j *fsx.FileSystem) resource.TestCheckFunc {
return func(s *terraform.State) error {
if aws.StringValue(i.FileSystemId) != aws.StringValue(j.FileSystemId) {
return fmt.Errorf("FSx OpenZFS File System (%s) recreated", aws.StringValue(i.FileSystemId))
return fmt.Errorf("FSx for OpenZFS File System (%s) recreated", aws.StringValue(i.FileSystemId))
}

return nil
Expand All @@ -969,7 +969,7 @@ func testAccCheckOpenZFSFileSystemNotRecreated(i, j *fsx.FileSystem) resource.Te
func testAccCheckOpenZFSFileSystemRecreated(i, j *fsx.FileSystem) resource.TestCheckFunc {
return func(s *terraform.State) error {
if aws.StringValue(i.FileSystemId) == aws.StringValue(j.FileSystemId) {
return fmt.Errorf("FSx OpenZFS File System (%s) not recreated", aws.StringValue(i.FileSystemId))
return fmt.Errorf("FSx for OpenZFS File System (%s) not recreated", aws.StringValue(i.FileSystemId))
}

return nil
Expand Down
32 changes: 0 additions & 32 deletions internal/service/fsx/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,6 @@ import (
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
)

func statusAdministrativeAction(ctx context.Context, conn *fsx.FSx, fsID, actionType string) retry.StateRefreshFunc {
return func() (interface{}, string, error) {
output, err := FindAdministrativeActionByFileSystemIDAndActionType(ctx, conn, fsID, actionType)

if tfresource.NotFound(err) {
return nil, "", nil
}

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

return output, aws.StringValue(output.Status), nil
}
}

func statusBackup(ctx context.Context, conn *fsx.FSx, id string) retry.StateRefreshFunc {
return func() (interface{}, string, error) {
output, err := FindBackupByID(ctx, conn, id)
Expand Down Expand Up @@ -59,22 +43,6 @@ func statusFileCache(ctx context.Context, conn *fsx.FSx, id string) retry.StateR
}
}

func statusFileSystem(ctx context.Context, conn *fsx.FSx, id string) retry.StateRefreshFunc {
return func() (interface{}, string, error) {
output, err := FindFileSystemByID(ctx, conn, id)

if tfresource.NotFound(err) {
return nil, "", nil
}

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

return output, aws.StringValue(output.Lifecycle), nil
}
}

func statusStorageVirtualMachine(ctx context.Context, conn *fsx.FSx, id string) retry.StateRefreshFunc {
return func() (interface{}, string, error) {
output, err := FindStorageVirtualMachineByID(ctx, conn, id)
Expand Down
Loading

0 comments on commit f36f9df

Please sign in to comment.