[cloud] s3: deleting a nonexistent bucket should not give a traceback Fixes #25445 (#25487)

* trying to delete a nonexistent bucket should not fail

* Improve error handling for deleting s3 bucket

* Allow successful deletion

* Add test for deleting a nonexistent bucket

rename integration test target from s3 to aws_s3
This commit is contained in:
Sloane Hertel 2017-06-12 13:52:25 -04:00 committed by Ryan Brown
parent 7521be73c1
commit 3f0c47196e
5 changed files with 36 additions and 4 deletions

View file

@ -350,13 +350,32 @@ def delete_bucket(module, s3, bucket):
if module.check_mode: if module.check_mode:
module.exit_json(msg="DELETE operation skipped - running in check mode", changed=True) module.exit_json(msg="DELETE operation skipped - running in check mode", changed=True)
try: try:
bucket = s3.lookup(bucket) bucket = s3.lookup(bucket, validate=False)
bucket_contents = bucket.list() bucket_contents = bucket.list()
bucket.delete_keys([key.name for key in bucket_contents]) bucket.delete_keys([key.name for key in bucket_contents])
except s3.provider.storage_response_error as e:
if e.status == 404:
# bucket doesn't appear to exist
return False
elif e.status == 403:
# bucket appears to exist but user doesn't have list bucket permission; may still be able to delete bucket
pass
else:
module.fail_json(msg=str(e), exception=traceback.format_exc())
try:
bucket.delete() bucket.delete()
return True return True
except s3.provider.storage_response_error as e: except s3.provider.storage_response_error as e:
module.fail_json(msg= str(e)) if e.status == 403:
module.exit_json(msg="Unable to complete DELETE operation. Check you have have s3:DeleteBucket "
"permission. Error: {0}.".format(e.message),
exception=traceback.format_exc())
elif e.status == 409:
module.exit_json(msg="Unable to complete DELETE operation. It appears there are contents in the "
"bucket that you don't have permission to delete. Error: {0}.".format(e.message),
exception=traceback.format_exc())
else:
module.fail_json(msg=str(e), exception=traceback.format_exc())
def delete_key(module, s3, bucket, obj, validate=True): def delete_key(module, s3, bucket, obj, validate=True):
if module.check_mode: if module.check_mode:
@ -676,8 +695,8 @@ def main():
if mode == 'delete': if mode == 'delete':
if bucket: if bucket:
deletertn = delete_bucket(module, s3, bucket) deletertn = delete_bucket(module, s3, bucket)
if deletertn is True: message = "Bucket {0} and all keys have been deleted.".format(bucket)
module.exit_json(msg="Bucket %s and all keys have been deleted."%bucket, changed=True) module.exit_json(msg=message, changed=deletertn)
else: else:
module.fail_json(msg="Bucket parameter is required.") module.fail_json(msg="Bucket parameter is required.")

View file

@ -215,3 +215,16 @@
that: that:
- result.changed == True - result.changed == True
# ============================================================ # ============================================================
- name: test delete a nonexistent bucket
s3:
bucket: "{{ bucket.stdout + '.bucket' }}"
mode: delete
security_token: "{{security_token}}"
aws_access_key: "{{ ec2_access_key }}"
aws_secret_key: "{{ ec2_secret_key }}"
register: result
- name: assert that changed is False
assert:
that:
- result.changed == False
# ============================================================