Skip to content

Commit

Permalink
r/s3_bucket_lifecycle_configuration: make new_noncurrent_versions arg…
Browse files Browse the repository at this point in the history
…uments nullable ints
  • Loading branch information
anGie44 committed Mar 2, 2022
1 parent 4604bb0 commit e40d97e
Show file tree
Hide file tree
Showing 4 changed files with 298 additions and 19 deletions.
4 changes: 2 additions & 2 deletions internal/service/s3/bucket_lifecycle_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ 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),
},
Expand All @@ -182,7 +182,7 @@ 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),
},
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)
}
29 changes: 16 additions & 13 deletions internal/service/s3/flex.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package s3

import (
"fmt"
"strconv"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-aws/internal/experimental/nullable"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
)

Expand Down Expand Up @@ -230,12 +232,12 @@ func ExpandLifecycleRuleFilter(l []interface{}) *s3.LifecycleRuleFilter {
result.And = ExpandLifecycleRuleFilterAndOperator(v[0].(map[string]interface{}))
}

if v, ok := m["object_size_greater_than"].(int); ok && v > 0 {
result.ObjectSizeGreaterThan = aws.Int64(int64(v))
if v, null, _ := nullable.Int(m["object_size_greater_than"].(string)).Value(); !null && v > 0 {
result.ObjectSizeGreaterThan = aws.Int64(v)
}

if v, ok := m["object_size_less_than"].(int); ok && v > 0 {
result.ObjectSizeLessThan = aws.Int64(int64(v))
if v, null, _ := nullable.Int(m["object_size_less_than"].(string)).Value(); !null && v > 0 {
result.ObjectSizeLessThan = aws.Int64(v)
}

if v, ok := m["tag"].([]interface{}); ok && len(v) > 0 && v[0] != nil {
Expand All @@ -244,7 +246,8 @@ func ExpandLifecycleRuleFilter(l []interface{}) *s3.LifecycleRuleFilter {

// Per AWS S3 API, "A Filter must have exactly one of Prefix, Tag, or And specified";
// Specifying more than one of the listed parameters results in a MalformedXML error.
if v, ok := m["prefix"].(string); ok && result.And == nil && result.Tag == nil {
// In practice, this also includes ObjectSizeGreaterThan and ObjectSizeLessThan.
if v, ok := m["prefix"].(string); ok && result.And == nil && result.Tag == nil && result.ObjectSizeGreaterThan == nil && result.ObjectSizeLessThan == nil {
result.Prefix = aws.String(v)
}

Expand Down Expand Up @@ -305,8 +308,8 @@ func ExpandLifecycleRuleNoncurrentVersionExpiration(m map[string]interface{}) *s

result := &s3.NoncurrentVersionExpiration{}

if v, ok := m["newer_noncurrent_versions"].(int); ok && v > 0 {
result.NewerNoncurrentVersions = aws.Int64(int64(v))
if v, null, _ := nullable.Int(m["newer_noncurrent_versions"].(string)).Value(); !null && v > 0 {
result.NewerNoncurrentVersions = aws.Int64(v)
}

if v, ok := m["noncurrent_days"].(int); ok {
Expand All @@ -332,8 +335,8 @@ func ExpandLifecycleRuleNoncurrentVersionTransitions(l []interface{}) []*s3.Nonc

transition := &s3.NoncurrentVersionTransition{}

if v, ok := tfMap["newer_noncurrent_versions"].(int); ok && v > 0 {
transition.NewerNoncurrentVersions = aws.Int64(int64(v))
if v, null, _ := nullable.Int(tfMap["newer_noncurrent_versions"].(string)).Value(); !null && v > 0 {
transition.NewerNoncurrentVersions = aws.Int64(v)
}

if v, ok := tfMap["noncurrent_days"].(int); ok {
Expand Down Expand Up @@ -910,11 +913,11 @@ func FlattenLifecycleRuleFilter(filter *s3.LifecycleRuleFilter) []interface{} {
}

if filter.ObjectSizeGreaterThan != nil {
m["object_size_greater_than"] = int(aws.Int64Value(filter.ObjectSizeGreaterThan))
m["object_size_greater_than"] = strconv.FormatInt(aws.Int64Value(filter.ObjectSizeGreaterThan), 10)
}

if filter.ObjectSizeLessThan != nil {
m["object_size_less_than"] = int(aws.Int64Value(filter.ObjectSizeLessThan))
m["object_size_less_than"] = strconv.FormatInt(aws.Int64Value(filter.ObjectSizeLessThan), 10)
}

if filter.Prefix != nil {
Expand Down Expand Up @@ -980,7 +983,7 @@ func FlattenLifecycleRuleNoncurrentVersionExpiration(expiration *s3.NoncurrentVe
m := make(map[string]interface{})

if expiration.NewerNoncurrentVersions != nil {
m["newer_noncurrent_versions"] = int(aws.Int64Value(expiration.NewerNoncurrentVersions))
m["newer_noncurrent_versions"] = strconv.FormatInt(aws.Int64Value(expiration.NewerNoncurrentVersions), 10)
}

if expiration.NoncurrentDays != nil {
Expand All @@ -1005,7 +1008,7 @@ func FlattenLifecycleRuleNoncurrentVersionTransitions(transitions []*s3.Noncurre
m := make(map[string]interface{})

if transition.NewerNoncurrentVersions != nil {
m["newer_noncurrent_versions"] = int(aws.Int64Value(transition.NewerNoncurrentVersions))
m["newer_noncurrent_versions"] = strconv.FormatInt(aws.Int64Value(transition.NewerNoncurrentVersions), 10)
}

if transition.NoncurrentDays != nil {
Expand Down
Loading

0 comments on commit e40d97e

Please sign in to comment.