From e37e2f3ff7789f09b91d06979214913f56d92471 Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Mon, 25 Nov 2024 03:03:40 +0900 Subject: [PATCH] Remove VMWare vSphere support It was deprecated a few cycles ago[1] and we haven't heard any request to keep it. [1] 297089a622c25795f97d647d54c6240ab0e12b1c Change-Id: Ib3290bb0d8739842c37d4b085a6d5a2f71de1b84 --- ceilometer/compute/virt/inspector.py | 6 +- ceilometer/compute/virt/vmware/__init__.py | 0 ceilometer/compute/virt/vmware/inspector.py | 228 ----------------- .../compute/virt/vmware/vsphere_operations.py | 235 ------------------ ceilometer/opts.py | 4 +- .../unit/compute/virt/vmware/__init__.py | 0 .../tests/unit/compute/virt/vmware/fake.py | 29 --- .../compute/virt/vmware/test_inspector.py | 196 --------------- .../virt/vmware/test_vsphere_operations.py | 181 -------------- devstack/plugin.sh | 27 +- doc/source/admin/telemetry-measurements.rst | 2 +- .../admin/telemetry-system-architecture.rst | 1 - ...move-vsphere-support-411c97b66bdcd264.yaml | 10 + setup.cfg | 1 - test-requirements.txt | 1 - 15 files changed, 17 insertions(+), 904 deletions(-) delete mode 100644 ceilometer/compute/virt/vmware/__init__.py delete mode 100644 ceilometer/compute/virt/vmware/inspector.py delete mode 100644 ceilometer/compute/virt/vmware/vsphere_operations.py delete mode 100644 ceilometer/tests/unit/compute/virt/vmware/__init__.py delete mode 100644 ceilometer/tests/unit/compute/virt/vmware/fake.py delete mode 100644 ceilometer/tests/unit/compute/virt/vmware/test_inspector.py delete mode 100644 ceilometer/tests/unit/compute/virt/vmware/test_vsphere_operations.py create mode 100644 releasenotes/notes/remove-vsphere-support-411c97b66bdcd264.yaml diff --git a/ceilometer/compute/virt/inspector.py b/ceilometer/compute/virt/inspector.py index e5fc5a85a0..9a547e43d6 100644 --- a/ceilometer/compute/virt/inspector.py +++ b/ceilometer/compute/virt/inspector.py @@ -26,8 +26,10 @@ import ceilometer OPTS = [ cfg.StrOpt('hypervisor_inspector', default='libvirt', - help='Inspector to use for inspecting the hypervisor layer. ' - 'Known inspectors are libvirt and vsphere.'), + choices=['libvirt'], + deprecated_for_removal=True, + deprecated_reason='libvirt is the only supported hypervisor', + help='Inspector to use for inspecting the hypervisor layer.') ] diff --git a/ceilometer/compute/virt/vmware/__init__.py b/ceilometer/compute/virt/vmware/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/ceilometer/compute/virt/vmware/inspector.py b/ceilometer/compute/virt/vmware/inspector.py deleted file mode 100644 index 79d7166119..0000000000 --- a/ceilometer/compute/virt/vmware/inspector.py +++ /dev/null @@ -1,228 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Implementation of Inspector abstraction for VMware vSphere""" - -import warnings - -from oslo_config import cfg -from oslo_utils import units - -from ceilometer.compute.virt import inspector as virt_inspector -from ceilometer.compute.virt.vmware import vsphere_operations -from ceilometer.i18n import _ - -vmware_api = None - -opt_group = cfg.OptGroup(name='vmware', - title='Options for VMware') - -OPTS = [ - cfg.HostAddressOpt('host_ip', - default='127.0.0.1', - deprecated_for_removal=True, - deprecated_reason='Support for VMWare vSphere has been ' - 'deprecated', - help='IP address of the VMware vSphere host.'), - cfg.PortOpt('host_port', - default=443, - deprecated_for_removal=True, - deprecated_reason='Support for VMWare vSphere is deprecated', - help='Port of the VMware vSphere host.'), - cfg.StrOpt('host_username', - default='', - deprecated_for_removal=True, - deprecated_reason='Support for VMWare vSphere is deprecated', - help='Username of VMware vSphere.'), - cfg.StrOpt('host_password', - default='', - deprecated_for_removal=True, - deprecated_reason='Support for VMWare vSphere is deprecated', - help='Password of VMware vSphere.', - secret=True), - cfg.StrOpt('ca_file', - deprecated_for_removal=True, - deprecated_reason='Support for VMWare vSphere is deprecated', - help='CA bundle file to use in verifying the vCenter server ' - 'certificate.'), - cfg.BoolOpt('insecure', - default=False, - deprecated_for_removal=True, - deprecated_reason='Support for VMWare vSphere is deprecated', - help='If true, the vCenter server certificate is not ' - 'verified. If false, then the default CA truststore is ' - 'used for verification. This option is ignored if ' - '"ca_file" is set.'), - cfg.IntOpt('api_retry_count', - default=10, - deprecated_for_removal=True, - deprecated_reason='Support for VMWare vSphere is deprecated', - help='Number of times a VMware vSphere API may be retried.'), - cfg.FloatOpt('task_poll_interval', - deprecated_for_removal=True, - deprecated_reason='Support for VMWare vSphere is deprecated', - default=0.5, - help='Sleep time in seconds for polling an ongoing async ' - 'task.'), - cfg.StrOpt('wsdl_location', - deprecated_for_removal=True, - deprecated_reason='Support for VMWare vSphere is deprecated', - help='Optional vim service WSDL location ' - 'e.g http:///vimService.wsdl. ' - 'Optional over-ride to default location for bug ' - 'work-arounds.'), -] - -VC_AVERAGE_MEMORY_CONSUMED_CNTR = 'mem:consumed:average' -VC_AVERAGE_CPU_CONSUMED_CNTR = 'cpu:usage:average' -VC_NETWORK_RX_COUNTER = 'net:received:average' -VC_NETWORK_TX_COUNTER = 'net:transmitted:average' -VC_DISK_READ_RATE_CNTR = "disk:read:average" -VC_DISK_READ_REQUESTS_RATE_CNTR = "disk:numberReadAveraged:average" -VC_DISK_WRITE_RATE_CNTR = "disk:write:average" -VC_DISK_WRITE_REQUESTS_RATE_CNTR = "disk:numberWriteAveraged:average" - - -def get_api_session(conf): - global vmware_api - if vmware_api is None: - vmware_api = __import__('oslo_vmware.api') - api_session = vmware_api.api.VMwareAPISession( - conf.vmware.host_ip, - conf.vmware.host_username, - conf.vmware.host_password, - conf.vmware.api_retry_count, - conf.vmware.task_poll_interval, - wsdl_loc=conf.vmware.wsdl_location, - port=conf.vmware.host_port, - cacert=conf.vmware.ca_file, - insecure=conf.vmware.insecure) - return api_session - - -class VsphereInspector(virt_inspector.Inspector): - - def __init__(self, conf): - super(VsphereInspector, self).__init__(conf) - self._ops = vsphere_operations.VsphereOperations( - get_api_session(self.conf), 1000) - - warnings.warn('Support for VMWare vSphere is deprecated.', - category=DeprecationWarning, stacklevel=2) - - def _get_vm_mobj_not_power_off_or_raise(self, instance): - vm_mobj = self._ops.get_vm_mobj(instance.id) - - if vm_mobj is None: - raise virt_inspector.InstanceNotFoundException( - _('VM %s not found in VMware vSphere') % instance.id) - - vm_powerState = self._ops.query_vm_property(vm_mobj, - 'runtime.powerState') - if vm_powerState == "poweredOff": - raise virt_inspector.InstanceShutOffException( - _('VM %s is poweredOff in VMware vSphere') % instance.id) - - return vm_mobj - - def inspect_vnic_rates(self, instance, duration): - vm_mobj = self._get_vm_mobj_not_power_off_or_raise(instance) - - vnic_stats = {} - vnic_ids = set() - - for net_counter in (VC_NETWORK_RX_COUNTER, VC_NETWORK_TX_COUNTER): - net_counter_id = self._ops.get_perf_counter_id(net_counter) - vnic_id_to_stats_map = self._ops.query_vm_device_stats( - vm_mobj, net_counter_id, duration) - # The sample for this map is: {4000: 0.0, vmnic5: 0.0, vmnic4: 0.0, - # vmnic3: 0.0, vmnic2: 0.0, vmnic1: 0.0, vmnic0: 0.0} - # "4000" is the virtual nic which we need. - # And these "vmnic*" are phynical nics in the host, so we remove it - vnic_id_to_stats_map = {k: v for (k, v) - in vnic_id_to_stats_map.items() - if not k.startswith('vmnic')} - vnic_stats[net_counter] = vnic_id_to_stats_map - vnic_ids.update(vnic_id_to_stats_map.keys()) - - # Stats provided from vSphere are in KB/s, converting it to B/s. - for vnic_id in sorted(vnic_ids): - rx_bytes_rate = (vnic_stats[VC_NETWORK_RX_COUNTER] - .get(vnic_id, 0) * units.Ki) - tx_bytes_rate = (vnic_stats[VC_NETWORK_TX_COUNTER] - .get(vnic_id, 0) * units.Ki) - yield virt_inspector.InterfaceRateStats( - name=vnic_id, - mac=None, - fref=None, - parameters=None, - rx_bytes_rate=rx_bytes_rate, - tx_bytes_rate=tx_bytes_rate) - - def inspect_disk_rates(self, instance, duration): - vm_mobj = self._get_vm_mobj_not_power_off_or_raise(instance) - - disk_stats = {} - disk_ids = set() - disk_counters = [ - VC_DISK_READ_RATE_CNTR, - VC_DISK_READ_REQUESTS_RATE_CNTR, - VC_DISK_WRITE_RATE_CNTR, - VC_DISK_WRITE_REQUESTS_RATE_CNTR - ] - - for disk_counter in disk_counters: - disk_counter_id = self._ops.get_perf_counter_id(disk_counter) - disk_id_to_stat_map = self._ops.query_vm_device_stats( - vm_mobj, disk_counter_id, duration) - disk_stats[disk_counter] = disk_id_to_stat_map - disk_ids.update(disk_id_to_stat_map.keys()) - - for disk_id in disk_ids: - - def stat_val(counter_name): - return disk_stats[counter_name].get(disk_id, 0) - - # Stats provided from vSphere are in KB/s, converting it to B/s. - yield virt_inspector.DiskRateStats( - device=disk_id, - read_bytes_rate=stat_val(VC_DISK_READ_RATE_CNTR) * units.Ki, - read_requests_rate=stat_val(VC_DISK_READ_REQUESTS_RATE_CNTR), - write_bytes_rate=stat_val(VC_DISK_WRITE_RATE_CNTR) * units.Ki, - write_requests_rate=stat_val(VC_DISK_WRITE_REQUESTS_RATE_CNTR) - ) - - def inspect_instance(self, instance, duration): - vm_mobj = self._get_vm_mobj_not_power_off_or_raise(instance) - cpu_util_counter_id = self._ops.get_perf_counter_id( - VC_AVERAGE_CPU_CONSUMED_CNTR) - cpu_util = self._ops.query_vm_aggregate_stats( - vm_mobj, cpu_util_counter_id, duration) - - # For this counter vSphere returns values scaled-up by 100, since the - # corresponding API can't return decimals, but only longs. - # For e.g. if the utilization is 12.34%, the value returned is 1234. - # Hence, dividing by 100.0. - cpu_util = cpu_util / 100.0 - - mem_counter_id = self._ops.get_perf_counter_id( - VC_AVERAGE_MEMORY_CONSUMED_CNTR) - memory = self._ops.query_vm_aggregate_stats( - vm_mobj, mem_counter_id, duration) - # Stat provided from vSphere is in KB, converting it to MB. - memory = memory / units.Ki - return virt_inspector.InstanceStats( - cpu_util=cpu_util, - memory_usage=memory) diff --git a/ceilometer/compute/virt/vmware/vsphere_operations.py b/ceilometer/compute/virt/vmware/vsphere_operations.py deleted file mode 100644 index 8f078e052a..0000000000 --- a/ceilometer/compute/virt/vmware/vsphere_operations.py +++ /dev/null @@ -1,235 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -try: - from oslo_vmware import vim_util -except ImportError: - # NOTE(sileht): this is safe because inspector will not load - vim_util = None - - -PERF_MANAGER_TYPE = "PerformanceManager" -PERF_COUNTER_PROPERTY = "perfCounter" -VM_INSTANCE_ID_PROPERTY = 'config.extraConfig["nvp.vm-uuid"].value' - -# ESXi Servers sample performance data every 20 seconds. 20-second interval -# data is called instance data or real-time data. To retrieve instance data, -# we need to specify a value of 20 seconds for the "PerfQuerySpec.intervalId" -# property. In that case the "QueryPerf" method operates as a raw data feed -# that bypasses the vCenter database and instead retrieves performance data -# from an ESXi host. -# The following value is time interval for real-time performance stats -# in seconds and it is not configurable. -VC_REAL_TIME_SAMPLING_INTERVAL = 20 - - -class VsphereOperations(object): - """Class to invoke vSphere APIs calls. - - vSphere APIs calls are required by various pollsters, collecting data from - VMware infrastructure. - """ - def __init__(self, api_session, max_objects): - self._api_session = api_session - self._max_objects = max_objects - # Mapping between "VM's Nova instance Id" -> "VM's managed object" - # In case a VM is deployed by Nova, then its name is instance ID. - # So this map essentially has VM names as keys. - self._vm_mobj_lookup_map = {} - - # Mapping from full name -> ID, for VC Performance counters - self._perf_counter_id_lookup_map = None - - def _init_vm_mobj_lookup_map(self): - session = self._api_session - result = session.invoke_api(vim_util, "get_objects", session.vim, - "VirtualMachine", self._max_objects, - [VM_INSTANCE_ID_PROPERTY], - False) - while result: - for object in result.objects: - vm_mobj = object.obj - # propSet will be set only if the server provides value - if hasattr(object, 'propSet') and object.propSet: - vm_instance_id = object.propSet[0].val - if vm_instance_id: - self._vm_mobj_lookup_map[vm_instance_id] = vm_mobj - - result = session.invoke_api(vim_util, "continue_retrieval", - session.vim, result) - - def get_vm_mobj(self, vm_instance_id): - """Method returns VC mobj of the VM by its NOVA instance ID.""" - if vm_instance_id not in self._vm_mobj_lookup_map: - self._init_vm_mobj_lookup_map() - - return self._vm_mobj_lookup_map.get(vm_instance_id, None) - - def _init_perf_counter_id_lookup_map(self): - - # Query details of all the performance counters from VC - session = self._api_session - client_factory = session.vim.client.factory - perf_manager = session.vim.service_content.perfManager - - prop_spec = vim_util.build_property_spec( - client_factory, PERF_MANAGER_TYPE, [PERF_COUNTER_PROPERTY]) - - obj_spec = vim_util.build_object_spec( - client_factory, perf_manager, None) - - filter_spec = vim_util.build_property_filter_spec( - client_factory, [prop_spec], [obj_spec]) - - options = client_factory.create('ns0:RetrieveOptions') - options.maxObjects = 1 - - prop_collector = session.vim.service_content.propertyCollector - result = session.invoke_api(session.vim, "RetrievePropertiesEx", - prop_collector, specSet=[filter_spec], - options=options) - - perf_counter_infos = result.objects[0].propSet[0].val.PerfCounterInfo - - # Extract the counter Id for each counter and populate the map - self._perf_counter_id_lookup_map = {} - for perf_counter_info in perf_counter_infos: - - counter_group = perf_counter_info.groupInfo.key - counter_name = perf_counter_info.nameInfo.key - counter_rollup_type = perf_counter_info.rollupType - counter_id = perf_counter_info.key - - counter_full_name = (counter_group + ":" + counter_name + ":" + - counter_rollup_type) - self._perf_counter_id_lookup_map[counter_full_name] = counter_id - - def get_perf_counter_id(self, counter_full_name): - """Method returns the ID of VC performance counter by its full name. - - A VC performance counter is uniquely identified by the - tuple {'Group Name', 'Counter Name', 'Rollup Type'}. - It will have an id - counter ID (changes from one VC to another), - which is required to query performance stats from that VC. - This method returns the ID for a counter, - assuming 'CounterFullName' => 'Group Name:CounterName:RollupType'. - """ - if not self._perf_counter_id_lookup_map: - self._init_perf_counter_id_lookup_map() - return self._perf_counter_id_lookup_map[counter_full_name] - - # TODO(akhils@vmware.com) Move this method to common library - # when it gets checked-in - def query_vm_property(self, vm_mobj, property_name): - """Method returns the value of specified property for a VM. - - :param vm_mobj: managed object of the VM whose property is to be - queried - :param property_name: path of the property - """ - session = self._api_session - return session.invoke_api(vim_util, "get_object_property", - session.vim, vm_mobj, property_name) - - def query_vm_aggregate_stats(self, vm_mobj, counter_id, duration): - """Method queries the aggregated real-time stat value for a VM. - - This method should be used for aggregate counters. - - :param vm_mobj: managed object of the VM - :param counter_id: id of the perf counter in VC - :param duration: in seconds from current time, - over which the stat value was applicable - :return: the aggregated stats value for the counter - """ - # For aggregate counters, device_name should be "" - stats = self._query_vm_perf_stats(vm_mobj, counter_id, "", duration) - - # Performance manager provides the aggregated stats value - # with device name -> None - return stats.get(None, 0) - - def query_vm_device_stats(self, vm_mobj, counter_id, duration): - """Method queries the real-time stat values for a VM, for all devices. - - This method should be used for device(non-aggregate) counters. - - :param vm_mobj: managed object of the VM - :param counter_id: id of the perf counter in VC - :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 - """ - # For device counters, device_name should be "*" to get stat values - # for all devices. - stats = self._query_vm_perf_stats(vm_mobj, counter_id, "*", duration) - - # For some device counters, in addition to the per device value - # the Performance manager also returns the aggregated value. - # Just to be consistent, deleting the aggregated value if present. - stats.pop(None, None) - return stats - - def _query_vm_perf_stats(self, vm_mobj, counter_id, device_name, duration): - """Method queries the real-time stat values for a VM. - - :param vm_mobj: managed object 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 = vm_mobj - 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 and ignore -1 (bug 1639114) - filtered = [i for i in metric_series.value if i != -1] - stat_value = float(sum(filtered)) / len(filtered) - device_id = metric_series.id.instance - stat_values[device_id] = stat_value - - return stat_values diff --git a/ceilometer/opts.py b/ceilometer/opts.py index ce9e48be18..cd540b1d64 100644 --- a/ceilometer/opts.py +++ b/ceilometer/opts.py @@ -21,7 +21,6 @@ import ceilometer.cmd.polling import ceilometer.compute.discovery import ceilometer.compute.virt.inspector import ceilometer.compute.virt.libvirt.utils -import ceilometer.compute.virt.vmware.inspector import ceilometer.event.converter import ceilometer.image.discovery import ceilometer.ipmi.platform.intel_node_manager @@ -106,8 +105,7 @@ def list_opts(): ceilometer.nova_client.SERVICE_OPTS, ceilometer.objectstore.rgw.SERVICE_OPTS, ceilometer.objectstore.swift.SERVICE_OPTS, - ceilometer.volume.discovery.SERVICE_OPTS,)), - ('vmware', ceilometer.compute.virt.vmware.inspector.OPTS), + ceilometer.volume.discovery.SERVICE_OPTS,)) ] diff --git a/ceilometer/tests/unit/compute/virt/vmware/__init__.py b/ceilometer/tests/unit/compute/virt/vmware/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/ceilometer/tests/unit/compute/virt/vmware/fake.py b/ceilometer/tests/unit/compute/virt/vmware/fake.py deleted file mode 100644 index 1c6eca1c03..0000000000 --- a/ceilometer/tests/unit/compute/virt/vmware/fake.py +++ /dev/null @@ -1,29 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -class ManagedObjectReference(object): - """A managed object reference is a remote identifier.""" - - def __init__(self, name="ManagedObject", value=None, propSetVal=None): - super(ManagedObjectReference, self) - # Managed Object Reference value attributes - # typically have values like vm-123 or - # host-232 and not UUID. - self.value = value - self._value_1 = value - # Managed Object Reference type - # attributes hold the name of the type - # of the vCenter object the value - # attribute is the identifier for - self.type = name - self._type = name diff --git a/ceilometer/tests/unit/compute/virt/vmware/test_inspector.py b/ceilometer/tests/unit/compute/virt/vmware/test_inspector.py deleted file mode 100644 index 37b63dd750..0000000000 --- a/ceilometer/tests/unit/compute/virt/vmware/test_inspector.py +++ /dev/null @@ -1,196 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -""" -Tests for VMware vSphere inspector. -""" - -from unittest import mock - -from oslo_vmware import api -from oslotest import base - -from ceilometer.compute.virt import inspector as virt_inspector -from ceilometer.compute.virt.vmware import inspector as vsphere_inspector -from ceilometer import service -from ceilometer.tests.unit.compute.virt.vmware import fake as vmware_fake - - -class TestVsphereInspection(base.BaseTestCase): - - def setUp(self): - super(TestVsphereInspection, self).setUp() - conf = service.prepare_service([], []) - api_session = api.VMwareAPISession("test_server", "test_user", - "test_password", 0, None, - create_session=False, port=7443) - vsphere_inspector.get_api_session = mock.Mock( - return_value=api_session) - self._inspector = vsphere_inspector.VsphereInspector(conf) - self._inspector._ops = mock.MagicMock() - - def test_instance_notFound(self): - test_vm_mobj = mock.MagicMock() - test_vm_mobj = None - ops_mock = self._inspector._ops - ops_mock.get_vm_mobj.return_value = test_vm_mobj - self.assertRaises(virt_inspector.InstanceNotFoundException, - self._inspector._get_vm_mobj_not_power_off_or_raise, - mock.MagicMock()) - - def test_instance_poweredOff(self): - test_vm_mobj = vmware_fake.ManagedObjectReference('VirtualMachine', - value='vm-21') - test_vm_mobj_powerState = "poweredOff" - - ops_mock = self._inspector._ops - ops_mock.get_vm_mobj.return_value = test_vm_mobj - ops_mock.query_vm_property.return_value = test_vm_mobj_powerState - self.assertRaises(virt_inspector.InstanceShutOffException, - self._inspector._get_vm_mobj_not_power_off_or_raise, - mock.MagicMock()) - - def test_instance_poweredOn(self): - test_vm_mobj = vmware_fake.ManagedObjectReference('VirtualMachine', - value='vm-21') - test_vm_mobj_powerState = "poweredOn" - - ops_mock = self._inspector._ops - ops_mock.get_vm_mobj.return_value = test_vm_mobj - ops_mock.query_vm_property.return_value = test_vm_mobj_powerState - vm_mobj = self._inspector._get_vm_mobj_not_power_off_or_raise( - mock.MagicMock()) - self.assertEqual(test_vm_mobj.value, vm_mobj.value) - - def test_inspect_memory_usage(self): - test_vm_mobj = vmware_fake.ManagedObjectReference('VirtualMachine', - value='vm-21') - fake_perf_counter_id = 'fake_perf_counter_id' - fake_memory_value = 1024.0 - - self._inspector._get_vm_mobj_not_power_off_or_raise = mock.MagicMock() - self._inspector._get_vm_mobj_not_power_off_or_raise.return_value = ( - test_vm_mobj) - - ops_mock = self._inspector._ops - ops_mock.get_perf_counter_id.return_value = fake_perf_counter_id - ops_mock.query_vm_aggregate_stats.return_value = fake_memory_value - stats = self._inspector.inspect_instance(mock.MagicMock(), None) - self.assertEqual(1.0, stats.memory_usage) - - def test_inspect_cpu_util(self): - test_vm_mobj = vmware_fake.ManagedObjectReference('VirtualMachine', - value='vm-21') - fake_perf_counter_id = 'fake_perf_counter_id' - fake_cpu_util_value = 60.0 - - self._inspector._get_vm_mobj_not_power_off_or_raise = mock.MagicMock() - self._inspector._get_vm_mobj_not_power_off_or_raise.return_value = ( - test_vm_mobj) - - ops_mock = self._inspector._ops - ops_mock.get_perf_counter_id.return_value = fake_perf_counter_id - (ops_mock.query_vm_aggregate_stats. - return_value) = fake_cpu_util_value * 100 - stats = self._inspector.inspect_instance(mock.MagicMock(), None) - self.assertEqual(60.0, stats.cpu_util) - - def test_inspect_vnic_rates(self): - - # construct test data - test_vm_mobj = mock.MagicMock() - test_vm_mobj.value = "vm-21" - vnic1 = "vnic-1" - vnic2 = "vnic-2" - counter_name_to_id_map = { - vsphere_inspector.VC_NETWORK_RX_COUNTER: 1, - vsphere_inspector.VC_NETWORK_TX_COUNTER: 2 - } - counter_id_to_stats_map = { - 1: {vnic1: 1, vnic2: 3}, - 2: {vnic1: 2, vnic2: 4}, - } - - def get_counter_id_side_effect(counter_full_name): - return counter_name_to_id_map[counter_full_name] - - def query_stat_side_effect(vm_mobj, counter_id, duration): - # assert inputs - self.assertEqual(test_vm_mobj.value, vm_mobj.value) - self.assertIn(counter_id, counter_id_to_stats_map) - return counter_id_to_stats_map[counter_id] - - self._inspector._get_vm_mobj_not_power_off_or_raise = mock.MagicMock() - self._inspector._get_vm_mobj_not_power_off_or_raise.return_value = ( - test_vm_mobj) - - # configure vsphere operations mock with the test data - ops_mock = self._inspector._ops - ops_mock.get_perf_counter_id.side_effect = get_counter_id_side_effect - ops_mock.query_vm_device_stats.side_effect = query_stat_side_effect - result = list(self._inspector.inspect_vnic_rates( - mock.MagicMock(), None)) - - self.assertEqual(1024.0, result[0].rx_bytes_rate) - self.assertEqual(2048.0, result[0].tx_bytes_rate) - self.assertEqual(3072.0, result[1].rx_bytes_rate) - self.assertEqual(4096.0, result[1].tx_bytes_rate) - - def test_inspect_disk_rates(self): - # construct test data - test_vm_mobj = mock.MagicMock() - test_vm_mobj.value = "vm-21" - disk1 = "disk-1" - disk2 = "disk-2" - counter_name_to_id_map = { - vsphere_inspector.VC_DISK_READ_RATE_CNTR: 1, - vsphere_inspector.VC_DISK_READ_REQUESTS_RATE_CNTR: 2, - vsphere_inspector.VC_DISK_WRITE_RATE_CNTR: 3, - vsphere_inspector.VC_DISK_WRITE_REQUESTS_RATE_CNTR: 4 - } - counter_id_to_stats_map = { - 1: {disk1: 1, disk2: 2}, - 2: {disk1: 300, disk2: 400}, - 3: {disk1: 5, disk2: 6}, - 4: {disk1: 700}, - } - - def get_counter_id_side_effect(counter_full_name): - return counter_name_to_id_map[counter_full_name] - - def query_stat_side_effect(vm_mobj, counter_id, duration): - # assert inputs - self.assertEqual(test_vm_mobj.value, vm_mobj.value) - self.assertIn(counter_id, counter_id_to_stats_map) - return counter_id_to_stats_map[counter_id] - - self._inspector._get_vm_mobj_not_power_off_or_raise = mock.MagicMock() - self._inspector._get_vm_mobj_not_power_off_or_raise.return_value = ( - test_vm_mobj) - - # configure vsphere operations mock with the test data - ops_mock = self._inspector._ops - ops_mock.get_perf_counter_id.side_effect = get_counter_id_side_effect - ops_mock.query_vm_device_stats.side_effect = query_stat_side_effect - - result = self._inspector.inspect_disk_rates(mock.MagicMock(), None) - - # validate result - expected_stats = { - disk1: virt_inspector.DiskRateStats(disk1, 1024, 300, 5120, 700), - disk2: virt_inspector.DiskRateStats(disk2, 2048, 400, 6144, 0) - } - - actual_stats = dict((stats.device, stats) for stats in result) - self.assertEqual(expected_stats, actual_stats) diff --git a/ceilometer/tests/unit/compute/virt/vmware/test_vsphere_operations.py b/ceilometer/tests/unit/compute/virt/vmware/test_vsphere_operations.py deleted file mode 100644 index dad45a495c..0000000000 --- a/ceilometer/tests/unit/compute/virt/vmware/test_vsphere_operations.py +++ /dev/null @@ -1,181 +0,0 @@ -# Copyright (c) 2014 VMware, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from unittest import mock - -from oslo_vmware import api -from oslotest import base - -from ceilometer.compute.virt.vmware import vsphere_operations -from ceilometer.tests.unit.compute.virt.vmware import fake as vmware_fake - - -class VsphereOperationsTest(base.BaseTestCase): - - def setUp(self): - api_session = api.VMwareAPISession("test_server", "test_user", - "test_password", 0, None, - create_session=False) - api_session._vim = mock.MagicMock() - self._vsphere_ops = vsphere_operations.VsphereOperations(api_session, - 1000) - super(VsphereOperationsTest, self).setUp() - - def test_get_vm_object(self): - - vm1_moid = "vm-1" - vm2_moid = "vm-2" - vm1_instance = "0a651a71-142c-4813-aaa6-42e5d5c80d85" - vm2_instance = "db1d2533-6bef-4cb2-aef3-920e109f5693" - - def construct_mock_vm_object(vm_moid, vm_instance): - vm_object = mock.MagicMock() - vm_object.obj = vmware_fake.ManagedObjectReference( - 'VirtualMachine', value=vm_moid) - vm_object.propSet[0].val = vm_instance - return vm_object - - def retrieve_props_side_effect(pc, specSet, - options, skip_op_id=False): - # assert inputs - self.assertEqual(self._vsphere_ops._max_objects, - options.maxObjects) - self.assertEqual(vsphere_operations.VM_INSTANCE_ID_PROPERTY, - specSet[0].pathSet[0]) - - # mock return result - vm1 = construct_mock_vm_object(vm1_moid, vm1_instance) - vm2 = construct_mock_vm_object(vm2_moid, vm2_instance) - result = mock.MagicMock() - result.objects.__iter__.return_value = [vm1, vm2] - return result - - vim_mock = self._vsphere_ops._api_session._vim - vim_mock.RetrievePropertiesEx.side_effect = retrieve_props_side_effect - vim_mock.ContinueRetrievePropertiesEx.return_value = None - - vm_object = self._vsphere_ops.get_vm_mobj(vm1_instance) - self.assertEqual(vm1_moid, vm_object.value) - self.assertEqual("VirtualMachine", vm_object._type) - - vm_object = self._vsphere_ops.get_vm_mobj(vm2_instance) - self.assertEqual(vm2_moid, vm_object.value) - self.assertEqual("VirtualMachine", vm_object._type) - - def test_query_vm_property(self): - vm_object = vmware_fake.ManagedObjectReference('VirtualMachine', - value='vm-21') - vm_property_name = "runtime.powerState" - vm_property_val = "poweredON" - - def retrieve_props_side_effect(pc, specSet, options, - skip_op_id=False): - # assert inputs - self.assertEqual(vm_object.value, specSet[0].obj.value) - self.assertEqual(vm_property_name, specSet[0].pathSet[0]) - - # mock return result - result = mock.MagicMock() - result.objects[0].propSet[0].val = vm_property_val - return result - - vim_mock = self._vsphere_ops._api_session._vim - vim_mock.RetrievePropertiesEx.side_effect = retrieve_props_side_effect - actual_val = self._vsphere_ops.query_vm_property(vm_object, - vm_property_name) - self.assertEqual(vm_property_val, actual_val) - - def test_get_perf_counter_id(self): - - def construct_mock_counter_info(group_name, counter_name, rollup_type, - counter_id): - counter_info = mock.MagicMock() - counter_info.groupInfo.key = group_name - counter_info.nameInfo.key = counter_name - counter_info.rollupType = rollup_type - counter_info.key = counter_id - return counter_info - - def retrieve_props_side_effect(pc, specSet, options, - skip_op_id=False): - # assert inputs - self.assertEqual(vsphere_operations.PERF_COUNTER_PROPERTY, - specSet[0].pathSet[0]) - - # mock return result - counter_info1 = construct_mock_counter_info("a", "b", "c", 1) - counter_info2 = construct_mock_counter_info("x", "y", "z", 2) - result = mock.MagicMock() - (result.objects[0].propSet[0].val.PerfCounterInfo.__iter__. - return_value) = [counter_info1, counter_info2] - return result - - vim_mock = self._vsphere_ops._api_session._vim - vim_mock.RetrievePropertiesEx.side_effect = retrieve_props_side_effect - - counter_id = self._vsphere_ops.get_perf_counter_id("a:b:c") - self.assertEqual(1, counter_id) - - counter_id = self._vsphere_ops.get_perf_counter_id("x:y:z") - self.assertEqual(2, counter_id) - - def test_query_vm_stats(self): - vm_object = vmware_fake.ManagedObjectReference('VirtualMachine', - value='vm-21') - device1 = "device-1" - device2 = "device-2" - device3 = "device-3" - counter_id = 5 - - def construct_mock_metric_series(device_name, stat_values): - metric_series = mock.MagicMock() - metric_series.value = stat_values - metric_series.id.instance = device_name - return metric_series - - def vim_query_perf_side_effect(perf_manager, querySpec): - # assert inputs - self.assertEqual(vm_object.value, querySpec[0].entity.value) - self.assertEqual(counter_id, querySpec[0].metricId[0].counterId) - self.assertEqual(vsphere_operations.VC_REAL_TIME_SAMPLING_INTERVAL, - querySpec[0].intervalId) - - # mock return result - perf_stats = mock.MagicMock() - perf_stats[0].sampleInfo = ["s1", "s2", "s3"] - perf_stats[0].value.__iter__.return_value = [ - construct_mock_metric_series(None, [111, 222, 333]), - construct_mock_metric_series(device1, [100, 200, 300]), - construct_mock_metric_series(device2, [10, 20, 30]), - construct_mock_metric_series(device3, [1, 2, 3]) - ] - return perf_stats - - vim_mock = self._vsphere_ops._api_session._vim - vim_mock.QueryPerf.side_effect = vim_query_perf_side_effect - ops = self._vsphere_ops - - # test aggregate stat - stat_val = ops.query_vm_aggregate_stats(vm_object, counter_id, 60) - self.assertEqual(222, stat_val) - - # test per-device(non-aggregate) stats - expected_device_stats = { - device1: 200, - device2: 20, - device3: 2 - } - stats = ops.query_vm_device_stats(vm_object, counter_id, 60) - self.assertEqual(expected_device_stats, stats) diff --git a/devstack/plugin.sh b/devstack/plugin.sh index 387c5d1b04..66a96d14c1 100644 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -93,20 +93,6 @@ function _ceilometer_prepare_coordination { fi } -# Install the python modules for inspecting nova virt instances -function _ceilometer_prepare_virt_drivers { - # Only install virt drivers if we're running nova compute - if is_service_enabled n-cpu ; then - # NOTE(tkajinam): pythonN-libvirt is installed using distro - # packages in devstack - - if [[ "$VIRT_DRIVER" = 'vsphere' ]]; then - pip_install_gr oslo.vmware - fi - fi -} - - # Create ceilometer related accounts in Keystone function ceilometer_create_accounts { # At this time, the /etc/openstack/clouds.yaml is available, @@ -279,13 +265,6 @@ function configure_ceilometer { iniset $CEILOMETER_CONF service_credentials region_name $REGION_NAME iniset $CEILOMETER_CONF service_credentials auth_url $KEYSTONE_SERVICE_URI - if [[ "$VIRT_DRIVER" = 'vsphere' ]]; then - iniset $CEILOMETER_CONF DEFAULT hypervisor_inspector vsphere - iniset $CEILOMETER_CONF vmware host_ip "$VMWAREAPI_IP" - iniset $CEILOMETER_CONF vmware host_username "$VMWAREAPI_USER" - iniset $CEILOMETER_CONF vmware host_password "$VMWAREAPI_PASSWORD" - fi - _ceilometer_configure_storage_backend if is_service_enabled ceilometer-aipmi; then @@ -319,10 +298,6 @@ function install_ceilometer { ! [[ $DEVSTACK_PLUGINS =~ 'gnocchi' ]] && [[ "$CEILOMETER_BACKENDS" =~ 'gnocchi' ]] && install_gnocchi - if is_service_enabled ceilometer-acompute ; then - _ceilometer_prepare_virt_drivers - fi - if [[ "$CEILOMETER_BACKENDS" =~ 'gnocchi' ]]; then extra=gnocchi fi @@ -347,7 +322,7 @@ function start_ceilometer { # operational keystone if using gnocchi run_process ceilometer-anotification "$CEILOMETER_BIN_DIR/ceilometer-agent-notification --config-file $CEILOMETER_CONF" - run_process ceilometer-acompute "$CEILOMETER_BIN_DIR/ceilometer-polling --polling-namespaces compute --config-file $CEILOMETER_CONF" + run_process ceilometer-acompute "$CEILOMETER_BIN_DIR/ceilometer-polling --polling-namespaces compute --config-file $CEILOMETER_CONF" $LIBVIRT_GROUP } # stop_ceilometer() - Stop running processes diff --git a/doc/source/admin/telemetry-measurements.rst b/doc/source/admin/telemetry-measurements.rst index 06f2d991b9..53cd923767 100644 --- a/doc/source/admin/telemetry-measurements.rst +++ b/doc/source/admin/telemetry-measurements.rst @@ -90,7 +90,7 @@ The following meters are collected for OpenStack Compute. | | | | | | | instance | +-----------+-------+------+----------+----------+---------+------------------+ | memory.\ | Gauge | MB | instance | Pollster | Libvirt,| Volume of RAM | -| usage | | | ID | | vSphere,| used by the inst\| +| usage | | | ID | | | used by the inst\| | | | | | | | ance from the | | | | | | | | amount of its | | | | | | | | allocated memory | diff --git a/doc/source/admin/telemetry-system-architecture.rst b/doc/source/admin/telemetry-system-architecture.rst index 5277cc3a0d..66472b57d4 100644 --- a/doc/source/admin/telemetry-system-architecture.rst +++ b/doc/source/admin/telemetry-system-architecture.rst @@ -78,7 +78,6 @@ compute hosts. The following is a list of supported hypervisors. - `Libvirt supported hypervisors `__ such as KVM and QEMU -- `VMware vSphere `__ .. note:: diff --git a/releasenotes/notes/remove-vsphere-support-411c97b66bdcd264.yaml b/releasenotes/notes/remove-vsphere-support-411c97b66bdcd264.yaml new file mode 100644 index 0000000000..5c6db27b18 --- /dev/null +++ b/releasenotes/notes/remove-vsphere-support-411c97b66bdcd264.yaml @@ -0,0 +1,10 @@ +--- +upgrade: + - | + Support for VMware vSphere has been removed. + +deprecations: + - | + The ``[DEFAULT] hypervisor_inspector`` option has been deprecated, because + libvirt is the only supported hypervisor currently. The option will be + removed in a future release. diff --git a/setup.cfg b/setup.cfg index 9160f8b6e5..5004b9ce56 100644 --- a/setup.cfg +++ b/setup.cfg @@ -142,7 +142,6 @@ ceilometer.poll.central = ceilometer.compute.virt = libvirt = ceilometer.compute.virt.libvirt.inspector:LibvirtInspector - vsphere = ceilometer.compute.virt.vmware.inspector:VsphereInspector ceilometer.sample.publisher = test = ceilometer.publisher.test:TestPublisher diff --git a/test-requirements.txt b/test-requirements.txt index db4a9f768c..b6db147193 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -2,7 +2,6 @@ coverage>=4.4.1 # Apache-2.0 fixtures>=3.0.0 # Apache-2.0/BSD oslo.messaging[kafka]>=8.0.0 # Apache-2.0 oslotest>=3.8.0 # Apache-2.0 -oslo.vmware>=2.17.0 # Apache-2.0 pyOpenSSL>=17.5.0 # Apache-2.0 testscenarios>=0.4 # Apache-2.0/BSD testtools>=2.2.0 # MIT