diff --git a/cloud/cloudstack/cs_template.py b/cloud/cloudstack/cs_template.py index dc043425ded..753a22abc82 100644 --- a/cloud/cloudstack/cs_template.py +++ b/cloud/cloudstack/cs_template.py @@ -23,7 +23,7 @@ DOCUMENTATION = ''' module: cs_template short_description: Manages templates on Apache CloudStack based clouds. description: - - Register a template from URL, create a template from a ROOT volume of a stopped VM or its snapshot and delete templates. + - Register a template from URL, create a template from a ROOT volume of a stopped VM or its snapshot, extract and delete templates. version_added: '2.0' author: "René Moser (@resmo)" options: @@ -33,7 +33,8 @@ options: required: true url: description: - - URL of where the template is hosted. + - URL of where the template is hosted on C(state=present). + - URL to which the template would be extracted on C(state=extracted). - Mutually exclusive with C(vm). required: false default: null @@ -174,7 +175,7 @@ options: - State of the template. required: false default: 'present' - choices: [ 'present', 'absent' ] + choices: [ 'present', 'absent', 'extacted' ] poll_async: description: - Poll async jobs until job has finished. @@ -314,6 +315,21 @@ hypervisor: returned: success type: string sample: VMware +mode: + description: Mode of extraction + returned: success + type: string + sample: http_download +state: + description: State of the extracted template + returned: success + type: string + sample: DOWNLOAD_URL_CREATED +url: + description: Url to which the template is extracted to + returned: success + type: string + sample: "http://1.2.3.4/userdata/eb307f13-4aca-45e8-b157-a414a14e6b04.ova" tags: description: List of resource tags associated with the template. returned: success @@ -370,6 +386,9 @@ class AnsibleCloudStackTemplate(AnsibleCloudStack): 'ispublic': 'is_public', 'format': 'format', 'hypervisor': 'hypervisor', + 'url': 'url', + 'extractMode': 'mode', + 'state': 'state', } @@ -506,6 +525,34 @@ class AnsibleCloudStackTemplate(AnsibleCloudStack): return None + def extract_template(self): + template = self.get_template() + if not template: + self.module.fail_json(msg="Failed: template not found") + + args = {} + args['id'] = template['id'] + args['url'] = self.module.params.get('url') + args['mode'] = self.module.params.get('mode') + args['zoneid'] = self.get_zone(key='id') + + if not args['url']: + self.module.fail_json(msg="Missing required arguments: url") + + self.result['changed'] = True + + if not self.module.check_mode: + template = self.cs.extractTemplate(**args) + + if 'errortext' in template: + self.module.fail_json(msg="Failed: '%s'" % template['errortext']) + + poll_async = self.module.params.get('poll_async') + if poll_async: + template = self._poll_job(template, 'template') + return template + + def remove_template(self): template = self.get_template() if template: @@ -553,8 +600,9 @@ def main(): format = dict(choices=['QCOW2', 'RAW', 'VHD', 'OVA'], default=None), details = dict(default=None), bits = dict(type='int', choices=[ 32, 64 ], default=64), - state = dict(choices=['present', 'absent'], default='present'), + state = dict(choices=['present', 'absent', 'extracted'], default='present'), cross_zones = dict(type='bool', default=False), + mode = dict(choices=['http_download', 'ftp_upload'], default='http_download'), zone = dict(default=None), domain = dict(default=None), account = dict(default=None), @@ -585,6 +633,10 @@ def main(): state = module.params.get('state') if state in ['absent']: tpl = acs_tpl.remove_template() + + elif state in ['extracted']: + tpl = acs_tpl.extract_template() + else: if module.params.get('url'): tpl = acs_tpl.register_template()