clipper/backend/cmd/s3-delete-all/main.go

87 lines
2.3 KiB
Go

package main
import (
"context"
"errors"
"flag"
"log"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/aws/smithy-go"
)
const cmdName = "s3-delete-all"
func main() {
var err error
ctx := context.Background()
cfg, err := config.LoadDefaultConfig(ctx)
if err != nil {
log.Fatal(err)
}
s3Client := s3.NewFromConfig(cfg)
var bucket string
flag.StringVar(&bucket, "bucket", "", "name of S3 bucket")
flag.Parse()
if bucket == "" {
log.Fatalf("usage: %s -bucket bucket", cmdName)
}
// Delete S3 objects
listObjectsInput := s3.ListObjectsV2Input{Bucket: aws.String(bucket), MaxKeys: 10_000}
listObjectsOutput, err := s3Client.ListObjectsV2(ctx, &listObjectsInput)
if err != nil {
log.Fatal(err)
}
for _, object := range listObjectsOutput.Contents {
deleteObjectInput := s3.DeleteObjectInput{Bucket: aws.String(bucket), Key: object.Key}
_, err = s3Client.DeleteObject(ctx, &deleteObjectInput)
if err != nil {
log.Fatal(err)
}
log.Printf("Deleted object %s", *object.Key)
}
// Delete S3 uploads and parts
listUploadsInput := s3.ListMultipartUploadsInput{Bucket: aws.String(bucket)}
listUploadsOutput, err := s3Client.ListMultipartUploads(ctx, &listUploadsInput)
if err != nil {
log.Fatal(err)
}
if listObjectsOutput.IsTruncated {
log.Fatal("TODO: handle IsTruncated")
}
for _, upload := range listUploadsOutput.Uploads {
abortUploadInput := s3.AbortMultipartUploadInput{Bucket: aws.String(bucket), Key: upload.Key, UploadId: upload.UploadId}
_, err := s3Client.AbortMultipartUpload(ctx, &abortUploadInput)
if err != nil {
log.Fatal(err)
}
listPartsInput := s3.ListPartsInput{Bucket: aws.String(bucket), Key: upload.Key, UploadId: upload.UploadId}
listPartsOutput, err := s3Client.ListParts(ctx, &listPartsInput)
if err != nil {
var ae smithy.APIError
if errors.As(err, &ae) && ae.ErrorCode() == "NoSuchUpload" {
log.Printf("Ignoring upload not found (id = %s)", *upload.UploadId)
continue
}
log.Fatal(err)
}
if len(listPartsOutput.Parts) > 0 {
log.Fatalf("some parts remain for key %s, upload %s (count = %d)", *upload.UploadId, *upload.Key, len(listPartsOutput.Parts))
}
log.Printf("Aborted upload %s", *upload.UploadId)
}
}