diff options
author | Rene Moser <mail@renemoser.net> | 2015-12-14 11:13:10 +0100 |
---|---|---|
committer | Brian Coca <brian.coca+git@gmail.com> | 2015-12-15 08:26:40 -0500 |
commit | 411d06861f7ed58047d5098b9d4af48c12ceee8a (patch) | |
tree | ed2125a9625b0ac1b9f507977c01c5ad797744bd | |
parent | cdf5e58cff1b879cdfaee87b599be5382045a0f7 (diff) | |
download | ansible-modules-extras-411d06861f7ed58047d5098b9d4af48c12ceee8a.tar.gz |
cloudstack: cs_instance: fixes and improvements
- cs_instance: fix VM not updated with states given stopped, started, restarted
A missing VM will be created though but an existing not updated. This fixes the lack of consistency.
- cs_instance: fix user data can not be cleared
- cs_instance: fix deleted VM not recovered on state=present
-rw-r--r-- | cloud/cloudstack/cs_instance.py | 172 |
1 files changed, 97 insertions, 75 deletions
diff --git a/cloud/cloudstack/cs_instance.py b/cloud/cloudstack/cs_instance.py index 22d3d815..852be68a 100644 --- a/cloud/cloudstack/cs_instance.py +++ b/cloud/cloudstack/cs_instance.py @@ -221,7 +221,7 @@ EXAMPLES = ''' - local_action: module: cs_instance name: web-vm-1 - display_name: web-vm-01.example.com + display_name: web-vm-01.example.com iso: Linux Debian 7 64-bit service_offering: 2cpu_2gb force: yes @@ -247,13 +247,13 @@ EXAMPLES = ''' - {'network': NetworkA, 'ip': '10.1.1.1'} - {'network': NetworkB, 'ip': '192.168.1.1'} -# Ensure a instance has stopped +# Ensure an instance is stopped - local_action: cs_instance name=web-vm-1 state=stopped -# Ensure a instance is running +# Ensure an instance is running - local_action: cs_instance name=web-vm-1 state=started -# Remove a instance +# Remove an instance - local_action: cs_instance name=web-vm-1 state=absent ''' @@ -544,23 +544,27 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): return network_ids - def present_instance(self): + def present_instance(self, start_vm=True): instance = self.get_instance() + if not instance: - instance = self.deploy_instance() + instance = self.deploy_instance(start_vm=start_vm) else: - instance = self.update_instance(instance) + instance = self.recover_instance(instance=instance) + instance = self.update_instance(instance=instance, start_vm=start_vm) # In check mode, we do not necessarely have an instance if instance: instance = self.ensure_tags(resource=instance, resource_type='UserVm') + # refresh instance data + self.instance = instance return instance def get_user_data(self): user_data = self.module.params.get('user_data') - if user_data: + if user_data is not None: user_data = base64.b64encode(str(user_data)) return user_data @@ -630,30 +634,43 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): return instance - def update_instance(self, instance): - args_service_offering = {} - args_service_offering['id'] = instance['id'] - args_service_offering['serviceofferingid'] = self.get_service_offering_id() + def update_instance(self, instance, start_vm=True): + # Service offering data + args_service_offering = {} + args_service_offering['id'] = instance['id'] + if self.module.params.get('service_offering'): + args_service_offering['serviceofferingid'] = self.get_service_offering_id() + + # Instance data + args_instance_update = {} + args_instance_update['id'] = instance['id'] + args_instance_update['userdata'] = self.get_user_data() + args_instance_update['ostypeid'] = self.get_os_type(key='id') + if self.module.params.get('group'): + args_instance_update['group'] = self.module.params.get('group') + if self.module.params.get('display_name'): + args_instance_update['displayname'] = self.module.params.get('display_name') + + # SSH key data + args_ssh_key = {} + args_ssh_key['id'] = instance['id'] + args_ssh_key['projectid'] = self.get_project(key='id') + if self.module.params.get('ssh_key'): + args_ssh_key['keypair'] = self.module.params.get('ssh_key') + + # SSH key data + args_ssh_key = {} + args_ssh_key['id'] = instance['id'] + args_ssh_key['projectid'] = self.get_project(key='id') + if self.module.params.get('ssh_key'): + args_ssh_key['keypair'] = self.module.params.get('ssh_key') - args_instance_update = {} - args_instance_update['id'] = instance['id'] - args_instance_update['group'] = self.module.params.get('group') - args_instance_update['displayname'] = self.get_or_fallback('display_name', 'name') - args_instance_update['userdata'] = self.get_user_data() - args_instance_update['ostypeid'] = self.get_os_type(key='id') - - args_ssh_key = {} - args_ssh_key['id'] = instance['id'] - args_ssh_key['keypair'] = self.module.params.get('ssh_key') - args_ssh_key['projectid'] = self.get_project(key='id') - if self._has_changed(args_service_offering, instance) or \ self._has_changed(args_instance_update, instance) or \ self._has_changed(args_ssh_key, instance): - + force = self.module.params.get('force') instance_state = instance['state'].lower() - if instance_state == 'stopped' or force: self.result['changed'] = True if not self.module.check_mode: @@ -689,11 +706,22 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): self.instance = instance # Start VM again if it was running before - if instance_state == 'running': + if instance_state == 'running' and start_vm: instance = self.start_instance() return instance + def recover_instance(self, instance): + 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']) + instance = res['virtualmachine'] + return instance + + def absent_instance(self): instance = self.get_instance() if instance: @@ -736,73 +764,64 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): def stop_instance(self): instance = self.get_instance() + # in check mode intance may not be instanciated + if instance: + if instance['state'].lower() in ['stopping', 'stopped']: + return instance - if not instance: - instance = self.deploy_instance(start_vm=False) - return instance - - elif instance['state'].lower() in ['stopping', 'stopped']: - return instance - - 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 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']) + if 'errortext' in instance: + self.module.fail_json(msg="Failed: '%s'" % instance['errortext']) - poll_async = self.module.params.get('poll_async') - if poll_async: - instance = self._poll_job(instance, 'virtualmachine') + 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 intance may not be instanciated + if instance: + if instance['state'].lower() in ['starting', 'running']: + return instance - if not instance: - instance = self.deploy_instance() - return instance - - elif instance['state'].lower() in ['starting', 'running']: - return instance - - 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 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']) + if 'errortext' in instance: + self.module.fail_json(msg="Failed: '%s'" % instance['errortext']) - poll_async = self.module.params.get('poll_async') - if poll_async: - instance = self._poll_job(instance, 'virtualmachine') + 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 intance may not be instanciated + if instance: + 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 not instance: - instance = self.deploy_instance() - return instance - - elif 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']) + if 'errortext' in instance: + self.module.fail_json(msg="Failed: '%s'" % instance['errortext']) - poll_async = self.module.params.get('poll_async') - if poll_async: - instance = self._poll_job(instance, 'virtualmachine') + poll_async = self.module.params.get('poll_async') + if poll_async: + instance = self._poll_job(instance, 'virtualmachine') - elif instance['state'].lower() in [ 'stopping', 'stopped' ]: - instance = self.start_instance() + elif instance['state'].lower() in [ 'stopping', 'stopped' ]: + instance = self.start_instance() return instance @@ -918,12 +937,15 @@ def main(): instance = acs_instance.present_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 ['restarted']: + acs_instance.present_instance() instance = acs_instance.restart_instance() if instance and 'state' in instance and instance['state'].lower() == 'error': |