Exemple #1
0
 def _call_method(self, module, method, *args, **kwargs):
     """Calls a method within the module specified with
     args provided.
     """
     try:
         if not self._is_vim_object(module):
             return self.invoke_api(module, method, self.vim, *args,
                                    **kwargs)
         return self.invoke_api(module, method, *args, **kwargs)
     except vexc.ManagedObjectNotFoundException as monfe:
         with excutils.save_and_reraise_exception() as ctxt:
             moref = monfe.details.get("obj") if monfe.details else None
             for arg in itertools.chain(args, kwargs.values()):
                 if not isinstance(arg, StableMoRefProxy):
                     continue
                 moref_arg = get_moref_value(arg.moref)
                 if moref != moref_arg:
                     continue
                 # We have found the argument with the moref
                 # causing the exception and we can try to recover it
                 arg.fetch_moref(self)
                 if not arg.moref:
                     # We didn't recover the reference
                     ctxt.reraise = True
                     break
                 moref_arg = get_moref_value(arg.moref)
                 if moref != moref_arg:
                     # We actually recovered, so do not raise `monfe`
                     LOG.info("Replaced moref %s with %s", moref, moref_arg)
                     ctxt.reraise = False
     # We only end up here when we have recovered a moref by changing
     # the stored value of an argument to a different value,
     # so let's try again (and recover again if it happens more than once)
     return self._call_method(module, method, *args, **kwargs)
Exemple #2
0
 def _get_ds_browser(self, ds_ref):
     ds_browser = self._ds_browser.get(vutil.get_moref_value(ds_ref))
     if not ds_browser:
         ds_browser = vutil.get_object_property(self._session.vim,
                                                ds_ref,
                                                "browser")
         self._ds_browser[vutil.get_moref_value(ds_ref)] = ds_browser
     return ds_browser
Exemple #3
0
def get_dc_info(session, ds_ref):
    """Get the datacenter name and the reference."""
    dc_info = _DS_DC_MAPPING.get(vutil.get_moref_value(ds_ref))
    if not dc_info:
        dcs = session._call_method(vim_util, "get_objects",
                "Datacenter", ["name", "datastore", "vmFolder"])
        _update_datacenter_cache_from_objects(session, dcs)
        dc_info = _DS_DC_MAPPING.get(vutil.get_moref_value(ds_ref))
    return dc_info
Exemple #4
0
        def _is_host_usable(host_ref):
            props = host_prop_map.get(vim_util.get_moref_value(host_ref))
            if props is None:
                props = self._get_host_properties(host_ref)
                host_prop_map[vim_util.get_moref_value(host_ref)] = props

            runtime = props.get('runtime')
            parent = props.get('parent')
            if runtime and parent:
                return (runtime.connectionState == 'connected'
                        and not runtime.inMaintenanceMode)
            else:
                return False
Exemple #5
0
    def _select_best_datastore(self, datastores, valid_host_refs=None):

        if not datastores:
            return

        def _sort_key(ds_props):
            host = ds_props.get('host')
            summary = ds_props.get('summary')
            space_utilization = (1.0 -
                                 (summary.freeSpace / float(summary.capacity)))
            return (-len(host), space_utilization)

        host_prop_map = {}

        def _is_host_usable(host_ref):
            props = host_prop_map.get(vim_util.get_moref_value(host_ref))
            if props is None:
                props = self._get_host_properties(host_ref)
                host_prop_map[vim_util.get_moref_value(host_ref)] = props

            runtime = props.get('runtime')
            parent = props.get('parent')
            if runtime and parent:
                return (runtime.connectionState == 'connected'
                        and not runtime.inMaintenanceMode)
            else:
                return False

        valid_host_refs = valid_host_refs or []
        valid_hosts = [
            vim_util.get_moref_value(host_ref) for host_ref in valid_host_refs
        ]

        def _select_host(host_mounts):
            random.shuffle(host_mounts)
            for host_mount in host_mounts:
                host_mount_key_value = vim_util.get_moref_value(host_mount.key)
                if valid_hosts and host_mount_key_value not in valid_hosts:
                    continue
                if (self._vops._is_usable(host_mount.mountInfo)
                        and _is_host_usable(host_mount.key)):
                    return host_mount.key

        sorted_ds_props = sorted(datastores.values(), key=_sort_key)
        for ds_props in sorted_ds_props:
            host_ref = _select_host(ds_props['host'])
            if host_ref:
                host_ref_value = vim_util.get_moref_value(host_ref)
                rp = self._get_resource_pool(
                    host_prop_map[host_ref_value]['parent'])
                return (host_ref, rp, ds_props['summary'])
def add_port_group(session, dvs_moref, name, vlan_id=None, trunk_mode=False):
    """Add a new port group to the dvs_moref

    :param session: vCenter soap session
    :param dvs_moref: managed DVS object reference
    :param name: the name of the port group
    :param vlan_id: vlan_id for the port
    :param trunk_mode: indicates if the port will have trunk mode or use
                       specific tag above
    :returns: The new portgroup moref
    """
    pg_spec = get_port_group_spec(session,
                                  name,
                                  vlan_id,
                                  trunk_mode=trunk_mode)
    task = session.invoke_api(session.vim,
                              'CreateDVPortgroup_Task',
                              dvs_moref,
                              spec=pg_spec)
    task_info = session.wait_for_task(task)
    LOG.info(
        "%(name)s create on %(dvs)s with %(value)s.", {
            'name': name,
            'dvs': vim_util.get_moref_value(dvs_moref),
            'value': task_info.result.value
        })
    return task_info.result
Exemple #7
0
 def _select_host(host_mounts):
     random.shuffle(host_mounts)
     for host_mount in host_mounts:
         host_mount_key_value = vim_util.get_moref_value(host_mount.key)
         if valid_hosts and host_mount_key_value not in valid_hosts:
             continue
         if (self._vops._is_usable(host_mount.mountInfo)
                 and _is_host_usable(host_mount.key)):
             return host_mount.key
Exemple #8
0
 def _filter_by_profile(self, datastores, profile_id):
     """Filter out input datastores that do not match the given profile."""
     cf = self._session.pbm.client.factory
     hubs = pbm.convert_datastores_to_hubs(cf, datastores)
     hubs = pbm.filter_hubs_by_profile(self._session, hubs, profile_id)
     hub_ids = [hub.hubId for hub in hubs]
     return {
         k: v
         for k, v in datastores.items()
         if vim_util.get_moref_value(k) in hub_ids
     }
    def test_get_dsc_by_name(self, cancel_retrieval, continue_retrieval):
        pod_prop = mock.Mock()
        pod_prop.val = 'ds-cluster'
        pod_ref = vim_util.get_moref('group-p456', 'StoragePod')
        pod = mock.Mock()
        pod.propSet = [pod_prop]
        pod.obj = pod_ref

        retrieve_result = mock.Mock()
        retrieve_result.objects = [pod]

        session = mock.Mock()
        session.invoke_api = mock.Mock()
        session.invoke_api.return_value = retrieve_result
        name = 'ds-cluster'
        dsc_ref, dsc_name = datastore.get_dsc_ref_and_name(session, name)
        self.assertEqual((vim_util.get_moref_value(pod_ref),
                          vim_util.get_moref_type(pod_ref)),
                         (vim_util.get_moref_value(dsc_ref),
                          vim_util.get_moref_type(dsc_ref)))
Exemple #10
0
    def _poll_task(self, task, ctx):
        """Poll the given task until completion.

        If the task completes successfully, the method returns the task info
        using the input event (param done). In case of any error, appropriate
        exception is set in the event.

        :param task: managed object reference of the task
        :param ctx: request context for the corresponding task
        """
        if ctx is not None:
            ctx.update_store()
        try:
            # we poll tasks too often, so skip logging the opID as it generates
            # too much noise in the logs
            task_info = self.invoke_api(vim_util,
                                        'get_object_property',
                                        self.vim,
                                        task,
                                        'info',
                                        skip_op_id=True)
        except exceptions.VimException:
            with excutils.save_and_reraise_exception():
                LOG.exception(
                    "Error occurred while reading info of "
                    "task: %s.", task)
        else:
            task_detail = {'id': vim_util.get_moref_value(task)}
            # some internal tasks do not have 'name' set
            if getattr(task_info, 'name', None):
                task_detail['name'] = task_info.name

            if task_info.state in ['queued', 'running']:
                if hasattr(task_info, 'progress'):
                    LOG.debug("Task: %(task)s progress is %(progress)s%%.", {
                        'task': task_detail,
                        'progress': task_info.progress
                    })
            elif task_info.state == 'success':

                def get_completed_task():
                    complete_time = getattr(task_info, 'completeTime', None)
                    if complete_time:
                        duration = complete_time - task_info.queueTime
                        task_detail['duration_secs'] = duration.total_seconds()
                    return task_detail

                LOG.debug("Task: %s completed successfully.",
                          get_completed_task())
                raise loopingcall.LoopingCallDone(task_info)
            else:
                raise exceptions.translate_fault(task_info.error)
Exemple #11
0
def filter_datastores_by_hubs(hubs, datastores):
    """Get filtered subset of datastores corresponding to the given hub list.

    :param hubs: list of PbmPlacementHub morefs
    :param datastores: all candidate datastores
    :returns: subset of datastores corresponding to the given hub list
    """
    filtered_dss = []
    hub_ids = [hub.hubId for hub in hubs]
    for ds in datastores:
        if vim_util.get_moref_value(ds) in hub_ids:
            filtered_dss.append(ds)
    return filtered_dss
Exemple #12
0
 def get_volume_connector(self, instance):
     """Return volume connector information."""
     try:
         vm_ref = vm_util.get_vm_ref(self._session, instance)
     except exception.InstanceNotFound:
         vm_ref = None
     iqn = self._iscsi_get_host_iqn(instance)
     connector = {'ip': CONF.vmware.host_ip,
                  'initiator': iqn,
                  'host': CONF.vmware.host_ip}
     if vm_ref:
         connector['instance'] = vutil.get_moref_value(vm_ref)
     return connector
Exemple #13
0
    def __init__(self, virtapi, scheme="https"):
        super(VMwareVCDriver, self).__init__(virtapi)

        if (CONF.vmware.host_ip is None or
            CONF.vmware.host_username is None or
            CONF.vmware.host_password is None):
            raise Exception(_("Must specify host_ip, host_username and "
                              "host_password to use vmwareapi.VMwareVCDriver"))

        self._datastore_regex = None
        if CONF.vmware.datastore_regex:
            try:
                self._datastore_regex = re.compile(CONF.vmware.datastore_regex)
            except re.error:
                raise exception.InvalidInput(reason=
                    _("Invalid Regular Expression %s")
                    % CONF.vmware.datastore_regex)

        self._session = VMwareAPISession(scheme=scheme)

        self._check_min_version()

        # Update the PBM location if necessary
        if CONF.vmware.pbm_enabled:
            self._update_pbm_location()

        self._validate_configuration()
        self._cluster_name = CONF.vmware.cluster_name
        self._cluster_ref = vm_util.get_cluster_ref_by_name(self._session,
                                                            self._cluster_name)
        if self._cluster_ref is None:
            raise exception.NotFound(_("The specified cluster '%s' was not "
                                       "found in vCenter")
                                     % self._cluster_name)
        self._vcenter_uuid = self._get_vcenter_uuid()
        self._nodename = \
            self._create_nodename(vim_util.get_moref_value(self._cluster_ref))
        self._volumeops = volumeops.VMwareVolumeOps(self._session,
                                                    self._cluster_ref)
        self._vmops = vmops.VMwareVMOps(self._session,
                                        virtapi,
                                        self._volumeops,
                                        self._cluster_ref,
                                        datastore_regex=self._datastore_regex)
        self._vc_state = host.VCState(self._session,
                                      self._nodename,
                                      self._cluster_ref,
                                      self._datastore_regex)

        # Register the OpenStack extension
        self._register_openstack_extension()
Exemple #14
0
def convert_datastores_to_hubs(pbm_client_factory, datastores):
    """Convert given datastore morefs to PbmPlacementHub morefs.

    :param pbm_client_factory: Factory to create PBM API input specs
    :param datastores: list of datastore morefs
    :returns: list of PbmPlacementHub morefs
    """
    hubs = []
    for ds in datastores:
        hub = pbm_client_factory.create('ns0:PbmPlacementHub')
        hub.hubId = vim_util.get_moref_value(ds)
        hub.hubType = 'Datastore'
        hubs.append(hub)
    return hubs
 def test_get_dsc_with_moid(self):
     session = mock.Mock()
     session.invoke_api = mock.Mock()
     session.invoke_api.return_value = 'ds-cluster'
     dsc_moid = 'group-p123'
     dsc_ref, dsc_name = datastore.get_dsc_ref_and_name(session, dsc_moid)
     self.assertEqual((dsc_moid, 'StoragePod'),
                      (vim_util.get_moref_value(dsc_ref),
                       vim_util.get_moref_type(dsc_ref)))
     self.assertEqual('ds-cluster', dsc_name)
     session.invoke_api.assert_called_once_with(vim_util,
                                                'get_object_property',
                                                session.vim, mock.ANY,
                                                'name')
Exemple #16
0
        def side_effect(mo, **kwargs):
            self.assertEqual(managed_object, vim_util.get_moref_type(mo))
            self.assertEqual(managed_object, vim_util.get_moref_value(mo))
            fault = mock.Mock(faultstring="MyFault")

            fault_children = mock.Mock()
            fault_children.name = "name"
            fault_children.getText.return_value = "value"
            child = mock.Mock()
            child.get.return_value = fault_name
            child.getChildren.return_value = [fault_children]
            detail = mock.Mock()
            detail.getChildren.return_value = [child]
            doc.childAtPath.return_value = detail
            raise suds.WebFault(fault, doc)
Exemple #17
0
def get_connected_hosts(session, datastore):
    """Get all the hosts to which the datastore is connected.

    :param datastore: Reference to the datastore entity
    :return: List of managed object references of all connected
             hosts
    """
    host_mounts = session._call_method(vutil, 'get_object_property',
                                       datastore, 'host')
    if not hasattr(host_mounts, 'DatastoreHostMount'):
        return []

    connected_hosts = []
    for host_mount in host_mounts.DatastoreHostMount:
        connected_hosts.append(vutil.get_moref_value(host_mount.key))

    return connected_hosts
Exemple #18
0
def get_profiles(session, vm):
    """Query storage profiles associated with the given vm.

    :param session: VMwareAPISession instance
    :param vm: vm reference
    :return: profile IDs
    """
    pbm = session.pbm
    profile_manager = pbm.service_content.profileManager

    object_ref = pbm.client.factory.create('ns0:PbmServerObjectRef')
    object_ref.key = vim_util.get_moref_value(vm)
    object_ref.objectType = 'virtualMachine'

    return session.invoke_api(pbm,
                              'PbmQueryAssociatedProfile',
                              profile_manager,
                              entity=object_ref)
Exemple #19
0
    def _retrieve_properties_ex_fault_checker(response):
        """Checks the RetrievePropertiesEx API response for errors.

        Certain faults are sent in the SOAP body as a property of missingSet.
        This method raises VimFaultException when a fault is found in the
        response.

        :param response: response from RetrievePropertiesEx API call
        :raises: VimFaultException
        """
        fault_list = []
        details = {}
        if not response:
            # This is the case when the session has timed out. ESX SOAP
            # server sends an empty RetrievePropertiesExResponse. Normally
            # missingSet in the response objects has the specifics about
            # the error, but that's not the case with a timed out idle
            # session. It is as bad as a terminated session for we cannot
            # use the session. Therefore setting fault to NotAuthenticated
            # fault.
            LOG.debug(
                "RetrievePropertiesEx API response is empty; setting "
                "fault to %s.", exceptions.NOT_AUTHENTICATED)
            fault_list = [exceptions.NOT_AUTHENTICATED]
        else:
            for obj_cont in response.objects:
                if hasattr(obj_cont, 'missingSet'):
                    for missing_elem in obj_cont.missingSet:
                        f_type = missing_elem.fault.fault
                        f_name = f_type.__class__.__name__
                        fault_list.append(f_name)
                        if f_name == exceptions.NO_PERMISSION:
                            details['object'] = \
                                vim_util.get_moref_value(f_type.object)
                            details['privilegeId'] = f_type.privilegeId

        if fault_list:
            fault_string = _("Error occurred while calling "
                             "RetrievePropertiesEx.")
            raise exceptions.VimFaultException(fault_list,
                                               fault_string,
                                               details=details)
Exemple #20
0
def _update_datacenter_cache_from_objects(session, dcs):
    """Updates the datastore/datacenter cache."""
    with vutil.WithRetrieval(session.vim, dcs) as dc_objs:
        for dco in dc_objs:
            dc_ref = dco.obj
            ds_refs = []
            prop_dict = vm_util.propset_dict(dco.propSet)
            name = prop_dict.get('name')
            vmFolder = prop_dict.get('vmFolder')
            datastore_refs = prop_dict.get('datastore')
            if datastore_refs:
                datastore_refs = datastore_refs.ManagedObjectReference
                for ds in datastore_refs:
                    ds_refs.append(vutil.get_moref_value(ds))
            else:
                LOG.debug("Datacenter %s doesn't have any datastore "
                          "associated with it, ignoring it", name)
            for ds_ref in ds_refs:
                _DS_DC_MAPPING[ds_ref] = DcInfo(ref=dc_ref, name=name,
                                                vmFolder=vmFolder)
Exemple #21
0
        def _is_ds_valid(ds_ref, ds_props):
            summary = ds_props.get('summary')
            host_mounts = ds_props.get('host')
            if (summary is None or host_mounts is None):
                return False

            if self._ds_regex and not self._ds_regex.match(summary.name):
                return False

            if (hard_anti_affinity_ds and vim_util.get_moref_value(ds_ref)
                    in hard_anti_affinity_ds):
                return False

            if summary.capacity == 0 or summary.freeSpace < size_bytes:
                return False

            if (valid_hosts
                    and not _is_ds_accessible_to_valid_host(host_mounts)):
                return False

            return _is_valid_ds_type(summary) and _is_ds_usable(summary)
    def test_filter_datastores_by_hubs(self):
        ds_values = []
        datastores = []
        for i in range(0, 10):
            value = "ds-%d" % i
            ds_values.append(value)
            datastores.append(self._create_datastore(value))

        hubs = []
        hub_ids = ds_values[0:int(len(ds_values) / 2)]
        for hub_id in hub_ids:
            hub = mock.Mock()
            hub.hubId = hub_id
            hubs.append(hub)

        filtered_ds = pbm.filter_datastores_by_hubs(hubs, datastores)
        self.assertEqual(len(hubs), len(filtered_ds))
        filtered_ds_values = [
            vim_util.get_moref_value(ds) for ds in filtered_ds
        ]
        self.assertEqual(set(hub_ids), set(filtered_ds_values))
 def test_get_dvs_moref(self):
     moref = dvs_util.get_dvs_moref('dvs-123')
     self.assertEqual('dvs-123', vim_util.get_moref_value(moref))
     self.assertEqual('VmwareDistributedVirtualSwitch',
                      vim_util.get_moref_type(moref))
Exemple #24
0
 def side_effect(mo, **kwargs):
     self.assertEqual(managed_object, vim_util.get_moref_type(mo))
     self.assertEqual(managed_object, vim_util.get_moref_value(mo))
     return resp
Exemple #25
0
    def _filter_datastores(self,
                           datastores,
                           size_bytes,
                           profile_id,
                           hard_anti_affinity_ds,
                           hard_affinity_ds_types,
                           valid_host_refs=None):

        if not datastores:
            return

        def _is_valid_ds_type(summary):
            ds_type = summary.type.lower()
            return (ds_type in DatastoreType.get_all_types()
                    and (hard_affinity_ds_types is None
                         or ds_type in hard_affinity_ds_types))

        def _is_ds_usable(summary):
            return summary.accessible and not self._vops._in_maintenance(
                summary)

        valid_host_refs = valid_host_refs or []
        valid_hosts = [
            vim_util.get_moref_value(host_ref) for host_ref in valid_host_refs
        ]

        def _is_ds_accessible_to_valid_host(host_mounts):
            for host_mount in host_mounts:
                if vim_util.get_moref_value(host_mount.key) in valid_hosts:
                    return True

        def _is_ds_valid(ds_ref, ds_props):
            summary = ds_props.get('summary')
            host_mounts = ds_props.get('host')
            if (summary is None or host_mounts is None):
                return False

            if self._ds_regex and not self._ds_regex.match(summary.name):
                return False

            if (hard_anti_affinity_ds and vim_util.get_moref_value(ds_ref)
                    in hard_anti_affinity_ds):
                return False

            if summary.capacity == 0 or summary.freeSpace < size_bytes:
                return False

            if (valid_hosts
                    and not _is_ds_accessible_to_valid_host(host_mounts)):
                return False

            return _is_valid_ds_type(summary) and _is_ds_usable(summary)

        datastores = {
            k: v
            for k, v in datastores.items() if _is_ds_valid(k, v)
        }

        if datastores and profile_id:
            datastores = self._filter_by_profile(datastores, profile_id)

        return datastores
Exemple #26
0
 def side_effect(mo, **kwargs):
     self.assertEqual(managed_object, vim_util.get_moref_type(mo))
     self.assertEqual(managed_object, vim_util.get_moref_value(mo))
     raise Exception(message)
Exemple #27
0
 def side_effect(mo, **kwargs):
     self.assertEqual(managed_object, vim_util.get_moref_type(mo))
     self.assertEqual(managed_object, vim_util.get_moref_value(mo))
     raise requests.HTTPError()
Exemple #28
0
 def side_effect(mo, **kwargs):
     self.assertEqual(managed_object, vim_util.get_moref_type(mo))
     self.assertEqual(managed_object, vim_util.get_moref_value(mo))
     raise httplib.CannotSendHeader()
Exemple #29
0
 def side_effect(mo, **kwargs):
     self.assertEqual(managed_object, vim_util.get_moref_type(mo))
     self.assertEqual(managed_object, vim_util.get_moref_value(mo))
     raise httplib.ResponseNotReady()
Exemple #30
0
 def _is_ds_accessible_to_valid_host(host_mounts):
     for host_mount in host_mounts:
         if vim_util.get_moref_value(host_mount.key) in valid_hosts:
             return True