Merge branch 'rb2' of https://github.com/bpennypacker/ansible into bpennypacker-rb2
This commit is contained in:
commit
7d69d1e289
2 changed files with 22 additions and 485 deletions
|
@ -60,6 +60,12 @@ options:
|
||||||
- The AWS region to use. If not specified then the value of the EC2_REGION environment variable, if any, is used.
|
- The AWS region to use. If not specified then the value of the EC2_REGION environment variable, if any, is used.
|
||||||
required: false
|
required: false
|
||||||
aliases: ['aws_region', 'ec2_region']
|
aliases: ['aws_region', 'ec2_region']
|
||||||
|
wait:
|
||||||
|
description:
|
||||||
|
- Wait for instance registration or deregistration to complete successfully before returning.
|
||||||
|
required: false
|
||||||
|
default: yes
|
||||||
|
choices: [ "yes", "no" ]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -124,20 +130,22 @@ class ElbManager:
|
||||||
else:
|
else:
|
||||||
self.changed = False
|
self.changed = False
|
||||||
|
|
||||||
def deregister(self):
|
def deregister(self, wait):
|
||||||
"""De-register the instance from all ELBs and wait for the ELB
|
"""De-register the instance from all ELBs and wait for the ELB
|
||||||
to report it out-of-service"""
|
to report it out-of-service"""
|
||||||
|
|
||||||
for lb in self.lbs:
|
for lb in self.lbs:
|
||||||
lb.deregister_instances([self.instance_id])
|
lb.deregister_instances([self.instance_id])
|
||||||
|
if wait:
|
||||||
self._await_elb_instance_state(lb, 'OutOfService')
|
self._await_elb_instance_state(lb, 'OutOfService')
|
||||||
|
|
||||||
def register(self):
|
def register(self, wait):
|
||||||
"""Register the instance for all ELBs and wait for the ELB
|
"""Register the instance for all ELBs and wait for the ELB
|
||||||
to report the instance in-service"""
|
to report the instance in-service"""
|
||||||
|
|
||||||
for lb in self.lbs:
|
for lb in self.lbs:
|
||||||
lb.register_instances([self.instance_id])
|
lb.register_instances([self.instance_id])
|
||||||
|
if wait:
|
||||||
self._await_elb_instance_state(lb, 'InService')
|
self._await_elb_instance_state(lb, 'InService')
|
||||||
|
|
||||||
def exists(self, lbtest):
|
def exists(self, lbtest):
|
||||||
|
@ -196,10 +204,11 @@ def main():
|
||||||
state={'required': True,
|
state={'required': True,
|
||||||
'choices': ['present', 'absent']},
|
'choices': ['present', 'absent']},
|
||||||
instance_id={'required': True},
|
instance_id={'required': True},
|
||||||
ec2_elbs={'default': None, 'required': False},
|
ec2_elbs={'default': None, 'required': False, 'type':'list'},
|
||||||
aws_secret_key={'default': None, 'aliases': ['ec2_secret_key', 'secret_key'], 'no_log': True},
|
aws_secret_key={'default': None, 'aliases': ['ec2_secret_key', 'secret_key'], 'no_log': True},
|
||||||
aws_access_key={'default': None, 'aliases': ['ec2_access_key', 'access_key']},
|
aws_access_key={'default': None, 'aliases': ['ec2_access_key', 'access_key']},
|
||||||
region={'default': None, 'required': False, 'aliases':['aws_region', 'ec2_region'], 'choices':AWS_REGIONS}
|
region={'default': None, 'required': False, 'aliases':['aws_region', 'ec2_region'], 'choices':AWS_REGIONS},
|
||||||
|
wait={'required': False, 'choices': BOOLEANS, 'default': True}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -207,6 +216,7 @@ def main():
|
||||||
aws_access_key = module.params['aws_access_key']
|
aws_access_key = module.params['aws_access_key']
|
||||||
ec2_elbs = module.params['ec2_elbs']
|
ec2_elbs = module.params['ec2_elbs']
|
||||||
region = module.params['region']
|
region = module.params['region']
|
||||||
|
wait = module.params['wait']
|
||||||
|
|
||||||
if module.params['state'] == 'present' and 'ec2_elbs' not in module.params:
|
if module.params['state'] == 'present' and 'ec2_elbs' not in module.params:
|
||||||
module.fail_json(msg="ELBs are required for registration")
|
module.fail_json(msg="ELBs are required for registration")
|
||||||
|
@ -230,21 +240,21 @@ def main():
|
||||||
region = os.environ['EC2_REGION']
|
region = os.environ['EC2_REGION']
|
||||||
|
|
||||||
if not region:
|
if not region:
|
||||||
module.fail_json(msg = str("Either region or EC2_REGION environment variable must be set."))
|
module.fail_json(msg=str("Either region or EC2_REGION environment variable must be set."))
|
||||||
|
|
||||||
instance_id = module.params['instance_id']
|
instance_id = module.params['instance_id']
|
||||||
elb_man = ElbManager(module, instance_id, ec2_elbs, aws_access_key,
|
elb_man = ElbManager(module, instance_id, ec2_elbs, aws_access_key,
|
||||||
aws_secret_key, region=region)
|
aws_secret_key, region=region)
|
||||||
|
|
||||||
for elb in [ ec2_elbs ]:
|
for elb in ec2_elbs:
|
||||||
if not elb_man.exists(elb):
|
if not elb_man.exists(elb):
|
||||||
str="ELB %s does not exist" % elb
|
msg="ELB %s does not exist" % elb
|
||||||
module.fail_json(msg=str)
|
module.fail_json(msg=msg)
|
||||||
|
|
||||||
if module.params['state'] == 'present':
|
if module.params['state'] == 'present':
|
||||||
elb_man.register()
|
elb_man.register(wait)
|
||||||
elif module.params['state'] == 'absent':
|
elif module.params['state'] == 'absent':
|
||||||
elb_man.deregister()
|
elb_man.deregister(wait)
|
||||||
|
|
||||||
ansible_facts = {'ec2_elbs': [lb.name for lb in elb_man.lbs]}
|
ansible_facts = {'ec2_elbs': [lb.name for lb in elb_man.lbs]}
|
||||||
ec2_facts_result = dict(changed=elb_man.changed, ansible_facts=ansible_facts)
|
ec2_facts_result = dict(changed=elb_man.changed, ansible_facts=ansible_facts)
|
||||||
|
|
|
@ -1,473 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
# This file is part of Ansible
|
|
||||||
#
|
|
||||||
# Ansible is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# Ansible is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
|
||||||
---
|
|
||||||
module: s3
|
|
||||||
short_description: idempotent S3 module putting a file into S3.
|
|
||||||
description:
|
|
||||||
- This module allows the user to dictate the presence of a given file in an S3 bucket. If or once the key (file) exists in the bucket, it returns a time-expired download URL. This module has a dependency on python-boto.
|
|
||||||
version_added: "1.1"
|
|
||||||
options:
|
|
||||||
bucket:
|
|
||||||
description:
|
|
||||||
- Bucket name.
|
|
||||||
required: true
|
|
||||||
default: null
|
|
||||||
aliases: []
|
|
||||||
object:
|
|
||||||
description:
|
|
||||||
- Keyname of the object inside the bucket. Can be used to create "virtual directories", see examples.
|
|
||||||
required: false
|
|
||||||
default: null
|
|
||||||
aliases: []
|
|
||||||
version_added: "1.3"
|
|
||||||
src:
|
|
||||||
description:
|
|
||||||
- The source file path when performing a PUT operation.
|
|
||||||
required: false
|
|
||||||
default: null
|
|
||||||
aliases: []
|
|
||||||
version_added: "1.3"
|
|
||||||
dest:
|
|
||||||
description:
|
|
||||||
- The destination file path when downloading an object/key with a GET operation.
|
|
||||||
required: false
|
|
||||||
default: 600
|
|
||||||
aliases: []
|
|
||||||
version_added: "1.3"
|
|
||||||
overwrite:
|
|
||||||
description:
|
|
||||||
- Force overwrite either locally on the filesystem or remotely with the object/key. Used with PUT and GET operations.
|
|
||||||
required: false
|
|
||||||
default: false
|
|
||||||
version_added: "1.2"
|
|
||||||
mode:
|
|
||||||
description:
|
|
||||||
- Switches the module behaviour between put (upload), get (download), geturl (return download url (Ansible 1.3+), getstr (download object as string (1.3+)), create (bucket) and delete (bucket).
|
|
||||||
required: true
|
|
||||||
default: null
|
|
||||||
aliases: []
|
|
||||||
expiry:
|
|
||||||
description:
|
|
||||||
- Time limit (in seconds) for the URL generated and returned by S3/Walrus when performing a mode=put or mode=geturl operation.
|
|
||||||
required: false
|
|
||||||
default: null
|
|
||||||
aliases: []
|
|
||||||
s3_url:
|
|
||||||
description:
|
|
||||||
- S3 URL endpoint. If not specified then the S3_URL environment variable is used, if that variable is defined.
|
|
||||||
default: null
|
|
||||||
aliases: [ S3_URL ]
|
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
|
|
||||||
>>>>>>> yet another rebase attempt
|
|
||||||
aws_secret_key:
|
|
||||||
description:
|
|
||||||
- AWS secret key. If not set then the value of the AWS_SECRET_KEY environment variable is used.
|
|
||||||
required: false
|
|
||||||
default: null
|
|
||||||
aliases: ['ec2_secret_key', 'secret_key']
|
|
||||||
aws_access_key:
|
|
||||||
description:
|
|
||||||
- AWS access key. If not set then the value of the AWS_ACCESS_KEY environment variable is used.
|
|
||||||
required: false
|
|
||||||
default: null
|
|
||||||
aliases: [ 'ec2_access_key', 'access_key' ]
|
|
||||||
requirements: [ "boto" ]
|
|
||||||
author: Lester Wade, Ralph Tice
|
|
||||||
'''
|
|
||||||
|
|
||||||
EXAMPLES = '''
|
|
||||||
# Simple PUT operation
|
|
||||||
- s3: bucket=mybucket object=/my/desired/key.txt src=/usr/local/myfile.txt mode=put
|
|
||||||
# Simple GET operation
|
|
||||||
- s3: bucket=mybucket object=/my/desired/key.txt dest=/usr/local/myfile.txt mode=get
|
|
||||||
# GET/download and overwrite local file (trust remote)
|
|
||||||
- s3: bucket=mybucket object=/my/desired/key.txt dest=/usr/local/myfile.txt mode=get overwrite=true
|
|
||||||
# PUT/upload and overwrite remote file (trust local)
|
|
||||||
- s3: bucket=mybucket object=/my/desired/key.txt src=/usr/local/myfile.txt mode=put overwrite=true
|
|
||||||
# Download an object as a string to use else where in your playbook
|
|
||||||
- s3: bucket=mybucket object=/my/desired/key.txt src=/usr/local/myfile.txt mode=getstr
|
|
||||||
# Create an empty bucket
|
|
||||||
- s3: bucket=mybucket mode=create
|
|
||||||
# Create a bucket with key as directory
|
|
||||||
- s3: bucket=mybucket object=/my/directory/path mode=create
|
|
||||||
# Delete a bucket and all contents
|
|
||||||
- s3: bucket=mybucket mode=delete
|
|
||||||
'''
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import urlparse
|
|
||||||
import hashlib
|
|
||||||
|
|
||||||
try:
|
|
||||||
import boto
|
|
||||||
except ImportError:
|
|
||||||
print "failed=True msg='boto required for this module'"
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def key_check(module, s3, bucket, obj):
|
|
||||||
try:
|
|
||||||
bucket = s3.lookup(bucket)
|
|
||||||
key_check = bucket.get_key(obj)
|
|
||||||
except s3.provider.storage_response_error, e:
|
|
||||||
module.fail_json(msg= str(e))
|
|
||||||
if key_check:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def keysum(module, s3, bucket, obj):
|
|
||||||
bucket = s3.lookup(bucket)
|
|
||||||
key_check = bucket.get_key(obj)
|
|
||||||
if key_check:
|
|
||||||
md5_remote = key_check.etag[1:-1]
|
|
||||||
etag_multipart = md5_remote.find('-')!=-1 #Check for multipart, etag is not md5
|
|
||||||
if etag_multipart is True:
|
|
||||||
module.fail_json(msg="Files uploaded with multipart of s3 are not supported with checksum, unable to compute checksum.")
|
|
||||||
sys.exit(0)
|
|
||||||
return md5_remote
|
|
||||||
|
|
||||||
def bucket_check(module, s3, bucket):
|
|
||||||
try:
|
|
||||||
result = s3.lookup(bucket)
|
|
||||||
except s3.provider.storage_response_error, e:
|
|
||||||
module.fail_json(msg= str(e))
|
|
||||||
if result:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def create_bucket(module, s3, bucket):
|
|
||||||
try:
|
|
||||||
bucket = s3.create_bucket(bucket)
|
|
||||||
except s3.provider.storage_response_error, e:
|
|
||||||
module.fail_json(msg= str(e))
|
|
||||||
if bucket:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def delete_bucket(module, s3, bucket):
|
|
||||||
try:
|
|
||||||
bucket = s3.lookup(bucket)
|
|
||||||
bucket_contents = bucket.list()
|
|
||||||
bucket.delete_keys([key.name for key in bucket_contents])
|
|
||||||
bucket.delete()
|
|
||||||
return True
|
|
||||||
except s3.provider.storage_response_error, e:
|
|
||||||
module.fail_json(msg= str(e))
|
|
||||||
|
|
||||||
def delete_key(module, s3, bucket, obj):
|
|
||||||
try:
|
|
||||||
bucket = s3.lookup(bucket)
|
|
||||||
bucket.delete_key(obj)
|
|
||||||
module.exit_json(msg="Object deleted from bucket %s"%bucket, changed=True)
|
|
||||||
except s3.provider.storage_response_error, e:
|
|
||||||
module.fail_json(msg= str(e))
|
|
||||||
|
|
||||||
def create_dirkey(module, s3, bucket, obj):
|
|
||||||
try:
|
|
||||||
bucket = s3.lookup(bucket)
|
|
||||||
key = bucket.new_key(obj)
|
|
||||||
key.set_contents_from_string('')
|
|
||||||
module.exit_json(msg="Virtual directory %s created in bucket %s" % (obj, bucket.name), changed=True)
|
|
||||||
except s3.provider.storage_response_error, e:
|
|
||||||
module.fail_json(msg= str(e))
|
|
||||||
|
|
||||||
def upload_file_check(src):
|
|
||||||
if os.path.exists(src):
|
|
||||||
file_exists is True
|
|
||||||
else:
|
|
||||||
file_exists is False
|
|
||||||
if os.path.isdir(src):
|
|
||||||
module.fail_json(msg="Specifying a directory is not a valid source for upload.", failed=True)
|
|
||||||
sys.exit(0)
|
|
||||||
return file_exists
|
|
||||||
|
|
||||||
def path_check(path):
|
|
||||||
if os.path.exists(path):
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def upload_s3file(module, s3, bucket, obj, src, expiry):
|
|
||||||
try:
|
|
||||||
bucket = s3.lookup(bucket)
|
|
||||||
key = bucket.new_key(obj)
|
|
||||||
key.set_contents_from_filename(src)
|
|
||||||
url = key.generate_url(expiry)
|
|
||||||
module.exit_json(msg="PUT operation complete", url=url, changed=True)
|
|
||||||
sys.exit(0)
|
|
||||||
except s3.provider.storage_copy_error, e:
|
|
||||||
module.fail_json(msg= str(e))
|
|
||||||
|
|
||||||
def download_s3file(module, s3, bucket, obj, dest):
|
|
||||||
try:
|
|
||||||
bucket = s3.lookup(bucket)
|
|
||||||
key = bucket.lookup(obj)
|
|
||||||
key.get_contents_to_filename(dest)
|
|
||||||
module.exit_json(msg="GET operation complete", changed=True)
|
|
||||||
sys.exit(0)
|
|
||||||
except s3.provider.storage_copy_error, e:
|
|
||||||
module.fail_json(msg= str(e))
|
|
||||||
|
|
||||||
def download_s3str(module, s3, bucket, obj):
|
|
||||||
try:
|
|
||||||
bucket = s3.lookup(bucket)
|
|
||||||
key = bucket.lookup(obj)
|
|
||||||
contents = key.get_contents_as_string()
|
|
||||||
module.exit_json(msg="GET operation complete", contents=contents, changed=True)
|
|
||||||
sys.exit(0)
|
|
||||||
except s3.provider.storage_copy_error, e:
|
|
||||||
module.fail_json(msg= str(e))
|
|
||||||
|
|
||||||
def get_download_url(module, s3, bucket, obj, expiry):
|
|
||||||
try:
|
|
||||||
bucket = s3.lookup(bucket)
|
|
||||||
key = bucket.lookup(obj)
|
|
||||||
url = key.generate_url(expiry)
|
|
||||||
module.exit_json(msg="Download url:", url=url, expiry=expiry, changed=True)
|
|
||||||
sys.exit(0)
|
|
||||||
except s3.provider.storage_response_error, e:
|
|
||||||
module.fail_json(msg= str(e))
|
|
||||||
|
|
||||||
def main():
|
|
||||||
module = AnsibleModule(
|
|
||||||
argument_spec = dict(
|
|
||||||
bucket = dict(required=True),
|
|
||||||
object = dict(),
|
|
||||||
src = dict(),
|
|
||||||
dest = dict(),
|
|
||||||
mode = dict(choices=['get', 'put', 'delete', 'create', 'geturl', 'getstr'], required=True),
|
|
||||||
expiry = dict(default=600, aliases=['expiration']),
|
|
||||||
s3_url = dict(aliases=['S3_URL']),
|
|
||||||
aws_secret_key = dict(aliases=['ec2_secret_key', 'secret_key'], no_log=True, required=False),
|
|
||||||
aws_access_key = dict(aliases=['ec2_access_key', 'access_key'], required=False),
|
|
||||||
overwrite = dict(default=False, type='bool'),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
bucket = module.params.get('bucket')
|
|
||||||
obj = module.params.get('object')
|
|
||||||
src = module.params.get('src')
|
|
||||||
dest = module.params.get('dest')
|
|
||||||
mode = module.params.get('mode')
|
|
||||||
expiry = int(module.params['expiry'])
|
|
||||||
s3_url = module.params.get('s3_url')
|
|
||||||
aws_secret_key = module.params.get('aws_secret_key')
|
|
||||||
aws_access_key = module.params.get('aws_access_key')
|
|
||||||
overwrite = module.params.get('overwrite')
|
|
||||||
|
|
||||||
if module.params.get('object'):
|
|
||||||
obj = os.path.expanduser(module.params['object'])
|
|
||||||
|
|
||||||
# allow eucarc environment variables to be used if ansible vars aren't set
|
|
||||||
if not s3_url and 'S3_URL' in os.environ:
|
|
||||||
s3_url = os.environ['S3_URL']
|
|
||||||
|
|
||||||
if not aws_secret_key:
|
|
||||||
if 'AWS_SECRET_KEY' in os.environ:
|
|
||||||
aws_secret_key = os.environ['AWS_SECRET_KEY']
|
|
||||||
elif 'EC2_SECRET_KEY' in os.environ:
|
|
||||||
aws_secret_key = os.environ['EC2_SECRET_KEY']
|
|
||||||
|
|
||||||
if not aws_access_key:
|
|
||||||
if 'AWS_ACCESS_KEY' in os.environ:
|
|
||||||
aws_access_key = os.environ['AWS_ACCESS_KEY']
|
|
||||||
elif 'EC2_ACCESS_KEY' in os.environ:
|
|
||||||
aws_access_key = os.environ['EC2_ACCESS_KEY']
|
|
||||||
|
|
||||||
# If we have an S3_URL env var set, this is likely to be Walrus, so change connection method
|
|
||||||
if 'S3_URL' in os.environ:
|
|
||||||
try:
|
|
||||||
walrus = urlparse.urlparse(s3_url).hostname
|
|
||||||
s3 = boto.connect_walrus(walrus, aws_access_key, aws_secret_key)
|
|
||||||
except boto.exception.NoAuthHandlerFound, e:
|
|
||||||
module.fail_json(msg = str(e))
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
s3 = boto.connect_s3(aws_access_key, aws_secret_key)
|
|
||||||
except boto.exception.NoAuthHandlerFound, e:
|
|
||||||
module.fail_json(msg = str(e))
|
|
||||||
|
|
||||||
# If our mode is a GET operation (download), go through the procedure as appropriate ...
|
|
||||||
if mode == 'get':
|
|
||||||
|
|
||||||
# First, we check to see if the bucket exists, we get "bucket" returned.
|
|
||||||
bucketrtn = bucket_check(module, s3, bucket)
|
|
||||||
if bucketrtn is False:
|
|
||||||
module.fail_json(msg="Target bucket cannot be found", failed=True)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
# Next, we check to see if the key in the bucket exists. If it exists, it also returns key_matches md5sum check.
|
|
||||||
keyrtn = key_check(module, s3, bucket, obj)
|
|
||||||
if keyrtn is False:
|
|
||||||
module.fail_json(msg="Target key cannot be found", failed=True)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
# If the destination path doesn't exist, no need to md5um etag check, so just download.
|
|
||||||
pathrtn = path_check(dest)
|
|
||||||
if pathrtn is False:
|
|
||||||
download_s3file(module, s3, bucket, obj, dest)
|
|
||||||
|
|
||||||
# Compare the remote MD5 sum of the object with the local dest md5sum, if it already exists.
|
|
||||||
if pathrtn is True:
|
|
||||||
md5_remote = keysum(module, s3, bucket, obj)
|
|
||||||
md5_local = hashlib.md5(open(dest, 'rb').read()).hexdigest()
|
|
||||||
if md5_local == md5_remote:
|
|
||||||
sum_matches = True
|
|
||||||
if overwrite is True:
|
|
||||||
download_s3file(module, s3, bucket, obj, dest)
|
|
||||||
else:
|
|
||||||
module.exit_json(msg="Local and remote object are identical, ignoring. Use overwrite parameter to force.", changed=False)
|
|
||||||
else:
|
|
||||||
sum_matches = False
|
|
||||||
if overwrite is True:
|
|
||||||
download_s3file(module, s3, bucket, obj, dest)
|
|
||||||
else:
|
|
||||||
module.fail_json(msg="WARNING: Checksums do not match. Use overwrite parameter to force download.", failed=True)
|
|
||||||
|
|
||||||
# If destination file doesn't already exist we can go ahead and download.
|
|
||||||
if pathrtn is False:
|
|
||||||
download_s3file(module, s3, bucket, obj, dest)
|
|
||||||
|
|
||||||
# Firstly, if key_matches is TRUE and overwrite is not enabled, we EXIT with a helpful message.
|
|
||||||
if sum_matches is True and overwrite is False:
|
|
||||||
module.exit_json(msg="Local and remote object are identical, ignoring. Use overwrite parameter to force.", changed=False)
|
|
||||||
|
|
||||||
# At this point explicitly define the overwrite condition.
|
|
||||||
if sum_matches is True and pathrtn is True and overwrite is True:
|
|
||||||
download_s3file(module, s3, bucket, obj, dest)
|
|
||||||
|
|
||||||
# If sum does not match but the destination exists, we
|
|
||||||
|
|
||||||
# if our mode is a PUT operation (upload), go through the procedure as appropriate ...
|
|
||||||
if mode == 'put':
|
|
||||||
|
|
||||||
# Use this snippet to debug through conditionals:
|
|
||||||
# module.exit_json(msg="Bucket return %s"%bucketrtn)
|
|
||||||
# sys.exit(0)
|
|
||||||
|
|
||||||
# Lets check the src path.
|
|
||||||
pathrtn = path_check(src)
|
|
||||||
if pathrtn is False:
|
|
||||||
module.fail_json(msg="Local object for PUT does not exist", failed=True)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
# Lets check to see if bucket exists to get ground truth.
|
|
||||||
bucketrtn = bucket_check(module, s3, bucket)
|
|
||||||
keyrtn = key_check(module, s3, bucket, obj)
|
|
||||||
|
|
||||||
# Lets check key state. Does it exist and if it does, compute the etag md5sum.
|
|
||||||
if bucketrtn is True and keyrtn is True:
|
|
||||||
md5_remote = keysum(module, s3, bucket, obj)
|
|
||||||
md5_local = hashlib.md5(open(src, 'rb').read()).hexdigest()
|
|
||||||
if md5_local == md5_remote:
|
|
||||||
sum_matches = True
|
|
||||||
if overwrite is True:
|
|
||||||
upload_s3file(module, s3, bucket, obj, src, expiry)
|
|
||||||
else:
|
|
||||||
module.exit_json(msg="Local and remote object are identical, ignoring. Use overwrite parameter to force.", changed=False)
|
|
||||||
else:
|
|
||||||
sum_matches = False
|
|
||||||
if overwrite is True:
|
|
||||||
upload_s3file(module, s3, bucket, obj, src, expiry)
|
|
||||||
else:
|
|
||||||
module.exit_json(msg="WARNING: Checksums do not match. Use overwrite parameter to force upload.", failed=True)
|
|
||||||
|
|
||||||
# If neither exist (based on bucket existence), we can create both.
|
|
||||||
if bucketrtn is False and pathrtn is True:
|
|
||||||
create_bucket(module, s3, bucket)
|
|
||||||
upload_s3file(module, s3, bucket, obj, src, expiry)
|
|
||||||
|
|
||||||
# If bucket exists but key doesn't, just upload.
|
|
||||||
if bucketrtn is True and pathrtn is True and keyrtn is False:
|
|
||||||
upload_s3file(module, s3, bucket, obj, src, expiry)
|
|
||||||
|
|
||||||
# Support for deleting an object if we have both params.
|
|
||||||
if mode == 'delete':
|
|
||||||
if bucket:
|
|
||||||
bucketrtn = bucket_check(module, s3, bucket)
|
|
||||||
if bucketrtn is True:
|
|
||||||
deletertn = delete_bucket(module, s3, bucket)
|
|
||||||
if deletertn is True:
|
|
||||||
module.exit_json(msg="Bucket %s and all keys have been deleted."%bucket, changed=True)
|
|
||||||
else:
|
|
||||||
module.fail_json(msg="Bucket does not exist.", failed=True)
|
|
||||||
else:
|
|
||||||
module.fail_json(msg="Bucket parameter is required.", failed=True)
|
|
||||||
|
|
||||||
# Need to research how to create directories without "populating" a key, so this should just do bucket creation for now.
|
|
||||||
# WE SHOULD ENABLE SOME WAY OF CREATING AN EMPTY KEY TO CREATE "DIRECTORY" STRUCTURE, AWS CONSOLE DOES THIS.
|
|
||||||
if mode == 'create':
|
|
||||||
if bucket and not obj:
|
|
||||||
bucketrtn = bucket_check(module, s3, bucket)
|
|
||||||
if bucketrtn is True:
|
|
||||||
module.exit_json(msg="Bucket already exists.", changed=False)
|
|
||||||
else:
|
|
||||||
created = create_bucket(module, s3, bucket)
|
|
||||||
if bucket and obj:
|
|
||||||
bucketrtn = bucket_check(module, s3, bucket)
|
|
||||||
if obj.endswith('/'):
|
|
||||||
dirobj = obj
|
|
||||||
else:
|
|
||||||
dirobj = obj + "/"
|
|
||||||
if bucketrtn is True:
|
|
||||||
keyrtn = key_check(module, s3, bucket, dirobj)
|
|
||||||
if keyrtn is True:
|
|
||||||
module.exit_json(msg="Bucket %s and key %s already exists."% (bucket, obj), changed=False)
|
|
||||||
else:
|
|
||||||
create_dirkey(module, s3, bucket, dirobj)
|
|
||||||
if bucketrtn is False:
|
|
||||||
created = create_bucket(module, s3, bucket)
|
|
||||||
create_dirkey(module, s3, bucket, dirobj)
|
|
||||||
|
|
||||||
# Support for grabbing the time-expired URL for an object in S3/Walrus.
|
|
||||||
if mode == 'geturl':
|
|
||||||
if bucket and obj:
|
|
||||||
bucketrtn = bucket_check(module, s3, bucket)
|
|
||||||
if bucketrtn is False:
|
|
||||||
module.fail_json(msg="Bucket %s does not exist."%bucket, failed=True)
|
|
||||||
else:
|
|
||||||
keyrtn = key_check(module, s3, bucket, obj)
|
|
||||||
if keyrtn is True:
|
|
||||||
get_download_url(module, s3, bucket, obj, expiry)
|
|
||||||
else:
|
|
||||||
module.fail_json(msg="Key %s does not exist."%obj, failed=True)
|
|
||||||
else:
|
|
||||||
module.fail_json(msg="Bucket and Object parameters must be set", failed=True)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
if mode == 'getstr':
|
|
||||||
if bucket and obj:
|
|
||||||
bucketrtn = bucket_check(module, s3, bucket)
|
|
||||||
if bucketrtn is False:
|
|
||||||
module.fail_json(msg="Bucket %s does not exist."%bucket, failed=True)
|
|
||||||
else:
|
|
||||||
keyrtn = key_check(module, s3, bucket, obj)
|
|
||||||
if keyrtn is True:
|
|
||||||
download_s3str(module, s3, bucket, obj)
|
|
||||||
else:
|
|
||||||
module.fail_json(msg="Key %s does not exist."%obj, failed=True)
|
|
||||||
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
# this is magic, see lib/ansible/module_common.py
|
|
||||||
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
|
|
||||||
|
|
||||||
main()
|
|
Loading…
Reference in a new issue