mirror of
				https://github.com/ansible-collections/community.general.git
				synced 2025-10-26 05:50:36 -07:00 
			
		
		
		
	vca module utility uses response object instead of response.content which raises exception in while fail_json call. Use content attribute from response object instead which is exact description of HTTP Response error. Fixes #25378 Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
		
			
				
	
	
		
			332 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			332 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
 |