mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-24 03:11:24 -07:00
vca depend on pyvcloud, who depend on PyYAML 3.10, which support python 2.5 as a minimum, cf https://github.com/vmware/pyvcloud/blob/master/requirements.txt and http://pyyaml.org/wiki/PyYAML vmware.py depend on PyVIM, who depend on python 2.6. So we can use the modern syntax for both of them.
329 lines
11 KiB
Python
329 lines
11 KiB
Python
#
|
|
# This file is part of Ansible
|
|
#
|
|
# 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 <http://www.gnu.org/licenses/>.
|
|
|
|
import os
|
|
try:
|
|
from pyvcloud.vcloudair import VCA
|
|
HAS_PYVCLOUD = True
|
|
except ImportError:
|
|
HAS_PYVCLOUD = False
|
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
|
|
SERVICE_MAP = {'vca': 'ondemand', 'vchs': 'subscription', 'vcd': 'vcd'}
|
|
LOGIN_HOST = {'vca': 'vca.vmware.com', 'vchs': 'vchs.vmware.com'}
|
|
|
|
DEFAULT_SERVICE_TYPE = 'vca'
|
|
DEFAULT_VERSION = '5.7'
|
|
|
|
class VcaError(Exception):
|
|
|
|
def __init__(self, msg, **kwargs):
|
|
self.kwargs = kwargs
|
|
super(VcaError, self).__init__(msg)
|
|
|
|
def vca_argument_spec():
|
|
return dict(
|
|
username=dict(type='str', aliases=['user'], required=True),
|
|
password=dict(type='str', aliases=['pass','passwd'], required=True, no_log=True),
|
|
org=dict(),
|
|
service_id=dict(),
|
|
instance_id=dict(),
|
|
host=dict(),
|
|
api_version=dict(default=DEFAULT_VERSION),
|
|
service_type=dict(default=DEFAULT_SERVICE_TYPE, choices=SERVICE_MAP.keys()),
|
|
vdc_name=dict(),
|
|
gateway_name=dict(default='gateway'),
|
|
verify_certs=dict(type='bool', default=True)
|
|
)
|
|
|
|
class VcaAnsibleModule(AnsibleModule):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
argument_spec = vca_argument_spec()
|
|
argument_spec.update(kwargs.get('argument_spec', dict()))
|
|
kwargs['argument_spec'] = argument_spec
|
|
|
|
super(VcaAnsibleModule, self).__init__(*args, **kwargs)
|
|
|
|
if not HAS_PYVCLOUD:
|
|
self.fail("python module pyvcloud is required for this module")
|
|
|
|
self._vca = self.create_instance()
|
|
self.login()
|
|
|
|
self._gateway = None
|
|
self._vdc = None
|
|
|
|
@property
|
|
def vca(self):
|
|
return self._vca
|
|
|
|
@property
|
|
def gateway(self):
|
|
if self._gateway is not None:
|
|
return self._gateway
|
|
vdc_name = self.params['vdc_name']
|
|
gateway_name = self.params['gateway_name']
|
|
_gateway = self.vca.get_gateway(vdc_name, gateway_name)
|
|
if not _gateway:
|
|
raise VcaError('vca instance has no gateway named %s' % gateway_name)
|
|
self._gateway = _gateway
|
|
return _gateway
|
|
|
|
@property
|
|
def vdc(self):
|
|
if self._vdc is not None:
|
|
return self._vdc
|
|
vdc_name = self.params['vdc_name']
|
|
_vdc = self.vca.get_vdc(vdc_name)
|
|
if not _vdc:
|
|
raise VcaError('vca instance has no vdc named %s' % vdc_name)
|
|
self._vdc = _vdc
|
|
return _vdc
|
|
|
|
def get_vapp(self, vapp_name):
|
|
vapp = self.vca.get_vapp(self.vdc, vapp_name)
|
|
if not vapp:
|
|
raise VcaError('vca instance has no vapp named %s' % vapp_name)
|
|
return vapp
|
|
|
|
def get_vm(self, vapp_name, vm_name):
|
|
vapp = self.get_vapp(vapp_name)
|
|
vms = [vm for vm in children.get_Vm() if vm.name == vm_name]
|
|
try:
|
|
return vms[0]
|
|
except IndexError:
|
|
raise VcaError('vapp has no vm named %s' % vm_name)
|
|
|
|
def create_instance(self):
|
|
service_type = self.params.get('service_type', DEFAULT_SERVICE_TYPE)
|
|
if service_type == 'vcd':
|
|
host = self.params['host']
|
|
else:
|
|
host = LOGIN_HOST[service_type]
|
|
username = self.params['username']
|
|
|
|
version = self.params.get('api_version')
|
|
if service_type == 'vchs':
|
|
version = '5.6'
|
|
|
|
verify = self.params.get('verify_certs')
|
|
|
|
return VCA(host=host, username=username,
|
|
service_type=SERVICE_MAP[service_type],
|
|
version=version, verify=verify)
|
|
|
|
def login(self):
|
|
service_type = self.params['service_type']
|
|
password = self.params['password']
|
|
|
|
login_org = None
|
|
if service_type == 'vcd':
|
|
login_org = self.params['org']
|
|
|
|
if not self.vca.login(password=password, org=login_org):
|
|
self.fail('Login to VCA failed', response=self.vca.response)
|
|
|
|
try:
|
|
method_name = 'login_%s' % service_type
|
|
meth = getattr(self, method_name)
|
|
meth()
|
|
except AttributeError:
|
|
self.fail('no login method exists for service_type %s' % service_type)
|
|
except VcaError as e:
|
|
self.fail(e.message, response=self.vca.response, **e.kwargs)
|
|
|
|
def login_vca(self):
|
|
instance_id = self.params['instance_id']
|
|
if not instance_id:
|
|
raise VcaError('missing required instance_id for service_type vca')
|
|
self.vca.login_to_instance_sso(instance=instance_id)
|
|
|
|
def login_vchs(self):
|
|
service_id = self.params['service_id']
|
|
if not service_id:
|
|
raise VcaError('missing required service_id for service_type vchs')
|
|
|
|
org = self.params['org']
|
|
if not org:
|
|
raise VcaError('missing required org for service_type vchs')
|
|
|
|
self.vca.login_to_org(service_id, org)
|
|
|
|
def login_vcd(self):
|
|
org = self.params['org']
|
|
if not org:
|
|
raise VcaError('missing required org for service_type vcd')
|
|
|
|
if not self.vca.token:
|
|
raise VcaError('unable to get token for service_type vcd')
|
|
|
|
if not self.vca.vcloud_session.org_url:
|
|
raise VcaError('unable to get org_url for service_type vcd')
|
|
|
|
self.vca.login(token=self.vca.token, org=org,
|
|
org_url=self.vca.vcloud_session.org_url)
|
|
|
|
def save_services_config(self, blocking=True):
|
|
task = self.gateway.save_services_configuration()
|
|
if not task:
|
|
self.fail(msg='unable to save gateway services configuration')
|
|
if blocking:
|
|
self.vca.block_until_completed(task)
|
|
|
|
def fail(self, msg, **kwargs):
|
|
self.fail_json(msg=msg, **kwargs)
|
|
|
|
def exit(self, **kwargs):
|
|
self.exit_json(**kwargs)
|
|
|
|
|
|
|
|
# -------------------------------------------------------------
|
|
# 9/18/2015 @privateip
|
|
# All of the functions below here were migrated from the original
|
|
# vca_* modules. All functions below should be considered deprecated
|
|
# and will be removed once all of the vca_* modules have been updated
|
|
# to use the new instance module above
|
|
# -------------------------------------------------------------
|
|
|
|
VCA_REQ_ARGS = ['instance_id', 'vdc_name']
|
|
VCHS_REQ_ARGS = ['service_id']
|
|
|
|
|
|
def _validate_module(module):
|
|
if not HAS_PYVCLOUD:
|
|
module.fail_json(msg="python module pyvcloud is needed for this module")
|
|
|
|
service_type = module.params.get('service_type', DEFAULT_SERVICE_TYPE)
|
|
|
|
if service_type == 'vca':
|
|
for arg in VCA_REQ_ARGS:
|
|
if module.params.get(arg) is None:
|
|
module.fail_json(msg="argument %s is mandatory when service type "
|
|
"is vca" % arg)
|
|
|
|
if service_type == 'vchs':
|
|
for arg in VCHS_REQ_ARGS:
|
|
if module.params.get(arg) is None:
|
|
module.fail_json(msg="argument %s is mandatory when service type "
|
|
"is vchs" % arg)
|
|
|
|
if service_type == 'vcd':
|
|
for arg in VCD_REQ_ARGS:
|
|
if module.params.get(arg) is None:
|
|
module.fail_json(msg="argument %s is mandatory when service type "
|
|
"is vcd" % arg)
|
|
|
|
|
|
def serialize_instances(instance_list):
|
|
instances = []
|
|
for i in instance_list:
|
|
instances.append(dict(apiUrl=i['apiUrl'], instance_id=i['id']))
|
|
return instances
|
|
|
|
def _vca_login(vca, password, instance):
|
|
if not vca.login(password=password):
|
|
raise VcaError("Login Failed: Please check username or password",
|
|
error=vca.response.content)
|
|
|
|
if not vca.login_to_instance_sso(instance=instance):
|
|
s_json = serialize_instances(vca.instances)
|
|
raise VcaError("Login to Instance failed: Seems like instance_id provided "
|
|
"is wrong .. Please check", valid_instances=s_json)
|
|
|
|
return vca
|
|
|
|
def _vchs_login(vca, password, service, org):
|
|
if not vca.login(password=password):
|
|
raise VcaError("Login Failed: Please check username or password",
|
|
error=vca.response.content)
|
|
|
|
if not vca.login_to_org(service, org):
|
|
raise VcaError("Failed to login to org, Please check the orgname",
|
|
error=vca.response.content)
|
|
|
|
|
|
def _vcd_login(vca, password, org):
|
|
# TODO: this function needs to be refactored
|
|
if not vca.login(password=password, org=org):
|
|
raise VcaError("Login Failed: Please check username or password "
|
|
"or host parameters")
|
|
|
|
if not vca.login(password=password, org=org):
|
|
raise VcaError("Failed to get the token",
|
|
error=vca.response.content)
|
|
|
|
if not vca.login(token=vca.token, org=org, org_url=vca.vcloud_session.org_url):
|
|
raise VcaError("Failed to login to org", error=vca.response.content)
|
|
|
|
def vca_login(module):
|
|
service_type = module.params.get('service_type')
|
|
username = module.params.get('username')
|
|
password = module.params.get('password')
|
|
instance = module.params.get('instance_id')
|
|
org = module.params.get('org')
|
|
vdc_name = module.params.get('vdc_name')
|
|
service = module.params.get('service_id')
|
|
version = module.params.get('api_version')
|
|
verify = module.params.get('verify_certs')
|
|
|
|
_validate_module(module)
|
|
|
|
if not vdc_name and service_type == 'vchs':
|
|
vdc_name = module.params.get('service_id')
|
|
|
|
if not org and service_type == 'vchs':
|
|
org = vdc_name or service
|
|
|
|
if service_type == 'vcd':
|
|
host = module.params.get('host')
|
|
else:
|
|
host = LOGIN_HOST[service_type]
|
|
|
|
username = os.environ.get('VCA_USER', username)
|
|
password = os.environ.get('VCA_PASS', password)
|
|
|
|
if not username or not password:
|
|
msg = "Either the username or password is not set, please check args"
|
|
module.fail_json(msg=msg)
|
|
|
|
if service_type == 'vchs':
|
|
version = '5.6'
|
|
elif service_type == 'vcd' and not version:
|
|
version == '5.6'
|
|
|
|
vca = VCA(host=host, username=username,
|
|
service_type=SERVICE_MAP[service_type],
|
|
version=version, verify=verify)
|
|
|
|
try:
|
|
if service_type == 'vca':
|
|
_vca_login(vca, password, instance)
|
|
elif service_type == 'vchs':
|
|
_vchs_login(vca, password, service, org)
|
|
elif service_type == 'vcd':
|
|
_vcd_login(vca, password, org)
|
|
except VcaError as e:
|
|
module.fail_json(msg=e.message, **e.kwargs)
|
|
|
|
return vca
|
|
|
|
|
|
|
|
|
|
|