diff --git a/util/pkg/vfs/tests/BUILD.bazel b/util/pkg/vfs/tests/BUILD.bazel new file mode 100644 index 0000000000..5d696533b7 --- /dev/null +++ b/util/pkg/vfs/tests/BUILD.bazel @@ -0,0 +1,12 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") + +go_test( + name = "go_default_test", + srcs = ["s3fs_test.go"], + deps = [ + "//upup/pkg/fi/cloudup/awsup:go_default_library", + "//upup/pkg/fi/cloudup/terraform:go_default_library", + "//util/pkg/vfs:go_default_library", + "//vendor/github.com/stretchr/testify/assert:go_default_library", + ], +) diff --git a/util/pkg/vfs/tests/s3fs_test.go b/util/pkg/vfs/tests/s3fs_test.go new file mode 100644 index 0000000000..3c2df7303e --- /dev/null +++ b/util/pkg/vfs/tests/s3fs_test.go @@ -0,0 +1,117 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package tests + +import ( + "encoding/json" + "fmt" + "os" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "k8s.io/kops/upup/pkg/fi/cloudup/awsup" + "k8s.io/kops/upup/pkg/fi/cloudup/terraform" + "k8s.io/kops/util/pkg/vfs" +) + +func TestS3RenderTerraform(t *testing.T) { + content := "hello world" + grid := []struct { + expectedPath string + s3Path string + s3Object string + expectedJSON string + }{ + { + s3Path: "s3://foo/bar", + s3Object: "bar", + expectedJSON: ` + { + "acl": "bucket-owner-full-control", + "bucket": "foo", + "content": "${file(\"${path.module}/data/aws_s3_bucket_object_bar_content\")}", + "key": "bar", + "provider": "${aws.files}", + "server_side_encryption": "AES256" + } + `, + }, + } + origEndpoint := os.Getenv("S3_ENDPOINT") + os.Setenv("S3_ENDPOINT", "foo.s3.amazonaws.com") + defer os.Setenv("S3_ENDPOINT", origEndpoint) + + origACL := os.Getenv("KOPS_STATE_S3_ACL") + os.Setenv("KOPS_STATE_S3_ACL", "bucket-owner-full-control") + defer os.Setenv("KOPS_STATE_S3_ACL", origACL) + for _, tc := range grid { + + t.Run(tc.s3Path, func(t *testing.T) { + cloud := awsup.BuildMockAWSCloud("us-east-1", "a") + path, err := vfs.Context.BuildVfsPath(tc.s3Path) + if err != nil { + t.Fatalf("error building VFS path: %v", err) + t.FailNow() + } + + vfsProvider, err := path.(vfs.TerraformPath).TerraformProvider() + if err != nil { + t.Fatalf("error building VFS Terraform provider: %v", err) + t.FailNow() + } + target := terraform.NewTerraformTarget(cloud, "", vfsProvider, "/dev/null", nil) + + err = path.(*vfs.S3Path).RenderTerraform( + &target.TerraformWriter, tc.s3Object, strings.NewReader(content), vfs.S3Acl{}, + ) + if err != nil { + t.Fatalf("error rendering terraform %v", err) + t.FailNow() + } + res, err := target.GetResourcesByType() + if err != nil { + t.Fatalf("error fetching terraform resources: %v", err) + t.FailNow() + } + if objs := res["aws_s3_bucket_object"]; objs == nil { + t.Fatalf("aws_s3_bucket_object resources not found: %v", res) + t.FailNow() + } + if obj := res["aws_s3_bucket_object"][tc.s3Object]; obj == nil { + t.Fatalf("aws_s3_bucket_object object not found: %v", res["aws_s3_bucket_object"]) + t.FailNow() + } + obj, err := json.Marshal(res["aws_s3_bucket_object"][tc.s3Object]) + if err != nil { + t.Fatalf("error marshaling s3 object: %v", err) + t.FailNow() + } + if !assert.JSONEq(t, tc.expectedJSON, string(obj), "JSON representation of terraform resource did not match") { + t.FailNow() + } + if objs := target.TerraformWriter.Files[fmt.Sprintf("data/aws_s3_bucket_object_%v_content", tc.s3Object)]; objs == nil { + t.Fatalf("aws_s3_bucket_object content file not found: %v", target.TerraformWriter.Files) + t.FailNow() + } + actualContent := string(target.TerraformWriter.Files[fmt.Sprintf("data/aws_s3_bucket_object_%v_content", tc.s3Object)]) + if !assert.Equal(t, content, actualContent, "aws_s3_bucket_object content did not match") { + t.FailNow() + } + }) + } +}