mirror of
https://github.com/thegeeklab/ansible-later.git
synced 2024-11-26 23:00:36 +00:00
333 lines
11 KiB
Python
333 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)
|
||
|
children = vapp.me.get_Children()
|
||
|
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.content)
|
||
|
|
||
|
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.content, **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']
|
||
|
VCD_REQ_ARGS = []
|
||
|
|
||
|
|
||
|
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
|