|
|
|
@ -15,15 +15,31 @@ |
|
|
|
|
# 3. You can empty the entire bucket by using '/' as the prefix. It will work, but this is |
|
|
|
|
# probably not the most efficient way to empty a whole bucket. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import botocore |
|
|
|
|
import boto3 |
|
|
|
|
import argparse |
|
|
|
|
import sys |
|
|
|
|
|
|
|
|
|
# a couple globals |
|
|
|
|
debug = False |
|
|
|
|
pageSize = 1000 # Will handle this many objects per API call. 1000 is AWS max. |
|
|
|
|
|
|
|
|
|
class initArgs(object): |
|
|
|
|
|
|
|
|
|
def __init__(self): |
|
|
|
|
self.parser = argparse.ArgumentParser() |
|
|
|
|
self.parser.add_argument( |
|
|
|
|
"--bucket", type=str, help="Bucket name", required=True) |
|
|
|
|
self.parser.add_argument( |
|
|
|
|
"--prefix", type=str, help="Prefix inside the bucket. Must end in /", required=True) |
|
|
|
|
self.parser.add_argument( |
|
|
|
|
"--pagesize", type=int, help="Number of objects to delete per run, max 1000. Default 1000.", |
|
|
|
|
default=1000, required=False) |
|
|
|
|
self.parser.add_argument( "--debug", action='store_true', help="don't actually do anything") |
|
|
|
|
self.args = self.parser.parse_args(sys.argv[1:]) |
|
|
|
|
|
|
|
|
|
# prefix must NOT start with a /, but MUST end with a slash: |
|
|
|
|
# "prefix/" = OK. "/prefix/" = BAD. "/prefix" = BAD. "prefix" = BAD. |
|
|
|
|
prefix = "myprefixname/" |
|
|
|
|
bucketname = "mybucketname" |
|
|
|
|
pageSize = 1000 # Will handle this many objects per API call. 1000 is AWS max. |
|
|
|
|
def get_args(self): |
|
|
|
|
return self.args |
|
|
|
|
|
|
|
|
|
def emptyFolder( bucketname: str, prefix: str): |
|
|
|
|
"""Given a bucket name and prefix, delete all objects in that bucket with |
|
|
|
@ -51,7 +67,8 @@ def emptyFolder( bucketname: str, prefix: str): |
|
|
|
|
page += 1 |
|
|
|
|
objectList = [{'Key': obj.get('Key')} for obj in s3Page.get('Contents', []) ] |
|
|
|
|
print( f"Deleting {len(objectList)} objects, page {page}") |
|
|
|
|
if objectList: |
|
|
|
|
# only delete if debug is false |
|
|
|
|
if objectList and (not debug): |
|
|
|
|
try: |
|
|
|
|
response = s3.delete_objects( Bucket=bucketname, |
|
|
|
|
Delete={ 'Objects': objectList } ) |
|
|
|
@ -63,4 +80,22 @@ def emptyFolder( bucketname: str, prefix: str): |
|
|
|
|
raise Exception("Unexpected HTTP response: " + |
|
|
|
|
response.get('ResponseMetadata')['HTTPStatusCode'] ) |
|
|
|
|
if __name__ == "__main__": |
|
|
|
|
emptyFolder(bucketname=bucketname, prefix=prefix) |
|
|
|
|
args = initArgs().get_args() |
|
|
|
|
pagesize=args.pagesize |
|
|
|
|
if( args.debug == True ): |
|
|
|
|
debug = True |
|
|
|
|
if( not args.prefix.endswith('/') ): |
|
|
|
|
print( f"ERROR: prefix doesn't end in a slash: \"{args.prefix}\"") |
|
|
|
|
exit(1) |
|
|
|
|
if( args.prefix.startswith('/') ): |
|
|
|
|
print( f"ERROR: prefix must NOT start with a slash: \"{args.prefix}\"") |
|
|
|
|
exit(1) |
|
|
|
|
if( (args.pagesize <= 0) or (args.pagesize > 1000) ): |
|
|
|
|
print( f"ERROR: pagesize must be > 0 and must be < 1000: pagesize=\"{args.pagesize}\"") |
|
|
|
|
exit(1) |
|
|
|
|
else: |
|
|
|
|
pageSize = args.pagesize |
|
|
|
|
if( args.prefix == "/" ): |
|
|
|
|
print( "WARNING: prefix is /. DELETING ALL OBJECTS" ) |
|
|
|
|
|
|
|
|
|
emptyFolder(bucketname=args.bucket, prefix=args.prefix) |