如何使用AWS SDK for Go v2删除一个非空的S3存储桶

huangapple go评论92阅读模式
英文:

How to delete a non-empty S3 bucket using AWS SDK for Go v2

问题

您好!根据您的要求,我将为您翻译以下内容:

我正在使用 AWS SDK v2,并且我需要删除一个包含对象的存储桶。如何以最佳方式进行删除?是否有一种强制删除的方法?或者是否有一种可以删除存储桶内所有对象的方法?

英文:

I'm using AWS sdk v2

and I need to delete a bucket that had objects

what's the best way to do so? is there something to force delete? or that deleted all the objects inside a bucket?

答案1

得分: 4

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进行批量调用,以减少请求开销。

英文:

The AWS documentation Deleting a bucket describes how to delete a bucket that has objects. The documentation also provides an SDK example (written in Java, but mainly serves as a guideline) that performs the following steps:

  • Delete all objects
  • Delete all object versions (for versioned buckets)
  • Finally delete bucket

There is no "force delete" option for non-empty buckets. You would need to implement the above steps.

The following sample code shows how to completely delete a non-empty bucket:

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)
}
}

You should probably optimize this further and use DeleteObjects for batch calls in order to reduce request overhead.

huangapple
  • 本文由 发表于 2021年6月21日 15:56:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/68064306.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定