在本地堆栈上使用 aws-sdk-go 创建的 S3 存储桶以位置结束:/none

S3 bucket creation with aws-sdk-go on local stack ends up with location :/none

我一直在尝试使用 golang 和 localstack 在 S3 存储桶上学习 CRUD 操作

使用下面的代码


import (
    "fmt"
    "io/ioutil"
    "os"
    "strings"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/awserr"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
)

var (
    s3session *s3.S3
)

const (
    REGION             = "us-east-1"
    Bucket_Name string = "sahil1234"
)

func init() {
    s3session = s3.New(session.Must(session.NewSession(&aws.Config{
        Region:   aws.String("us-east-1"),
        Endpoint: aws.String("http://localhost:4566/"),
    })))
}

func listBuckets() (resp *s3.ListBucketsOutput) {
    resp, err := s3session.ListBuckets(&s3.ListBucketsInput{})
    if err != nil {
        panic(err)
    }
    return resp
}

func createBucket() (resp *s3.CreateBucketOutput) {
    resp, err := s3session.CreateBucket(&s3.CreateBucketInput{
        // ACL: aws.String(s3.BucketCannedACLPrivate),
        // ACL: aws.String(s3.BucketCannedACLPublicRead),
        Bucket: aws.String(Bucket_Name),
        CreateBucketConfiguration: &s3.CreateBucketConfiguration{
            LocationConstraint: aws.String(REGION),
        },
    })
    if err != nil {
        if aerr, ok := err.(awserr.Error); ok {
            switch aerr.Code() {
            case s3.ErrCodeBucketAlreadyExists:
                fmt.Println("Bucket name already in use!")
                panic(err)
            case s3.ErrCodeBucketAlreadyOwnedByYou:
                fmt.Println("Bucket exists and is owned by you!")
            default:
                panic(err)
            }
        }
    }

    return resp
}

func uploadObject(filename string) (resp *s3.PutObjectOutput) {
    f, err := os.Open(filename)
    if err != nil {
        panic(err)
    }

    fmt.Println("Uploading:", filename)
    resp, err = s3session.PutObject(&s3.PutObjectInput{
        Body:   f,
        Bucket: aws.String(Bucket_Name),
        Key:    aws.String(strings.Split(filename, "/")[1]),
        ACL:    aws.String(s3.BucketCannedACLPublicRead),
    })

    if err != nil {
        panic(err)
    }

    return resp
}

func listObjects() (resp *s3.ListObjectsV2Output) {
    resp, err := s3session.ListObjectsV2(&s3.ListObjectsV2Input{
        Bucket: aws.String(Bucket_Name),
    })

    if err != nil {
        panic(err)
    }

    return resp
}

func getObject(filename string) {
    fmt.Println("Downloading: ", filename)

    resp, err := s3session.GetObject(&s3.GetObjectInput{
        Bucket: aws.String(Bucket_Name),
        Key:    aws.String(filename),
    })

    if err != nil {
        panic(err)
    }

    body, err := ioutil.ReadAll(resp.Body)
    err = ioutil.WriteFile(filename, body, 0644)
    if err != nil {
        panic(err)
    }
}

func deleteObject(filename string) (resp *s3.DeleteObjectOutput) {
    fmt.Println("Deleting: ", filename)
    resp, err := s3session.DeleteObject(&s3.DeleteObjectInput{
        Bucket: aws.String(Bucket_Name),
        Key:    aws.String(filename),
    })

    if err != nil {
        panic(err)
    }

    return resp
}

func main() {
    
    fmt.Println(listBuckets())
    fmt.Println(createBucket())
    fmt.Println(listBuckets())
}

即使 creatBucket returns 成功,它也不会创建实际的存储桶, 它只是 returns

{
  Location: "/None"
}

当我这样做时,桶也没有出现 aws --endpoint-url=http://localhost:4566 s3 ls

如有任何帮助,我们将不胜感激!

输出:

{
  Buckets: [{
      CreationDate: 2021-09-29 07:25:21 +0000 UTC,
      Name: "my-bucket1212"
    }],
  Owner: {
    DisplayName: "webfile",
    ID: "bcaf1ffd86f41161ca5fb16fd081034f"
  }
}
{
  Location: "/None"
}
{
  Buckets: [{
      CreationDate: 2021-09-29 07:25:21 +0000 UTC,
      Name: "my-bucket1212"
    }],
  Owner: {
    DisplayName: "webfile",
    ID: "bcaf1ffd86f41161ca5fb16fd081034f"
  }
}

PS: mybucket1212 是我使用 aws-cli 创建的存储桶

现在最简单的选择是在您的配置中设置 S3ForcePathStyle

S3ForcePathStyle: aws.Bool(true),

这就是 aws-cli 的做法。

但此选项正在 deprecated by AWS,即使没有设定日期。

我会尝试找到一种方法让它在没有这个选项的情况下工作并更新这个答案。