From bb6d983290e030502bd407ba800ba0eb2f60209c Mon Sep 17 00:00:00 2001 From: Rene Moser Date: Thu, 26 Mar 2015 10:26:33 +0100 Subject: [PATCH] cloudstack: add utils for common functionality --- lib/ansible/module_utils/cloudstack.py | 182 +++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 lib/ansible/module_utils/cloudstack.py diff --git a/lib/ansible/module_utils/cloudstack.py b/lib/ansible/module_utils/cloudstack.py new file mode 100644 index 00000000000..cb482ae9932 --- /dev/null +++ b/lib/ansible/module_utils/cloudstack.py @@ -0,0 +1,182 @@ +# -*- coding: utf-8 -*- +# +# (c) 2015, René Moser +# +# This code is part of Ansible, but is an independent component. +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +import sys + +try: + from cs import CloudStack, CloudStackException, read_config +except ImportError: + print("failed=True " + \ + "msg='python library cs required: pip install cs'") + sys.exit(1) + + +class AnsibleCloudStack: + + def __init__(self, module): + self.module = module + self._connect() + + self.project_id = None + self.ip_address_id = None + self.zone_id = None + self.vm_id = None + self.os_type_id = None + self.hypervisor = None + + + def _connect(self): + api_key = self.module.params.get('api_key') + api_secret = self.module.params.get('secret_key') + api_url = self.module.params.get('api_url') + api_http_method = self.module.params.get('api_http_method') + + if api_key and api_secret and api_url: + self.cs = CloudStack( + endpoint=api_url, + key=api_key, + secret=api_secret, + method=api_http_method + ) + else: + self.cs = CloudStack(**read_config()) + + + def get_project_id(self): + if self.project_id: + return self.project_id + + project = self.module.params.get('project') + if not project: + return None + + projects = self.cs.listProjects() + if projects: + for p in projects['project']: + if project in [ p['name'], p['displaytext'], p['id'] ]: + self.project_id = p['id'] + return self.project_id + self.module.fail_json(msg="project '%s' not found" % project) + + + def get_ip_address_id(self): + if self.ip_address_id: + return self.ip_address_id + + ip_address = self.module.params.get('ip_address') + if not ip_address: + self.module.fail_json(msg="IP address param 'ip_address' is required") + + args = {} + args['ipaddress'] = ip_address + args['projectid'] = self.get_project_id() + ip_addresses = self.cs.listPublicIpAddresses(**args) + + if not ip_addresses: + self.module.fail_json(msg="IP address '%s' not found" % args['ipaddress']) + + self.ip_address_id = ip_addresses['publicipaddress'][0]['id'] + return self.ip_address_id + + + def get_vm_id(self): + if self.vm_id: + return self.vm_id + + vm = self.module.params.get('vm') + if not vm: + self.module.fail_json(msg="Virtual machine param 'vm' is required") + + args = {} + args['projectid'] = self.get_project_id() + vms = self.cs.listVirtualMachines(**args) + if vms: + for v in vms['virtualmachine']: + if vm in [ v['name'], v['id'] ]: + self.vm_id = v['id'] + return self.vm_id + self.module.fail_json(msg="Virtual machine '%s' not found" % vm) + + + def get_zone_id(self): + if self.zone_id: + return self.zone_id + + zone = self.module.params.get('zone') + zones = self.cs.listZones() + + # use the first zone if no zone param given + if not zone: + self.zone_id = zones['zone'][0]['id'] + return self.zone_id + + if zones: + for z in zones['zone']: + if zone in [ z['name'], z['id'] ]: + self.zone_id = z['id'] + return self.zone_id + self.module.fail_json(msg="zone '%s' not found" % zone) + + + def get_os_type_id(self): + if self.os_type_id: + return self.os_type_id + + os_type = self.module.params.get('os_type') + if not os_type: + return None + + os_types = self.cs.listOsTypes() + if os_types: + for o in os_types['ostype']: + if os_type in [ o['description'], o['id'] ]: + self.os_type_id = o['id'] + return self.os_type_id + self.module.fail_json(msg="OS type '%s' not found" % os_type) + + + def get_hypervisor(self): + if self.hypervisor: + return self.hypervisor + + hypervisor = self.module.params.get('hypervisor') + hypervisors = self.cs.listHypervisors() + + # use the first hypervisor if no hypervisor param given + if not hypervisor: + self.hypervisor = hypervisors['hypervisor'][0]['name'] + return self.hypervisor + + for h in hypervisors['hypervisor']: + if hypervisor.lower() == h['name'].lower(): + self.hypervisor = h['name'] + return self.hypervisor + self.module.fail_json(msg="Hypervisor '%s' not found" % hypervisor) + + + def _poll_job(self, job=None, key=None): + if 'jobid' in job: + while True: + res = self.cs.queryAsyncJobResult(jobid=job['jobid']) + if res['jobstatus'] != 0: + if 'jobresult' in res and key is not None and key in res['jobresult']: + job = res['jobresult'][key] + break + time.sleep(2) + return job