mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-20 11:48:24 -06:00
* Handle missing EFS mount target in aws_efs_mount_target. This commit resolves issue where the EFS mount target would be already deleted (e.g. it was deleted outside of Terraform, etc.). Also, correct how values are begin set in the ReadFunc to avoid nil pointer dereference. Signed-off-by: Krzysztof Wilczynski <krzysztof.wilczynski@linux.com> * Add EFS mount target DNS helper function. Signed-off-by: Krzysztof Wilczynski <krzysztof.wilczynski@linux.com> * Add EFS mount target response helper. This commit adds a helper which can be used to check whether the response contains a valid and non-empty list of EFS file system mount targets. Signed-off-by: Krzysztof Wilczynski <krzysztof.wilczynski@linux.com> * Add acceptance test to check for non-empty plan. This commit adds a test to verify the condition where the underlying EFS mount target would be deleted and/or disappear resulting in a new resource to be created to replace it. Signed-off-by: Krzysztof Wilczynski <krzysztof.wilczynski@linux.com>
273 lines
6.8 KiB
Go
273 lines
6.8 KiB
Go
package aws
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
"github.com/aws/aws-sdk-go/service/efs"
|
|
|
|
"github.com/hashicorp/terraform/helper/resource"
|
|
"github.com/hashicorp/terraform/terraform"
|
|
)
|
|
|
|
func TestAccAWSEFSMountTarget_basic(t *testing.T) {
|
|
var mount efs.MountTargetDescription
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
Providers: testAccProviders,
|
|
CheckDestroy: testAccCheckEfsMountTargetDestroy,
|
|
Steps: []resource.TestStep{
|
|
resource.TestStep{
|
|
Config: testAccAWSEFSMountTargetConfig,
|
|
Check: resource.ComposeTestCheckFunc(
|
|
testAccCheckEfsMountTarget(
|
|
"aws_efs_mount_target.alpha",
|
|
&mount,
|
|
),
|
|
resource.TestMatchResourceAttr(
|
|
"aws_efs_mount_target.alpha",
|
|
"dns_name",
|
|
regexp.MustCompile("^us-west-2a.[^.]+.efs.us-west-2.amazonaws.com$"),
|
|
),
|
|
),
|
|
},
|
|
resource.TestStep{
|
|
Config: testAccAWSEFSMountTargetConfigModified,
|
|
Check: resource.ComposeTestCheckFunc(
|
|
testAccCheckEfsMountTarget(
|
|
"aws_efs_mount_target.alpha",
|
|
&mount,
|
|
),
|
|
resource.TestMatchResourceAttr(
|
|
"aws_efs_mount_target.alpha",
|
|
"dns_name",
|
|
regexp.MustCompile("^us-west-2a.[^.]+.efs.us-west-2.amazonaws.com$"),
|
|
),
|
|
testAccCheckEfsMountTarget(
|
|
"aws_efs_mount_target.beta",
|
|
&mount,
|
|
),
|
|
resource.TestMatchResourceAttr(
|
|
"aws_efs_mount_target.beta",
|
|
"dns_name",
|
|
regexp.MustCompile("^us-west-2b.[^.]+.efs.us-west-2.amazonaws.com$"),
|
|
),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccAWSEFSMountTarget_disappears(t *testing.T) {
|
|
var mount efs.MountTargetDescription
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
Providers: testAccProviders,
|
|
CheckDestroy: testAccCheckVpnGatewayDestroy,
|
|
Steps: []resource.TestStep{
|
|
resource.TestStep{
|
|
Config: testAccAWSEFSMountTargetConfig,
|
|
Check: resource.ComposeTestCheckFunc(
|
|
testAccCheckEfsMountTarget(
|
|
"aws_efs_mount_target.alpha",
|
|
&mount,
|
|
),
|
|
testAccAWSEFSMountTargetDisappears(&mount),
|
|
),
|
|
ExpectNonEmptyPlan: true,
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestResourceAWSEFSMountTarget_mountTargetDnsName(t *testing.T) {
|
|
actual := resourceAwsEfsMountTargetDnsName("non-existant-1c",
|
|
"fs-123456ab", "non-existant-1")
|
|
|
|
expected := "non-existant-1c.fs-123456ab.efs.non-existant-1.amazonaws.com"
|
|
if actual != expected {
|
|
t.Fatalf("Expected EFS mount target DNS name to be %s, got %s",
|
|
expected, actual)
|
|
}
|
|
}
|
|
|
|
func TestResourceAWSEFSMountTarget_hasEmptyMountTargets(t *testing.T) {
|
|
mto := &efs.DescribeMountTargetsOutput{
|
|
MountTargets: []*efs.MountTargetDescription{},
|
|
}
|
|
|
|
var actual bool
|
|
|
|
actual = hasEmptyMountTargets(mto)
|
|
if !actual {
|
|
t.Fatalf("Expected return value to be true, got %t", actual)
|
|
}
|
|
|
|
// Add an empty mount target.
|
|
mto.MountTargets = append(mto.MountTargets, &efs.MountTargetDescription{})
|
|
|
|
actual = hasEmptyMountTargets(mto)
|
|
if actual {
|
|
t.Fatalf("Expected return value to be false, got %t", actual)
|
|
}
|
|
|
|
}
|
|
|
|
func testAccCheckEfsMountTargetDestroy(s *terraform.State) error {
|
|
conn := testAccProvider.Meta().(*AWSClient).efsconn
|
|
for _, rs := range s.RootModule().Resources {
|
|
if rs.Type != "aws_efs_mount_target" {
|
|
continue
|
|
}
|
|
|
|
resp, err := conn.DescribeMountTargets(&efs.DescribeMountTargetsInput{
|
|
MountTargetId: aws.String(rs.Primary.ID),
|
|
})
|
|
if err != nil {
|
|
if efsErr, ok := err.(awserr.Error); ok && efsErr.Code() == "MountTargetNotFound" {
|
|
// gone
|
|
return nil
|
|
}
|
|
return fmt.Errorf("Error describing EFS Mount in tests: %s", err)
|
|
}
|
|
if len(resp.MountTargets) > 0 {
|
|
return fmt.Errorf("EFS Mount target %q still exists", rs.Primary.ID)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func testAccCheckEfsMountTarget(resourceID string, mount *efs.MountTargetDescription) resource.TestCheckFunc {
|
|
return func(s *terraform.State) error {
|
|
rs, ok := s.RootModule().Resources[resourceID]
|
|
if !ok {
|
|
return fmt.Errorf("Not found: %s", resourceID)
|
|
}
|
|
|
|
if rs.Primary.ID == "" {
|
|
return fmt.Errorf("No ID is set")
|
|
}
|
|
|
|
fs, ok := s.RootModule().Resources[resourceID]
|
|
if !ok {
|
|
return fmt.Errorf("Not found: %s", resourceID)
|
|
}
|
|
|
|
conn := testAccProvider.Meta().(*AWSClient).efsconn
|
|
mt, err := conn.DescribeMountTargets(&efs.DescribeMountTargetsInput{
|
|
MountTargetId: aws.String(fs.Primary.ID),
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if *mt.MountTargets[0].MountTargetId != fs.Primary.ID {
|
|
return fmt.Errorf("Mount target ID mismatch: %q != %q",
|
|
*mt.MountTargets[0].MountTargetId, fs.Primary.ID)
|
|
}
|
|
|
|
*mount = *mt.MountTargets[0]
|
|
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func testAccAWSEFSMountTargetDisappears(mount *efs.MountTargetDescription) resource.TestCheckFunc {
|
|
return func(s *terraform.State) error {
|
|
conn := testAccProvider.Meta().(*AWSClient).efsconn
|
|
|
|
_, err := conn.DeleteMountTarget(&efs.DeleteMountTargetInput{
|
|
MountTargetId: mount.MountTargetId,
|
|
})
|
|
|
|
if err != nil {
|
|
if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "MountTargetNotFound" {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
|
|
return resource.Retry(3*time.Minute, func() *resource.RetryError {
|
|
resp, err := conn.DescribeMountTargets(&efs.DescribeMountTargetsInput{
|
|
MountTargetId: mount.MountTargetId,
|
|
})
|
|
if err != nil {
|
|
if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "MountTargetNotFound" {
|
|
return nil
|
|
}
|
|
return resource.NonRetryableError(
|
|
fmt.Errorf("Error reading EFS mount target: %s", err))
|
|
}
|
|
if resp.MountTargets == nil || len(resp.MountTargets) < 1 {
|
|
return nil
|
|
}
|
|
if *resp.MountTargets[0].LifeCycleState == "deleted" {
|
|
return nil
|
|
}
|
|
return resource.RetryableError(fmt.Errorf(
|
|
"Waiting for EFS mount target: %s", mount.MountTargetId))
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
const testAccAWSEFSMountTargetConfig = `
|
|
resource "aws_efs_file_system" "foo" {
|
|
creation_token = "radeksimko"
|
|
}
|
|
|
|
resource "aws_efs_mount_target" "alpha" {
|
|
file_system_id = "${aws_efs_file_system.foo.id}"
|
|
subnet_id = "${aws_subnet.alpha.id}"
|
|
}
|
|
|
|
resource "aws_vpc" "foo" {
|
|
cidr_block = "10.0.0.0/16"
|
|
}
|
|
|
|
resource "aws_subnet" "alpha" {
|
|
vpc_id = "${aws_vpc.foo.id}"
|
|
availability_zone = "us-west-2a"
|
|
cidr_block = "10.0.1.0/24"
|
|
}
|
|
`
|
|
|
|
const testAccAWSEFSMountTargetConfigModified = `
|
|
resource "aws_efs_file_system" "foo" {
|
|
creation_token = "radeksimko"
|
|
}
|
|
|
|
resource "aws_efs_mount_target" "alpha" {
|
|
file_system_id = "${aws_efs_file_system.foo.id}"
|
|
subnet_id = "${aws_subnet.alpha.id}"
|
|
}
|
|
|
|
resource "aws_efs_mount_target" "beta" {
|
|
file_system_id = "${aws_efs_file_system.foo.id}"
|
|
subnet_id = "${aws_subnet.beta.id}"
|
|
}
|
|
|
|
resource "aws_vpc" "foo" {
|
|
cidr_block = "10.0.0.0/16"
|
|
}
|
|
|
|
resource "aws_subnet" "alpha" {
|
|
vpc_id = "${aws_vpc.foo.id}"
|
|
availability_zone = "us-west-2a"
|
|
cidr_block = "10.0.1.0/24"
|
|
}
|
|
|
|
resource "aws_subnet" "beta" {
|
|
vpc_id = "${aws_vpc.foo.id}"
|
|
availability_zone = "us-west-2b"
|
|
cidr_block = "10.0.2.0/24"
|
|
}
|
|
`
|