diff --git a/lib/ansible/modules/cloud/cloudstack/cs_instance.py b/lib/ansible/modules/cloud/cloudstack/cs_instance.py index 825c815533..e7e60f62c6 100644 --- a/lib/ansible/modules/cloud/cloudstack/cs_instance.py +++ b/lib/ansible/modules/cloud/cloudstack/cs_instance.py @@ -27,192 +27,134 @@ options: - Host name of the instance. C(name) can only contain ASCII letters. - Name will be generated (UUID) by CloudStack if not specified and can not be changed afterwards. - Either C(name) or C(display_name) is required. - required: false - default: null display_name: description: - Custom display name of the instances. - Display name will be set to C(name) if not specified. - Either C(name) or C(display_name) is required. - required: false - default: null group: description: - Group in where the new instance should be in. - required: false - default: null state: description: - State of the instance. - required: false - default: 'present' - choices: [ 'deployed', 'started', 'stopped', 'restarted', 'restored', 'destroyed', 'expunged', 'present', 'absent' ] + default: present + choices: [ deployed, started, stopped, restarted, restored, destroyed, expunged, present, absent ] service_offering: description: - Name or id of the service offering of the new instance. - If not set, first found service offering is used. - required: false - default: null cpu: description: - The number of CPUs to allocate to the instance, used with custom service offerings - required: false - default: null cpu_speed: description: - The clock speed/shares allocated to the instance, used with custom service offerings - required: false - default: null memory: description: - The memory allocated to the instance, used with custom service offerings - required: false - default: null template: description: - Name or id of the template to be used for creating the new instance. - Required when using C(state=present). - Mutually exclusive with C(ISO) option. - required: false - default: null iso: description: - Name or id of the ISO to be used for creating the new instance. - Required when using C(state=present). - Mutually exclusive with C(template) option. - required: false - default: null template_filter: description: - Name of the filter used to search for the template or iso. - Used for params C(iso) or C(template) on C(state=present). - required: false - default: 'executable' - choices: [ 'featured', 'self', 'selfexecutable', 'sharedexecutable', 'executable', 'community' ] - aliases: [ 'iso_filter' ] + default: executable + choices: [ featured, self, selfexecutable, sharedexecutable, executable, community ] + aliases: [ iso_filter ] version_added: '2.1' hypervisor: description: - Name the hypervisor to be used for creating the new instance. - Relevant when using C(state=present), but only considered if not set on ISO/template. - If not set or found on ISO/template, first found hypervisor will be used. - required: false - default: null - choices: [ 'KVM', 'VMware', 'BareMetal', 'XenServer', 'LXC', 'HyperV', 'UCS', 'OVM' ] + choices: [ KVM, VMware, BareMetal, XenServer, LXC, HyperV, UCS, OVM, Simulator ] keyboard: description: - Keyboard device type for the instance. - required: false - default: null - choices: [ 'de', 'de-ch', 'es', 'fi', 'fr', 'fr-be', 'fr-ch', 'is', 'it', 'jp', 'nl-be', 'no', 'pt', 'uk', 'us' ] + choices: [ de, de-ch, es, fi, fr, fr-be, fr-ch, is, it, jp, nl-be, no, pt, uk, us ] networks: description: - List of networks to use for the new instance. - required: false - default: [] - aliases: [ 'network' ] + aliases: [ network ] ip_address: description: - IPv4 address for default instance's network during creation. - required: false - default: null ip6_address: description: - IPv6 address for default instance's network. - required: false - default: null ip_to_networks: description: - "List of mappings in the form {'network': NetworkName, 'ip': 1.2.3.4}" - Mutually exclusive with C(networks) option. - required: false - default: null - aliases: [ 'ip_to_network' ] + aliases: [ ip_to_network ] disk_offering: description: - Name of the disk offering to be used. - required: false - default: null disk_size: description: - Disk size in GByte required if deploying instance from ISO. - required: false - default: null root_disk_size: description: - Root disk size in GByte required if deploying instance with KVM hypervisor and want resize the root disk size at startup (need CloudStack >= 4.4, cloud-initramfs-growroot installed and enabled in the template) - required: false - default: null security_groups: description: - List of security groups the instance to be applied to. - required: false - default: null - aliases: [ 'security_group' ] + aliases: [ security_group ] domain: description: - Domain the instance is related to. - required: false - default: null account: description: - Account the instance is related to. - required: false - default: null project: description: - Name of the project the instance to be deployed in. - required: false - default: null zone: description: - Name of the zone in which the instance should be deployed. - If not set, default zone is used. - required: false - default: null ssh_key: description: - Name of the SSH key to be deployed on the new instance. - required: false - default: null affinity_groups: description: - Affinity groups names to be applied to the new instance. - required: false - default: [] - aliases: [ 'affinity_group' ] + aliases: [ affinity_group ] user_data: description: - Optional data (ASCII) that can be sent to the instance upon a successful deployment. - The data will be automatically base64 encoded. - Consider switching to HTTP_POST by using C(CLOUDSTACK_METHOD=post) to increase the HTTP_GET size limit of 2KB to 32 KB. - required: false - default: null force: description: - Force stop/start the instance if required to apply changes, otherwise a running instance will not be changed. - required: false default: false tags: description: - List of tags. Tags are a list of dictionaries having keys C(key) and C(value). - "If you want to delete all tags, set a empty list e.g. C(tags: [])." - required: false - default: null - aliases: [ 'tag' ] + aliases: [ tag ] poll_async: description: - Poll async jobs until job has finished. - required: false default: true extends_documentation_fragment: cloudstack ''' EXAMPLES = ''' -# Create a instance from an ISO # NOTE: Names of offerings and ISOs depending on the CloudStack configuration. -- cs_instance: +- name: create a instance from an ISO + cs_instance: name: web-vm-1 iso: Linux Debian 7 64-bit hypervisor: VMware @@ -227,7 +169,7 @@ EXAMPLES = ''' - Storage Integration delegate_to: localhost -# For changing a running instance, use the 'force' parameter +- name: for changing a running instance, use the 'force' parameter - cs_instance: name: web-vm-1 display_name: web-vm-01.example.com @@ -236,9 +178,9 @@ EXAMPLES = ''' force: yes delegate_to: localhost -# Create or update a instance on Exoscale's public cloud using display_name. -# Note: user_data can be used to kickstart the instance using cloud-init yaml config. -- cs_instance: +# NOTE: user_data can be used to kickstart the instance using cloud-init yaml config. +- name: create or update a instance on Exoscale's public cloud using display_name. + cs_instance: display_name: web-vm-1 template: Linux Debian 7 64-bit service_offering: Tiny @@ -254,8 +196,8 @@ EXAMPLES = ''' - nginx delegate_to: localhost -# Create an instance with multiple interfaces specifying the IP addresses -- cs_instance: +- name: create an instance with multiple interfaces specifying the IP addresses + cs_instance: name: web-vm-1 template: Linux Debian 7 64-bit service_offering: Tiny @@ -266,19 +208,19 @@ EXAMPLES = ''' ip: 192.0.2.1 delegate_to: localhost -# Ensure an instance is stopped -- cs_instance: +- name: ensure an instance is stopped + cs_instance: name: web-vm-1 state: stopped delegate_to: localhost -# Ensure an instance is running -- cs_instance: +- name: ensure an instance is running + cs_instance: name: web-vm-1 state: started delegate_to: localhost -# Remove an instance +- name: remove an instance - cs_instance: name: web-vm-1 state: absent @@ -405,12 +347,6 @@ instance_name: ''' import base64 - -try: - from cs import CloudStackException -except ImportError: - pass # Handled in AnsibleCloudStack.__init__ - from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.cloudstack import (AnsibleCloudStack, CS_HYPERVISORS, cs_argument_spec, cs_required_together) @@ -421,35 +357,33 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): def __init__(self, module): super(AnsibleCloudStackInstance, self).__init__(module) self.returns = { - 'group': 'group', - 'hypervisor': 'hypervisor', - 'instancename': 'instance_name', - 'publicip': 'public_ip', - 'passwordenabled': 'password_enabled', - 'password': 'password', - 'serviceofferingname': 'service_offering', - 'isoname': 'iso', - 'templatename': 'template', - 'keypair': 'ssh_key', + 'group': 'group', + 'hypervisor': 'hypervisor', + 'instancename': 'instance_name', + 'publicip': 'public_ip', + 'passwordenabled': 'password_enabled', + 'password': 'password', + 'serviceofferingname': 'service_offering', + 'isoname': 'iso', + 'templatename': 'template', + 'keypair': 'ssh_key', } self.instance = None self.template = None self.iso = None - def get_service_offering_id(self): service_offering = self.module.params.get('service_offering') - service_offerings = self.cs.listServiceOfferings() + service_offerings = self.query_api('listServiceOfferings', ) if service_offerings: if not service_offering: return service_offerings['serviceoffering'][0]['id'] for s in service_offerings['serviceoffering']: - if service_offering in [ s['name'], s['id'] ]: + if service_offering in [s['name'], s['id']]: return s['id'] - self.module.fail_json(msg="Service offering '%s' not found" % service_offering) - + self.fail_json(msg="Service offering '%s' not found" % service_offering) def get_template_or_iso(self, key=None): template = self.module.params.get('template') @@ -458,12 +392,13 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): if not template and not iso: 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['zoneid'] = self.get_zone(key='id') - args['isrecursive'] = True + args = { + 'account': self.get_account(key='name'), + 'domainid': self.get_domain(key='id'), + 'projectid': self.get_project(key='id'), + 'zoneid': self.get_zone(key='id'), + 'isrecursive': True, + } if template: if self.template: @@ -471,29 +406,34 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): rootdisksize = self.module.params.get('root_disk_size') args['templatefilter'] = self.module.params.get('template_filter') - templates = self.cs.listTemplates(**args) + templates = self.query_api('listTemplates', **args) if templates: for t in templates['template']: - if template in [ t['displaytext'], t['name'], t['id'] ]: - if rootdisksize and t['size'] > rootdisksize*1024**3: + if template in [t['displaytext'], t['name'], t['id']]: + if rootdisksize and t['size'] > rootdisksize * 1024 ** 3: continue self.template = t return self._get_by_key(key, self.template) - more_info = "" + if rootdisksize: more_info = " (with size <= %s)" % rootdisksize + else: + more_info = "" + self.module.fail_json(msg="Template '%s' not found%s" % (template, more_info)) elif iso: if self.iso: return self._get_by_key(key, self.iso) + args['isofilter'] = self.module.params.get('template_filter') - isos = self.cs.listIsos(**args) + isos = self.query_api('listIsos', **args) if isos: for i in isos['iso']: - if iso in [ i['displaytext'], i['name'], i['id'] ]: + if iso in [i['displaytext'], i['name'], i['id']]: self.iso = i return self._get_by_key(key, self.iso) + self.module.fail_json(msg="ISO '%s' not found" % iso) def get_instance(self): @@ -506,7 +446,7 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): 'projectid': self.get_project(key='id'), } # Do not pass zoneid, as the instance name must be unique across zones. - instances = self.cs.listVirtualMachines(**args) + instances = self.query_api('listVirtualMachines', **args) if instances: for v in instances['virtualmachine']: if instance_name.lower() in [v['name'].lower(), v['displayname'].lower(), v['id']]: @@ -514,7 +454,6 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): break return self.instance - def _get_instance_user_data(self, instance): # Query the user data if we need to if 'userdata' in instance: @@ -522,11 +461,10 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): user_data = "" if self.get_user_data() is not None: - res = self.cs.getVirtualMachineUserData(virtualmachineid=instance['id']) - user_data = res['virtualmachineuserdata'].get('userdata',"") + res = self.query_api('getVirtualMachineUserData', virtualmachineid=instance['id']) + user_data = res['virtualmachineuserdata'].get('userdata', "") return user_data - def get_iptonetwork_mappings(self): network_mappings = self.module.params.get('ip_to_networks') if network_mappings is None: @@ -553,11 +491,8 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): 'projectid': self.get_project('id'), 'name': ssh_key_name, } - ssh_key_pairs = self.cs.listSSHKeyPairs(**args) - if 'errortext' in ssh_key_pairs: - self.module.fail_json(msg="Failed: '%s'" % ssh_key_pairs['errortext']) - - elif 'sshkeypair' in ssh_key_pairs: + ssh_key_pairs = self.query_api('listSSHKeyPairs', **args) + if 'sshkeypair' in ssh_key_pairs: return self._get_by_key(key=key, my_dict=ssh_key_pairs['sshkeypair'][0]) elif fail_on_missing: @@ -592,7 +527,7 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): return False security_groups = [s.lower() for s in security_groups] - instance_security_groups = self.instance.get('securitygroup',[]) + instance_security_groups = self.instance.get('securitygroup') or [] instance_security_group_names = [] for instance_security_group in instance_security_groups: @@ -606,7 +541,6 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): return True return False - def get_network_ids(self, network_names=None): if network_names is None: network_names = self.module.params.get('networks') @@ -620,7 +554,7 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): 'projectid': self.get_project(key='id'), 'zoneid': self.get_zone(key='id'), } - networks = self.cs.listNetworks(**args) + networks = self.query_api('listNetworks', **args) if not networks: self.module.fail_json(msg="No networks available") @@ -628,7 +562,7 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): network_displaytexts = [] for network_name in network_names: for n in networks['network']: - if network_name in [ n['displaytext'], n['name'], n['id'] ]: + if network_name in [n['displaytext'], n['name'], n['id']]: network_ids.append(n['id']) network_displaytexts.append(n['name']) break @@ -638,7 +572,6 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): return network_ids - def present_instance(self, start_vm=True): instance = self.get_instance() @@ -656,14 +589,12 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): return instance - def get_user_data(self): user_data = self.module.params.get('user_data') if user_data is not None: user_data = base64.b64encode(str(user_data)) return user_data - def get_details(self): res = None cpu = self.module.params.get('cpu') @@ -677,43 +608,39 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): }] return res - def deploy_instance(self, start_vm=True): self.result['changed'] = True networkids = self.get_network_ids() if networkids is not None: networkids = ','.join(networkids) - args = {} - args['templateid'] = self.get_template_or_iso(key='id') + args = {} + args['templateid'] = self.get_template_or_iso(key='id') if not args['templateid']: self.module.fail_json(msg="Template or ISO is required.") - args['zoneid'] = self.get_zone(key='id') - args['serviceofferingid'] = self.get_service_offering_id() - args['account'] = self.get_account(key='name') - args['domainid'] = self.get_domain(key='id') - args['projectid'] = self.get_project(key='id') - args['diskofferingid'] = self.get_disk_offering(key='id') - args['networkids'] = networkids - args['iptonetworklist'] = self.get_iptonetwork_mappings() - args['userdata'] = self.get_user_data() - args['keyboard'] = self.module.params.get('keyboard') - args['ipaddress'] = self.module.params.get('ip_address') - args['ip6address'] = self.module.params.get('ip6_address') - args['name'] = self.module.params.get('name') - args['displayname'] = self.get_or_fallback('display_name', 'name') - args['group'] = self.module.params.get('group') - args['keypair'] = self.get_ssh_keypair(key='name') - args['size'] = self.module.params.get('disk_size') - args['startvm'] = start_vm - args['rootdisksize'] = self.module.params.get('root_disk_size') - args['affinitygroupnames'] = ','.join(self.module.params.get('affinity_groups')) - args['details'] = self.get_details() - - security_groups = self.module.params.get('security_groups') - if security_groups is not None: - args['securitygroupnames'] = ','.join(security_groups) + args['zoneid'] = self.get_zone(key='id') + args['serviceofferingid'] = self.get_service_offering_id() + args['account'] = self.get_account(key='name') + args['domainid'] = self.get_domain(key='id') + args['projectid'] = self.get_project(key='id') + args['diskofferingid'] = self.get_disk_offering(key='id') + args['networkids'] = networkids + args['iptonetworklist'] = self.get_iptonetwork_mappings() + args['userdata'] = self.get_user_data() + args['keyboard'] = self.module.params.get('keyboard') + args['ipaddress'] = self.module.params.get('ip_address') + args['ip6address'] = self.module.params.get('ip6_address') + args['name'] = self.module.params.get('name') + args['displayname'] = self.get_or_fallback('display_name', 'name') + args['group'] = self.module.params.get('group') + args['keypair'] = self.get_ssh_keypair(key='name') + args['size'] = self.module.params.get('disk_size') + args['startvm'] = start_vm + args['rootdisksize'] = self.module.params.get('root_disk_size') + args['affinitygroupnames'] = self.module.params.get('affinity_groups') + args['details'] = self.get_details() + args['securitygroupnames'] = self.module.params.get('security_groups') template_iso = self.get_template_or_iso() if 'hypervisor' not in template_iso: @@ -721,29 +648,27 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): instance = None if not self.module.check_mode: - instance = self.cs.deployVirtualMachine(**args) - - if 'errortext' in instance: - self.module.fail_json(msg="Failed: '%s'" % instance['errortext']) + instance = self.query_api('deployVirtualMachine', **args) poll_async = self.module.params.get('poll_async') if poll_async: instance = self.poll_job(instance, 'virtualmachine') return instance - def update_instance(self, instance, start_vm=True): # Service offering data - args_service_offering = {} - args_service_offering['id'] = instance['id'] + args_service_offering = { + 'id': instance['id'], + } if self.module.params.get('service_offering'): args_service_offering['serviceofferingid'] = self.get_service_offering_id() service_offering_changed = self.has_changed(args_service_offering, instance) # Instance data - args_instance_update = {} - args_instance_update['id'] = instance['id'] - args_instance_update['userdata'] = self.get_user_data() + args_instance_update = { + 'id': instance['id'], + 'userdata': self.get_user_data(), + } instance['userdata'] = self._get_instance_user_data(instance) args_instance_update['ostypeid'] = self.get_os_type(key='id') if self.module.params.get('group'): @@ -777,9 +702,7 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): # Change service offering if service_offering_changed: - res = self.cs.changeServiceForVirtualMachine(**args_service_offering) - if 'errortext' in res: - self.module.fail_json(msg="Failed: '%s'" % res['errortext']) + res = self.query_api('changeServiceForVirtualMachine', **args_service_offering) instance = res['virtualmachine'] self.instance = instance @@ -787,9 +710,7 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): if instance_changed or security_groups_changed: if security_groups_changed: args_instance_update['securitygroupnames'] = ','.join(self.module.params.get('security_groups')) - res = self.cs.updateVirtualMachine(**args_instance_update) - if 'errortext' in res: - self.module.fail_json(msg="Failed: '%s'" % res['errortext']) + res = self.query_api('updateVirtualMachine', **args_instance_update) instance = res['virtualmachine'] self.instance = instance @@ -800,10 +721,7 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): args_ssh_key['id'] = instance['id'] args_ssh_key['projectid'] = self.get_project(key='id') args_ssh_key['keypair'] = self.module.params.get('ssh_key') - instance = self.cs.resetSSHKeyForVirtualMachine(**args_ssh_key) - if 'errortext' in instance: - self.module.fail_json(msg="Failed: '%s'" % instance['errortext']) - + instance = self.query_api('resetSSHKeyForVirtualMachine', **args_ssh_key) instance = self.poll_job(instance, 'virtualmachine') self.instance = instance @@ -815,58 +733,46 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): "Use force=true to allow the instance %s to be stopped/started." % instance['name']) return instance - def recover_instance(self, instance): - if instance['state'].lower() in [ 'destroying', 'destroyed' ]: + if instance['state'].lower() in ['destroying', 'destroyed']: self.result['changed'] = True if not self.module.check_mode: - res = self.cs.recoverVirtualMachine(id=instance['id']) - if 'errortext' in res: - self.module.fail_json(msg="Failed: '%s'" % res['errortext']) + res = self.query_api('recoverVirtualMachine', id=instance['id']) instance = res['virtualmachine'] return instance - def absent_instance(self): instance = self.get_instance() if instance: if instance['state'].lower() not in ['expunging', 'destroying', 'destroyed']: self.result['changed'] = True if not self.module.check_mode: - res = self.cs.destroyVirtualMachine(id=instance['id']) - - if 'errortext' in res: - self.module.fail_json(msg="Failed: '%s'" % res['errortext']) + res = self.query_api('destroyVirtualMachine', id=instance['id']) poll_async = self.module.params.get('poll_async') if poll_async: instance = self.poll_job(res, 'virtualmachine') return instance - def expunge_instance(self): instance = self.get_instance() if instance: res = {} - if instance['state'].lower() in [ 'destroying', 'destroyed' ]: + if instance['state'].lower() in ['destroying', 'destroyed']: self.result['changed'] = True if not self.module.check_mode: - res = self.cs.destroyVirtualMachine(id=instance['id'], expunge=True) + res = self.query_api('destroyVirtualMachine', id=instance['id'], expunge=True) - elif instance['state'].lower() not in [ 'expunging' ]: + elif instance['state'].lower() not in ['expunging']: self.result['changed'] = True if not self.module.check_mode: - res = self.cs.destroyVirtualMachine(id=instance['id'], expunge=True) - - if res and 'errortext' in res: - self.module.fail_json(msg="Failed: '%s'" % res['errortext']) + res = self.query_api('destroyVirtualMachine', id=instance['id'], expunge=True) poll_async = self.module.params.get('poll_async') if poll_async: res = self.poll_job(res, 'virtualmachine') return instance - def stop_instance(self): instance = self.get_instance() # in check mode instance may not be instanciated @@ -877,17 +783,13 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): if instance['state'].lower() in ['starting', 'running']: self.result['changed'] = True if not self.module.check_mode: - instance = self.cs.stopVirtualMachine(id=instance['id']) - - if 'errortext' in instance: - self.module.fail_json(msg="Failed: '%s'" % instance['errortext']) + instance = self.query_api('stopVirtualMachine', id=instance['id']) poll_async = self.module.params.get('poll_async') if poll_async: instance = self.poll_job(instance, 'virtualmachine') return instance - def start_instance(self): instance = self.get_instance() # in check mode instance may not be instanciated @@ -898,38 +800,30 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): if instance['state'].lower() in ['stopped', 'stopping']: self.result['changed'] = True if not self.module.check_mode: - instance = self.cs.startVirtualMachine(id=instance['id']) - - if 'errortext' in instance: - self.module.fail_json(msg="Failed: '%s'" % instance['errortext']) + instance = self.query_api('startVirtualMachine', id=instance['id']) poll_async = self.module.params.get('poll_async') if poll_async: instance = self.poll_job(instance, 'virtualmachine') return instance - def restart_instance(self): instance = self.get_instance() # in check mode instance may not be instanciated if instance: - if instance['state'].lower() in [ 'running', 'starting' ]: + if instance['state'].lower() in ['running', 'starting']: self.result['changed'] = True if not self.module.check_mode: - instance = self.cs.rebootVirtualMachine(id=instance['id']) - - if 'errortext' in instance: - self.module.fail_json(msg="Failed: '%s'" % instance['errortext']) + instance = self.query_api('rebootVirtualMachine', id=instance['id']) poll_async = self.module.params.get('poll_async') if poll_async: instance = self.poll_job(instance, 'virtualmachine') - elif instance['state'].lower() in [ 'stopping', 'stopped' ]: + elif instance['state'].lower() in ['stopping', 'stopped']: instance = self.start_instance() return instance - def restore_instance(self): instance = self.get_instance() self.result['changed'] = True @@ -938,16 +832,13 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): args = {} args['templateid'] = self.get_template_or_iso(key='id') args['virtualmachineid'] = instance['id'] - res = self.cs.restoreVirtualMachine(**args) - if 'errortext' in res: - self.module.fail_json(msg="Failed: '%s'" % res['errortext']) + res = self.query_api('restoreVirtualMachine', **args) poll_async = self.module.params.get('poll_async') if poll_async: instance = self.poll_job(res, 'virtualmachine') return instance - def get_result(self, instance): super(AnsibleCloudStackInstance, self).get_result(instance) if instance: @@ -972,38 +863,38 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): def main(): argument_spec = cs_argument_spec() argument_spec.update(dict( - name = dict(default=None), - display_name = dict(default=None), - group = dict(default=None), - state = dict(choices=['present', 'deployed', 'started', 'stopped', 'restarted', 'restored', 'absent', 'destroyed', 'expunged'], default='present'), - service_offering = dict(default=None), - cpu = dict(default=None, type='int'), - cpu_speed = dict(default=None, type='int'), - memory = dict(default=None, type='int'), - template = dict(default=None), - iso = dict(default=None), - template_filter = dict(default="executable", aliases=['iso_filter'], choices=['featured', 'self', 'selfexecutable', 'sharedexecutable', 'executable', - 'community']), - networks = dict(type='list', aliases=[ 'network' ], default=None), - ip_to_networks = dict(type='list', aliases=['ip_to_network'], default=None), - ip_address = dict(defaul=None), - ip6_address = dict(defaul=None), - disk_offering = dict(default=None), - disk_size = dict(type='int', default=None), - root_disk_size = dict(type='int', default=None), - keyboard = dict(choices=['de', 'de-ch', 'es', 'fi', 'fr', 'fr-be', 'fr-ch', 'is', 'it', 'jp', 'nl-be', 'no', 'pt', 'uk', 'us'], default=None), - hypervisor = dict(choices=CS_HYPERVISORS, default=None), - security_groups = dict(type='list', aliases=[ 'security_group' ], default=None), - affinity_groups = dict(type='list', aliases=[ 'affinity_group' ], default=[]), - domain = dict(default=None), - account = dict(default=None), - project = dict(default=None), - user_data = dict(default=None), - zone = dict(default=None), - ssh_key = dict(default=None), - force = dict(type='bool', default=False), - tags = dict(type='list', aliases=[ 'tag' ], default=None), - poll_async = dict(type='bool', default=True), + name=dict(), + display_name=dict(), + group=dict(), + state=dict(choices=['present', 'deployed', 'started', 'stopped', 'restarted', 'restored', 'absent', 'destroyed', 'expunged'], default='present'), + service_offering=dict(), + cpu=dict(type='int'), + cpu_speed=dict(type='int'), + memory=dict(type='int'), + template=dict(), + iso=dict(), + template_filter=dict(default="executable", aliases=['iso_filter'], choices=['featured', 'self', 'selfexecutable', 'sharedexecutable', 'executable', + 'community']), + networks=dict(type='list', aliases=['network']), + ip_to_networks=dict(type='list', aliases=['ip_to_network']), + ip_address=dict(defaul=None), + ip6_address=dict(defaul=None), + disk_offering=dict(), + disk_size=dict(type='int'), + root_disk_size=dict(type='int'), + keyboard=dict(choices=['de', 'de-ch', 'es', 'fi', 'fr', 'fr-be', 'fr-ch', 'is', 'it', 'jp', 'nl-be', 'no', 'pt', 'uk', 'us']), + hypervisor=dict(choices=CS_HYPERVISORS), + security_groups=dict(type='list', aliases=['security_group']), + affinity_groups=dict(type='list', aliases=['affinity_group']), + domain=dict(), + account=dict(), + project=dict(), + user_data=dict(), + zone=dict(), + ssh_key=dict(), + force=dict(type='bool', default=False), + tags=dict(type='list', aliases=['tag']), + poll_async=dict(type='bool', default=True), )) required_together = cs_required_together() @@ -1014,53 +905,48 @@ def main(): module = AnsibleModule( argument_spec=argument_spec, required_together=required_together, - required_one_of = ( + required_one_of=( ['display_name', 'name'], ), - mutually_exclusive = ( + mutually_exclusive=( ['template', 'iso'], ), supports_check_mode=True ) - try: - acs_instance = AnsibleCloudStackInstance(module) + acs_instance = AnsibleCloudStackInstance(module) - state = module.params.get('state') + state = module.params.get('state') - if state in ['absent', 'destroyed']: - instance = acs_instance.absent_instance() + if state in ['absent', 'destroyed']: + instance = acs_instance.absent_instance() - elif state in ['expunged']: - instance = acs_instance.expunge_instance() + elif state in ['expunged']: + instance = acs_instance.expunge_instance() - elif state in ['restored']: - acs_instance.present_instance() - instance = acs_instance.restore_instance() + elif state in ['restored']: + acs_instance.present_instance() + instance = acs_instance.restore_instance() - elif state in ['present', 'deployed']: - instance = acs_instance.present_instance() + elif state in ['present', 'deployed']: + instance = acs_instance.present_instance() - elif state in ['stopped']: - acs_instance.present_instance(start_vm=False) - instance = acs_instance.stop_instance() + elif state in ['stopped']: + acs_instance.present_instance(start_vm=False) + instance = acs_instance.stop_instance() - elif state in ['started']: - acs_instance.present_instance() - instance = acs_instance.start_instance() + elif state in ['started']: + acs_instance.present_instance() + instance = acs_instance.start_instance() - elif state in ['restarted']: - acs_instance.present_instance() - instance = acs_instance.restart_instance() + elif state in ['restarted']: + acs_instance.present_instance() + instance = acs_instance.restart_instance() - if instance and 'state' in instance and instance['state'].lower() == 'error': - module.fail_json(msg="Instance named '%s' in error state." % module.params.get('name')) - - result = acs_instance.get_result(instance) - - except CloudStackException as e: - module.fail_json(msg='CloudStackException: %s' % str(e)) + if instance and 'state' in instance and instance['state'].lower() == 'error': + module.fail_json(msg="Instance named '%s' in error state." % module.params.get('name')) + result = acs_instance.get_result(instance) module.exit_json(**result) diff --git a/test/sanity/pep8/legacy-files.txt b/test/sanity/pep8/legacy-files.txt index 6e7ee10452..92ceeb6bdd 100644 --- a/test/sanity/pep8/legacy-files.txt +++ b/test/sanity/pep8/legacy-files.txt @@ -64,7 +64,6 @@ lib/ansible/modules/cloud/azure/azure_rm_virtualmachine.py lib/ansible/modules/cloud/azure/azure_rm_virtualnetwork.py lib/ansible/modules/cloud/azure/azure_rm_virtualnetwork_facts.py lib/ansible/modules/cloud/centurylink/clc_loadbalancer.py -lib/ansible/modules/cloud/cloudstack/cs_instance.py lib/ansible/modules/cloud/cloudstack/_cs_nic.py lib/ansible/modules/cloud/docker/_docker.py lib/ansible/modules/cloud/docker/docker_container.py