Skip to content

Commit

Permalink
Merge pull request #20569 from DrFaust92/fsx_backup
Browse files Browse the repository at this point in the history
Fsx backup - new resource
  • Loading branch information
ewbankkit authored Aug 17, 2021
2 parents f2d8fea + 1e5ba04 commit 1b5a715
Show file tree
Hide file tree
Showing 8 changed files with 685 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/20569.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
aws_fsx_backup
```
36 changes: 36 additions & 0 deletions aws/internal/service/fsx/finder/finder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package finder

import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/fsx"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func BackupByID(conn *fsx.FSx, id string) (*fsx.Backup, error) {
input := &fsx.DescribeBackupsInput{
BackupIds: aws.StringSlice([]string{id}),
}

output, err := conn.DescribeBackups(input)

if tfawserr.ErrCodeEquals(err, fsx.ErrCodeFileSystemNotFound) || tfawserr.ErrCodeEquals(err, fsx.ErrCodeBackupNotFound) {
return nil, &resource.NotFoundError{
LastError: err,
LastRequest: input,
}
}

if err != nil {
return nil, err
}

if output == nil || len(output.Backups) == 0 || output.Backups[0] == nil {
return nil, &resource.NotFoundError{
Message: "Empty result",
LastRequest: input,
}
}

return output.Backups[0], nil
}
25 changes: 25 additions & 0 deletions aws/internal/service/fsx/waiter/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package waiter

import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/fsx"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/fsx/finder"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource"
)

func BackupStatus(conn *fsx.FSx, id string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
output, err := finder.BackupByID(conn, id)

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

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

return output, aws.StringValue(output.Lifecycle), nil
}
}
47 changes: 47 additions & 0 deletions aws/internal/service/fsx/waiter/waiter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package waiter

import (
"time"

"github.com/aws/aws-sdk-go/service/fsx"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

const (
BackupAvailableTimeout = 10 * time.Minute
BackupDeletedTimeout = 10 * time.Minute
)

func BackupAvailable(conn *fsx.FSx, id string) (*fsx.Backup, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{fsx.BackupLifecycleCreating, fsx.BackupLifecyclePending, fsx.BackupLifecycleTransferring},
Target: []string{fsx.BackupLifecycleAvailable},
Refresh: BackupStatus(conn, id),
Timeout: BackupAvailableTimeout,
}

outputRaw, err := stateConf.WaitForState()

if output, ok := outputRaw.(*fsx.Backup); ok {
return output, err
}

return nil, err
}

func BackupDeleted(conn *fsx.FSx, id string) (*fsx.Backup, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{fsx.FileSystemLifecycleDeleting},
Target: []string{},
Refresh: BackupStatus(conn, id),
Timeout: BackupDeletedTimeout,
}

outputRaw, err := stateConf.WaitForState()

if output, ok := outputRaw.(*fsx.Backup); ok {
return output, err
}

return nil, err
}
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,7 @@ func Provider() *schema.Provider {
"aws_emr_managed_scaling_policy": resourceAwsEMRManagedScalingPolicy(),
"aws_emr_security_configuration": resourceAwsEMRSecurityConfiguration(),
"aws_flow_log": resourceAwsFlowLog(),
"aws_fsx_backup": resourceAwsFsxBackup(),
"aws_fsx_lustre_file_system": resourceAwsFsxLustreFileSystem(),
"aws_fsx_windows_file_system": resourceAwsFsxWindowsFileSystem(),
"aws_fms_admin_account": resourceAwsFmsAdminAccount(),
Expand Down
173 changes: 173 additions & 0 deletions aws/resource_aws_fsx_backup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package aws

import (
"fmt"
"log"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/fsx"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
"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/keyvaluetags"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/fsx/finder"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/fsx/waiter"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource"
)

func resourceAwsFsxBackup() *schema.Resource {
return &schema.Resource{
Create: resourceAwsFsxBackupCreate,
Read: resourceAwsFsxBackupRead,
Update: resourceAwsFsxBackupUpdate,
Delete: resourceAwsFsxBackupDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(30 * time.Minute),
Delete: schema.DefaultTimeout(30 * time.Minute),
},

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"file_system_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"kms_key_id": {
Type: schema.TypeString,
Computed: true,
},
"owner_id": {
Type: schema.TypeString,
Computed: true,
},
"tags": tagsSchemaComputed(),
"tags_all": tagsSchemaComputed(),
"type": {
Type: schema.TypeString,
Computed: true,
},
},

CustomizeDiff: customdiff.Sequence(
SetTagsDiff,
),
}
}

func resourceAwsFsxBackupCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).fsxconn
defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig
tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{})))

input := &fsx.CreateBackupInput{
ClientRequestToken: aws.String(resource.UniqueId()),
FileSystemId: aws.String(d.Get("file_system_id").(string)),
}

if len(tags) > 0 {
input.Tags = tags.IgnoreAws().FsxTags()
}

result, err := conn.CreateBackup(input)
if err != nil {
return fmt.Errorf("error creating FSx Backup: %w", err)
}

d.SetId(aws.StringValue(result.Backup.BackupId))

log.Println("[DEBUG] Waiting for FSx backup to become available")
if _, err := waiter.BackupAvailable(conn, d.Id()); err != nil {
return fmt.Errorf("error waiting for FSx Backup (%s) to be available: %w", d.Id(), err)
}

return resourceAwsFsxBackupRead(d, meta)
}

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

if d.HasChange("tags_all") {
o, n := d.GetChange("tags_all")

if err := keyvaluetags.FsxUpdateTags(conn, d.Get("arn").(string), o, n); err != nil {
return fmt.Errorf("error updating FSx Backup (%s) tags: %w", d.Get("arn").(string), err)
}
}

return resourceAwsFsxBackupRead(d, meta)
}

func resourceAwsFsxBackupRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).fsxconn
defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig
ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig

backup, err := finder.BackupByID(conn, d.Id())
if !d.IsNewResource() && tfresource.NotFound(err) {
log.Printf("[WARN] FSx Backup (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

if err != nil {
return fmt.Errorf("error reading FSx Backup (%s): %w", d.Id(), err)
}

d.Set("arn", backup.ResourceARN)
d.Set("type", backup.Type)

fs := backup.FileSystem
d.Set("file_system_id", fs.FileSystemId)

d.Set("kms_key_id", backup.KmsKeyId)

d.Set("owner_id", backup.OwnerId)

tags := keyvaluetags.FsxKeyValueTags(backup.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)
}

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

return nil
}

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

request := &fsx.DeleteBackupInput{
BackupId: aws.String(d.Id()),
}

log.Printf("[INFO] Deleting FSx Backup: %s", d.Id())
_, err := conn.DeleteBackup(request)

if err != nil {
if tfawserr.ErrCodeEquals(err, fsx.ErrCodeBackupNotFound) {
return nil
}
return fmt.Errorf("error deleting FSx Backup (%s): %w", d.Id(), err)
}

log.Println("[DEBUG] Waiting for filesystem to delete")
if _, err := waiter.BackupDeleted(conn, d.Id()); err != nil {
return fmt.Errorf("error waiting for FSx Backup (%s) to deleted: %w", d.Id(), err)
}

return nil
}
Loading

0 comments on commit 1b5a715

Please sign in to comment.