首页 > 解决方案 > 如何使用适用于 Go v2 的 AWS 开发工具包删除非空 S3 存储桶

问题描述

我正在使用 AWS sdk v2

我需要删除一个有对象的桶

最好的方法是什么?有什么东西可以强制删除吗?还是删除了存储桶中的所有对象?

标签: amazon-web-servicesgoamazon-s3aws-sdk-go

解决方案


AWS 文档删除存储桶描述了如何删除包含对象的存储桶。该文档还提供了一个 SDK 示例(用 Java 编写,但主要用作指南),该示例执行以下步骤:

  • 删除所有对象
  • 删除所有对象版本(对于版本化存储桶)
  • 最后删除桶

非空存储桶没有“强制删除”选项。您需要执行上述步骤。

以下示例代码展示了如何完全删除非空存储桶:

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("us-east-1"))
    if err != nil {
        log.Fatalf("Failed to load config: %v", err)
    }

    bucket := aws.String("your-bucket-name")
    client := s3.NewFromConfig(cfg)

    deleteObject := func(bucket, key, versionId *string) {
        log.Printf("Object: %s/%s\n", *key, aws.ToString(versionId))
        _, err := client.DeleteObject(context.TODO(), &s3.DeleteObjectInput{
            Bucket:    bucket,
            Key:       key,
            VersionId: versionId,
        })
        if err != nil {
            log.Fatalf("Failed to delete object: %v", err)
        }
    }

    in := &s3.ListObjectsV2Input{Bucket: bucket}
    for {
        out, err := client.ListObjectsV2(context.TODO(), in)
        if err != nil {
            log.Fatalf("Failed to list objects: %v", err)
        }

        for _, item := range out.Contents {
            deleteObject(bucket, item.Key, nil)
        }

        if out.IsTruncated {
            in.ContinuationToken = out.ContinuationToken
        } else {
            break
        }
    }

    inVer := &s3.ListObjectVersionsInput{Bucket: bucket}
    for {
        out, err := client.ListObjectVersions(context.TODO(), inVer)
        if err != nil {
            log.Fatalf("Failed to list version objects: %v", err)
        }

        for _, item := range out.DeleteMarkers {
            deleteObject(bucket, item.Key, item.VersionId)
        }

        for _, item := range out.Versions {
            deleteObject(bucket, item.Key, item.VersionId)
        }

        if out.IsTruncated {
            inVer.VersionIdMarker = out.NextVersionIdMarker
            inVer.KeyMarker = out.NextKeyMarker
        } else {
            break
        }
    }

    _, err = client.DeleteBucket(context.TODO(), &s3.DeleteBucketInput{Bucket: bucket})
    if err != nil {
        log.Fatalf("Failed to delete bucket: %v", err)
    }
}

您可能应该进一步优化它并DeleteObjects用于批处理调用以减少请求开销。


推荐阅读