summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRene Moser <mail@renemoser.net>2017-06-19 09:18:19 +0200
committerRene Moser <mail@renemoser.net>2017-06-26 14:41:48 +0200
commit4b49b96ca12ba187372fce18e668467dae6662cc (patch)
treea8090c7f59513d3b6a8b2c9161f2a89038378ba7
parent7c38f7cdfab6f1bbe4ef160b708451c6a1e50a96 (diff)
downloadansible-4b49b96ca12ba187372fce18e668467dae6662cc.tar.gz
cloudstack: cs_host: revamp fixes several issues
(cherry picked from commit 1f5839777b28c479783c9a9316c702ee3b6f96bf)
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_host.py96
1 files changed, 79 insertions, 17 deletions
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_host.py b/lib/ansible/modules/cloud/cloudstack/cs_host.py
index c1fd8d1f04..d5417ce279 100644
--- a/lib/ansible/modules/cloud/cloudstack/cs_host.py
+++ b/lib/ansible/modules/cloud/cloudstack/cs_host.py
@@ -36,7 +36,14 @@ options:
description:
- Name of the host.
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:
description:
- Username for the host.
@@ -301,6 +308,11 @@ resource_state:
returned: success
type: string
sample: Enabled
+allocation_state::
+ description: Allocation state of the host.
+ returned: success
+ type: string
+ sample: enabled
state:
description: State of the host.
returned: success
@@ -334,7 +346,14 @@ zone:
'''
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):
@@ -359,7 +378,6 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
'events': 'events',
'hahost': 'ha_host',
'hasenoughcapacity': 'has_enough_capacity',
- 'hosttags': 'host_tags',
'hypervisor': 'hypervisor',
'hypervisorversion': 'hypervisor_version',
'ipaddress': 'ip_address',
@@ -380,12 +398,12 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
'type': 'host_type',
'version': 'host_version',
'gpugroup': 'gpu_group',
-
}
self.allocation_states = {
- 'enabled': 'enable',
- 'disabled': 'disable',
+ 'enabled': 'Enable',
+ 'disabled': 'Disable',
}
+ self.host = None
def get_pod(self, key=None):
pod_name = self.module.params.get('pod')
@@ -425,8 +443,10 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
return None
return self.allocation_states[allocation_state]
- def get_host(self):
- host = None
+ def get_host(self, refresh=False):
+ if self.host is not None and not refresh:
+ return self.host
+
name = self.module.params.get('name')
args = {
'zoneid': self.get_zone(key='id'),
@@ -435,8 +455,8 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
if res:
for h in res['host']:
if name in [h['ipaddress'], h['name']]:
- host = h
- return host
+ self.host = h
+ return self.host
def present_host(self):
host = self.get_host()
@@ -446,6 +466,13 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
host = self._update_host(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):
required_params = [
'password',
@@ -457,7 +484,7 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
self.result['changed'] = True
args = {
'hypervisor': self.module.params.get('hypervisor'),
- 'url': self.module.params.get('name'),
+ 'url': self._get_url(),
'username': self.module.params.get('username'),
'password': self.module.params.get('password'),
'podid': self.get_pod(key='id'),
@@ -470,24 +497,24 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
host = self.cs.addHost(**args)
if 'errortext' in host:
self.module.fail_json(msg="Failed: '%s'" % host['errortext'])
- host = host['host']
+ host = host['host'][0]
return host
def _update_host(self, host):
args = {
'id': host['id'],
'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):
- args['allocationstate'] = self.get_allocation_state()
self.result['changed'] = True
if not self.module.check_mode:
host = self.cs.updateHost(**args)
if 'errortext' in host:
self.module.fail_json(msg="Failed: '%s'" % host['errortext'])
host = host['host']
+
return host
def absent_host(self):
@@ -498,16 +525,51 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
'id': host['id'],
}
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:
self.module.fail_json(msg="Failed: '%s'" % res['errortext'])
+ host = self.poll_job(res, 'host')
+ self._poll_for_maintenance()
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():
argument_spec = cs_argument_spec()
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),
username=dict(default=None),
hypervisor=dict(choices=CS_HYPERVISORS, default=None),