Merge pull request #33571 from hashicorp/s3/add-legacy-acceptance-tests

S3 Backend: Add legacy authentication flow tests
This commit is contained in:
Graham Davison 2023-07-31 13:27:02 -07:00 committed by GitHub
commit 84edaaed57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 1352 additions and 24 deletions

File diff suppressed because it is too large Load Diff

View File

@ -50,7 +50,7 @@ func TestBackend_impl(t *testing.T) {
var _ backend.Backend = new(Backend)
}
func TestBackendConfig(t *testing.T) {
func TestBackendConfig_original(t *testing.T) {
testACC(t)
config := map[string]interface{}{
"region": "us-west-1",
@ -62,10 +62,10 @@ func TestBackendConfig(t *testing.T) {
b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(config)).(*Backend)
if *b.s3Client.Config.Region != "us-west-1" {
if aws.StringValue(b.s3Client.Config.Region) != "us-west-1" {
t.Fatalf("Incorrect region was populated")
}
if *b.s3Client.Config.MaxRetries != 5 {
if aws.IntValue(b.s3Client.Config.MaxRetries) != 5 {
t.Fatalf("Default max_retries was not set")
}
if b.bucketName != "tf-test" {
@ -188,7 +188,7 @@ func TestBackendConfig_RegionEnvVar(t *testing.T) {
b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(config)).(*Backend)
if *b.s3Client.Config.Region != "us-west-1" {
if aws.StringValue(b.s3Client.Config.Region) != "us-west-1" {
t.Fatalf("Incorrect region was populated")
}
})
@ -1259,7 +1259,7 @@ func createS3Bucket(t *testing.T, s3Client *s3.S3, bucketName string) {
// Be clear about what we're doing in case the user needs to clean
// this up later.
t.Logf("creating S3 bucket %s in %s", bucketName, *s3Client.Config.Region)
t.Logf("creating S3 bucket %s in %s", bucketName, aws.StringValue(s3Client.Config.Region))
_, err := s3Client.CreateBucket(createBucketReq)
if err != nil {
t.Fatal("failed to create test S3 bucket:", err)
@ -1449,25 +1449,6 @@ func unmarshalObject(dec cty.Value, atys map[string]cty.Type, path cty.Path) (ct
return cty.ObjectVal(vals), nil
}
func stashEnv() []string {
env := os.Environ()
os.Clearenv()
return env
}
func popEnv(env []string) {
os.Clearenv()
for _, e := range env {
p := strings.SplitN(e, "=", 2)
k, v := p[0], ""
if len(p) > 1 {
v = p[1]
}
os.Setenv(k, v)
}
}
func must[T any](v T, err error) T {
if err != nil {
panic(err)

View File

@ -0,0 +1,34 @@
package s3
import (
"strings"
"github.com/hashicorp/terraform/internal/tfdiags"
)
func diagnosticString(diag tfdiags.Diagnostic) string {
var buffer strings.Builder
buffer.WriteString(diag.Severity().String() + ": ")
buffer.WriteString(diag.Description().Summary)
if diag.Description().Detail != "" {
buffer.WriteString("\n\n")
buffer.WriteString(diag.Description().Detail)
}
return buffer.String()
}
func diagnosticsString(diags tfdiags.Diagnostics) string {
l := len(diags)
if l == 0 {
return ""
}
var buffer strings.Builder
for i, d := range diags {
buffer.WriteString(diagnosticString(d))
if i < l-1 {
buffer.WriteString(",\n")
}
}
return buffer.String()
}

View File

@ -0,0 +1,129 @@
package s3
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/http/httptest"
"os"
"strings"
"time"
servicemocks "github.com/hashicorp/aws-sdk-go-base"
)
// TODO: replace with `aws-sdk-go-base/v2/servicemocks.InitSessionTestEnv`
func initSessionTestEnv() (oldEnv []string) {
oldEnv = stashEnv()
os.Setenv("AWS_CONFIG_FILE", "file_not_exists")
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", "file_not_exists")
return oldEnv
}
// TODO: replace with `aws-sdk-go-base/v2/servicemocks.StashEnv`
func stashEnv() []string {
env := os.Environ()
os.Clearenv()
return env
}
// TODO: replace with `aws-sdk-go-base/v2/servicemocks.PopEnv`
func popEnv(env []string) {
os.Clearenv()
for _, e := range env {
p := strings.SplitN(e, "=", 2)
k, v := p[0], ""
if len(p) > 1 {
v = p[1]
}
os.Setenv(k, v)
}
}
// TODO: replace with `aws-sdk-go-base/v2/servicemocks.AwsMetadataApiMock`
// awsMetadataApiMock establishes a httptest server to mock out the internal AWS Metadata
// service. IAM Credentials are retrieved by the EC2RoleProvider, which makes
// API calls to this internal URL. By replacing the server with a test server,
// we can simulate an AWS environment
func awsMetadataApiMock(responses []*servicemocks.MetadataResponse) func() {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Header().Add("Server", "MockEC2")
log.Printf("[DEBUG] Mock EC2 metadata server received request: %s", r.RequestURI)
for _, e := range responses {
if r.RequestURI == e.Uri {
fmt.Fprintln(w, e.Body)
return
}
}
w.WriteHeader(http.StatusBadRequest)
}))
os.Setenv("AWS_METADATA_URL", ts.URL+"/latest")
return ts.Close
}
// TODO: replace with `aws-sdk-go-base/v2/servicemocks.Ec2metadata_securityCredentialsEndpoints`
var ec2metadata_securityCredentialsEndpoints = []*servicemocks.MetadataResponse{
{
Uri: "/latest/api/token",
Body: "Ec2MetadataApiToken",
},
{
Uri: "/latest/meta-data/iam/security-credentials/",
Body: "test_role",
},
{
Uri: "/latest/meta-data/iam/security-credentials/test_role",
Body: "{\"Code\":\"Success\",\"LastUpdated\":\"2015-12-11T17:17:25Z\",\"Type\":\"AWS-HMAC\",\"AccessKeyId\":\"Ec2MetadataAccessKey\",\"SecretAccessKey\":\"Ec2MetadataSecretKey\",\"Token\":\"Ec2MetadataSessionToken\"}",
},
}
// TODO: replace with `aws-sdk-go-base/v2/servicemocks.Ec2metadata_iamInfoEndpoint`
var ec2metadata_instanceIdEndpoint = &servicemocks.MetadataResponse{
Uri: "/latest/meta-data/instance-id",
Body: "mock-instance-id",
}
var ec2metadata_iamInfoEndpoint = &servicemocks.MetadataResponse{
Uri: "/latest/meta-data/iam/info",
Body: "{\"Code\": \"Success\",\"LastUpdated\": \"2016-03-17T12:27:32Z\",\"InstanceProfileArn\": \"arn:aws:iam::000000000000:instance-profile/my-instance-profile\",\"InstanceProfileId\": \"AIPAABCDEFGHIJKLMN123\"}",
}
// TODO: replace with `aws-sdk-go-base/v2/servicemocks.EcsCredentialsApiMock`
func ecsCredentialsApiMock() func() {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Add("Server", "MockECS")
log.Printf("[DEBUG] Mock ECS credentials server received request: %s", r.RequestURI)
if r.RequestURI == "/creds" {
_ = json.NewEncoder(w).Encode(map[string]string{
"AccessKeyId": servicemocks.MockEcsCredentialsAccessKey,
"Expiration": time.Now().UTC().Format(time.RFC3339),
"RoleArn": "arn:aws:iam::000000000000:role/EcsCredentials",
"SecretAccessKey": servicemocks.MockEcsCredentialsSecretKey,
"Token": servicemocks.MockEcsCredentialsSessionToken,
})
return
}
w.WriteHeader(http.StatusBadRequest)
}))
os.Setenv("AWS_CONTAINER_CREDENTIALS_FULL_URI", ts.URL+"/creds")
return ts.Close
}
// TODO: replace with `aws-sdk-go-base/v2/servicemocks.Ec2metadata_instanceIdentityEndpoint`
func ec2metadata_instanceIdentityEndpoint(region string) *servicemocks.MetadataResponse {
return &servicemocks.MetadataResponse{
Uri: "/latest/dynamic/instance-identity/document",
Body: fmt.Sprintf(`{
"version": "2017-09-30",
"instanceId": "mock-instance-id",
"region": %q
}`, region),
}
}