def disconnect_volume(self, connection_properties, device_info, force=False, ignore_errors=False): tmp_file_path = device_info['path'] if not os.path.exists(tmp_file_path): msg = _("Vmdk: %s not found.") % tmp_file_path raise exception.NotFound(message=msg) session = None try: # We upload the temporary file to vCenter server only if it is # modified after connect_volume. if os.path.getmtime(tmp_file_path) > device_info['last_modified']: self._load_config(connection_properties) session = self._create_session() backing = vim_util.get_moref(connection_properties['volume'], "VirtualMachine") # Currently there is no way we can restore the volume if it # contains redo-log based snapshots (bug 1599026). if self._snapshot_exists(session, backing): msg = (_("Backing of volume: %s contains one or more " "snapshots; cannot disconnect.") % connection_properties['volume_id']) raise exception.BrickException(message=msg) ds_ref = vim_util.get_moref( connection_properties['datastore'], "Datastore") dc_ref = vim_util.get_moref( connection_properties['datacenter'], "Datacenter") vmdk_path = connection_properties['vmdk_path'] self._disconnect( backing, tmp_file_path, session, ds_ref, dc_ref, vmdk_path) finally: os.remove(tmp_file_path) if session: session.logout()
def test_get_network_no_match(self): net_morefs = [ vim_util.get_moref("dvportgroup-135", "DistributedVirtualPortgroup"), vim_util.get_moref("dvportgroup-136", "DistributedVirtualPortgroup") ] networks = self._build_cluster_networks(net_morefs) self._continue_retrieval_called = False def mock_call_method(module, method, *args, **kwargs): if method == 'get_object_properties': return networks if method == 'get_object_property': result = fake.DataObject() result.name = 'no-match' return result if method == 'continue_retrieval': self._continue_retrieval_called = True with mock.patch.object(self._session, '_call_method', mock_call_method): res = network_util.get_network_with_the_name( self._session, 'fake_net', 'fake_cluster') self.assertTrue(self._continue_retrieval_called) self.assertIsNone(res)
def disconnect_volume(self, connection_properties, device_info, force=False, ignore_errors=False): tmp_file_path = device_info['path'] if not os.path.exists(tmp_file_path): msg = _("Vmdk: %s not found.") % tmp_file_path raise exception.NotFound(message=msg) session = None try: # We upload the temporary file to vCenter server only if it is # modified after connect_volume. if os.path.getmtime(tmp_file_path) > device_info['last_modified']: self._load_config(connection_properties) session = self._create_session() backing = vim_util.get_moref(connection_properties['volume'], "VirtualMachine") # Currently there is no way we can restore the volume if it # contains redo-log based snapshots (bug 1599026). if self._snapshot_exists(session, backing): msg = (_("Backing of volume: %s contains one or more " "snapshots; cannot disconnect.") % connection_properties['volume_id']) raise exception.BrickException(message=msg) ds_ref = vim_util.get_moref( connection_properties['datastore'], "Datastore") dc_ref = vim_util.get_moref( connection_properties['datacenter'], "Datacenter") vmdk_path = connection_properties['vmdk_path'] self._disconnect( tmp_file_path, session, ds_ref, dc_ref, vmdk_path) finally: os.remove(tmp_file_path) if session: session.logout()
def test_get_network_no_match(self): net_morefs = [vim_util.get_moref("dvportgroup-135", "DistributedVirtualPortgroup"), vim_util.get_moref("dvportgroup-136", "DistributedVirtualPortgroup")] networks = self._build_cluster_networks(net_morefs) self._continue_retrieval_called = False def mock_call_method(module, method, *args, **kwargs): if method == 'get_object_properties': return networks if method == 'get_object_property': result = fake.DataObject() result.name = 'no-match' return result if method == 'continue_retrieval': self._continue_retrieval_called = True with mock.patch.object(self._session, '_call_method', mock_call_method): res = network_util.get_network_with_the_name(self._session, 'fake_net', 'fake_cluster') self.assertTrue(self._continue_retrieval_called) self.assertIsNone(res)
def update_cluster_edge_failover(self, resource_id, vm_moids, host_group_names): """Updates cluster for vm placement using DRS""" session = self._session resource = vim_util.get_moref(resource_id, 'ResourcePool') # TODO(garyk): cache the cluster details cluster = session.invoke_api( vim_util, "get_object_property", self._session.vim, resource, "owner") cluster_config = session.invoke_api( vim_util, "get_object_property", self._session.vim, cluster, "configurationEx") vms = [vim_util.get_moref(vm_moid, 'VirtualMachine') if vm_moid else None for vm_moid in vm_moids] client_factory = session.vim.client.factory config_spec = client_factory.create('ns0:ClusterConfigSpecEx') num_host_groups = len(host_group_names) rules = [] if hasattr(cluster_config, 'rule'): rules = cluster_config.rule for index, vm in enumerate(vms, start=1): if not vm: continue vmGroup = None groups = [] if hasattr(cluster_config, 'group'): groups = cluster_config.group for group in groups: if 'neutron-group-%s' % index == group.name: vmGroup = group break # Create/update the VM group groupSpec = self._create_vm_group_spec( client_factory, 'neutron-group-%s' % index, [vm], vmGroup) config_spec.groupSpec.append(groupSpec) config_rule = None # Create the config rule if it does not exist for rule in rules: if 'neutron-rule-%s' % index == rule.name: config_rule = rule break if config_rule is None and index <= num_host_groups: ruleSpec = self._create_cluster_rules_spec( client_factory, 'neutron-rule-%s' % index, 'neutron-group-%s' % index, host_group_names[index - 1]) config_spec.rulesSpec.append(ruleSpec) self._reconfigure_cluster(session, cluster, config_spec)
def update_cluster_edge_failover(self, resource_id, vm_moids, host_group_names): """Updates cluster for vm placement using DRS""" session = self._session resource = vim_util.get_moref(resource_id, 'ResourcePool') # TODO(garyk): cache the cluster details cluster = session.invoke_api( vim_util, "get_object_property", self._session.vim, resource, "owner") cluster_config = session.invoke_api( vim_util, "get_object_property", self._session.vim, cluster, "configurationEx") vms = [vim_util.get_moref(vm_moid, 'VirtualMachine') if vm_moid else None for vm_moid in vm_moids] client_factory = session.vim.client.factory config_spec = client_factory.create('ns0:ClusterConfigSpecEx') num_host_groups = len(host_group_names) rules = [] if hasattr(cluster_config, 'rule'): rules = cluster_config.rule for index, vm in enumerate(vms, start=1): if not vm: continue vmGroup = None groups = [] if hasattr(cluster_config, 'group'): groups = cluster_config.group for group in groups: if self._group_name(index, host_group_names) == group.name: vmGroup = group break # Create/update the VM group groupSpec = self._create_vm_group_spec( client_factory, self._group_name(index, host_group_names), [vm], vmGroup) config_spec.groupSpec.append(groupSpec) config_rule = None # Create the config rule if it does not exist for rule in rules: if self._rule_name(index, host_group_names) == rule.name: config_rule = rule break if config_rule is None and index <= num_host_groups: ruleSpec = self._create_cluster_rules_spec( client_factory, self._rule_name(index, host_group_names), self._group_name(index, host_group_names), host_group_names[index - 1]) config_spec.rulesSpec.append(ruleSpec) self._reconfigure_cluster(session, cluster, config_spec)
def relocate_vm_spec(self, client_factory, respool_moref=None, datastore_moref=None, host_moref=None, disk_move_type="moveAllDiskBackingsAndAllowSharing"): rel_spec = client_factory.create('ns0:VirtualMachineRelocateSpec') if datastore_moref: datastore = vim_util.get_moref(datastore_moref, 'Datastore') else: datastore = None rel_spec.datastore = datastore host = vim_util.get_moref(host_moref, 'HostSystem') rel_spec.host = host res_pool = vim_util.get_moref(respool_moref, 'ResourcePool') rel_spec.pool = res_pool return rel_spec
def _get_network_dvs_match(self, name, token=False): net_morefs = [ vim_util.get_moref("dvportgroup-135", "DistributedVirtualPortgroup") ] networks = self._build_cluster_networks(net_morefs) def mock_call_method(module, method, *args, **kwargs): if method == 'get_object_properties': return networks if method == 'get_object_property': result = fake.DataObject() if not token or self._continue_retrieval_called: result.name = name else: result.name = 'fake_name' result.key = 'fake_key' result.distributedVirtualSwitch = 'fake_dvs' return result if method == 'continue_retrieval': if token: self._continue_retrieval_called = True return networks if method == 'cancel_retrieval': self._cancel_retrieval_called = True with mock.patch.object(self._session, '_call_method', mock_call_method): res = network_util.get_network_with_the_name( self._session, 'fake_net', 'fake_cluster') self.assertIsNotNone(res)
def get_configured_vms(self, resource_id, host_group_names): n_host_groups = len(host_group_names) session = self._session resource = vim_util.get_moref(resource_id, 'ResourcePool') # TODO(garyk): cache the cluster details cluster = session.invoke_api( vim_util, "get_object_property", self._session.vim, resource, "owner") cluster_config = session.invoke_api( vim_util, "get_object_property", self._session.vim, cluster, "configurationEx") configured_vms = [] for index in range(n_host_groups): vm_group = None entry_id = index + 1 groups = [] if hasattr(cluster_config, 'group'): groups = cluster_config.group for group in groups: if self._group_name(entry_id, host_group_names) == group.name: vm_group = group break if vm_group and hasattr(vm_group, 'vm'): for vm in vm_group.vm: configured_vms.append(vm.value) return configured_vms
def _get_dvs_moref_from_teaming_data(self, teaming_data): """Get the moref dvs that belongs to the teaming data""" if 'switchObj' in teaming_data: if 'objectId' in teaming_data['switchObj']: dvs_id = teaming_data['switchObj']['objectId'] return vim_util.get_moref( dvs_id, 'VmwareDistributedVirtualSwitch')
def _get_network_dvs_match(self, name, token=False): net_morefs = [vim_util.get_moref("dvportgroup-135", "DistributedVirtualPortgroup")] networks = self._build_cluster_networks(net_morefs) def mock_call_method(module, method, *args, **kwargs): if method == 'get_object_properties': return networks if method == 'get_object_property': result = fake.DataObject() if not token or self._continue_retrieval_called: result.name = name else: result.name = 'fake_name' result.key = 'fake_key' result.distributedVirtualSwitch = 'fake_dvs' return result if method == 'continue_retrieval': if token: self._continue_retrieval_called = True return networks if method == 'cancel_retrieval': self._cancel_retrieval_called = True with mock.patch.object(self._session, '_call_method', mock_call_method): res = network_util.get_network_with_the_name(self._session, 'fake_net', 'fake_cluster') self.assertIsNotNone(res)
def get_configured_vms(self, resource_id, n_host_groups=2): session = self._session resource = vim_util.get_moref(resource_id, 'ResourcePool') # TODO(garyk): cache the cluster details cluster = session.invoke_api( vim_util, "get_object_property", self._session.vim, resource, "owner") cluster_config = session.invoke_api( vim_util, "get_object_property", self._session.vim, cluster, "configurationEx") configured_vms = [] for index in range(n_host_groups): vm_group = None entry_id = index + 1 groups = [] if hasattr(cluster_config, 'group'): groups = cluster_config.group for group in groups: if 'neutron-group-%s' % entry_id == group.name: vm_group = group break if vm_group and hasattr(vm_group, 'vm'): for vm in vm_group.vm: configured_vms.append(vm.value) return configured_vms
def get_dsc_ref_and_name(session, dsc_val): """Return reference and name of the specified datastore cluster. :param ds_val: datastore cluster name or datastore cluster moid :return: tuple of dastastore cluster moref and datastore cluster name """ if re.match(r"group-p\d+", dsc_val): # the configured value is moid dsc_ref = vim_util.get_moref(dsc_val, 'StoragePod') try: dsc_name = session.invoke_api(vim_util, 'get_object_property', session.vim, dsc_ref, 'name') return dsc_ref, dsc_name except exceptions.ManagedObjectNotFoundException: # not a moid, try as a datastore cluster name pass result = session.invoke_api(vim_util, 'get_objects', session.vim, 'StoragePod', 100, ['name']) with vim_util.WithRetrieval(session.vim, result) as objs: for obj in objs: if not hasattr(obj, 'propSet'): continue if obj.propSet[0].val == dsc_val: return obj.obj, dsc_val return None, None
def __init__(self, connection_info_data): volume_ref_value = connection_info_data.get('volume') ref = None if volume_ref_value: ref = vutil.get_moref(volume_ref_value, 'VirtualMachine') super(VolumeMoRefProxy, self).__init__(ref) self._connection_info_data = connection_info_data
def _get_dvs_moref_from_teaming_data(self, teaming_data): """Get the moref dvs that belongs to the teaming data""" if 'switchObj' in teaming_data: if 'objectId' in teaming_data['switchObj']: dvs_id = teaming_data['switchObj']['objectId'] return vim_util.get_moref(dvs_id, 'VmwareDistributedVirtualSwitch')
def validate_host_groups(self, resource_id, host_group_names): session = self._session resource = vim_util.get_moref(resource_id, 'ResourcePool') cluster = session.invoke_api(vim_util, "get_object_property", self._session.vim, resource, "owner") client_factory = session.vim.client.factory config_spec = client_factory.create('ns0:ClusterConfigSpecEx') cluster_config = session.invoke_api(vim_util, "get_object_property", self._session.vim, cluster, "configurationEx") groups = [] if hasattr(cluster_config, 'group'): groups = cluster_config.group for host_group_name in host_group_names: found = False for group in groups: if host_group_name == group.name: found = True break if not found: LOG.error("%s does not exist", host_group_name) raise exceptions.NotFound() update_cluster = False num_host_groups = len(host_group_names) rules = [] if hasattr(cluster_config, 'rule'): rules = cluster_config.rule # Ensure that the VM groups are created for index in range(num_host_groups): entry_id = index + 1 vmGroup = None for group in groups: if 'neutron-group-%s' % entry_id == group.name: vmGroup = group break if vmGroup is None: groupSpec = self._create_vm_group_spec( client_factory, 'neutron-group-%s' % entry_id, [], vmGroup) config_spec.groupSpec.append(groupSpec) update_cluster = True config_rule = None # Create the config rule if it does not exist for rule in rules: if 'neutron-rule-%s' % entry_id == rule.name: config_rule = rule break if config_rule is None and index < num_host_groups: ruleSpec = self._create_cluster_rules_spec( client_factory, 'neutron-rule-%s' % entry_id, 'neutron-group-%s' % entry_id, host_group_names[index - 1]) config_spec.rulesSpec.append(ruleSpec) update_cluster = True if update_cluster: try: self._reconfigure_cluster(session, cluster, config_spec) except Exception as e: LOG.error('Unable to update cluster for host groups %s', e)
def copy_volume_to_image(self, context, volume, image_service, image_meta): """Copy the volume to the specified image. :param context: Security/policy info for the request. :param volume: The volume to copy. :param image_service: The image service to use. :param image_meta: Information about the image. :returns: Model updates. """ self._validate_disk_format(image_meta['disk_format']) fcd_loc = vops.FcdLocation.from_provider_location( volume.provider_location) hosts = self.volumeops.get_connected_hosts(fcd_loc.ds_ref()) host = vim_util.get_moref(hosts[0], 'HostSystem') LOG.debug("Selected host: %(host)s for downloading fcd: %(fcd_loc)s.", { 'host': host, 'fcd_loc': fcd_loc }) attached = False try: create_params = {vmdk.CREATE_PARAM_DISK_LESS: True} backing = self._create_backing(volume, host, create_params) self.volumeops.attach_fcd(backing, fcd_loc) attached = True vmdk_file_path = self.volumeops.get_vmdk_path(backing) conf = self.configuration # retrieve store information from extra-specs store_id = volume.volume_type.extra_specs.get( 'image_service:store_id') # TODO (whoami-rajat): Remove store_id and base_image_ref # parameters when oslo.vmware calls volume_utils wrapper of # upload_volume instead of image_utils.upload_volume image_transfer.upload_image( context, conf.vmware_image_transfer_timeout_secs, image_service, image_meta['id'], volume.project_id, session=self.session, host=conf.vmware_host_ip, port=conf.vmware_host_port, vm=backing, vmdk_file_path=vmdk_file_path, vmdk_size=volume.size * units.Gi, image_name=image_meta['name'], store_id=store_id, base_image_ref=volume_utils.get_base_image_ref(volume)) finally: if attached: self.volumeops.detach_fcd(backing, fcd_loc) backing = self.volumeops.get_backing_by_uuid(volume.id) if backing: self._delete_temp_backing(backing)
def query_vm_property(self, vm_moid, property_name): """Method returns the value of specified property for a VM. :param vm_moid: moid of the VM whose property is to be queried :param property_name: path of the property """ vm_mobj = vim_util.get_moref(vm_moid, "VirtualMachine") session = self._api_session return session.invoke_api(vim_util, "get_object_property", session.vim, vm_mobj, property_name)
def get_dvs_moref(value): """Get managed DVS object reference. :param value: value of the DVS managed object :returns: managed object reference with given value and type 'VmwareDistributedVirtualSwitch' """ return vim_util.get_moref(value, 'VmwareDistributedVirtualSwitch')
def _update_net_port_groups_config(self, net_moref, spec_update_calback, spec_update_data): pg_moref = vim_util.get_moref(net_moref, "DistributedVirtualPortgroup") self._reconfigure_port_group(pg_moref, spec_update_calback, spec_update_data)
def _query_vm_perf_stats(self, vm_moid, counter_id, device_name, duration): """Method queries the real-time stat values for a VM. :param vm_moid: moid of the VM for which stats are needed :param counter_id: id of the perf counter in VC :param device_name: name of the device for which stats are to be queried. For aggregate counters pass empty string (""). For device counters pass "*", if stats are required over all devices. :param duration: in seconds from current time, over which the stat value was applicable :return: a map containing the stat values keyed by the device ID/name """ session = self._api_session client_factory = session.vim.client.factory # Construct the QuerySpec metric_id = client_factory.create('ns0:PerfMetricId') metric_id.counterId = counter_id metric_id.instance = device_name query_spec = client_factory.create('ns0:PerfQuerySpec') query_spec.entity = vim_util.get_moref(vm_moid, "VirtualMachine") query_spec.metricId = [metric_id] query_spec.intervalId = VC_REAL_TIME_SAMPLING_INTERVAL # We query all samples which are applicable over the specified duration samples_cnt = (int(duration / VC_REAL_TIME_SAMPLING_INTERVAL) if duration and duration >= VC_REAL_TIME_SAMPLING_INTERVAL else 1) query_spec.maxSample = samples_cnt perf_manager = session.vim.service_content.perfManager perf_stats = session.invoke_api(session.vim, 'QueryPerf', perf_manager, querySpec=[query_spec]) stat_values = {} if perf_stats: entity_metric = perf_stats[0] sample_infos = entity_metric.sampleInfo if len(sample_infos) > 0: for metric_series in entity_metric.value: # Take the average of all samples to improve the accuracy # of the stat value stat_value = float(sum(metric_series.value)) / samples_cnt device_id = metric_series.id.instance stat_values[device_id] = stat_value return stat_values
def test_get_network_network_match(self): net_morefs = [vim_util.get_moref("network-54", "Network")] networks = self._build_cluster_networks(net_morefs) def mock_call_method(module, method, *args, **kwargs): if method == "get_object_properties": return networks if method == "get_object_property": return "fake_net" with mock.patch.object(self._session, "_call_method", mock_call_method): res = network_util.get_network_with_the_name(self._session, "fake_net", "fake_cluster") self.assertIsNotNone(res)
def test_get_summary(self): ds_ref = vim_util.get_moref('ds-0', 'Datastore') ds = datastore.Datastore(ds_ref, 'ds-name') summary = mock.sentinel.summary session = mock.Mock() session.invoke_api = mock.Mock() session.invoke_api.return_value = summary ret = ds.get_summary(session) self.assertEqual(summary, ret) session.invoke_api.assert_called_once_with(vim_util, 'get_object_property', session.vim, ds.ref, 'summary')
def _query_vm_perf_stats(self, vm_moid, counter_id, device_name, duration): """Method queries the real-time stat values for a VM. :param vm_moid: moid of the VM for which stats are needed :param counter_id: id of the perf counter in VC :param device_name: name of the device for which stats are to be queried. For aggregate counters pass empty string (""). For device counters pass "*", if stats are required over all devices. :param duration: in seconds from current time, over which the stat value was applicable :return: a map containing the stat values keyed by the device ID/name """ session = self._api_session client_factory = session.vim.client.factory # Construct the QuerySpec metric_id = client_factory.create("ns0:PerfMetricId") metric_id.counterId = counter_id metric_id.instance = device_name query_spec = client_factory.create("ns0:PerfQuerySpec") query_spec.entity = vim_util.get_moref(vm_moid, "VirtualMachine") query_spec.metricId = [metric_id] query_spec.intervalId = VC_REAL_TIME_SAMPLING_INTERVAL # We query all samples which are applicable over the specified duration samples_cnt = ( int(duration / VC_REAL_TIME_SAMPLING_INTERVAL) if duration and duration >= VC_REAL_TIME_SAMPLING_INTERVAL else 1 ) query_spec.maxSample = samples_cnt perf_manager = session.vim.service_content.perfManager perf_stats = session.invoke_api(session.vim, "QueryPerf", perf_manager, querySpec=[query_spec]) stat_values = {} if perf_stats: entity_metric = perf_stats[0] sample_infos = entity_metric.sampleInfo if len(sample_infos) > 0: for metric_series in entity_metric.value: # Take the average of all samples to improve the accuracy # of the stat value stat_value = float(sum(metric_series.value)) / samples_cnt device_id = metric_series.id.instance stat_values[device_id] = stat_value return stat_values
def test_get_network_network_match(self): net_morefs = [vim_util.get_moref("network-54", "Network")] networks = self._build_cluster_networks(net_morefs) def mock_call_method(module, method, *args, **kwargs): if method == 'get_object_properties': return networks if method == 'get_object_property': return 'fake_net' with mock.patch.object(self._session, '_call_method', mock_call_method): res = network_util.get_network_with_the_name( self._session, 'fake_net', 'fake_cluster') self.assertIsNotNone(res)
def copy_volume_to_image(self, context, volume, image_service, image_meta): """Copy the volume to the specified image. :param context: Security/policy info for the request. :param volume: The volume to copy. :param image_service: The image service to use. :param image_meta: Information about the image. :returns: Model updates. """ self._validate_disk_format(image_meta['disk_format']) fcd_loc = vops.FcdLocation.from_provider_location( volume.provider_location) hosts = self.volumeops.get_connected_hosts(fcd_loc.ds_ref()) host = vim_util.get_moref(hosts[0], 'HostSystem') LOG.debug("Selected host: %(host)s for downloading fcd: %(fcd_loc)s.", {'host': host, 'fcd_loc': fcd_loc}) attached = False try: create_params = {vmdk.CREATE_PARAM_DISK_LESS: True} backing = self._create_backing(volume, host, create_params) self.volumeops.attach_fcd(backing, fcd_loc) attached = True vmdk_file_path = self.volumeops.get_vmdk_path(backing) conf = self.configuration image_transfer.upload_image( context, conf.vmware_image_transfer_timeout_secs, image_service, image_meta['id'], volume.project_id, session=self.session, host=conf.vmware_host_ip, port=conf.vmware_host_port, vm=backing, vmdk_file_path=vmdk_file_path, vmdk_size=volume.size * units.Gi, image_name=image_meta['name']) finally: if attached: self.volumeops.detach_fcd(backing, fcd_loc) backing = self.volumeops.get_backing_by_uuid(volume.id) if backing: self._delete_temp_backing(backing)
def _test_get_connected_hosts(self, in_maintenance_mode, m1_accessible=True): session = mock.Mock() ds_ref = vim_util.get_moref('ds-0', 'Datastore') ds = datastore.Datastore(ds_ref, 'ds-name') ds.get_summary = mock.Mock() ds.get_summary.return_value.accessible = False self.assertEqual([], ds.get_connected_hosts(session)) ds.get_summary.return_value.accessible = True m1 = HostMount("m1", MountInfo('readWrite', True, m1_accessible)) m2 = HostMount("m2", MountInfo('read', True, True)) m3 = HostMount("m3", MountInfo('readWrite', False, True)) m4 = HostMount("m4", MountInfo('readWrite', True, False)) ds.get_summary.assert_called_once_with(session) class Prop(object): DatastoreHostMount = [m1, m2, m3, m4] class HostRuntime(object): inMaintenanceMode = in_maintenance_mode class HostProp(object): name = 'runtime' val = HostRuntime() class Object(object): obj = "m1" propSet = [HostProp()] class Runtime(object): objects = [Object()] session.invoke_api = mock.Mock(side_effect=[Prop(), Runtime()]) hosts = ds.get_connected_hosts(session) calls = [ mock.call(vim_util, 'get_object_property', session.vim, ds_ref, 'host') ] if m1_accessible: calls.append( mock.call(vim_util, 'get_properties_for_a_collection_of_objects', session.vim, 'HostSystem', ["m1"], ['runtime'])) self.assertEqual(calls, session.invoke_api.mock_calls) return hosts
def __init__(self, dvs_id=None): """Initializer. A global session with the VC will be established. In addition to this the moref of the configured DVS will be learnt. This will be used in the operations supported by the manager. NOTE: the DVS port group name will be the Neutron network UUID. """ self._session = dvs_utils.dvs_create_session() # In the future we may decide to support more than one DVS if dvs_id is None: self._dvs_moref = self._get_dvs_moref(self._session, dvs_utils.dvs_name_get()) else: self._dvs_moref = vim_util.get_moref(dvs_id, 'VmwareDistributedVirtualSwitch')
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((pod_ref.value, pod_ref._type), (dsc_ref.value, dsc_ref._type))
def _build_cluster_networks(self, networks): """Returns a set of results for a cluster network lookup. This is an example: (ObjectContent){ obj = (obj){ value = "domain-c7" _type = "ClusterComputeResource" } propSet[] = (DynamicProperty){ name = "network" val = (ArrayOfManagedObjectReference){ ManagedObjectReference[] = (ManagedObjectReference){ value = "network-54" _type = "Network" }, (ManagedObjectReference){ value = "dvportgroup-14" _type = "DistributedVirtualPortgroup" }, } }, }] """ objects = [] obj = ObjectContent(obj=vim_util.get_moref("domain-c7", "ClusterComputeResource"), propSet=[]) value = fake.DataObject() value.ManagedObjectReference = [] for network in networks: value.ManagedObjectReference.append(network) obj.propSet.append( DynamicProperty(name='network', val=value)) objects.append(obj) return ResultSet(objects=objects)
def _test_get_connected_hosts(self, in_maintenance_mode, m1_accessible=True): session = mock.Mock() ds_ref = vim_util.get_moref('ds-0', 'Datastore') ds = datastore.Datastore(ds_ref, 'ds-name') ds.get_summary = mock.Mock() ds.get_summary.return_value.accessible = False self.assertEqual([], ds.get_connected_hosts(session)) ds.get_summary.return_value.accessible = True m1 = HostMount("m1", MountInfo('readWrite', True, m1_accessible)) m2 = HostMount("m2", MountInfo('read', True, True)) m3 = HostMount("m3", MountInfo('readWrite', False, True)) m4 = HostMount("m4", MountInfo('readWrite', True, False)) ds.get_summary.assert_called_once_with(session) class Prop(object): DatastoreHostMount = [m1, m2, m3, m4] class HostRuntime(object): inMaintenanceMode = in_maintenance_mode class HostProp(object): name = 'runtime' val = HostRuntime() class Object(object): obj = "m1" propSet = [HostProp()] class Runtime(object): objects = [Object()] session.invoke_api = mock.Mock(side_effect=[Prop(), Runtime()]) hosts = ds.get_connected_hosts(session) calls = [mock.call(vim_util, 'get_object_property', session.vim, ds_ref, 'host')] if m1_accessible: calls.append( mock.call(vim_util, 'get_properties_for_a_collection_of_objects', session.vim, 'HostSystem', ["m1"], ['runtime'])) self.assertEqual(calls, session.invoke_api.mock_calls) return hosts
def test_add_port_group(self, mock_spec): session = mock.Mock() dvs_moref = dvs_util.get_dvs_moref('dvs-123') spec = dvs_util.get_port_group_spec(session, 'pg', 7) mock_spec.return_value = spec pg_moref = vim_util.get_moref('dvportgroup-7', 'DistributedVirtualPortgroup') def wait_for_task_side_effect(task): task_info = mock.Mock() task_info.result = pg_moref return task_info session.wait_for_task.side_effect = wait_for_task_side_effect pg = dvs_util.add_port_group(session, dvs_moref, 'pg', vlan_id=7) self.assertEqual(pg, pg_moref) session.invoke_api.assert_called_once_with( session.vim, 'CreateDVPortgroup_Task', dvs_moref, spec=spec)
def test_add_port_group(self, mock_spec): session = mock.Mock() dvs_moref = dvs_util.get_dvs_moref('dvs-123') spec = dvs_util.get_port_group_spec(session, 'pg', 7) mock_spec.return_value = spec pg_moref = vim_util.get_moref('dvportgroup-7', 'DistributedVirtualPortgroup') def wait_for_task_side_effect(task): task_info = mock.Mock() task_info.result = pg_moref return task_info session.wait_for_task.side_effect = wait_for_task_side_effect pg = dvs_util.add_port_group(session, dvs_moref, 'pg', vlan_id=7) self.assertEqual(pg, pg_moref) session.invoke_api.assert_called_once_with(session.vim, 'CreateDVPortgroup_Task', dvs_moref, spec=spec)
def _poll_task_well_known_exceptions(self, fault, expected_exception): api_session = self._create_api_session(False) def fake_invoke_api(self, module, method, *args, **kwargs): task_info = mock.Mock() task_info.progress = -1 task_info.state = 'error' error = mock.Mock() error.localizedMessage = "Error message" error_fault = mock.Mock() error_fault.__class__.__name__ = fault error.fault = error_fault task_info.error = error return task_info with (mock.patch.object(api_session, 'invoke_api', fake_invoke_api)): fake_task = vim_util.get_moref('Task', 'task-1') ctx = mock.Mock() self.assertRaises(expected_exception, api_session._poll_task, fake_task, ctx)
def _get_network_dvs_match(self, name): net_morefs = [vim_util.get_moref("dvportgroup-135", "DistributedVirtualPortgroup")] networks = self._build_cluster_networks(net_morefs) def mock_call_method(module, method, *args, **kwargs): if method == 'get_object_properties': return networks if method == 'get_object_property': result = fake.DataObject() result.name = name result.key = 'fake_key' result.distributedVirtualSwitch = 'fake_dvs' return result with mock.patch.object(self._session, '_call_method', mock_call_method): res = network_util.get_network_with_the_name(self._session, 'fake_net', 'fake_cluster') self.assertIsNotNone(res)
def test_get_connected_hosts(self): session = mock.Mock() ds_ref = vim_util.get_moref('ds-0', 'Datastore') ds = datastore.Datastore(ds_ref, 'ds-name') ds.get_summary = mock.Mock() ds.get_summary.return_value.accessible = False self.assertEqual([], ds.get_connected_hosts(session)) ds.get_summary.return_value.accessible = True m1 = HostMount("m1", MountInfo('readWrite', True, True)) m2 = HostMount("m2", MountInfo('read', True, True)) m3 = HostMount("m3", MountInfo('readWrite', False, True)) m4 = HostMount("m4", MountInfo('readWrite', True, False)) ds.get_summary.assert_called_once_with(session) class Prop(object): DatastoreHostMount = [m1, m2, m3, m4] session.invoke_api = mock.Mock() session.invoke_api.return_value = Prop() hosts = ds.get_connected_hosts(session) self.assertEqual(1, len(hosts)) self.assertEqual("m1", hosts.pop())
def cluster_host_group_cleanup(self, resource_id, host_group_names): n_host_groups = len(host_group_names) session = self._session resource = vim_util.get_moref(resource_id, 'ResourcePool') # TODO(garyk): cache the cluster details cluster = session.invoke_api( vim_util, "get_object_property", self._session.vim, resource, "owner") client_factory = session.vim.client.factory config_spec = client_factory.create('ns0:ClusterConfigSpecEx') cluster_config = session.invoke_api( vim_util, "get_object_property", self._session.vim, cluster, "configurationEx") groups = [] if hasattr(cluster_config, 'group'): groups = cluster_config.group rules = [] if hasattr(cluster_config, 'rule'): rules = cluster_config.rule groupSpec = [] ruleSpec = [] for index in range(n_host_groups): entry_id = index + 1 for group in groups: if self._group_name(entry_id, host_group_names) == group.name: groupSpec.append(self._delete_vm_group_spec( client_factory, group.name)) # Delete the config rule if it exists for rule in rules: if self._rule_name(entry_id, host_group_names) == rule.name: ruleSpec.append(self._delete_cluster_rules_spec( client_factory, rule)) if groupSpec: config_spec.groupSpec = groupSpec if ruleSpec: config_spec.rulesSpec = ruleSpec if groupSpec or ruleSpec: self._reconfigure_cluster(session, cluster, config_spec)
def test_get_profiles(self): pbm_service = mock.Mock() session = mock.Mock(pbm=pbm_service) object_ref = mock.Mock() pbm_service.client.factory.create.return_value = object_ref profile_id = mock.sentinel.profile_id session.invoke_api.return_value = profile_id value = 'vm-1' vm = vim_util.get_moref(value, 'VirtualMachine') ret = pbm.get_profiles(session, vm) self.assertEqual(profile_id, ret) session.invoke_api.assert_called_once_with( pbm_service, 'PbmQueryAssociatedProfile', pbm_service.service_content.profileManager, entity=object_ref) self.assertEqual(value, object_ref.key) self.assertEqual('virtualMachine', object_ref.objectType)
def test_get_portgroups(self): session = mock.Mock() dvs_moref = dvs_util.get_dvs_moref('dvs-123') pg_moref = vim_util.get_moref('dvportgroup-7', 'DistributedVirtualPortgroup') def session_invoke_api_side_effect(module, method, *args, **kwargs): if module == vim_util and method == 'get_object_properties': if ['portgroup'] in args: propSet = [ DynamicProperty(name='portgroup', val=[[pg_moref]]) ] return [ObjectContent(obj=dvs_moref, propSet=propSet)] if ['name'] in args: propSet = [DynamicProperty(name='name', val='pg-name')] return [ObjectContent(obj=pg_moref, propSet=propSet)] session.invoke_api.side_effect = session_invoke_api_side_effect session._call_method.return_value = [] pgs = dvs_util.get_portgroups(session, dvs_moref) result = [('pg-name', pg_moref)] self.assertEqual(result, pgs)
def connect_volume(self, connection_properties): # Download the volume vmdk from vCenter server to a temporary file # and return its path. self._load_config(connection_properties) session = self._create_session() tmp_file_path = self._create_temp_file( suffix=".vmdk", prefix=connection_properties['volume_id']) backing = vim_util.get_moref(connection_properties['volume'], "VirtualMachine") vmdk_path = connection_properties['vmdk_path'] vmdk_size = connection_properties['vmdk_size'] try: self._download_vmdk( tmp_file_path, session, backing, vmdk_path, vmdk_size) finally: session.logout() # Save the last modified time of the temporary so that we can decide # whether to upload the file back to vCenter server during disconnect. last_modified = os.path.getmtime(tmp_file_path) return {'path': tmp_file_path, 'last_modified': last_modified}
def test_get_object_properties(self, cancel_retrieval): vim = mock.Mock() moref = vim_util.get_moref('fake-ref', 'VirtualMachine') retrieve_result = mock.Mock() def vim_RetrievePropertiesEx_side_effect(pc, specSet, options, skip_op_id=False): self.assertTrue(pc is vim.service_content.propertyCollector) self.assertEqual(1, options.maxObjects) self.assertEqual(1, len(specSet)) property_filter_spec = specSet[0] propSet = property_filter_spec.propSet self.assertEqual(1, len(propSet)) prop_spec = propSet[0] self.assertTrue(prop_spec.all) self.assertEqual(['name'], prop_spec.pathSet) self.assertEqual(vim_util.get_moref_type(moref), prop_spec.type) objSet = property_filter_spec.objectSet self.assertEqual(1, len(objSet)) obj_spec = objSet[0] self.assertEqual(moref, obj_spec.obj) self.assertEqual([], obj_spec.selectSet) self.assertFalse(obj_spec.skip) return retrieve_result vim.RetrievePropertiesEx.side_effect = ( vim_RetrievePropertiesEx_side_effect) res = vim_util.get_object_properties(vim, moref, None) self.assertEqual(1, vim.RetrievePropertiesEx.call_count) self.assertTrue(res is retrieve_result.objects) cancel_retrieval.assert_called_once_with(vim, retrieve_result)
def test_get_portgroups(self): session = mock.Mock() dvs_moref = dvs_util.get_dvs_moref('dvs-123') pg_moref = vim_util.get_moref('dvportgroup-7', 'DistributedVirtualPortgroup') def session_invoke_api_side_effect(module, method, *args, **kwargs): if module == vim_util and method == 'get_object_properties': if ['portgroup'] in args: propSet = [DynamicProperty(name='portgroup', val=[[pg_moref]])] return [ObjectContent(obj=dvs_moref, propSet=propSet)] if ['name'] in args: propSet = [DynamicProperty(name='name', val='pg-name')] return [ObjectContent(obj=pg_moref, propSet=propSet)] session.invoke_api.side_effect = session_invoke_api_side_effect session._call_method.return_value = [] pgs = dvs_util.get_portgroups(session, dvs_moref) result = [('pg-name', pg_moref)] self.assertEqual(result, pgs)
def _get_dvs_moref_by_id(self, dvs_id): return vim_util.get_moref(dvs_id, 'VmwareDistributedVirtualSwitch')
def make_moref(value, type_): return vim_util.get_moref(value, type_)
def validate_host_groups(self, resource_id, host_group_names): session = self._session resource = vim_util.get_moref(resource_id, 'ResourcePool') cluster = session.invoke_api( vim_util, "get_object_property", self._session.vim, resource, "owner") client_factory = session.vim.client.factory config_spec = client_factory.create('ns0:ClusterConfigSpecEx') cluster_config = session.invoke_api( vim_util, "get_object_property", self._session.vim, cluster, "configurationEx") groups = [] if hasattr(cluster_config, 'group'): groups = cluster_config.group for host_group_name in host_group_names: found = False for group in groups: if host_group_name == group.name: found = True break if not found: LOG.error("%s does not exist", host_group_name) raise exceptions.NotFound() update_cluster = False num_host_groups = len(host_group_names) rules = [] if hasattr(cluster_config, 'rule'): rules = cluster_config.rule # Ensure that the VM groups are created for index in range(num_host_groups): entry_id = index + 1 vmGroup = None for group in groups: if self._group_name(entry_id, host_group_names) == group.name: vmGroup = group break if vmGroup is None: groupSpec = self._create_vm_group_spec( client_factory, self._group_name(entry_id, host_group_names), [], vmGroup) config_spec.groupSpec.append(groupSpec) update_cluster = True config_rule = None # Create the config rule if it does not exist for rule in rules: if self._rule_name(entry_id, host_group_names) == rule.name: config_rule = rule break if config_rule is None and index < num_host_groups: ruleSpec = self._create_cluster_rules_spec( client_factory, self._rule_name(entry_id, host_group_names), self._group_name(entry_id, host_group_names), host_group_names[index - 1]) config_spec.rulesSpec.append(ruleSpec) update_cluster = True if update_cluster: try: self._reconfigure_cluster(session, cluster, config_spec) except Exception as e: LOG.error('Unable to update cluster for host groups %s', e)
def request_handler(managed_object, **kwargs): """Handler for vSphere API calls. Invokes the API and parses the response for fault checking and other errors. :param managed_object: managed object reference argument of the API call :param kwargs: keyword arguments of the API call :returns: response of the API call :raises: VimException, VimFaultException, VimAttributeException, VimSessionOverLoadException, VimConnectionException """ try: if isinstance(managed_object, str): # For strings, use string value for value and type # of the managed object. managed_object = vim_util.get_moref(managed_object, managed_object) if managed_object is None: return request = getattr(self.client.service, attr_name) response = request(managed_object, **kwargs) if (attr_name.lower() == 'retrievepropertiesex'): Service._retrieve_properties_ex_fault_checker(response) return response except exceptions.VimFaultException: # Catch the VimFaultException that is raised by the fault # check of the SOAP response. raise except suds.WebFault as excep: fault_string = None if excep.fault: fault_string = excep.fault.faultstring doc = excep.document detail = None if doc is not None: detail = doc.childAtPath('/detail') if not detail: # NOTE(arnaud): this is needed with VC 5.1 detail = doc.childAtPath('/Envelope/Body/Fault/detail') fault_list = [] details = {} if detail: for fault in detail.getChildren(): fault_type = fault.get('type') if fault_type.endswith(exceptions.SECURITY_ERROR): fault_type = exceptions.NOT_AUTHENTICATED fault_list.append(fault_type) for child in fault.getChildren(): details[child.name] = child.getText() raise exceptions.VimFaultException(fault_list, fault_string, excep, details) except AttributeError as excep: raise exceptions.VimAttributeException( _("No such SOAP method %s.") % attr_name, excep) except (httplib.CannotSendRequest, httplib.ResponseNotReady, httplib.CannotSendHeader) as excep: raise exceptions.VimSessionOverLoadException( _("httplib error in %s.") % attr_name, excep) except requests.RequestException as excep: raise exceptions.VimConnectionException( _("requests error in %s.") % attr_name, excep) except Exception as excep: # TODO(vbala) should catch specific exceptions and raise # appropriate VimExceptions. # Socket errors which need special handling; some of these # might be caused by server API call overload. if (six.text_type(excep).find(ADDRESS_IN_USE_ERROR) != -1 or six.text_type(excep).find(CONN_ABORT_ERROR)) != -1: raise exceptions.VimSessionOverLoadException( _("Socket error in %s.") % attr_name, excep) # Type error which needs special handling; it might be caused # by server API call overload. elif six.text_type(excep).find(RESP_NOT_XML_ERROR) != -1: raise exceptions.VimSessionOverLoadException( _("Type error in %s.") % attr_name, excep) else: raise exceptions.VimException( _("Exception in %s.") % attr_name, excep)
def retrieve_service_content(self): ref = vim_util.get_moref(service.SERVICE_INSTANCE, SERVICE_TYPE) return self.PbmRetrieveServiceContent(ref)
def _get_volume_ref(self, volume_ref_name): """Get the volume moref from the ref name.""" return vutil.get_moref(volume_ref_name, 'VirtualMachine')
def test_get_moref(self): moref = vim_util.get_moref("vm-0", "VirtualMachine") self.assertEqual("vm-0", moref.value) self.assertEqual("VirtualMachine", moref._type)