cloudstack: cs_host: revamp fixes several issues

This commit is contained in:
Rene Moser 2017-06-19 09:18:19 +02:00 committed by René Moser
commit 1f5839777b

View file

@ -36,7 +36,14 @@ options:
description: description:
- Name of the host. - Name of the host.
required: true required: true
aliases: [ 'url', 'ip_address' ] aliases: [ 'ip_address' ]
url:
description:
- Url of the host used to create a host.
- If not provided, C(http://) and param C(name) is used as url.
- Only considered if C(state=present) and host does not yet exist.
required: false
default: null
username: username:
description: description:
- Username for the host. - Username for the host.
@ -301,6 +308,11 @@ resource_state:
returned: success returned: success
type: string type: string
sample: Enabled sample: Enabled
allocation_state::
description: Allocation state of the host.
returned: success
type: string
sample: enabled
state: state:
description: State of the host. description: State of the host.
returned: success returned: success
@ -335,7 +347,14 @@ zone:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.cloudstack import AnsibleCloudStack, CloudStackException, cs_argument_spec, cs_required_together, CS_HYPERVISORS from ansible.module_utils.cloudstack import (
AnsibleCloudStack,
CloudStackException,
cs_argument_spec,
cs_required_together,
CS_HYPERVISORS
)
import time
class AnsibleCloudStackHost(AnsibleCloudStack): class AnsibleCloudStackHost(AnsibleCloudStack):
@ -360,7 +379,6 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
'events': 'events', 'events': 'events',
'hahost': 'ha_host', 'hahost': 'ha_host',
'hasenoughcapacity': 'has_enough_capacity', 'hasenoughcapacity': 'has_enough_capacity',
'hosttags': 'host_tags',
'hypervisor': 'hypervisor', 'hypervisor': 'hypervisor',
'hypervisorversion': 'hypervisor_version', 'hypervisorversion': 'hypervisor_version',
'ipaddress': 'ip_address', 'ipaddress': 'ip_address',
@ -381,12 +399,12 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
'type': 'host_type', 'type': 'host_type',
'version': 'host_version', 'version': 'host_version',
'gpugroup': 'gpu_group', 'gpugroup': 'gpu_group',
} }
self.allocation_states = { self.allocation_states = {
'enabled': 'enable', 'enabled': 'Enable',
'disabled': 'disable', 'disabled': 'Disable',
} }
self.host = None
def get_pod(self, key=None): def get_pod(self, key=None):
pod_name = self.module.params.get('pod') pod_name = self.module.params.get('pod')
@ -426,8 +444,10 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
return None return None
return self.allocation_states[allocation_state] return self.allocation_states[allocation_state]
def get_host(self): def get_host(self, refresh=False):
host = None if self.host is not None and not refresh:
return self.host
name = self.module.params.get('name') name = self.module.params.get('name')
args = { args = {
'zoneid': self.get_zone(key='id'), 'zoneid': self.get_zone(key='id'),
@ -436,8 +456,8 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
if res: if res:
for h in res['host']: for h in res['host']:
if name in [h['ipaddress'], h['name']]: if name in [h['ipaddress'], h['name']]:
host = h self.host = h
return host return self.host
def present_host(self): def present_host(self):
host = self.get_host() host = self.get_host()
@ -447,6 +467,13 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
host = self._update_host(host) host = self._update_host(host)
return host return host
def _get_url(self):
url = self.module.params.get('url')
if url:
return url
else:
return "http://%s" % self.module.params.get('name')
def _create_host(self, host): def _create_host(self, host):
required_params = [ required_params = [
'password', 'password',
@ -458,7 +485,7 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
self.result['changed'] = True self.result['changed'] = True
args = { args = {
'hypervisor': self.module.params.get('hypervisor'), 'hypervisor': self.module.params.get('hypervisor'),
'url': self.module.params.get('name'), 'url': self._get_url(),
'username': self.module.params.get('username'), 'username': self.module.params.get('username'),
'password': self.module.params.get('password'), 'password': self.module.params.get('password'),
'podid': self.get_pod(key='id'), 'podid': self.get_pod(key='id'),
@ -471,24 +498,24 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
host = self.cs.addHost(**args) host = self.cs.addHost(**args)
if 'errortext' in host: if 'errortext' in host:
self.module.fail_json(msg="Failed: '%s'" % host['errortext']) self.module.fail_json(msg="Failed: '%s'" % host['errortext'])
host = host['host'] host = host['host'][0]
return host return host
def _update_host(self, host): def _update_host(self, host):
args = { args = {
'id': host['id'], 'id': host['id'],
'hosttags': self.get_host_tags(), 'hosttags': self.get_host_tags(),
'allocationstate': self.module.params.get('allocation_state'), 'allocationstate': self.get_allocation_state()
} }
host['allocationstate'] = host['resourcestate'].lower() host['allocationstate'] = self.allocation_states[host['resourcestate'].lower()]
if self.has_changed(args, host): if self.has_changed(args, host):
args['allocationstate'] = self.get_allocation_state()
self.result['changed'] = True self.result['changed'] = True
if not self.module.check_mode: if not self.module.check_mode:
host = self.cs.updateHost(**args) host = self.cs.updateHost(**args)
if 'errortext' in host: if 'errortext' in host:
self.module.fail_json(msg="Failed: '%s'" % host['errortext']) self.module.fail_json(msg="Failed: '%s'" % host['errortext'])
host = host['host'] host = host['host']
return host return host
def absent_host(self): def absent_host(self):
@ -499,16 +526,51 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
'id': host['id'], 'id': host['id'],
} }
if not self.module.check_mode: if not self.module.check_mode:
res = self.cs.deleteHost(**args) res = self.enable_maintenance()
if res:
res = self.cs.deleteHost(**args)
if 'errortext' in res:
self.module.fail_json(msg="Failed: '%s'" % res['errortext'])
return host
def enable_maintenance(self):
host = self.get_host()
if host['resourcestate'] not in ['PrepareForMaintenance', 'Maintenance']:
self.result['changed'] = True
args = {
'id': host['id'],
}
if not self.module.check_mode:
res = self.cs.prepareHostForMaintenance(**args)
if 'errortext' in res: if 'errortext' in res:
self.module.fail_json(msg="Failed: '%s'" % res['errortext']) self.module.fail_json(msg="Failed: '%s'" % res['errortext'])
host = self.poll_job(res, 'host')
self._poll_for_maintenance()
return host return host
def _poll_for_maintenance(self):
for i in range(0, 300):
time.sleep(2)
host = self.get_host(refresh=True)
if not host:
return None
elif host['resourcestate'] != 'PrepareForMaintenance':
return host
self.fail_json("Polling for maintenance timed out")
def get_result(self, host):
super(AnsibleCloudStackHost, self).get_result(host)
if host:
self.result['allocation_state'] = host['resourcestate'].lower()
self.result['host_tags'] = host['hosttags'].split(',') if host.get('hosttags') else []
return self.result
def main(): def main():
argument_spec = cs_argument_spec() argument_spec = cs_argument_spec()
argument_spec.update(dict( argument_spec.update(dict(
name=dict(required=True, aliases=['url', 'ip_address']), name=dict(required=True, aliases=['ip_address']),
url=dict(),
password=dict(default=None, no_log=True), password=dict(default=None, no_log=True),
username=dict(default=None), username=dict(default=None),
hypervisor=dict(choices=CS_HYPERVISORS, default=None), hypervisor=dict(choices=CS_HYPERVISORS, default=None),