def clone_vm(self, clone_params, logger, cancellation_context):
        """
        Clone a VM from a template/VM and return the vm oject or throws argument is not valid

        :param cancellation_context:
        :param clone_params: CloneVmParameters =
        :param logger:
        """
        result = self.CloneVmResult()

        if not isinstance(clone_params.si, self.vim.ServiceInstance):
            result.error = 'si must be init as ServiceInstance'
            return result

        if clone_params.template_name is None:
            result.error = 'template_name param cannot be None'
            return result

        if clone_params.vm_name is None:
            result.error = 'vm_name param cannot be None'
            return result

        if clone_params.vm_folder is None:
            result.error = 'vm_folder param cannot be None'
            return result

        datacenter = self.get_datacenter(clone_params)

        dest_folder = self._get_destination_folder(clone_params)

        vm_location = VMLocation.create_from_full_path(clone_params.template_name)

        template = self._get_template(clone_params, vm_location)

        snapshot = self._get_snapshot(clone_params, template)

        resource_pool, host = self._get_resource_pool(datacenter.name, clone_params)

        if not resource_pool and not host:
            raise ValueError('The specifed host, cluster or resource pool could not be found')

        '# set relo_spec'
        placement = self.vim.vm.RelocateSpec()
        if resource_pool:
            placement.pool = resource_pool
        if host:
            placement.host = host

        clone_spec = self.vim.vm.CloneSpec()

        if snapshot:
            clone_spec.snapshot = snapshot
            clone_spec.template = False
            placement.diskMoveType = 'createNewChildDiskBacking'

        placement.datastore = self._get_datastore(clone_params)

        # after deployment the vm must be powered off and will be powered on if needed by orchestration driver
        clone_spec.location = placement
        # clone_params.power_on
        # due to hotfix 1 for release 1.0,
        clone_spec.powerOn = False

        logger.info("cloning VM...")
        try:
            task = template.Clone(folder=dest_folder, name=clone_params.vm_name, spec=clone_spec)
            vm = self.task_waiter.wait_for_task(task=task, logger=logger, action_name='Clone VM',
                                                cancellation_context=cancellation_context)
        except TaskFaultException:
            raise
        except vim.fault.NoPermission as error:
            logger.error("vcenter returned - no permission: {0}".format(error))
            raise Exception('Permissions is not set correctly, please check the log for more info.')
        except Exception as e:
            logger.error("error deploying: {0}".format(e))
            raise Exception('Error has occurred while deploying, please look at the log for more info.')

        result.vm = vm
        return result