Merge "Allow to pass dict from resource discovery"

This commit is contained in:
Jenkins 2014-09-12 12:51:56 +00:00 committed by Gerrit Code Review
commit f47161a2bb
9 changed files with 74 additions and 22 deletions

View File

@ -41,22 +41,36 @@ class NodesDiscoveryTripleO(plugin.DiscoveryBase):
super(NodesDiscoveryTripleO, self).__init__()
self.nova_cli = nova_client.Client()
@staticmethod
def _address(instance, field):
return instance.addresses['ctlplane'][0].get(field)
def discover(self, param=None):
"""Discover resources to monitor."""
instances = self.nova_cli.instance_get_all()
ip_addresses = []
resources = []
for instance in instances:
try:
ip_address = instance.addresses['ctlplane'][0]['addr']
ip_address = self._address(instance, 'addr')
final_address = (
cfg.CONF.hardware.url_scheme +
cfg.CONF.hardware.readonly_user_name + ':' +
cfg.CONF.hardware.readonly_user_password + '@' +
ip_address)
ip_addresses.append(final_address)
resource = {
'resource_id': instance.id,
'resource_url': final_address,
'mac_addr': self._address(instance,
'OS-EXT-IPS-MAC:mac_addr'),
'image_id': instance.image['id'],
'flavor_id': instance.flavor['id']
}
resources.append(resource)
except KeyError:
LOG.error(_("Couldn't obtain IP address of"
"instance %s") % instance.id)
return ip_addresses
return resources

View File

@ -25,14 +25,15 @@ import six
@six.add_metaclass(abc.ABCMeta)
class Inspector(object):
@abc.abstractmethod
def inspect_generic(self, host, identifier, cache):
def inspect_generic(self, host, identifier, cache, extra_metadata=None):
"""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
:return: an iterator of (value, metadata, extra)
:return value: the sample value
:return metadata: dict to construct sample's metadata
:return extra: dict of extra info to help constructing sample
"""
:return extra: dict of extra metadata to help constructing sample
"""

View File

@ -354,7 +354,7 @@ class SNMPInspector(base.Inspector):
new_oids.append(metadata[0])
return new_oids
def inspect_generic(self, host, identifier, cache):
def inspect_generic(self, host, identifier, cache, extra_metadata=None):
# the snmp definition for the corresponding meter
meter_def = self.MAPPING[identifier]
# collect oids that needs to be queried
@ -373,6 +373,7 @@ class SNMPInspector(base.Inspector):
meter_def['metric_oid'][0],
meter_def['matching_type'],
False)
extra_metadata = extra_metadata or {}
for oid in oids_for_sample_values:
suffix = oid[len(meter_def['metric_oid'][0]):]
value = self.get_oid_value(oid_cache,
@ -382,15 +383,14 @@ class SNMPInspector(base.Inspector):
metadata = self.construct_metadata(oid_cache,
meter_def['metadata'],
suffix)
extra = {}
# call post_op for special cases
if meter_def['post_op']:
func = getattr(self, meter_def['post_op'], None)
if func:
value = func(host, cache, meter_def,
value, metadata, extra,
value, metadata, extra_metadata,
suffix)
yield (value, metadata, extra)
yield (value, metadata, extra_metadata)
def _post_op_net(self, host, cache, meter_def,
value, metadata, extra, suffix):

View File

@ -47,7 +47,36 @@ class HardwarePollster(plugin.CentralPollster):
def default_discovery(self):
return 'tripleo_overcloud_nodes'
def get_samples(self, manager, cache, resources):
@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
@ -57,17 +86,19 @@ class HardwarePollster(plugin.CentralPollster):
resources = resources or []
h_cache = cache.setdefault(self.CACHE_KEY, {})
sample_iters = []
for res in resources:
parsed_url = netutils.urlsplit(res)
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))
i_cache,
extra_metadata))
# Generate samples
if i_cache[self.IDENTIFIER]:
sample_iters.append(self.generate_samples(

View File

@ -29,7 +29,7 @@ class _Base(plugin.HardwarePollster):
def generate_one_sample(self, host, c_data):
value, metadata, extra = c_data
res_id = host.hostname
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,

View File

@ -29,7 +29,7 @@ class _Base(plugin.HardwarePollster):
def generate_one_sample(self, host, c_data):
value, metadata, extra = c_data
res_id = host.hostname
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,

View File

@ -44,15 +44,16 @@ def make_sample_from_host(host_url, name, sample_type, unit, volume,
res_metadata=None, extra={}):
resource_metadata = make_resource_metadata(res_metadata, host_url)
resource_metadata.update(extra)
res_id = extra.get('resource_id') or resource_id or host_url.hostname
res_id = resource_id or extra.get('resource_id') or host_url.hostname
return sample.Sample(
name='hardware.' + name,
type=sample_type,
unit=unit,
volume=volume,
user_id=extra.get('user_id') or user_id,
project_id=extra.get('project_id') or project_id,
user_id=user_id or extra.get('user_id'),
project_id=project_id or extra.get('project_id'),
resource_id=res_id,
timestamp=timeutils.isotime(),
resource_metadata=resource_metadata,

View File

@ -42,7 +42,7 @@ class FakeInspector(inspector_base.Inspector):
'disk.size.used': (90, disk_metadata, {}),
}
def inspect_generic(self, host, identifier, cache):
def inspect_generic(self, host, identifier, cache, extra_metadata=None):
yield self.DATA[identifier]

View File

@ -53,4 +53,9 @@ class TestPollsterUtils(test_base.BaseTestCase):
extra=extra)
self.assertEqual(None, s.user_id)
self.assertEqual('project', s.project_id)
self.assertEqual('resource', s.resource_id)
self.assertEqual('resource', s.resource_id)
self.assertEqual({'resource_url': 'snmp://127.0.0.1:161',
'project_id': 'project',
'resource_id':
'resource'},
s.resource_metadata)