Migrate the old snmp pollsters to new declarative pollster

Delete all the old snmp pollsters and to register the new declarative
snmp pollster to be used.

Change-Id: I8ebb2a53bca52eed77229d4cc56cf1f42aaa1a7b
Implements: blueprint declarative-snmp-metrics
This commit is contained in:
Lianhao Lu 2015-08-28 14:41:39 +08:00
parent f9981f3e3e
commit 8b1ba63d29
20 changed files with 54 additions and 978 deletions

View File

@ -25,13 +25,10 @@ import six
@six.add_metaclass(abc.ABCMeta)
class Inspector(object):
@abc.abstractmethod
def inspect_generic(self, host, identifier, cache,
extra_metadata=None,
param=None):
def inspect_generic(self, host, cache, extra_metadata, param):
"""A generic inspect function.
:param host: the target host
:param identifier: the identifier of the metric
:param cache: cache passed from the pollster
:param extra_metadata: extra dict to be used as metadata
:param param: a dict of inspector specific param

View File

@ -62,56 +62,15 @@ PREFIX = 'type_prefix'
class SNMPInspector(base.Inspector):
# CPU OIDs
_cpu_1_min_load_oid = "1.3.6.1.4.1.2021.10.1.3.1"
_cpu_5_min_load_oid = "1.3.6.1.4.1.2021.10.1.3.2"
_cpu_15_min_load_oid = "1.3.6.1.4.1.2021.10.1.3.3"
# Memory OIDs
_memory_total_oid = "1.3.6.1.4.1.2021.4.5.0"
_memory_avail_real_oid = "1.3.6.1.4.1.2021.4.6.0"
_memory_total_swap_oid = "1.3.6.1.4.1.2021.4.3.0"
_memory_avail_swap_oid = "1.3.6.1.4.1.2021.4.4.0"
_memory_buffer_oid = "1.3.6.1.4.1.2021.4.14.0"
_memory_cached_oid = "1.3.6.1.4.1.2021.4.15.0"
# Disk OIDs
_disk_index_oid = "1.3.6.1.4.1.2021.9.1.1"
_disk_path_oid = "1.3.6.1.4.1.2021.9.1.2"
_disk_device_oid = "1.3.6.1.4.1.2021.9.1.3"
_disk_size_oid = "1.3.6.1.4.1.2021.9.1.6"
_disk_used_oid = "1.3.6.1.4.1.2021.9.1.8"
# Network Interface OIDs
_interface_index_oid = "1.3.6.1.2.1.2.2.1.1"
_interface_name_oid = "1.3.6.1.2.1.2.2.1.2"
_interface_speed_oid = "1.3.6.1.2.1.2.2.1.5"
_interface_mac_oid = "1.3.6.1.2.1.2.2.1.6"
_interface_ip_oid = "1.3.6.1.2.1.4.20.1.2"
_interface_received_oid = "1.3.6.1.2.1.2.2.1.10"
_interface_transmitted_oid = "1.3.6.1.2.1.2.2.1.16"
_interface_error_oid = "1.3.6.1.2.1.2.2.1.20"
# System stats
_system_stats_cpu_idle_oid = "1.3.6.1.4.1.2021.11.11.0"
_system_stats_io_raw_sent_oid = "1.3.6.1.4.1.2021.11.57.0"
_system_stats_io_raw_received_oid = "1.3.6.1.4.1.2021.11.58.0"
# Network stats
_network_ip_out_requests_oid = "1.3.6.1.2.1.4.10.0"
_network_ip_in_receives_oid = "1.3.6.1.2.1.4.3.0"
# Default port
_port = 161
_disk_metadata = {
'path': (_disk_path_oid, str),
'device': (_disk_device_oid, str),
}
_net_metadata = {
'name': (_interface_name_oid, str),
'speed': (_interface_speed_oid, lambda x: int(x) / 8),
'mac': (_interface_mac_oid,
lambda x: x.prettyPrint().replace('0x', '')),
}
_CACHE_KEY_OID = "snmp_cached_oid"
# NOTE: The folloing mapping has been moved to the yaml file identified by
# the config options hardware.meter_definitions_file. However, we still
# keep the description here for code reading purpose.
"""
The following mapping define how to construct
@ -169,123 +128,6 @@ class SNMPInspector(base.Inspector):
extra.update('project_id': xy, 'user_id': zw)
"""
MAPPING = {
'cpu.load.1min': {
'matching_type': EXACT,
'metric_oid': (_cpu_1_min_load_oid, lambda x: float(str(x))),
'metadata': {},
'post_op': None
},
'cpu.load.5min': {
'matching_type': EXACT,
'metric_oid': (_cpu_5_min_load_oid, lambda x: float(str(x))),
'metadata': {},
'post_op': None,
},
'cpu.load.15min': {
'matching_type': EXACT,
'metric_oid': (_cpu_15_min_load_oid, lambda x: float(str(x))),
'metadata': {},
'post_op': None,
},
'memory.total': {
'matching_type': EXACT,
'metric_oid': (_memory_total_oid, int),
'metadata': {},
'post_op': None,
},
'memory.used': {
'matching_type': EXACT,
'metric_oid': (_memory_avail_real_oid, int),
'metadata': {},
'post_op': "_post_op_memory_avail_to_used",
},
'memory.swap.total': {
'matching_type': EXACT,
'metric_oid': (_memory_total_swap_oid, int),
'metadata': {},
'post_op': None,
},
'memory.swap.avail': {
'matching_type': EXACT,
'metric_oid': (_memory_avail_swap_oid, int),
'metadata': {},
'post_op': None,
},
'memory.buffer': {
'matching_type': EXACT,
'metric_oid': (_memory_buffer_oid, int),
'metadata': {},
'post_op': None,
},
'memory.cached': {
'matching_type': EXACT,
'metric_oid': (_memory_cached_oid, int),
'metadata': {},
'post_op': None,
},
'disk.size.total': {
'matching_type': PREFIX,
'metric_oid': (_disk_size_oid, int),
'metadata': _disk_metadata,
'post_op': None,
},
'disk.size.used': {
'matching_type': PREFIX,
'metric_oid': (_disk_used_oid, int),
'metadata': _disk_metadata,
'post_op': None,
},
'network.incoming.bytes': {
'matching_type': PREFIX,
'metric_oid': (_interface_received_oid, int),
'metadata': _net_metadata,
'post_op': "_post_op_net",
},
'network.outgoing.bytes': {
'matching_type': PREFIX,
'metric_oid': (_interface_transmitted_oid, int),
'metadata': _net_metadata,
'post_op': "_post_op_net",
},
'network.outgoing.errors': {
'matching_type': PREFIX,
'metric_oid': (_interface_error_oid, int),
'metadata': _net_metadata,
'post_op': "_post_op_net",
},
'network.ip.outgoing.datagrams': {
'matching_type': EXACT,
'metric_oid': (_network_ip_out_requests_oid, int),
'metadata': {},
'post_op': None,
},
'network.ip.incoming.datagrams': {
'matching_type': EXACT,
'metric_oid': (_network_ip_in_receives_oid, int),
'metadata': {},
'post_op': None,
},
'system_stats.cpu.idle': {
'matching_type': EXACT,
'metric_oid': (_system_stats_cpu_idle_oid, int),
'metadata': {},
'post_op': None,
},
'system_stats.io.outgoing.blocks': {
'matching_type': EXACT,
'metric_oid': (_system_stats_io_raw_sent_oid, int),
'metadata': {},
'post_op': None,
},
'system_stats.io.incoming.blocks': {
'matching_type': EXACT,
'metric_oid': (_system_stats_io_raw_received_oid, int),
'metadata': {},
'post_op': None,
},
}
def __init__(self):
super(SNMPInspector, self).__init__()
self._cmdGen = cmdgen.CommandGenerator()
@ -371,14 +213,9 @@ class SNMPInspector(base.Inspector):
new_oids.append(metadata[0])
return new_oids
def inspect_generic(self, host, identifier, cache,
extra_metadata=None,
param=None):
def inspect_generic(self, host, cache, extra_metadata, param):
# the snmp definition for the corresponding meter
if param:
meter_def = param
else:
meter_def = self.MAPPING[identifier]
# collect oids that needs to be queried
oids_to_query = self._find_missing_oids(meter_def, cache)
# query oids and populate into caches
@ -418,35 +255,44 @@ class SNMPInspector(base.Inspector):
def _post_op_memory_avail_to_used(self, host, cache, meter_def,
value, metadata, extra, suffix):
if self._memory_total_oid not in cache[self._CACHE_KEY_OID]:
self._query_oids(host, [self._memory_total_oid], cache, False)
value = int(cache[self._CACHE_KEY_OID][self._memory_total_oid]) - value
_memory_total_oid = "1.3.6.1.4.1.2021.4.5.0"
if _memory_total_oid not in cache[self._CACHE_KEY_OID]:
self._query_oids(host, [_memory_total_oid], cache, False)
value = int(cache[self._CACHE_KEY_OID][_memory_total_oid]) - value
return value
def _post_op_net(self, host, cache, meter_def,
value, metadata, extra, suffix):
# add ip address into metadata
_interface_ip_oid = "1.3.6.1.2.1.4.20.1.2"
oid_cache = cache.setdefault(self._CACHE_KEY_OID, {})
if not self.find_matching_oids(oid_cache,
self._interface_ip_oid,
_interface_ip_oid,
PREFIX):
# populate the oid into cache
self._query_oids(host, [self._interface_ip_oid], cache, True)
self._query_oids(host, [_interface_ip_oid], cache, True)
ip_addr = ''
for k, v in six.iteritems(oid_cache):
if k.startswith(self._interface_ip_oid) and v == int(suffix[1:]):
ip_addr = k.replace(self._interface_ip_oid + ".", "")
if k.startswith(_interface_ip_oid) and v == int(suffix[1:]):
ip_addr = k.replace(_interface_ip_oid + ".", "")
metadata.update(ip=ip_addr)
# update resource_id for each nic interface
self._suffix_resource_id(host, metadata, 'name', extra)
return value
def _post_op_disk(self, host, cache, meter_def,
value, metadata, extra, suffix):
if metadata.get('device'):
res_id = extra.get('resource_id') or host.hostname
res_id = res_id + ".%s" % metadata.get('device')
extra.update(resource_id=res_id)
self._suffix_resource_id(host, metadata, 'device', extra)
return value
@staticmethod
def _suffix_resource_id(host, metadata, key, extra):
prefix = metadata.get(key)
if prefix:
res_id = extra.get('resource_id') or host.hostname
res_id = res_id + ".%s" % metadata.get(key)
extra.update(resource_id=res_id)
@staticmethod
def _get_auth_strategy(host):
if host.password:

View File

@ -1,144 +0,0 @@
#
# Copyright 2013 ZHAW SoE
# Copyright 2014 Intel Corp.
#
# Authors: Lucas Graf <graflu0@students.zhaw.ch>
# Toni Zehnder <zehndton@students.zhaw.ch>
# Lianhao Lu <lianhao.lu@intel.com>
#
# 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.
"""Base class for plugins used by the hardware agent."""
import abc
import itertools
from oslo_log import log
from oslo_utils import netutils
import six
from ceilometer.agent import plugin_base
from ceilometer.hardware import inspector as insloader
from ceilometer.i18n import _
LOG = log.getLogger(__name__)
@six.add_metaclass(abc.ABCMeta)
class HardwarePollster(plugin_base.PollsterBase):
"""Base class for plugins that support the polling API."""
CACHE_KEY = None
IDENTIFIER = None
def __init__(self):
super(HardwarePollster, self).__init__()
self.inspectors = {}
@property
def default_discovery(self):
return 'tripleo_overcloud_nodes'
@staticmethod
def _parse_resource(res):
"""Parse resource from discovery.
Either URL can be given or dict. Dict has to contain at least
keys 'resource_id' and 'resource_url', all the dict keys will be stored
as metadata.
:param res: URL or dict containing all resource info.
:return parsed_url, resource_id, metadata: Returns parsed URL used for
SNMP query, unique identifier of the resource and metadata
of the resource.
"""
if isinstance(res, dict):
if 'resource_url' not in res or 'resource_id' not in res:
LOG.exception(_('Passed resource dict must contain keys '
'resource_id and resource_url.'))
metadata = res
parsed_url = netutils.urlsplit(res['resource_url'])
resource_id = res['resource_id']
else:
metadata = {}
parsed_url = netutils.urlsplit(res)
resource_id = res
return parsed_url, resource_id, metadata
def get_samples(self, manager, cache, resources=None):
"""Return an iterable of Sample instances from polling the resources.
:param manager: The service manager invoking the plugin
:param cache: A dictionary for passing data between plugins
:param resources: end point to poll data from
"""
resources = resources or []
h_cache = cache.setdefault(self.CACHE_KEY, {})
sample_iters = []
for resource in resources:
parsed_url, res, extra_metadata = self._parse_resource(resource)
ins = self._get_inspector(parsed_url)
try:
# Call hardware inspector to poll for the data
i_cache = h_cache.setdefault(res, {})
if self.IDENTIFIER not in i_cache:
i_cache[self.IDENTIFIER] = list(ins.inspect_generic(
parsed_url,
self.IDENTIFIER,
i_cache,
extra_metadata))
# Generate samples
if i_cache[self.IDENTIFIER]:
sample_iters.append(self.generate_samples(
parsed_url,
i_cache[self.IDENTIFIER]))
except Exception as err:
LOG.exception(_('inspector call failed for %(ident)s '
'host %(host)s: %(err)s'),
dict(ident=self.IDENTIFIER,
host=parsed_url.hostname,
err=err))
return itertools.chain(*sample_iters)
def generate_samples(self, host_url, data):
"""Generate an iterable Sample from the data returned by inspector
:param host_url: host url of the endpoint
:param data: list of data returned by the corresponding inspector
"""
return (self.generate_one_sample(host_url, datum) for datum in data)
@abc.abstractmethod
def generate_one_sample(self, host_url, c_data):
"""Return one Sample.
:param host_url: host url of the endpoint
:param c_data: data returned by the inspector.inspect_generic,
tuple of (value, metadata, extra)
"""
def _get_inspector(self, parsed_url):
if parsed_url.scheme not in self.inspectors:
try:
driver = insloader.get_inspector(parsed_url)
self.inspectors[parsed_url.scheme] = driver
except Exception as err:
LOG.exception(_("Can NOT load inspector %(name)s: %(err)s"),
dict(name=parsed_url.scheme,
err=err))
raise err
return self.inspectors[parsed_url.scheme]

View File

@ -1,50 +0,0 @@
#
# Copyright 2013 ZHAW SoE
# Copyright 2014 Intel Corp.
#
# Authors: Lucas Graf <graflu0@students.zhaw.ch>
# Toni Zehnder <zehndton@students.zhaw.ch>
# Lianhao Lu <lianhao.lu@intel.com>
#
# 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 ceilometer.hardware import plugin
from ceilometer.hardware.pollsters import util
from ceilometer import sample
class _Base(plugin.HardwarePollster):
CACHE_KEY = 'cpu'
def generate_one_sample(self, host, c_data):
value, metadata, extra = c_data
return util.make_sample_from_host(host,
name=self.IDENTIFIER,
sample_type=sample.TYPE_GAUGE,
unit='process',
volume=value,
res_metadata=metadata,
extra=extra)
class CPULoad1MinPollster(_Base):
IDENTIFIER = 'cpu.load.1min'
class CPULoad5MinPollster(_Base):
IDENTIFIER = 'cpu.load.5min'
class CPULoad15MinPollster(_Base):
IDENTIFIER = 'cpu.load.15min'

View File

@ -1,50 +0,0 @@
#
# Copyright 2013 ZHAW SoE
# Copyright 2014 Intel Corp.
#
# Authors: Lucas Graf <graflu0@students.zhaw.ch>
# Toni Zehnder <zehndton@students.zhaw.ch>
# Lianhao Lu <lianhao.lu@intel.com>
#
# 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 ceilometer.hardware import plugin
from ceilometer.hardware.pollsters import util
from ceilometer import sample
class _Base(plugin.HardwarePollster):
CACHE_KEY = 'disk'
def generate_one_sample(self, host, c_data):
value, metadata, extra = c_data
res_id = extra.get('resource_id') or host.hostname
if metadata.get('device'):
res_id = res_id + ".%s" % metadata.get('device')
return util.make_sample_from_host(host,
name=self.IDENTIFIER,
sample_type=sample.TYPE_GAUGE,
unit='KB',
volume=value,
res_metadata=metadata,
extra=extra,
resource_id=res_id)
class DiskTotalPollster(_Base):
IDENTIFIER = 'disk.size.total'
class DiskUsedPollster(_Base):
IDENTIFIER = 'disk.size.used'

View File

@ -165,10 +165,9 @@ class GenericHardwareDeclarativePollster(plugin_base.PollsterBase):
if identifier not in i_cache:
i_cache[identifier] = list(ins.inspect_generic(
parsed_url,
identifier,
i_cache,
extra_metadata,
host=parsed_url,
cache=i_cache,
extra_metadata=extra_metadata,
param=inspector_param))
# Generate samples
if i_cache[identifier]:

View File

@ -1,62 +0,0 @@
#
# Copyright 2013 ZHAW SoE
# Copyright 2014 Intel Corp.
#
# Authors: Lucas Graf <graflu0@students.zhaw.ch>
# Toni Zehnder <zehndton@students.zhaw.ch>
# Lianhao Lu <lianhao.lu@intel.com>
#
# 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 ceilometer.hardware import plugin
from ceilometer.hardware.pollsters import util
from ceilometer import sample
class _Base(plugin.HardwarePollster):
CACHE_KEY = 'memory'
def generate_one_sample(self, host, c_data):
value, metadata, extra = c_data
return util.make_sample_from_host(host,
name=self.IDENTIFIER,
sample_type=sample.TYPE_GAUGE,
unit='KB',
volume=value,
res_metadata=metadata,
extra=extra)
class MemoryTotalPollster(_Base):
IDENTIFIER = 'memory.total'
class MemoryUsedPollster(_Base):
IDENTIFIER = 'memory.used'
class MemorySwapTotalPollster(_Base):
IDENTIFIER = 'memory.swap.total'
class MemorySwapAvailPollster(_Base):
IDENTIFIER = 'memory.swap.avail'
class MemoryBufferPollster(_Base):
IDENTIFIER = 'memory.buffer'
class MemoryCachedPollster(_Base):
IDENTIFIER = 'memory.cached'

View File

@ -1,57 +0,0 @@
#
# Copyright 2013 ZHAW SoE
# Copyright 2014 Intel Corp.
#
# Authors: Lucas Graf <graflu0@students.zhaw.ch>
# Toni Zehnder <zehndton@students.zhaw.ch>
# Lianhao Lu <lianhao.lu@intel.com>
#
# 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 ceilometer.hardware import plugin
from ceilometer.hardware.pollsters import util
from ceilometer import sample
class _Base(plugin.HardwarePollster):
CACHE_KEY = 'nic'
def generate_one_sample(self, host, c_data):
value, metadata, extra = c_data
res_id = extra.get('resource_id') or host.hostname
if metadata.get('name'):
res_id = res_id + ".%s" % metadata.get('name')
return util.make_sample_from_host(host,
name=self.IDENTIFIER,
sample_type=sample.TYPE_CUMULATIVE,
unit=self.unit,
volume=value,
res_metadata=metadata,
extra=extra,
resource_id=res_id)
class IncomingBytesPollster(_Base):
IDENTIFIER = 'network.incoming.bytes'
unit = 'B'
class OutgoingBytesPollster(_Base):
IDENTIFIER = 'network.outgoing.bytes'
unit = 'B'
class OutgoingErrorsPollster(_Base):
IDENTIFIER = 'network.outgoing.errors'
unit = 'packet'

View File

@ -1,38 +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.
from ceilometer.hardware import plugin
from ceilometer.hardware.pollsters import util
from ceilometer import sample
class _Base(plugin.HardwarePollster):
CACHE_KEY = 'network'
def generate_one_sample(self, host, c_data):
value, metadata, extra = c_data
return util.make_sample_from_host(host,
name=self.IDENTIFIER,
sample_type=sample.TYPE_CUMULATIVE,
unit='datagrams',
volume=value,
res_metadata=metadata,
extra=extra)
class NetworkAggregatedIPOutRequests(_Base):
IDENTIFIER = 'network.ip.outgoing.datagrams'
class NetworkAggregatedIPInReceives(_Base):
IDENTIFIER = 'network.ip.incoming.datagrams'

View File

@ -1,50 +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.
from ceilometer.hardware import plugin
from ceilometer.hardware.pollsters import util
from ceilometer import sample
class _Base(plugin.HardwarePollster):
CACHE_KEY = 'system'
class _SystemBase(_Base):
def generate_one_sample(self, host, c_data):
value, metadata, extra = c_data
return util.make_sample_from_host(host,
name=self.IDENTIFIER,
sample_type=self.TYPE,
unit=self.UNIT,
volume=value,
res_metadata=metadata,
extra=extra)
class SystemCpuIdlePollster(_SystemBase):
IDENTIFIER = 'system_stats.cpu.idle'
TYPE = sample.TYPE_GAUGE
UNIT = '%'
class SystemIORawSentPollster(_SystemBase):
IDENTIFIER = 'system_stats.io.outgoing.blocks'
TYPE = sample.TYPE_CUMULATIVE
UNIT = 'blocks'
class SystemIORawReceivedPollster(_SystemBase):
IDENTIFIER = 'system_stats.io.incoming.blocks'
TYPE = sample.TYPE_CUMULATIVE
UNIT = 'blocks'

View File

@ -72,7 +72,6 @@ class TestSNMPInspector(test_base.BaseTestCase):
super(TestSNMPInspector, self).setUp()
self.inspector = snmp.SNMPInspector()
self.host = netutils.urlsplit("snmp://localhost")
self.inspector.MAPPING = self.mapping
self.useFixture(mockpatch.PatchObject(
self.inspector._cmdGen, 'getCmd', new=faux_getCmd_new))
self.useFixture(mockpatch.PatchObject(
@ -91,9 +90,10 @@ class TestSNMPInspector(test_base.BaseTestCase):
self.assertRaises(snmp.SNMPException,
get_list,
self.inspector.inspect_generic,
self.host,
'test_exact',
{})
host=self.host,
cache={},
extra_metadata={},
param=self.mapping['test_exact'])
@staticmethod
def _fake_post_op(host, cache, meter_def, value, metadata, extra, suffix):
@ -105,8 +105,9 @@ class TestSNMPInspector(test_base.BaseTestCase):
self.inspector._fake_post_op = self._fake_post_op
cache = {}
ret = list(self.inspector.inspect_generic(self.host,
'test_exact',
cache))
cache,
{},
self.mapping['test_exact']))
keys = cache[ins._CACHE_KEY_OID].keys()
self.assertIn('1.3.6.1.4.1.2021.10.1.3.1', keys)
self.assertIn('1.3.6.1.4.1.2021.10.1.3.8', keys)
@ -119,8 +120,9 @@ class TestSNMPInspector(test_base.BaseTestCase):
def test_inspect_generic_prefix(self):
cache = {}
ret = list(self.inspector.inspect_generic(self.host,
'test_prefix',
cache))
cache,
{},
self.mapping['test_prefix']))
keys = cache[ins._CACHE_KEY_OID].keys()
self.assertIn('1.3.6.1.4.1.2021.9.1.8' + '.1', keys)
self.assertIn('1.3.6.1.4.1.2021.9.1.8' + '.2', keys)
@ -134,15 +136,20 @@ class TestSNMPInspector(test_base.BaseTestCase):
self.useFixture(mockpatch.PatchObject(
self.inspector._cmdGen, 'bulkCmd', new=faux_bulkCmd_new))
cache = {}
metadata = {}
metadata = dict(name='lo',
speed=0,
mac='ba21e43302fe')
extra = {}
ret = self.inspector._post_op_net(self.host, cache, None,
value=8,
metadata=metadata,
extra={},
extra=extra,
suffix=".2")
self.assertEqual(8, ret)
self.assertIn('ip', metadata)
self.assertIn("2", metadata['ip'])
self.assertIn('resource_id', extra)
self.assertEqual("localhost.lo", extra['resource_id'])
def test_post_op_disk(self):
cache = {}

View File

@ -1,86 +0,0 @@
#
# Copyright 2013 Intel Corp
#
# Authors: Lianhao Lu <lianhao.lu@intel.com>
#
# 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.
import fixtures
import mock
from ceilometer.agent import manager
from ceilometer.hardware.inspector import base as inspector_base
from ceilometer.tests import base as test_base
class FakeInspector(inspector_base.Inspector):
net_metadata = dict(name='test.teest',
mac='001122334455',
ip='10.0.0.2',
speed=1000)
disk_metadata = dict(device='/dev/sda1', path='/')
DATA = {
'cpu.load.1min': (0.99, {}, {}),
'cpu.load.5min': (0.77, {}, {}),
'cpu.load.15min': (0.55, {}, {}),
'memory.total': (1000, {}, {}),
'memory.used': (90, {}, {}),
'memory.buffer': (500, {}, {}),
'memory.cached': (200, {}, {}),
'network.incoming.bytes': (90, net_metadata, {}),
'network.outgoing.bytes': (80, net_metadata, {}),
'network.outgoing.errors': (1, net_metadata, {}),
'disk.size.total': (1000, disk_metadata, {}),
'disk.size.used': (90, disk_metadata, {}),
'system_stats.cpu.idle': (62, {}, {}),
'system_stats.io.outgoing.blocks': (100, {}, {}),
'system_stats.io.incoming.blocks': (120, {}, {}),
'network.ip.outgoing.datagrams': (200, {}, {}),
'network.ip.incoming.datagrams': (300, {}, {}),
}
def inspect_generic(self, host, identifier, cache, extra_metadata=None):
yield self.DATA[identifier]
class TestPollsterBase(test_base.BaseTestCase):
@staticmethod
def faux_get_inspector(url, namespace=None):
return FakeInspector()
def setUp(self):
super(TestPollsterBase, self).setUp()
self.hosts = ["test://test", "test://test2"]
self.useFixture(fixtures.MonkeyPatch(
'ceilometer.hardware.inspector.get_inspector',
self.faux_get_inspector))
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
def _check_get_samples(self, factory, name,
expected_value, expected_type, expected_unit=None):
mgr = manager.AgentManager()
pollster = factory()
cache = {}
samples = list(pollster.get_samples(mgr, cache, self.hosts))
self.assertTrue(samples)
self.assertIn(pollster.CACHE_KEY, cache)
for host in self.hosts:
self.assertIn(host, cache[pollster.CACHE_KEY])
self.assertEqual(set([name]),
set([s.name for s in samples]))
match = [s for s in samples if s.name == name]
self.assertEqual(expected_value, match[0].volume)
self.assertEqual(expected_type, match[0].type)
if expected_unit:
self.assertEqual(expected_unit, match[0].unit)

View File

@ -1,40 +0,0 @@
#
# Copyright 2013 Intel Corp
#
# Authors: Lianhao Lu <lianhao.lu@intel.com>
#
# 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 ceilometer.hardware.pollsters import cpu
from ceilometer import sample
from ceilometer.tests.unit.hardware.pollsters import base
class TestCPUPollsters(base.TestPollsterBase):
def test_1min(self):
self._check_get_samples(cpu.CPULoad1MinPollster,
'hardware.cpu.load.1min',
0.99, sample.TYPE_GAUGE,
expected_unit='process')
def test_5min(self):
self._check_get_samples(cpu.CPULoad5MinPollster,
'hardware.cpu.load.5min',
0.77, sample.TYPE_GAUGE,
expected_unit='process')
def test_15min(self):
self._check_get_samples(cpu.CPULoad15MinPollster,
'hardware.cpu.load.15min',
0.55, sample.TYPE_GAUGE,
expected_unit='process')

View File

@ -1,32 +0,0 @@
#
# Copyright 2013 Intel Corp
#
# Authors: Lianhao Lu <lianhao.lu@intel.com>
#
# 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 ceilometer.hardware.pollsters import disk
from ceilometer import sample
from ceilometer.tests.unit.hardware.pollsters import base
class TestDiskPollsters(base.TestPollsterBase):
def test_disk_size_total(self):
self._check_get_samples(disk.DiskTotalPollster,
'hardware.disk.size.total',
1000, sample.TYPE_GAUGE)
def test_disk_size_used(self):
self._check_get_samples(disk.DiskUsedPollster,
'hardware.disk.size.used',
90, sample.TYPE_GAUGE)

View File

@ -72,13 +72,13 @@ class FakeInspector(inspector_base.Inspector):
ip='10.0.0.2',
speed=1000)
DATA = {
'hardware.test1': (0.99, {}, {}),
'hardware.test2.abc': (90, net_metadata, {}),
'test': (0.99, {}, {}),
'test2': (90, net_metadata, {}),
}
def inspect_generic(self, host, identifier, cache,
def inspect_generic(self, host, cache,
extra_metadata=None, param=None):
yield self.DATA[identifier]
yield self.DATA[host.hostname]
class TestGenericPollsters(test_base.BaseTestCase):

View File

@ -1,42 +0,0 @@
#
# Copyright 2013 Intel Corp
#
# Authors: Lianhao Lu <lianhao.lu@intel.com>
#
# 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 ceilometer.hardware.pollsters import memory
from ceilometer import sample
from ceilometer.tests.unit.hardware.pollsters import base
class TestMemoryPollsters(base.TestPollsterBase):
def test_memory_size_total(self):
self._check_get_samples(memory.MemoryTotalPollster,
'hardware.memory.total',
1000, sample.TYPE_GAUGE)
def test_memory_size_used(self):
self._check_get_samples(memory.MemoryUsedPollster,
'hardware.memory.used',
90, sample.TYPE_GAUGE)
def test_memory_size_buffer(self):
self._check_get_samples(memory.MemoryBufferPollster,
'hardware.memory.buffer',
500, sample.TYPE_GAUGE)
def test_memory_size_cached(self):
self._check_get_samples(memory.MemoryCachedPollster,
'hardware.memory.cached',
200, sample.TYPE_GAUGE)

View File

@ -1,40 +0,0 @@
#
# Copyright 2013 Intel Corp
#
# Authors: Lianhao Lu <lianhao.lu@intel.com>
#
# 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 ceilometer.hardware.pollsters import net
from ceilometer import sample
from ceilometer.tests.unit.hardware.pollsters import base
class TestNetPollsters(base.TestPollsterBase):
def test_incoming(self):
self._check_get_samples(net.IncomingBytesPollster,
'hardware.network.incoming.bytes',
90, sample.TYPE_CUMULATIVE,
expected_unit='B')
def test_outgoing(self):
self._check_get_samples(net.OutgoingBytesPollster,
'hardware.network.outgoing.bytes',
80, sample.TYPE_CUMULATIVE,
expected_unit='B')
def test_error(self):
self._check_get_samples(net.OutgoingErrorsPollster,
'hardware.network.outgoing.errors',
1, sample.TYPE_CUMULATIVE,
expected_unit='packet')

View File

@ -1,31 +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.
from ceilometer.hardware.pollsters import network_aggregated
from ceilometer import sample
from ceilometer.tests.unit.hardware.pollsters import base
class TestNetworkAggregatedPollsters(base.TestPollsterBase):
def test_incoming(self):
self._check_get_samples(network_aggregated.
NetworkAggregatedIPOutRequests,
'hardware.network.ip.outgoing.datagrams',
200, sample.TYPE_CUMULATIVE,
expected_unit='datagrams')
def test_outgoing(self):
self._check_get_samples(network_aggregated.
NetworkAggregatedIPInReceives,
'hardware.network.ip.incoming.datagrams',
300, sample.TYPE_CUMULATIVE,
expected_unit='datagrams')

View File

@ -1,35 +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.
from ceilometer.hardware.pollsters import system
from ceilometer import sample
from ceilometer.tests.unit.hardware.pollsters import base
class TestSystemPollsters(base.TestPollsterBase):
def test_cpu_idle(self):
self._check_get_samples(system.SystemCpuIdlePollster,
'hardware.system_stats.cpu.idle',
62, sample.TYPE_GAUGE,
expected_unit='%')
def test_io_outgoing(self):
self._check_get_samples(system.SystemIORawSentPollster,
'hardware.system_stats.io.outgoing.blocks',
100, sample.TYPE_CUMULATIVE,
expected_unit='blocks')
def test_io_incoming(self):
self._check_get_samples(system.SystemIORawReceivedPollster,
'hardware.system_stats.io.incoming.blocks',
120, sample.TYPE_CUMULATIVE,
expected_unit='blocks')

View File

@ -166,25 +166,6 @@ ceilometer.poll.central =
switch.flow.duration.nanoseconds = ceilometer.network.statistics.flow:FlowPollsterDurationNanoseconds
switch.flow.duration.seconds = ceilometer.network.statistics.flow:FlowPollsterDurationSeconds
switch.flow.packets = ceilometer.network.statistics.flow:FlowPollsterPackets
hardware.cpu.load.1min = ceilometer.hardware.pollsters.cpu:CPULoad1MinPollster
hardware.cpu.load.5min = ceilometer.hardware.pollsters.cpu:CPULoad5MinPollster
hardware.cpu.load.15min = ceilometer.hardware.pollsters.cpu:CPULoad15MinPollster
hardware.disk.size.total = ceilometer.hardware.pollsters.disk:DiskTotalPollster
hardware.disk.size.used = ceilometer.hardware.pollsters.disk:DiskUsedPollster
hardware.network.incoming.bytes = ceilometer.hardware.pollsters.net:IncomingBytesPollster
hardware.network.outgoing.bytes = ceilometer.hardware.pollsters.net:OutgoingBytesPollster
hardware.network.outgoing.errors = ceilometer.hardware.pollsters.net:OutgoingErrorsPollster
hardware.memory.total = ceilometer.hardware.pollsters.memory:MemoryTotalPollster
hardware.memory.used = ceilometer.hardware.pollsters.memory:MemoryUsedPollster
hardware.memory.buffer = ceilometer.hardware.pollsters.memory:MemoryBufferPollster
hardware.memory.cached = ceilometer.hardware.pollsters.memory:MemoryCachedPollster
hardware.memory.swap.total = ceilometer.hardware.pollsters.memory:MemorySwapTotalPollster
hardware.memory.swap.avail = ceilometer.hardware.pollsters.memory:MemorySwapAvailPollster
hardware.system_stats.cpu.idle = ceilometer.hardware.pollsters.system:SystemCpuIdlePollster
hardware.system_stats.io.outgoing.blocks = ceilometer.hardware.pollsters.system:SystemIORawSentPollster
hardware.system_stats.io.incoming.blocks = ceilometer.hardware.pollsters.system:SystemIORawReceivedPollster
hardware.network.ip.outgoing.datagrams = ceilometer.hardware.pollsters.network_aggregated:NetworkAggregatedIPOutRequests
hardware.network.ip.incoming.datagrams = ceilometer.hardware.pollsters.network_aggregated:NetworkAggregatedIPInReceives
network.services.lb.pool = ceilometer.network.services.lbaas:LBPoolPollster
network.services.lb.vip = ceilometer.network.services.lbaas:LBVipPollster
network.services.lb.member = ceilometer.network.services.lbaas:LBMemberPollster
@ -198,6 +179,9 @@ ceilometer.poll.central =
network.services.firewall = ceilometer.network.services.fwaas:FirewallPollster
network.services.firewall.policy = ceilometer.network.services.fwaas:FirewallPolicyPollster
ceilometer.builder.poll.central =
hardware.snmp = ceilometer.hardware.pollsters.generic:GenericHardwareDeclarativePollster
ceilometer.alarm.storage =
log = ceilometer.alarm.storage.impl_log:Connection
mongodb = ceilometer.alarm.storage.impl_mongodb:Connection