plugins/modules/ali_oss_object.py (326 lines of code) (raw):

#!/usr/bin/python # Copyright (c) 2017-present Alibaba Group Holding Limited. <xiaozhu36> # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} DOCUMENTATION = ''' --- module: ali_oss_object version_added: "1.5.0" short_description: Manage object in OSS description: - This module allows the user to manage OSS objects within bucket. Includes support for uploading and downloading objects, retrieving object keys. options: mode: description: - Switches the module behaviour between put (upload), get (download), list (list objects) and delete (delete object). required: true choices: ['get', 'put', 'delete', 'list'] bucket: description: - Bucket name. required: true permission: description: - This option lets the user set the canned permissions on the objects that are put. The permissions that can be set are 'private', 'public-read', 'public-read-write'. default: 'private' choices: [ 'private', 'public-read', 'public-read-write' ] aliases: [ 'acl' ] headers: description: - Custom headers for PUT or GET operation, as a dictionary of 'key=value' and 'key=value,key=value'. overwrite: description: - Force overwrite specified object content when putting object. If it is true/false, object will be normal/appendable. Appendable Object can be convert to Noraml by setting overwrite to true, but conversely, it won't be work. default: False type: bool content: description: - The object content that will be upload. It is conflict with 'file_name' when mode is 'put'. file_name: description: - The name of file that used to upload or download object. aliases: [ "file" ] object: description: - Name to object after uploaded to bucket required: true aliases: [ 'key', 'object_name' ] byte_range: description: - The range of object content that would be download. Its format like 1-100 that indicates range from one to hundred bytes of object. aliases: [ 'range' ] requirements: - "python >= 2.6" - "footmark >= 1.1.16" extends_documentation_fragment: - alibaba.alicloud.alicloud author: - "He Guimin (@xiaozhu36)" ''' EXAMPLES = ''' # basic provisioning example to upload a content - name: simple upload to bucket hosts: localhost connection: local vars: alicloud_access_key: <your-alicloud-access-key-id> alicloud_secret_key: <your-alicloud-access-secret-key> alicloud_region: cn-hangzhou mode: put bucket: bucketname content: 'Hello world! I come from alicloud.' object: 'remote_file.txt' headers: Content-Type: 'text/html' Content-Encoding: md5 tasks: - name: simple upload to bucket alibaba.alicloud.ali_oss_object: alicloud_access_key: '{{ alicloud_access_key }}' alicloud_secret_key: '{{ alicloud_secret_key }}' alicloud_region: '{{ alicloud_region }}' mode: '{{ mode }}' bucket: '{{ bucket }}' content: '{{ content }}' headers: '{{ headers }}' register: result - debug: var=result # basic provisioning example to upload a file - name: simple upload to bucket hosts: localhost connection: local vars: alicloud_access_key: <your-alicloud-access-key-id> alicloud_secret_key: <your-alicloud-access-secret-key> alicloud_region: cn-hangzhou mode: put bucket: bucketname file_name: 'test_oss.yml' object: 'remote_file.txt' headers: Content-Type: 'text/html' Content-Encoding: md5 tasks: - name: simple upload to bucket alibaba.alicloud.ali_oss_object: alicloud_access_key: '{{ alicloud_access_key }}' alicloud_secret_key: '{{ alicloud_secret_key }}' alicloud_region: '{{ alicloud_region }}' mode: '{{ mode }}' file_name: '{{ file_name }}' content: '{{ content }}' headers: '{{ headers }}' register: result - debug: var=result # basic provisioning example to download a object - name: simple upload to bucket hosts: localhost connection: local vars: alicloud_access_key: <your-alicloud-access-key-id> alicloud_secret_key: <your-alicloud-access-secret-key> alicloud_region: cn-hangzhou mode: get bucket: bucketname download: 'my_test.json' byte_range: 0-100 object: 'remote_file.txt' headers: Content-Type: 'text/html' Content-Encoding: md5 tasks: - name: simple upload to bucket alibaba.alicloud.ali_oss_object: alicloud_access_key: '{{ alicloud_access_key }}' alicloud_secret_key: '{{ alicloud_secret_key }}' alicloud_region: '{{ alicloud_region }}' mode: '{{ mode }}' file_name: '{{ download }}' byte_range: '{{ byte_range }}' content: '{{ content }}' headers: '{{ headers }}' register: result - debug: var=result # basic provisioning example to list bucket objects - name: list bucket objects hosts: localhost connection: local vars: alicloud_access_key: <your-alicloud-access-key-id> alicloud_secret_key: <your-alicloud-access-secret-key> alicloud_region: cn-hangzhou mode: list bucket: bucketname tasks: - name: list bucket objects alibaba.alicloud.ali_oss_object: alicloud_access_key: '{{ alicloud_access_key }}' alicloud_secret_key: '{{ alicloud_secret_key }}' alicloud_region: '{{ alicloud_region }}' mode: '{{ mode }}' bucket: '{{ bucket }}' register: list_result - debug: var=list_result # basic provisioning example to delete bucket object - name: delete bucket objects hosts: localhost connection: local vars: alicloud_access_key: <your-alicloud-access-key-id> alicloud_secret_key: <your-alicloud-access-secret-key> alicloud_region: cn-hangzhou mode: delete bucket: bucketname object: 'remote_file.txt' tasks: - name: delete bucket objects alibaba.alicloud.ali_oss_object: alicloud_access_key: '{{ alicloud_access_key }}' alicloud_secret_key: '{{ alicloud_secret_key }}' alicloud_region: '{{ alicloud_region }}' mode: '{{ mode }}' bucket: '{{ bucket }}' object: '{{ object }}' register: delete_object_result - debug: var=delete_object_result ''' RETURN = ''' changed: description: current operation whether changed the resource returned: when success type: bool sample: true key: description: the name of oss object returned: expect list type: bool sample: true object: description: the object's information returned: on put or get type: dict sample: { "etag": "A57B09D4A76BCF486DDD755900000000", "key": "newobject-2", "last_modified": "2017-07-24 19:43:41", "next_append_position": 11, "size": "11 B", "storage_class": "Standard", "type": "Appendable" } objects: description: the list all objects that has the prefix of 'object' value in the specified bucket returned: when list type: list sample: [ { "etag": "54739B1D5AEBFD38C83356D8A8A3EDFC", "key": "newobject-1", "last_modified": "2017-07-24 19:42:46", "size": "2788 B", "storage_class": "Standard", "type": "Normal" }, { "etag": "EB8BDADA044D58D58CDE755900000000", "key": "newobject-2", "last_modified": "2017-07-24 19:48:28", "next_append_position": 5569, "size": "5569 B", "storage_class": "Standard", "type": "Appendable" } ] ''' # import module snippets from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.alicloud_oss import oss_bucket_argument_spec, oss_bucket_connect import time HAS_FOOTMARK = False try: from footmark.exception import ECSResponseError, OSSResponseError HAS_FOOTMARK = True except ImportError: HAS_FOOTMARK = False def get_object_info(obj): result = {'key': obj.key, 'last_modified': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(obj.last_modified)), 'etag': obj.etag, 'type': obj.type, 'size': str(obj.size) + ' B', 'storage_class': obj.storage_class} if obj.type == 'Appendable': result['next_append_position'] = obj.size return result def main(): argument_spec = oss_bucket_argument_spec() argument_spec.update(dict( bucket=dict(type='str', required=True), mode=dict(type='str', required=True, choices=['put', 'get', 'list', 'delete']), permission=dict(type='str', default='private', choices=['private', 'public-read', 'public-read-write']), headers=dict(type='dict'), overwrite=dict(type='bool', default=False), content=dict(type='str'), file_name=dict(type='str', aliases=['file']), object=dict(type='str', aliases=['key', 'object_name']), byte_range=dict(type='str', aliases=['range']) ) ) module = AnsibleModule(argument_spec=argument_spec) if HAS_FOOTMARK is False: module.fail_json(msg="Package 'footmark' required for the module ali_oss_object.") oss_bucket = oss_bucket_connect(module) mode = module.params['mode'] file_name = module.params['file_name'] object_key = module.params['object'] headers = module.params['headers'] changed = False if mode == 'put': content = module.params['content'] if content and file_name: module.fail_json(msg="'content' and 'file_name' only one can be specified when mode is put.") overwrite = module.params['overwrite'] permission = module.params['permission'] try: if content: oss_bucket.put_object(object_key, content, overwrite, headers=headers) changed = True elif file_name: oss_bucket.put_object_from_file(object_key, file_name, overwrite, headers=headers) changed = True elif oss_bucket.is_object_exist(object_key): if permission: oss_bucket.put_object_acl(object_key, permission) changed = True if headers: oss_bucket.update_object_headers(object_key, headers) changed = True module.exit_json(changed=changed, key=object_key, object=get_object_info(oss_bucket.get_object_info(object_key))) except Exception as e: module.fail_json(msg="Unable to upload an object {0} or " "modify its permission and headers, and got an error: {1}".format(object_key, e)) elif mode == 'get': byte_range = module.params['byte_range'] try: if file_name: oss_bucket.get_object_to_file(object_key, file_name, byte_range=byte_range, headers=headers) else: module.fail_json(msg="'file_name' must be specified when mode is get.") module.exit_json(changed=changed, key=object_key, object=get_object_info(oss_bucket.get_object_info(object_key))) except Exception as e: module.fail_json(msg="Unable to download object {0}, and got an error: {1}".format(object_key, e)) elif mode == 'list': objects = [] max_keys = 500 try: while True: results = oss_bucket.list_objects(prefix=object_key, max_keys=max_keys) for obj in results: objects.append(get_object_info(obj)) if len(results) < max_keys: break module.exit_json(changed=False, objects=objects) except Exception as e: module.fail_json(msg="Unable to retrieve all objects, and got an error: {0}".format(e)) else: try: oss_bucket.delete_object(object_key) module.exit_json(changed=changed, key=object_key) except Exception as e: module.fail_json(msg="Unable to delete an object {0}, and got an error: {1}".format(object_key, e)) if __name__ == '__main__': main()