Skip to content

Commit

Permalink
Merge pull request #10 from minamijoyo/add-object-lock-configuration
Browse files Browse the repository at this point in the history
Add support for object_lock_configuration of aws_s3_bucket
  • Loading branch information
minamijoyo authored Mar 12, 2022
2 parents d5035e7 + 1633481 commit bc2e74f
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ For upgrading AWS provider v4, some rules have not been implemented yet. The cur
- [x] grant
- [x] lifecycle_rule
- [x] logging
- [ ] object_lock_configuration rule
- [x] object_lock_configuration rule
- [x] policy
- [ ] replication_configuration
- [x] request_payer
Expand Down
2 changes: 1 addition & 1 deletion filter/awsv4upgrade/aws_s3_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func NewAWSS3BucketFilter() editor.Filter {
&AWSS3BucketGrantFilter{},
&AWSS3BucketLifecycleRuleFilter{},
&AWSS3BucketLoggingFilter{},
// &AWSS3BucketObjectLockConfigurationFilter{},
&AWSS3BucketObjectLockConfigurationFilter{},
&AWSS3BucketPolicyFilter{},
// &AWSS3BucketReplicationConfigurationFilter{},
&AWSS3BucketRequestPayerFilter{},
Expand Down
47 changes: 47 additions & 0 deletions filter/awsv4upgrade/aws_s3_bucket_object_lock_configuration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package awsv4upgrade

import (
"github.com/minamijoyo/tfedit/tfeditor"
"github.com/minamijoyo/tfedit/tfwrite"
)

// AWSS3BucketObjectLockConfigurationFilter is a filter implementation for
// upgrading the object_lock_configuration argument of aws_s3_bucket.
// https://registry.terraform.io/providers/hashicorp/aws/latest/docs/guides/version-4-upgrade#object_lock_configuration-rule-argument
type AWSS3BucketObjectLockConfigurationFilter struct{}

var _ tfeditor.ResourceFilter = (*AWSS3BucketObjectLockConfigurationFilter)(nil)

// NewAWSS3BucketObjectLockConfigurationFilter creates a new instance of
// AWSS3BucketObjectLockConfigurationFilter.
func NewAWSS3BucketObjectLockConfigurationFilter() tfeditor.ResourceFilter {
return &AWSS3BucketObjectLockConfigurationFilter{}
}

// ResourceFilter upgrades the object_lock_configuration argument of
// aws_s3_bucket.
func (f *AWSS3BucketObjectLockConfigurationFilter) ResourceFilter(inFile *tfwrite.File, resource *tfwrite.Resource) (*tfwrite.File, error) {
oldNestedBlock := "object_lock_configuration"
newResourceType := "aws_s3_bucket_object_lock_configuration"

nestedBlocks := resource.FindNestedBlocksByType(oldNestedBlock)
if len(nestedBlocks) == 0 {
return inFile, nil
}

resourceName := resource.Name()
newResource := tfwrite.NewEmptyResource(newResourceType, resourceName)
inFile.AppendResource(newResource)
setBucketArgument(newResource, resource)

objectLockBlock := nestedBlocks[0]

// Move a rule block to a new resource
ruleBlocks := objectLockBlock.FindNestedBlocksByType("rule")
for _, ruleBlock := range ruleBlocks {
newResource.AppendNestedBlock(ruleBlock)
objectLockBlock.RemoveNestedBlock(ruleBlock)
}

return inFile, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package awsv4upgrade

import (
"testing"

"github.com/google/go-cmp/cmp"
"github.com/minamijoyo/hcledit/editor"
"github.com/minamijoyo/tfedit/tfeditor"
)

func TestAWSS3BucketObjectLockConfigurationFilter(t *testing.T) {
cases := []struct {
name string
src string
ok bool
want string
}{
{
name: "simple",
src: `
resource "aws_s3_bucket" "example" {
bucket = "tfedit-test"
object_lock_configuration {
object_lock_enabled = "Enabled"
rule {
default_retention {
mode = "COMPLIANCE"
days = 3
}
}
}
}
`,
ok: true,
want: `
resource "aws_s3_bucket" "example" {
bucket = "tfedit-test"
object_lock_configuration {
object_lock_enabled = "Enabled"
}
}
resource "aws_s3_bucket_object_lock_configuration" "example" {
bucket = aws_s3_bucket.example.id
rule {
default_retention {
mode = "COMPLIANCE"
days = 3
}
}
}
`,
},
{
name: "argument not found",
src: `
resource "aws_s3_bucket" "example" {
bucket = "tfedit-test"
foo {}
}
`,
ok: true,
want: `
resource "aws_s3_bucket" "example" {
bucket = "tfedit-test"
foo {}
}
`,
},
}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
filter := &AWSS3BucketFilter{filters: []tfeditor.ResourceFilter{&AWSS3BucketObjectLockConfigurationFilter{}}}
o := editor.NewEditOperator(filter)
output, err := o.Apply([]byte(tc.src), "test")
if tc.ok && err != nil {
t.Fatalf("unexpected err = %s", err)
}

got := string(output)
if !tc.ok && err == nil {
t.Fatalf("expected to return an error, but no error, outStream: \n%s", got)
}

if diff := cmp.Diff(got, tc.want); diff != "" {
t.Fatalf("got:\n%s\nwant:\n%s\ndiff:\n%s", got, tc.want, diff)
}
})
}
}
27 changes: 27 additions & 0 deletions filter/awsv4upgrade/aws_s3_bucket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,17 @@ resource "aws_s3_bucket" "example" {
target_prefix = "log/"
}
object_lock_configuration {
object_lock_enabled = "Enabled"
rule {
default_retention {
mode = "COMPLIANCE"
days = 3
}
}
}
policy = <<EOF
{
"Id": "Policy1446577137248",
Expand Down Expand Up @@ -218,6 +229,11 @@ EOF
want: `
resource "aws_s3_bucket" "example" {
bucket = "tfedit-test"
object_lock_configuration {
object_lock_enabled = "Enabled"
}
}
resource "aws_s3_bucket_accelerate_configuration" "example" {
Expand Down Expand Up @@ -284,6 +300,17 @@ resource "aws_s3_bucket_logging" "example" {
target_prefix = "log/"
}
resource "aws_s3_bucket_object_lock_configuration" "example" {
bucket = aws_s3_bucket.example.id
rule {
default_retention {
mode = "COMPLIANCE"
days = 3
}
}
}
resource "aws_s3_bucket_policy" "example" {
bucket = aws_s3_bucket.example.id
policy = <<EOF
Expand Down
5 changes: 5 additions & 0 deletions tfwrite/nested_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,8 @@ func (b *NestedBlock) AppendUnwrappedNestedBlockBody(nestedBlock *NestedBlock) {
unwrapped := nestedBlock.raw.Body().BuildTokens(nil)
b.raw.Body().AppendUnstructuredTokens(unwrapped)
}

// RemoveNestedBlock removes a given nested block from the resource.
func (b *NestedBlock) RemoveNestedBlock(nestedBlock *NestedBlock) {
b.raw.Body().RemoveBlock(nestedBlock.raw)
}

0 comments on commit bc2e74f

Please sign in to comment.