From 1c082e93ef50cffc9833884b79f0c8a80c9dd0de Mon Sep 17 00:00:00 2001 From: Ryan Brown Date: Mon, 30 Jul 2018 11:22:00 -0400 Subject: [PATCH] [aws] Catch errors raised when deleting objects remaining in an s3_bucket (#43358) * Catch errors raised when deleting objects remaining in a bucket * Also remove VersionId when it is not needed --- lib/ansible/modules/cloud/amazon/s3_bucket.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/ansible/modules/cloud/amazon/s3_bucket.py b/lib/ansible/modules/cloud/amazon/s3_bucket.py index 4b18d88a37b..584d4b55551 100644 --- a/lib/ansible/modules/cloud/amazon/s3_bucket.py +++ b/lib/ansible/modules/cloud/amazon/s3_bucket.py @@ -444,8 +444,23 @@ def destroy_bucket(s3_client, module): try: for key_version_pairs in paginated_versions_list(s3_client, Bucket=name): formatted_keys = [{'Key': key, 'VersionId': version} for key, version in key_version_pairs] + for fk in formatted_keys: + # remove VersionId from cases where they are `None` so that + # unversioned objects are deleted using `DeleteObject` + # rather than `DeleteObjectVersion`, improving backwards + # compatibility with older IAM policies. + if not fk.get('VersionId'): + fk.pop('VersionId') + if formatted_keys: - s3_client.delete_objects(Bucket=name, Delete={'Objects': formatted_keys}) + resp = s3_client.delete_objects(Bucket=name, Delete={'Objects': formatted_keys}) + if resp.get('Errors'): + module.fail_json( + msg='Could not empty bucket before deleting. Could not delete objects: {0}'.format( + ', '.join([k['Key'] for k in resp['Errors']]) + ), + errors=resp['Errors'], response=resp + ) except (BotoCoreError, ClientError) as e: module.fail_json_aws(e, msg="Failed while deleting bucket")