|
|
|
@ -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
|
|
|
|
@ -335,7 +347,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):
|
|
|
|
@ -360,7 +379,6 @@ class AnsibleCloudStackHost(AnsibleCloudStack):
|
|
|
|
|
'events': 'events',
|
|
|
|
|
'hahost': 'ha_host',
|
|
|
|
|
'hasenoughcapacity': 'has_enough_capacity',
|
|
|
|
|
'hosttags': 'host_tags',
|
|
|
|
|
'hypervisor': 'hypervisor',
|
|
|
|
|
'hypervisorversion': 'hypervisor_version',
|
|
|
|
|
'ipaddress': 'ip_address',
|
|
|
|
@ -381,12 +399,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')
|
|
|
|
@ -426,8 +444,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'),
|
|
|
|
@ -436,8 +456,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()
|
|
|
|
@ -447,6 +467,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',
|
|
|
|
@ -458,7 +485,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'),
|
|
|
|
@ -471,24 +498,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):
|
|
|
|
@ -499,16 +526,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),
|
|
|
|
|