Skip to content

Commit

Permalink
Merge pull request #23441 from hashicorp/b-s3-bucket-lifecycle-config…
Browse files Browse the repository at this point in the history
…uration-noncurrent-versioning-transition

r/s3_bucket_lifecycle_configuration: make `new_noncurrent_versions` arguments nullable ints to prevent drift and fix other nullable int args (`filter.object_size_greater_than` and `filter.object_size_less_than`)
  • Loading branch information
anGie44 authored Mar 10, 2022
2 parents e8d5a71 + 57e2c5d commit 998611c
Show file tree
Hide file tree
Showing 5 changed files with 307 additions and 21 deletions.
7 changes: 7 additions & 0 deletions .changelog/23441.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:bug
resource/aws_s3_bucket_lifecycle_configuration: Correctly configure `rule.filter.object_size_greater_than` and `rule.filter.object_size_less_than` in API requests and terraform state
```

```release-note:bug
resource/aws_s3_bucket_lifecycle_configuration: Prevent drift when `rule.noncurrent_version_expiration.newer_noncurrent_versions` or `rule.noncurrent_version_transition.newer_noncurrent_versions` is not specified
```
8 changes: 4 additions & 4 deletions internal/service/s3/bucket_lifecycle_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,9 @@ func ResourceBucketLifecycleConfiguration() *schema.Resource {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"newer_noncurrent_versions": {
Type: schema.TypeInt,
Type: nullable.TypeNullableInt,
Optional: true,
ValidateFunc: validation.IntAtLeast(1),
ValidateFunc: nullable.ValidateTypeStringNullableIntAtLeast(1),
},
"noncurrent_days": {
Type: schema.TypeInt,
Expand All @@ -182,9 +182,9 @@ func ResourceBucketLifecycleConfiguration() *schema.Resource {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"newer_noncurrent_versions": {
Type: schema.TypeInt,
Type: nullable.TypeNullableInt,
Optional: true,
ValidateFunc: validation.IntAtLeast(1),
ValidateFunc: nullable.ValidateTypeStringNullableIntAtLeast(1),
},
"noncurrent_days": {
Type: schema.TypeInt,
Expand Down
276 changes: 276 additions & 0 deletions internal/service/s3/bucket_lifecycle_configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,151 @@ func TestAccS3BucketLifecycleConfiguration_filterWithPrefix(t *testing.T) {
})
}

func TestAccS3BucketLifecycleConfiguration_Filter_ObjectSizeGreaterThan(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_s3_bucket_lifecycle_configuration.test"
currTime := time.Now()
date := time.Date(currTime.Year(), currTime.Month()+1, currTime.Day(), 0, 0, 0, 0, time.UTC).Format(time.RFC3339)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckBucketLifecycleConfigurationDestroy,
Steps: []resource.TestStep{
{
Config: testAccBucketLifecycleConfiguration_filterWithObjectSizeGreaterThanConfig(rName, date, 100),
Check: resource.ComposeTestCheckFunc(
testAccCheckBucketLifecycleConfigurationExists(resourceName),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule.*", map[string]string{
"expiration.#": "1",
"expiration.0.date": date,
"filter.#": "1",
"filter.0.object_size_greater_than": "100",
"id": rName,
"status": tfs3.LifecycleRuleStatusEnabled,
}),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccS3BucketLifecycleConfiguration_Filter_ObjectSizeLessThan(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_s3_bucket_lifecycle_configuration.test"
currTime := time.Now()
date := time.Date(currTime.Year(), currTime.Month()+1, currTime.Day(), 0, 0, 0, 0, time.UTC).Format(time.RFC3339)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckBucketLifecycleConfigurationDestroy,
Steps: []resource.TestStep{
{
Config: testAccBucketLifecycleConfiguration_filterWithObjectSizeLessThanConfig(rName, date, 500),
Check: resource.ComposeTestCheckFunc(
testAccCheckBucketLifecycleConfigurationExists(resourceName),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule.*", map[string]string{
"expiration.#": "1",
"expiration.0.date": date,
"filter.#": "1",
"filter.0.object_size_less_than": "500",
"id": rName,
"status": tfs3.LifecycleRuleStatusEnabled,
}),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccS3BucketLifecycleConfiguration_Filter_ObjectSizeRange(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_s3_bucket_lifecycle_configuration.test"
currTime := time.Now()
date := time.Date(currTime.Year(), currTime.Month()+1, currTime.Day(), 0, 0, 0, 0, time.UTC).Format(time.RFC3339)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckBucketLifecycleConfigurationDestroy,
Steps: []resource.TestStep{
{
Config: testAccBucketLifecycleConfiguration_filterWithObjectSizeRangeConfig(rName, date, 500, 64000),
Check: resource.ComposeTestCheckFunc(
testAccCheckBucketLifecycleConfigurationExists(resourceName),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule.*", map[string]string{
"expiration.#": "1",
"expiration.0.date": date,
"filter.#": "1",
"filter.0.and.#": "1",
"filter.0.and.0.object_size_greater_than": "500",
"filter.0.and.0.object_size_less_than": "64000",
"id": rName,
"status": tfs3.LifecycleRuleStatusEnabled,
}),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccS3BucketLifecycleConfiguration_Filter_ObjectSizeRangeAndPrefix(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_s3_bucket_lifecycle_configuration.test"
currTime := time.Now()
date := time.Date(currTime.Year(), currTime.Month()+1, currTime.Day(), 0, 0, 0, 0, time.UTC).Format(time.RFC3339)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckBucketLifecycleConfigurationDestroy,
Steps: []resource.TestStep{
{
Config: testAccBucketLifecycleConfiguration_filterWithObjectSizeRangeAndPrefixConfig(rName, date, 500, 64000),
Check: resource.ComposeTestCheckFunc(
testAccCheckBucketLifecycleConfigurationExists(resourceName),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule.*", map[string]string{
"expiration.#": "1",
"expiration.0.date": date,
"filter.#": "1",
"filter.0.and.#": "1",
"filter.0.and.0.object_size_greater_than": "500",
"filter.0.and.0.object_size_less_than": "64000",
"filter.0.and.0.prefix": rName,
"id": rName,
"status": tfs3.LifecycleRuleStatusEnabled,
}),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccS3BucketLifecycleConfiguration_disableRule(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_s3_bucket_lifecycle_configuration.test"
Expand Down Expand Up @@ -1241,3 +1386,134 @@ resource "aws_s3_bucket_lifecycle_configuration" "test" {
}
`, rName)
}

func testAccBucketLifecycleConfiguration_filterWithObjectSizeGreaterThanConfig(rName, date string, sizeGreaterThan int) string {
return fmt.Sprintf(`
resource "aws_s3_bucket" "test" {
bucket = %[1]q
}
resource "aws_s3_bucket_acl" "test" {
bucket = aws_s3_bucket.test.id
acl = "private"
}
resource "aws_s3_bucket_lifecycle_configuration" "test" {
bucket = aws_s3_bucket.test.bucket
rule {
id = %[1]q
expiration {
date = %[2]q
}
filter {
object_size_greater_than = %[3]d
}
status = "Enabled"
}
}
`, rName, date, sizeGreaterThan)
}

func testAccBucketLifecycleConfiguration_filterWithObjectSizeLessThanConfig(rName, date string, sizeLessThan int) string {
return fmt.Sprintf(`
resource "aws_s3_bucket" "test" {
bucket = %[1]q
}
resource "aws_s3_bucket_acl" "test" {
bucket = aws_s3_bucket.test.id
acl = "private"
}
resource "aws_s3_bucket_lifecycle_configuration" "test" {
bucket = aws_s3_bucket.test.bucket
rule {
id = %[1]q
expiration {
date = %[2]q
}
filter {
object_size_less_than = %[3]d
}
status = "Enabled"
}
}
`, rName, date, sizeLessThan)
}

func testAccBucketLifecycleConfiguration_filterWithObjectSizeRangeConfig(rName, date string, sizeGreaterThan, sizeLessThan int) string {
return fmt.Sprintf(`
resource "aws_s3_bucket" "test" {
bucket = %[1]q
}
resource "aws_s3_bucket_acl" "test" {
bucket = aws_s3_bucket.test.id
acl = "private"
}
resource "aws_s3_bucket_lifecycle_configuration" "test" {
bucket = aws_s3_bucket.test.bucket
rule {
id = %[1]q
expiration {
date = %[2]q
}
filter {
and {
object_size_greater_than = %[3]d
object_size_less_than = %[4]d
}
}
status = "Enabled"
}
}
`, rName, date, sizeGreaterThan, sizeLessThan)
}

func testAccBucketLifecycleConfiguration_filterWithObjectSizeRangeAndPrefixConfig(rName, date string, sizeGreaterThan, sizeLessThan int) string {
return fmt.Sprintf(`
resource "aws_s3_bucket" "test" {
bucket = %[1]q
}
resource "aws_s3_bucket_acl" "test" {
bucket = aws_s3_bucket.test.id
acl = "private"
}
resource "aws_s3_bucket_lifecycle_configuration" "test" {
bucket = aws_s3_bucket.test.bucket
rule {
id = %[1]q
expiration {
date = %[2]q
}
filter {
and {
object_size_greater_than = %[3]d
object_size_less_than = %[4]d
prefix = %[1]q
}
}
status = "Enabled"
}
}
`, rName, date, sizeGreaterThan, sizeLessThan)
}
Loading

0 comments on commit 998611c

Please sign in to comment.