Merge pull request #1372 from resmo/for-ansible

cloudstack: cs_instance: fixes and improvements
This commit is contained in:
Brian Coca 2015-12-15 08:17:41 -05:00
commit bcabac510d

View file

@ -247,13 +247,13 @@ EXAMPLES = '''
- {'network': NetworkA, 'ip': '10.1.1.1'} - {'network': NetworkA, 'ip': '10.1.1.1'}
- {'network': NetworkB, 'ip': '192.168.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 - 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 - 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 - local_action: cs_instance name=web-vm-1 state=absent
''' '''
@ -544,23 +544,27 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
return network_ids return network_ids
def present_instance(self): def present_instance(self, start_vm=True):
instance = self.get_instance() instance = self.get_instance()
if not instance: if not instance:
instance = self.deploy_instance() instance = self.deploy_instance(start_vm=start_vm)
else: 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 # In check mode, we do not necessarely have an instance
if instance: if instance:
instance = self.ensure_tags(resource=instance, resource_type='UserVm') instance = self.ensure_tags(resource=instance, resource_type='UserVm')
# refresh instance data
self.instance = instance
return instance return instance
def get_user_data(self): def get_user_data(self):
user_data = self.module.params.get('user_data') user_data = self.module.params.get('user_data')
if user_data: if user_data is not None:
user_data = base64.b64encode(str(user_data)) user_data = base64.b64encode(str(user_data))
return user_data return user_data
@ -630,22 +634,36 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
return instance return instance
def update_instance(self, instance): def update_instance(self, instance, start_vm=True):
args_service_offering = {} # Service offering data
args_service_offering['id'] = instance['id'] args_service_offering = {}
args_service_offering['serviceofferingid'] = self.get_service_offering_id() args_service_offering['id'] = instance['id']
if self.module.params.get('service_offering'):
args_service_offering['serviceofferingid'] = self.get_service_offering_id()
args_instance_update = {} # Instance data
args_instance_update['id'] = instance['id'] args_instance_update = {}
args_instance_update['group'] = self.module.params.get('group') args_instance_update['id'] = instance['id']
args_instance_update['displayname'] = self.get_or_fallback('display_name', 'name') args_instance_update['userdata'] = self.get_user_data()
args_instance_update['userdata'] = self.get_user_data() args_instance_update['ostypeid'] = self.get_os_type(key='id')
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')
args_ssh_key = {} # SSH key data
args_ssh_key['id'] = instance['id'] args_ssh_key = {}
args_ssh_key['keypair'] = self.module.params.get('ssh_key') args_ssh_key['id'] = instance['id']
args_ssh_key['projectid'] = self.get_project(key='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')
if self._has_changed(args_service_offering, instance) or \ if self._has_changed(args_service_offering, instance) or \
self._has_changed(args_instance_update, instance) or \ self._has_changed(args_instance_update, instance) or \
@ -653,7 +671,6 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
force = self.module.params.get('force') force = self.module.params.get('force')
instance_state = instance['state'].lower() instance_state = instance['state'].lower()
if instance_state == 'stopped' or force: if instance_state == 'stopped' or force:
self.result['changed'] = True self.result['changed'] = True
if not self.module.check_mode: if not self.module.check_mode:
@ -689,11 +706,22 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
self.instance = instance self.instance = instance
# Start VM again if it was running before # Start VM again if it was running before
if instance_state == 'running': if instance_state == 'running' and start_vm:
instance = self.start_instance() instance = self.start_instance()
return 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): def absent_instance(self):
instance = self.get_instance() instance = self.get_instance()
if instance: if instance:
@ -736,73 +764,64 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
def stop_instance(self): def stop_instance(self):
instance = self.get_instance() 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: if instance['state'].lower() in ['starting', 'running']:
instance = self.deploy_instance(start_vm=False) self.result['changed'] = True
return instance if not self.module.check_mode:
instance = self.cs.stopVirtualMachine(id=instance['id'])
elif instance['state'].lower() in ['stopping', 'stopped']: if 'errortext' in instance:
return instance self.module.fail_json(msg="Failed: '%s'" % instance['errortext'])
if instance['state'].lower() in ['starting', 'running']: poll_async = self.module.params.get('poll_async')
self.result['changed'] = True if poll_async:
if not self.module.check_mode: instance = self._poll_job(instance, 'virtualmachine')
instance = self.cs.stopVirtualMachine(id=instance['id'])
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')
return instance return instance
def start_instance(self): def start_instance(self):
instance = self.get_instance() 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: if instance['state'].lower() in ['stopped', 'stopping']:
instance = self.deploy_instance() self.result['changed'] = True
return instance if not self.module.check_mode:
instance = self.cs.startVirtualMachine(id=instance['id'])
elif instance['state'].lower() in ['starting', 'running']: if 'errortext' in instance:
return instance self.module.fail_json(msg="Failed: '%s'" % instance['errortext'])
if instance['state'].lower() in ['stopped', 'stopping']: poll_async = self.module.params.get('poll_async')
self.result['changed'] = True if poll_async:
if not self.module.check_mode: instance = self._poll_job(instance, 'virtualmachine')
instance = self.cs.startVirtualMachine(id=instance['id'])
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')
return instance return instance
def restart_instance(self): def restart_instance(self):
instance = self.get_instance() 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: if 'errortext' in instance:
instance = self.deploy_instance() self.module.fail_json(msg="Failed: '%s'" % instance['errortext'])
return instance
elif instance['state'].lower() in [ 'running', 'starting' ]: poll_async = self.module.params.get('poll_async')
self.result['changed'] = True if poll_async:
if not self.module.check_mode: instance = self._poll_job(instance, 'virtualmachine')
instance = self.cs.rebootVirtualMachine(id=instance['id'])
if 'errortext' in instance: elif instance['state'].lower() in [ 'stopping', 'stopped' ]:
self.module.fail_json(msg="Failed: '%s'" % instance['errortext']) instance = self.start_instance()
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()
return instance return instance
@ -918,12 +937,15 @@ def main():
instance = acs_instance.present_instance() instance = acs_instance.present_instance()
elif state in ['stopped']: elif state in ['stopped']:
acs_instance.present_instance(start_vm=False)
instance = acs_instance.stop_instance() instance = acs_instance.stop_instance()
elif state in ['started']: elif state in ['started']:
acs_instance.present_instance()
instance = acs_instance.start_instance() instance = acs_instance.start_instance()
elif state in ['restarted']: elif state in ['restarted']:
acs_instance.present_instance()
instance = acs_instance.restart_instance() instance = acs_instance.restart_instance()
if instance and 'state' in instance and instance['state'].lower() == 'error': if instance and 'state' in instance and instance['state'].lower() == 'error':