Skip to content

Commit

Permalink
Add pagination to force delete bucket containing objects
Browse files Browse the repository at this point in the history
  • Loading branch information
zliang-akamai committed Jul 31, 2024
1 parent 80c54a7 commit 32aa751
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 16 deletions.
3 changes: 2 additions & 1 deletion linodecli/plugins/obj/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,8 @@ def get_client():
COMMAND_MAP[parsed.command](
get_client, args, suppress_warnings=parsed.suppress_warnings
)
except ClientError:
except ClientError as e:
print(e)
sys.exit(ExitCodes.REQUEST_FAILED)
elif parsed.command == "regenerate-keys":
regenerate_s3_credentials(
Expand Down
17 changes: 2 additions & 15 deletions linodecli/plugins/obj/buckets.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from linodecli.exit_codes import ExitCodes
from linodecli.plugins import inherit_plugin_args
from linodecli.plugins.obj.config import PLUGIN_BASE
from linodecli.plugins.obj.helpers import _delete_all_objects


def create_bucket(
Expand Down Expand Up @@ -61,23 +62,9 @@ def delete_bucket(
bucket_name = parsed.name

if parsed.recursive:
objects = [
{"Key": obj.get("Key")}
for obj in client.list_objects_v2(Bucket=bucket_name).get(
"Contents", []
)
if obj.get("Key")
]
client.delete_objects(
Bucket=bucket_name,
Delete={
"Objects": objects,
"Quiet": False,
},
)
_delete_all_objects(client, bucket_name)

client.delete_bucket(Bucket=bucket_name)

print(f"Bucket {parsed.name} removed")

sys.exit(ExitCodes.SUCCESS)
47 changes: 47 additions & 0 deletions linodecli/plugins/obj/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,50 @@ def flip_to_page(iterable: Iterable, page: int = 1):
sys.exit(ExitCodes.REQUEST_FAILED)

return next(iterable)


def _get_objects_for_deletion_from_page(object_type, page, versioned=False):
return [
(
{"Key": obj["Key"], "VersionId": obj["VersionId"]}
if versioned
else {"Key": obj["Key"]}
)
for obj in page.get(object_type, [])
]


def _delete_all_objects(client, bucket_name):
pages = client.get_paginator("list_objects_v2").paginate(
Bucket=bucket_name, PaginationConfig={"PageSize": 1000}
)
for page in pages:
client.delete_objects(
Bucket=bucket_name,
Delete={
"Objects": _get_objects_for_deletion_from_page(
"Contents", page
),
"Quiet": False,
},
)

for page in client.get_paginator("list_object_versions").paginate(
Bucket=bucket_name, PaginationConfig={"PageSize": 1000}
):
client.delete_objects(
Bucket=bucket_name,
Delete={
"Objects": _get_objects_for_deletion_from_page(
"Versions", page, True
)
},
)
client.delete_objects(
Bucket=bucket_name,
Delete={
"Objects": _get_objects_for_deletion_from_page(
"DeleteMarkers", page, True
)
},
)

0 comments on commit 32aa751

Please sign in to comment.