diff --git a/lib/ansible/modules/cloud/cloudstack/cs_template.py b/lib/ansible/modules/cloud/cloudstack/cs_template.py index 825b14ba5b4..dc4abe73d4a 100644 --- a/lib/ansible/modules/cloud/cloudstack/cs_template.py +++ b/lib/ansible/modules/cloud/cloudstack/cs_template.py @@ -41,182 +41,141 @@ options: - 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 vm: description: - VM name the template will be created from its volume or alternatively from a snapshot. - VM must be in stopped state if created from its volume. - Mutually exclusive with C(url). - required: false - default: null snapshot: description: - Name of the snapshot, created from the VM ROOT volume, the template will be created from. - C(vm) is required together with this argument. - required: false - default: null os_type: description: - OS type that best represents the OS of this template. - required: false - default: null checksum: description: - The MD5 checksum value of this template. - If set, we search by checksum instead of name. - required: false default: false is_ready: description: - This flag is used for searching existing templates. - If set to C(true), it will only list template ready for deployment e.g. successfully downloaded and installed. - Recommended to set it to C(false). - required: false default: false is_public: description: - Register the template to be publicly available to all users. - Only used if C(state) is present. - required: false default: false is_featured: description: - Register the template to be featured. - Only used if C(state) is present. - required: false default: false is_dynamically_scalable: description: - Register the template having XS/VMWare tools installed in order to support dynamic scaling of VM CPU/memory. - Only used if C(state) is present. - required: false default: false cross_zones: description: - Whether the template should be synced or removed across zones. - Only used if C(state) is present or absent. - required: false default: false mode: description: - Mode for the template extraction. - Only used if C(state=extracted). required: false - default: 'http_download' - choices: [ 'http_download', 'ftp_upload' ] + default: http_download + choices: [ http_download, ftp_upload ] domain: description: - Domain the template, snapshot or VM is related to. - required: false - default: null account: description: - Account the template, snapshot or VM is related to. - required: false - default: null project: description: - Name of the project the template to be registered in. - required: false - default: null zone: description: - Name of the zone you wish the template to be registered or deleted from. - If not specified, first found zone will be used. - required: false - default: null template_filter: description: - Name of the filter used to search for the template. required: false - default: 'self' - choices: [ 'featured', 'self', 'selfexecutable', 'sharedexecutable', 'executable', 'community' ] + default: self + choices: [ featured, self, selfexecutable, sharedexecutable, executable, community ] hypervisor: description: - Name the hypervisor to be used for creating the new template. - Relevant when using C(state=present). - required: false - default: null - choices: [ 'KVM', 'VMware', 'BareMetal', 'XenServer', 'LXC', 'HyperV', 'UCS', 'OVM' ] + choices: [ KVM, VMware, BareMetal, XenServer, LXC, HyperV, UCS, OVM, Simulator ] requires_hvm: description: - true if this template requires HVM. - required: false default: false password_enabled: description: - True if the template supports the password reset feature. - required: false default: false template_tag: description: - the tag for this template. - required: false - default: null sshkey_enabled: description: - True if the template supports the sshkey upload feature. - required: false default: false is_routing: description: - True if the template type is routing i.e., if template is used to deploy router. - Only considered if C(url) is used. - required: false - default: null format: description: - The format for the template. - Relevant when using C(state=present). - required: false - default: null - choices: [ 'QCOW2', 'RAW', 'VHD', 'OVA' ] + choices: [ QCOW2, RAW, VHD, OVA ] is_extractable: description: - True if the template or its derivatives are extractable. - required: false default: false details: description: - Template details in key/value pairs. - required: false - default: null bits: description: - 32 or 64 bits support. required: false - default: '64' + default: 64 display_text: description: - Display text of the template. - required: false - default: null state: description: - State of the template. required: false - default: 'present' - choices: [ 'present', 'absent', 'extacted' ] + default: present + choices: [ present, absent, extracted ] poll_async: description: - Poll async jobs until job has finished. - required: false default: true tags: description: - List of tags. Tags are a list of dictionaries having keys C(key) and C(value). - "To delete all tags, set a empty list e.g. C(tags: [])." - required: false - default: null - aliases: [ 'tag' ] + aliases: [ tag ] version_added: "2.4" extends_documentation_fragment: cloudstack ''' EXAMPLES = ''' -# Register a systemvm template -- local_action: +- name: register a systemvm template + local_action: module: cs_template name: systemvm-vmware-4.5 url: "http://packages.shapeblue.com/systemvmtemplate/4.5/systemvm64template-4.5-vmware.ova" @@ -225,8 +184,8 @@ EXAMPLES = ''' cross_zones: yes os_type: Debian GNU/Linux 7(64-bit) -# Create a template from a stopped virtual machine's volume -- local_action: +- name: create a template from a stopped virtual machine's volume + local_action: module: cs_template name: debian-base-template vm: debian-base-vm @@ -235,8 +194,8 @@ EXAMPLES = ''' password_enabled: yes is_public: yes -# Create a template from a virtual machine's root volume snapshot -- local_action: +- name: create a template from a virtual machine's root volume snapshot + local_action: module: cs_template name: debian-base-template vm: debian-base-vm @@ -246,8 +205,8 @@ EXAMPLES = ''' password_enabled: yes is_public: yes -# Remove a template -- local_action: +- name: Remove a template + local_action: module: cs_template name: systemvm-4.2 cross_zones: yes @@ -388,8 +347,13 @@ project: sample: Production ''' -# import cloudstack common -from ansible.module_utils.cloudstack import * +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.cloudstack import ( + AnsibleCloudStack, + cs_argument_spec, + cs_required_together, + CS_HYPERVISORS +) class AnsibleCloudStackTemplate(AnsibleCloudStack): @@ -397,78 +361,76 @@ class AnsibleCloudStackTemplate(AnsibleCloudStack): def __init__(self, module): super(AnsibleCloudStackTemplate, self).__init__(module) self.returns = { - 'checksum': 'checksum', - 'status': 'status', - 'isready': 'is_ready', - 'templatetag': 'template_tag', - 'sshkeyenabled': 'sshkey_enabled', - 'passwordenabled': 'password_enabled', - 'tempaltetype': 'template_type', - 'ostypename': 'os_type', - 'crossZones': 'cross_zones', - 'isextractable': 'is_extractable', - 'isfeatured': 'is_featured', - 'ispublic': 'is_public', - 'format': 'format', - 'hypervisor': 'hypervisor', - 'url': 'url', - 'extractMode': 'mode', - 'state': 'state', + 'checksum': 'checksum', + 'status': 'status', + 'isready': 'is_ready', + 'templatetag': 'template_tag', + 'sshkeyenabled': 'sshkey_enabled', + 'passwordenabled': 'password_enabled', + 'tempaltetype': 'template_type', + 'ostypename': 'os_type', + 'crossZones': 'cross_zones', + 'isextractable': 'is_extractable', + 'isfeatured': 'is_featured', + 'ispublic': 'is_public', + 'format': 'format', + 'hypervisor': 'hypervisor', + 'url': 'url', + 'extractMode': 'mode', + 'state': 'state', } - def _get_args(self): - args = {} - args['name'] = self.module.params.get('name') - args['displaytext'] = self.get_or_fallback('display_text', 'name') - args['bits'] = self.module.params.get('bits') - args['isdynamicallyscalable'] = self.module.params.get('is_dynamically_scalable') - args['isextractable'] = self.module.params.get('is_extractable') - args['isfeatured'] = self.module.params.get('is_featured') - args['ispublic'] = self.module.params.get('is_public') - args['passwordenabled'] = self.module.params.get('password_enabled') - args['requireshvm'] = self.module.params.get('requires_hvm') - args['templatetag'] = self.module.params.get('template_tag') - args['ostypeid'] = self.get_os_type(key='id') + args = { + 'name': self.module.params.get('name'), + 'displaytext': self.get_or_fallback('display_text', 'name'), + 'bits': self.module.params.get('bits'), + 'isdynamicallyscalable': self.module.params.get('is_dynamically_scalable'), + 'isextractable': self.module.params.get('is_extractable'), + 'isfeatured': self.module.params.get('is_featured'), + 'ispublic': self.module.params.get('is_public'), + 'passwordenabled': self.module.params.get('password_enabled'), + 'requireshvm': self.module.params.get('requires_hvm'), + 'templatetag': self.module.params.get('template_tag'), + 'ostypeid': self.get_os_type(key='id'), + } if not args['ostypeid']: self.module.fail_json(msg="Missing required arguments: os_type") return args - def get_root_volume(self, key=None): - args = {} - args['account'] = self.get_account(key='name') - args['domainid'] = self.get_domain(key='id') - args['projectid'] = self.get_project(key='id') - args['virtualmachineid'] = self.get_vm(key='id') - args['type'] = "ROOT" - - volumes = self.cs.listVolumes(**args) + args = { + 'account': self.get_account(key='name'), + 'domainid': self.get_domain(key='id'), + 'projectid': self.get_project(key='id'), + 'virtualmachineid': self.get_vm(key='id'), + 'type': "ROOT" + } + volumes = self.query_api('listVolumes', **args) if volumes: return self._get_by_key(key, volumes['volume'][0]) self.module.fail_json(msg="Root volume for '%s' not found" % self.get_vm('name')) - def get_snapshot(self, key=None): snapshot = self.module.params.get('snapshot') if not snapshot: return None - args = {} - args['account'] = self.get_account(key='name') - args['domainid'] = self.get_domain(key='id') - args['projectid'] = self.get_project(key='id') - args['volumeid'] = self.get_root_volume('id') - snapshots = self.cs.listSnapshots(**args) + args = { + 'account': self.get_account(key='name'), + 'domainid': self.get_domain(key='id'), + 'projectid': self.get_project(key='id'), + 'volumeid': self.get_root_volume('id') + } + snapshots = self.query_api('listSnapshots', **args) if snapshots: for s in snapshots['snapshot']: - if snapshot in [ s['name'], s['id'] ]: + if snapshot in [s['name'], s['id']]: return self._get_by_key(key, s) self.module.fail_json(msg="Snapshot '%s' not found" % snapshot) - def create_template(self): template = self.get_template() if not template: @@ -479,13 +441,10 @@ class AnsibleCloudStackTemplate(AnsibleCloudStack): if snapshot_id: args['snapshotid'] = snapshot_id else: - args['volumeid'] = self.get_root_volume('id') + args['volumeid'] = self.get_root_volume('id') if not self.module.check_mode: - template = self.cs.createTemplate(**args) - - if 'errortext' in template: - self.module.fail_json(msg="Failed: '%s'" % template['errortext']) + template = self.query_api('createTemplate', **args) poll_async = self.module.params.get('poll_async') if poll_async: @@ -495,7 +454,6 @@ class AnsibleCloudStackTemplate(AnsibleCloudStack): return template - def register_template(self): required_params = [ 'format', @@ -506,17 +464,19 @@ class AnsibleCloudStackTemplate(AnsibleCloudStack): template = self.get_template() if not template: self.result['changed'] = True - args = self._get_args() - args['url'] = self.module.params.get('url') - args['format'] = self.module.params.get('format') - args['checksum'] = self.module.params.get('checksum') - args['isextractable'] = self.module.params.get('is_extractable') - args['isrouting'] = self.module.params.get('is_routing') - args['sshkeyenabled'] = self.module.params.get('sshkey_enabled') - args['hypervisor'] = self.get_hypervisor() - args['domainid'] = self.get_domain(key='id') - args['account'] = self.get_account(key='name') - args['projectid'] = self.get_project(key='id') + args = self._get_args() + args.update({ + 'url': self.module.params.get('url'), + 'format': self.module.params.get('format'), + 'checksum': self.module.params.get('checksum'), + 'isextractable': self.module.params.get('is_extractable'), + 'isrouting': self.module.params.get('is_routing'), + 'sshkeyenabled': self.module.params.get('sshkey_enabled'), + 'hypervisor': self.get_hypervisor(), + 'domainid': self.get_domain(key='id'), + 'account': self.get_account(key='name'), + 'projectid': self.get_project(key='id'), + }) if not self.module.params.get('cross_zones'): args['zoneid'] = self.get_zone(key='id') @@ -524,21 +484,18 @@ class AnsibleCloudStackTemplate(AnsibleCloudStack): args['zoneid'] = -1 if not self.module.check_mode: - res = self.cs.registerTemplate(**args) - if 'errortext' in res: - self.module.fail_json(msg="Failed: '%s'" % res['errortext']) + res = self.query_api('registerTemplate', **args) template = res['template'] return template - def get_template(self): - args = {} - args['isready'] = self.module.params.get('is_ready') - args['templatefilter'] = self.module.params.get('template_filter') - args['domainid'] = self.get_domain(key='id') - args['account'] = self.get_account(key='name') - args['projectid'] = self.get_project(key='id') - + args = { + 'isready': self.module.params.get('is_ready'), + 'templatefilter': self.module.params.get('template_filter'), + 'domainid': self.get_domain(key='id'), + 'account': self.get_account(key='name'), + 'projectid': self.get_project(key='id') + } if not self.module.params.get('cross_zones'): args['zoneid'] = self.get_zone(key='id') @@ -547,7 +504,7 @@ class AnsibleCloudStackTemplate(AnsibleCloudStack): if not checksum: args['name'] = self.module.params.get('name') - templates = self.cs.listTemplates(**args) + templates = self.query_api('listTemplates', **args) if templates: # if checksum is set, we only look on that. if not checksum: @@ -558,48 +515,40 @@ class AnsibleCloudStackTemplate(AnsibleCloudStack): return i 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') - + args = { + 'id': template['id'], + 'url': self.module.params.get('url'), + 'mode': self.module.params.get('mode'), + 'zoneid': self.get_zone(key='id') + } 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']) + template = self.query_api('extractTemplate', **args) 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: self.result['changed'] = True - args = {} - args['id'] = template['id'] - + args = { + 'id': template['id'] + } if not self.module.params.get('cross_zones'): - args['zoneid'] = self.get_zone(key='id') + args['zoneid'] = self.get_zone(key='id') if not self.module.check_mode: - res = self.cs.deleteTemplate(**args) - - if 'errortext' in res: - self.module.fail_json(msg="Failed: '%s'" % res['errortext']) + res = self.query_api('deleteTemplate', **args) poll_async = self.module.params.get('poll_async') if poll_async: @@ -607,79 +556,73 @@ class AnsibleCloudStackTemplate(AnsibleCloudStack): return template - def main(): argument_spec = cs_argument_spec() argument_spec.update(dict( - name = dict(required=True), - display_text = dict(default=None), - url = dict(default=None), - vm = dict(default=None), - snapshot = dict(default=None), - os_type = dict(default=None), - is_ready = dict(type='bool', default=False), - is_public = dict(type='bool', default=True), - is_featured = dict(type='bool', default=False), - is_dynamically_scalable = dict(type='bool', default=False), - is_extractable = dict(type='bool', default=False), - is_routing = dict(type='bool', default=None), - checksum = dict(default=None), - template_filter = dict(default='self', choices=['featured', 'self', 'selfexecutable', 'sharedexecutable', 'executable', 'community']), - hypervisor = dict(choices=CS_HYPERVISORS, default=None), - requires_hvm = dict(type='bool', default=False), - password_enabled = dict(type='bool', default=False), - template_tag = dict(default=None), - sshkey_enabled = dict(type='bool', default=False), - 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', '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), - project = dict(default=None), - poll_async = dict(type='bool', default=True), - tags=dict(type='list', aliases=['tag'], default=None), + name=dict(required=True), + display_text=dict(), + url=dict(), + vm=dict(), + snapshot=dict(), + os_type=dict(), + is_ready=dict(type='bool', default=False), + is_public=dict(type='bool', default=True), + is_featured=dict(type='bool', default=False), + is_dynamically_scalable=dict(type='bool', default=False), + is_extractable=dict(type='bool', default=False), + is_routing=dict(type='bool'), + checksum=dict(), + template_filter=dict(default='self', choices=['featured', 'self', 'selfexecutable', 'sharedexecutable', 'executable', 'community']), + hypervisor=dict(choices=CS_HYPERVISORS), + requires_hvm=dict(type='bool', default=False), + password_enabled=dict(type='bool', default=False), + template_tag=dict(), + sshkey_enabled=dict(type='bool', default=False), + format=dict(choices=['QCOW2', 'RAW', 'VHD', 'OVA'], ), + details=dict(), + bits=dict(type='int', choices=[32, 64], default=64), + 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(), + domain=dict(), + account=dict(), + project=dict(), + poll_async=dict(type='bool', default=True), + tags=dict(type='list', aliases=['tag']), )) module = AnsibleModule( argument_spec=argument_spec, required_together=cs_required_together(), - mutually_exclusive = ( + mutually_exclusive=( ['url', 'vm'], ['zone', 'cross_zones'], ), supports_check_mode=True ) - try: - acs_tpl = AnsibleCloudStackTemplate(module) + acs_tpl = AnsibleCloudStackTemplate(module) - state = module.params.get('state') - if state in ['absent']: - tpl = acs_tpl.remove_template() + state = module.params.get('state') + if state in ['absent']: + tpl = acs_tpl.remove_template() - elif state in ['extracted']: - tpl = acs_tpl.extract_template() + elif state in ['extracted']: + tpl = acs_tpl.extract_template() + else: + if module.params.get('url'): + tpl = acs_tpl.register_template() + elif module.params.get('vm'): + tpl = acs_tpl.create_template() else: - if module.params.get('url'): - tpl = acs_tpl.register_template() - elif module.params.get('vm'): - tpl = acs_tpl.create_template() - else: - module.fail_json(msg="one of the following is required on state=present: url,vm") - - result = acs_tpl.get_result(tpl) + module.fail_json(msg="one of the following is required on state=present: url,vm") - except CloudStackException as e: - module.fail_json(msg='CloudStackException: %s' % str(e)) + result = acs_tpl.get_result(tpl) module.exit_json(**result) -# import module snippets -from ansible.module_utils.basic import * + if __name__ == '__main__': main() diff --git a/test/sanity/pep8/legacy-files.txt b/test/sanity/pep8/legacy-files.txt index 4edacdbb8b5..947c94ba5bb 100644 --- a/test/sanity/pep8/legacy-files.txt +++ b/test/sanity/pep8/legacy-files.txt @@ -77,7 +77,6 @@ lib/ansible/modules/cloud/cloudstack/cs_portforward.py lib/ansible/modules/cloud/cloudstack/cs_securitygroup.py lib/ansible/modules/cloud/cloudstack/cs_securitygroup_rule.py lib/ansible/modules/cloud/cloudstack/cs_snapshot_policy.py -lib/ansible/modules/cloud/cloudstack/cs_template.py lib/ansible/modules/cloud/docker/_docker.py lib/ansible/modules/cloud/docker/docker_container.py lib/ansible/modules/cloud/docker/docker_image.py