Skip to content

Commit

Permalink
Add support for website argument of aws_s3_bucket
Browse files Browse the repository at this point in the history
  • Loading branch information
minamijoyo committed Mar 4, 2022
1 parent 8524969 commit 36aeef9
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ For upgrading AWS provider v4, some rules have not been implemented yet. The cur
- [ ] request_payer
- [x] server_side_encryption_configuration
- [x] versioning
- [ ] website
- [x] website
- [ ] Meta arguments of resource
- [ ] count
- [ ] for_each
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 @@ -31,7 +31,7 @@ func NewAWSS3BucketFilter() editor.Filter {
// &AWSS3BucketRequestPayerFilter{},
&AWSS3BucketServerSideEncryptionConfigurationFilter{},
&AWSS3BucketVersioningFilter{},
// &AWSS3BucketWebsiteFilter{},
&AWSS3BucketWebsiteFilter{},

// Remove redundant TokenNewLine tokens in the resource block after removing nested blocks.
// Since VerticalFormat clears tokens internally, we should call it at the end.
Expand Down
18 changes: 18 additions & 0 deletions filter/awsv4upgrade/aws_s3_bucket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@ EOF
versioning {
enabled = true
}
website {
index_document = "index.html"
error_document = "error.html"
}
}
`,
ok: true,
Expand Down Expand Up @@ -310,6 +315,19 @@ resource "aws_s3_bucket_versioning" "example" {
status = "Enabled"
}
}
resource "aws_s3_bucket_website_configuration" "example" {
bucket = aws_s3_bucket.example.id
index_document {
suffix = "index.html"
}
error_document {
key = "error.html"
}
}
`,
},
}
Expand Down
71 changes: 71 additions & 0 deletions filter/awsv4upgrade/aws_s3_bucket_website.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package awsv4upgrade

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

// AWSS3BucketWebsiteFilter is a filter implementation for upgrading the
// website argument of aws_s3_bucket.
// https://registry.terraform.io/providers/hashicorp/aws/latest/docs/guides/version-4-upgrade#website-website_domain-and-website_endpoint-arguments
type AWSS3BucketWebsiteFilter struct{}

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

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

// ResourceFilter upgrades the website argument of aws_s3_bucket.
func (f *AWSS3BucketWebsiteFilter) ResourceFilter(inFile *tfwrite.File, resource *tfwrite.Resource) (*tfwrite.File, error) {
oldNestedBlock := "website"
newResourceType := "aws_s3_bucket_website_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)

websiteBlock := nestedBlocks[0]

// Map an `index_document` attribute to an `index_document` block
// index_document = "index.html"
// =>
// index_document {
// suffix = "index.html"
// }
indexDocumentAttr := websiteBlock.GetAttribute("index_document")
if indexDocumentAttr != nil {
indexDocumentBlock := tfwrite.NewEmptyNestedBlock("index_document")
newResource.AppendNestedBlock(indexDocumentBlock)
suffix := indexDocumentAttr.ValueAsTokens()
indexDocumentBlock.SetAttributeRaw("suffix", suffix)
websiteBlock.RemoveAttribute("index_document")
}

// Map an `error_document` attribute to an `error_document` block
// error_document = "error.html"
// =>
// error_document {
// key = "error.html"
// }
errorDocumentAttr := websiteBlock.GetAttribute("error_document")
if errorDocumentAttr != nil {
errorDocumentBlock := tfwrite.NewEmptyNestedBlock("error_document")
newResource.AppendNestedBlock(errorDocumentBlock)
key := errorDocumentAttr.ValueAsTokens()
errorDocumentBlock.SetAttributeRaw("key", key)
websiteBlock.RemoveAttribute("error_document")
}

newResource.AppendUnwrappedNestedBlockBody(websiteBlock)
resource.RemoveNestedBlock(websiteBlock)

return inFile, nil
}
88 changes: 88 additions & 0 deletions filter/awsv4upgrade/aws_s3_bucket_website_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package awsv4upgrade

import (
"testing"

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

func TestAWSS3BucketWebsiteFilter(t *testing.T) {
cases := []struct {
name string
src string
ok bool
want string
}{
{
name: "simple",
src: `
resource "aws_s3_bucket" "example" {
bucket = "tfedit-test"
website {
index_document = "index.html"
error_document = "error.html"
}
}
`,
ok: true,
want: `
resource "aws_s3_bucket" "example" {
bucket = "tfedit-test"
}
resource "aws_s3_bucket_website_configuration" "example" {
bucket = aws_s3_bucket.example.id
index_document {
suffix = "index.html"
}
error_document {
key = "error.html"
}
}
`,
},
{
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{&AWSS3BucketWebsiteFilter{}}}
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)
}
})
}
}

0 comments on commit 36aeef9

Please sign in to comment.