@ -107,9 +107,10 @@ EXAMPLES = '''
tags :
example : tag1
another : tag2
'''
import os
import xml . etree . ElementTree as ET
import urlparse
@ -126,16 +127,13 @@ except ImportError:
HAS_BOTO = False
def get_request_payment_status ( bucket ) :
response = bucket . get_request_payment ( )
root = ET . fromstring ( response )
for message in root . findall ( ' .// { http://s3.amazonaws.com/doc/2006-03-01/}Payer ' ) :
payer = message . text
if payer == " BucketOwner " :
return False
else :
return True
return ( payer != " BucketOwner " )
def create_tags_container ( tags ) :
@ -147,7 +145,7 @@ def create_tags_container(tags):
tags_obj . add_tag_set ( tag_set )
return tags_obj
def _create_ bucket( connection , module , location ) :
def _create_ or_update_ bucket( connection , module , location ) :
policy = module . params . get ( " policy " )
name = module . params . get ( " name " )
@ -155,7 +153,7 @@ def _create_bucket(connection, module, location):
tags = module . params . get ( " tags " )
versioning = module . params . get ( " versioning " )
changed = False
try :
bucket = connection . get_bucket ( name )
except S3ResponseError as e :
@ -164,42 +162,38 @@ def _create_bucket(connection, module, location):
changed = True
except S3CreateError as e :
module . fail_json ( msg = e . message )
# Versioning
versioning_status = bucket . get_versioning_status ( )
if not versioning_status and versioning :
try :
bucket . configure_versioning ( versioning )
changed = True
versioning_status = bucket . get_versioning_status ( )
except S3ResponseError as e :
module . fail_json ( msg = e . message )
elif not versioning_status and not versioning :
# do nothing
pass
else :
if versioning_status [ ' Versioning ' ] == " Enabled " and not versioning :
bucket . configure_versioning ( versioning )
changed = True
versioning_status = bucket . get_versioning_status ( )
elif ( ( versioning_status [ ' Versioning ' ] == " Disabled " and versioning ) or ( versioning_status [ ' Versioning ' ] == " Suspended " and versioning ) ) :
bucket . configure_versioning ( versioning )
changed = True
versioning_status = bucket . get_versioning_status ( )
if not versioning_status :
if versioning :
try :
bucket . configure_versioning ( versioning )
changed = True
versioning_status = bucket . get_versioning_status ( )
except S3ResponseError as e :
module . fail_json ( msg = e . message )
elif versioning_status [ ' Versioning ' ] == " Enabled " and not versioning :
bucket . configure_versioning ( versioning )
changed = True
versioning_status = bucket . get_versioning_status ( )
elif ( ( versioning_status [ ' Versioning ' ] == " Disabled " and versioning ) or ( versioning_status [ ' Versioning ' ] == " Suspended " and versioning ) ) :
bucket . configure_versioning ( versioning )
changed = True
versioning_status = bucket . get_versioning_status ( )
# Requester pays
requester_pays_status = get_request_payment_status ( bucket )
if requester_pays_status != requester_pays :
if requester_pays :
bucket . set_request_payment ( payer = ' Requester ' )
changed = True
requester_pays_status = get_request_payment_status ( bucket )
payer = ' Requester '
else :
bucket . set_request_payment ( payer = ' BucketOwner ' )
changed = True
requester_pays_status = get_request_payment_status ( bucket )
payer = ' BucketOwner '
bucket . set_request_payment ( payer = payer )
changed = True
requester_pays_status = get_request_payment_status ( bucket )
# Policy
# Policy
try :
current_policy = bucket . get_policy ( )
except S3ResponseError as e :
@ -207,30 +201,25 @@ def _create_bucket(connection, module, location):
current_policy = None
else :
module . fail_json ( msg = e . message )
if current_policy is not None and policy is not None :
if policy is not None :
policy = json . dumps ( policy )
if json . loads ( current_policy ) != json . loads ( policy ) :
if policy is not None :
# Deal with policy if either JSON formatted string or just data structure
if isinstance ( policy , basestring ) :
compare_policy = json . dumps ( policy )
load_policy = policy
else :
compare_policy = policy
load_policy = json . loads ( policy )
if current_policy is None or json . loads ( current_policy ) != compare_policy :
try :
bucket . set_policy ( policy )
bucket . set_policy ( load_ policy)
changed = True
current_policy = bucket . get_policy ( )
except S3ResponseError as e :
module . fail_json ( msg = e . message )
elif current_policy is not None :
elif current_policy is None and policy is not None :
policy = json . dumps ( policy )
try :
bucket . set_policy ( policy )
changed = True
current_policy = bucket . get_policy ( )
except S3ResponseError as e :
module . fail_json ( msg = e . message )
elif current_policy is not None and policy is None :
try :
bucket . delete_policy ( )
changed = True
@ -240,23 +229,17 @@ def _create_bucket(connection, module, location):
current_policy = None
else :
module . fail_json ( msg = e . message )
####
## Fix up json of policy so it's not escaped
####
# Tags
try :
current_tags = bucket . get_tags ( )
tag_set = TagSet ( )
except S3ResponseError as e :
if e . error_code == " NoSuchTagSet " :
current_tags = None
else :
module . fail_json ( msg = e . message )
if current_tags is not None or tags is not None :
if current_tags is None :
current_tags_dict = { }
else :
@ -274,13 +257,13 @@ def _create_bucket(connection, module, location):
module . fail_json ( msg = e . message )
module . exit_json ( changed = changed , name = bucket . name , versioning = versioning_status , requester_pays = requester_pays_status , policy = current_policy , tags = current_tags_dict )
def _destroy_bucket ( connection , module ) :
force = module . params . get ( " force " )
name = module . params . get ( " name " )
changed = False
try :
bucket = connection . get_bucket ( name )
except S3ResponseError as e :
@ -289,25 +272,26 @@ def _destroy_bucket(connection, module):
else :
# Bucket already absent
module . exit_json ( changed = changed )
if force :
try :
# Empty the bucket
for key in bucket . list ( ) :
key . delete ( )
except BotoServerError as e :
module . fail_json ( msg = e . message )
try :
bucket = connection . delete_bucket ( name )
changed = True
except S3ResponseError as e :
module . fail_json ( msg = e . message )
module . exit_json ( changed = changed )
def _create_bucket_ceph ( connection , module , location ) :
def _create_or_update_bucket_ceph ( connection , module , location ) :
#TODO: add update
name = module . params . get ( " name " )
@ -322,17 +306,20 @@ def _create_bucket_ceph(connection, module, location):
except S3CreateError as e :
module . fail_json ( msg = e . message )
module . exit_json ( changed = changed )
if bucket :
module . exit_json ( changed = changed )
else :
module . fail_json ( msg = ' Unable to create bucket, no error from the API ' )
def _destroy_bucket_ceph ( connection , module ) :
_destroy_bucket ( connection , module )
def create_ bucket( connection , module , location , flavour = ' aws ' ) :
def create_ or_update_ bucket( connection , module , location , flavour = ' aws ' ) :
if flavour == ' ceph ' :
_create_ bucket_ceph( connection , module , location )
_create_ or_update_ bucket_ceph( connection , module , location )
else :
_create_ bucket( connection , module , location )
_create_ or_update_ bucket( connection , module , location )
def destroy_bucket ( connection , module , flavour = ' aws ' ) :
if flavour == ' ceph ' :
@ -358,27 +345,27 @@ def is_walrus(s3_url):
return False
def main ( ) :
argument_spec = ec2_argument_spec ( )
argument_spec . update (
dict (
force = dict ( required = False , default = ' no ' , type = ' bool ' ) ,
policy = dict ( required = False , default = None ),
name = dict ( required = True ),
policy = dict ( required = False ),
name = dict ( required = True , type = ' str ' ),
requester_pays = dict ( default = ' no ' , type = ' bool ' ) ,
s3_url = dict ( aliases = [ ' S3_URL ' ] ),
state = dict ( default = ' present ' , choices = [ ' present ' , ' absent ' ] ) ,
s3_url = dict ( aliases = [ ' S3_URL ' ] , type = ' str ' ),
state = dict ( default = ' present ' , type = ' str ' , choices = [ ' present ' , ' absent ' ] ) ,
tags = dict ( required = None , default = { } , type = ' dict ' ) ,
versioning = dict ( default = ' no ' , type = ' bool ' ) ,
ceph = dict ( default = ' no ' , type = ' bool ' )
)
)
module = AnsibleModule ( argument_spec = argument_spec )
if not HAS_BOTO :
module . fail_json ( msg = ' boto required for this module ' )
region , ec2_url , aws_connect_params = get_aws_connection_info ( module )
if region in ( ' us-east-1 ' , ' ' , None ) :
@ -444,7 +431,7 @@ def main():
state = module . params . get ( " state " )
if state == ' present ' :
create_ bucket( connection , module , location , flavour = flavour )
create_ or_update_ bucket( connection , module , location )
elif state == ' absent ' :
destroy_bucket ( connection , module , flavour = flavour )