Remove VMWare vSphere support
It was deprecated a few cycles ago[1] and we haven't heard any request
to keep it.
[1] 297089a622
Change-Id: Ib3290bb0d8739842c37d4b085a6d5a2f71de1b84
This commit is contained in:
@@ -26,8 +26,10 @@ import ceilometer
|
|||||||
OPTS = [
|
OPTS = [
|
||||||
cfg.StrOpt('hypervisor_inspector',
|
cfg.StrOpt('hypervisor_inspector',
|
||||||
default='libvirt',
|
default='libvirt',
|
||||||
help='Inspector to use for inspecting the hypervisor layer. '
|
choices=['libvirt'],
|
||||||
'Known inspectors are libvirt and vsphere.'),
|
deprecated_for_removal=True,
|
||||||
|
deprecated_reason='libvirt is the only supported hypervisor',
|
||||||
|
help='Inspector to use for inspecting the hypervisor layer.')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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://<server>/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)
|
|
@@ -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
|
|
@@ -21,7 +21,6 @@ import ceilometer.cmd.polling
|
|||||||
import ceilometer.compute.discovery
|
import ceilometer.compute.discovery
|
||||||
import ceilometer.compute.virt.inspector
|
import ceilometer.compute.virt.inspector
|
||||||
import ceilometer.compute.virt.libvirt.utils
|
import ceilometer.compute.virt.libvirt.utils
|
||||||
import ceilometer.compute.virt.vmware.inspector
|
|
||||||
import ceilometer.event.converter
|
import ceilometer.event.converter
|
||||||
import ceilometer.image.discovery
|
import ceilometer.image.discovery
|
||||||
import ceilometer.ipmi.platform.intel_node_manager
|
import ceilometer.ipmi.platform.intel_node_manager
|
||||||
@@ -106,8 +105,7 @@ def list_opts():
|
|||||||
ceilometer.nova_client.SERVICE_OPTS,
|
ceilometer.nova_client.SERVICE_OPTS,
|
||||||
ceilometer.objectstore.rgw.SERVICE_OPTS,
|
ceilometer.objectstore.rgw.SERVICE_OPTS,
|
||||||
ceilometer.objectstore.swift.SERVICE_OPTS,
|
ceilometer.objectstore.swift.SERVICE_OPTS,
|
||||||
ceilometer.volume.discovery.SERVICE_OPTS,)),
|
ceilometer.volume.discovery.SERVICE_OPTS,))
|
||||||
('vmware', ceilometer.compute.virt.vmware.inspector.OPTS),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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
|
|
@@ -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)
|
|
@@ -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)
|
|
@@ -93,20 +93,6 @@ function _ceilometer_prepare_coordination {
|
|||||||
fi
|
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
|
# Create ceilometer related accounts in Keystone
|
||||||
function ceilometer_create_accounts {
|
function ceilometer_create_accounts {
|
||||||
# At this time, the /etc/openstack/clouds.yaml is available,
|
# 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 region_name $REGION_NAME
|
||||||
iniset $CEILOMETER_CONF service_credentials auth_url $KEYSTONE_SERVICE_URI
|
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
|
_ceilometer_configure_storage_backend
|
||||||
|
|
||||||
if is_service_enabled ceilometer-aipmi; then
|
if is_service_enabled ceilometer-aipmi; then
|
||||||
@@ -319,10 +298,6 @@ function install_ceilometer {
|
|||||||
|
|
||||||
! [[ $DEVSTACK_PLUGINS =~ 'gnocchi' ]] && [[ "$CEILOMETER_BACKENDS" =~ 'gnocchi' ]] && install_gnocchi
|
! [[ $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
|
if [[ "$CEILOMETER_BACKENDS" =~ 'gnocchi' ]]; then
|
||||||
extra=gnocchi
|
extra=gnocchi
|
||||||
fi
|
fi
|
||||||
@@ -347,7 +322,7 @@ function start_ceilometer {
|
|||||||
# operational keystone if using gnocchi
|
# operational keystone if using gnocchi
|
||||||
run_process ceilometer-anotification "$CEILOMETER_BIN_DIR/ceilometer-agent-notification --config-file $CEILOMETER_CONF"
|
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
|
# stop_ceilometer() - Stop running processes
|
||||||
|
@@ -90,7 +90,7 @@ The following meters are collected for OpenStack Compute.
|
|||||||
| | | | | | | instance |
|
| | | | | | | instance |
|
||||||
+-----------+-------+------+----------+----------+---------+------------------+
|
+-----------+-------+------+----------+----------+---------+------------------+
|
||||||
| memory.\ | Gauge | MB | instance | Pollster | Libvirt,| Volume of RAM |
|
| 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 |
|
| | | | | | | ance from the |
|
||||||
| | | | | | | amount of its |
|
| | | | | | | amount of its |
|
||||||
| | | | | | | allocated memory |
|
| | | | | | | allocated memory |
|
||||||
|
@@ -78,7 +78,6 @@ compute hosts.
|
|||||||
The following is a list of supported hypervisors.
|
The following is a list of supported hypervisors.
|
||||||
|
|
||||||
- `Libvirt supported hypervisors <http://libvirt.org/>`__ such as KVM and QEMU
|
- `Libvirt supported hypervisors <http://libvirt.org/>`__ such as KVM and QEMU
|
||||||
- `VMware vSphere <https://www.vmware.com/support/vsphere-hypervisor.html>`__
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
@@ -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.
|
@@ -142,7 +142,6 @@ ceilometer.poll.central =
|
|||||||
|
|
||||||
ceilometer.compute.virt =
|
ceilometer.compute.virt =
|
||||||
libvirt = ceilometer.compute.virt.libvirt.inspector:LibvirtInspector
|
libvirt = ceilometer.compute.virt.libvirt.inspector:LibvirtInspector
|
||||||
vsphere = ceilometer.compute.virt.vmware.inspector:VsphereInspector
|
|
||||||
|
|
||||||
ceilometer.sample.publisher =
|
ceilometer.sample.publisher =
|
||||||
test = ceilometer.publisher.test:TestPublisher
|
test = ceilometer.publisher.test:TestPublisher
|
||||||
|
@@ -2,7 +2,6 @@ coverage>=4.4.1 # Apache-2.0
|
|||||||
fixtures>=3.0.0 # Apache-2.0/BSD
|
fixtures>=3.0.0 # Apache-2.0/BSD
|
||||||
oslo.messaging[kafka]>=8.0.0 # Apache-2.0
|
oslo.messaging[kafka]>=8.0.0 # Apache-2.0
|
||||||
oslotest>=3.8.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
|
pyOpenSSL>=17.5.0 # Apache-2.0
|
||||||
testscenarios>=0.4 # Apache-2.0/BSD
|
testscenarios>=0.4 # Apache-2.0/BSD
|
||||||
testtools>=2.2.0 # MIT
|
testtools>=2.2.0 # MIT
|
||||||
|
Reference in New Issue
Block a user