diff options
Diffstat (limited to 'ceilometer')
-rw-r--r-- | ceilometer/cache_utils.py | 55 | ||||
-rw-r--r-- | ceilometer/polling/discovery/non_openstack_credentials_discovery.py | 2 | ||||
-rw-r--r-- | ceilometer/polling/manager.py | 15 | ||||
-rw-r--r-- | ceilometer/publisher/gnocchi.py | 31 | ||||
-rw-r--r-- | ceilometer/tests/unit/polling/test_non_openstack_credentials_discovery.py | 10 | ||||
-rw-r--r-- | ceilometer/tests/unit/test_cache_utils.py | 65 |
6 files changed, 124 insertions, 54 deletions
diff --git a/ceilometer/cache_utils.py b/ceilometer/cache_utils.py index 55a9e263..31c1c0e9 100644 --- a/ceilometer/cache_utils.py +++ b/ceilometer/cache_utils.py @@ -14,9 +14,22 @@ # under the License. """Simple wrapper for oslo_cache.""" - +import uuid from oslo_cache import core as cache +from oslo_cache import exception +from oslo_log import log +from oslo_utils.secretutils import md5 + +# Default cache expiration period +CACHE_DURATION = 86400 + +NAME_ENCODED = __name__.encode('utf-8') +CACHE_NAMESPACE = uuid.UUID( + bytes=md5(NAME_ENCODED, usedforsecurity=False).digest() +) + +LOG = log.getLogger(__name__) class CacheClient(object): @@ -36,18 +49,30 @@ class CacheClient(object): return self.region.delete(key) -def get_client(conf, expiration_time=0): +def get_client(conf): cache.configure(conf) - if conf.cache.enabled: - return CacheClient(_get_default_cache_region( - conf, - expiration_time=expiration_time - )) - - -def _get_default_cache_region(conf, expiration_time): - region = cache.create_region() - if expiration_time != 0: - conf.cache.expiration_time = expiration_time - cache.configure_cache_region(conf, region) - return region + if 'cache' in conf.keys() and conf.cache.enabled: + region = get_cache_region(conf) + if region: + return CacheClient(region) + + +def get_cache_region(conf): + # Set expiration time to default CACHE_DURATION if missing in conf + if not conf.cache.expiration_time: + conf.cache.expiration_time = CACHE_DURATION + + try: + region = cache.create_region() + cache.configure_cache_region(conf, region) + cache.key_mangler = cache_key_mangler + return region + except exception.ConfigurationError as e: + LOG.error("failed to configure oslo_cache. %s", str(e)) + LOG.warning("using keystone to identify names from polled samples") + + +def cache_key_mangler(key): + """Construct an opaque cache key.""" + + return uuid.uuid5(CACHE_NAMESPACE, key).hex diff --git a/ceilometer/polling/discovery/non_openstack_credentials_discovery.py b/ceilometer/polling/discovery/non_openstack_credentials_discovery.py index 61459452..0b3ccec8 100644 --- a/ceilometer/polling/discovery/non_openstack_credentials_discovery.py +++ b/ceilometer/polling/discovery/non_openstack_credentials_discovery.py @@ -38,7 +38,7 @@ class NonOpenStackCredentialsDiscovery(EndpointDiscovery): if not param: return [barbican_secret] barbican_endpoints = super(NonOpenStackCredentialsDiscovery, - self).discover("key-manager") + self).discover(manager, "key-manager") if not barbican_endpoints: LOG.warning("No Barbican endpoints found to execute the" " credentials discovery process to [%s].", diff --git a/ceilometer/polling/manager.py b/ceilometer/polling/manager.py index 3545801f..5835fe25 100644 --- a/ceilometer/polling/manager.py +++ b/ceilometer/polling/manager.py @@ -46,8 +46,6 @@ from ceilometer import utils LOG = log.getLogger(__name__) -CACHE_DURATION = 3600 - POLLING_OPTS = [ cfg.StrOpt('cfg_file', default="polling.yaml", @@ -154,10 +152,7 @@ class PollingTask(object): self.ks_client = self.manager.keystone - self.cache_client = cache_utils.get_client( - self.manager.conf, - expiration_time=CACHE_DURATION - ) + self.cache_client = cache_utils.get_client(self.manager.conf) def add(self, pollster, source): self.pollster_matches[source.name].add(pollster) @@ -169,9 +164,11 @@ class PollingTask(object): name = self.cache_client.get(uuid) if name: return name - name = self.resolve_uuid_from_keystone(attr, uuid) - self.cache_client.set(uuid, name) - return name + # empty cache_client means either caching is not enabled or + # there was an error configuring cache + name = self.resolve_uuid_from_keystone(attr, uuid) + self.cache_client.set(uuid, name) + return name # Retrieve project and user names from Keystone only # if ceilometer doesn't have a caching backend diff --git a/ceilometer/publisher/gnocchi.py b/ceilometer/publisher/gnocchi.py index 79a659e1..45f32766 100644 --- a/ceilometer/publisher/gnocchi.py +++ b/ceilometer/publisher/gnocchi.py @@ -14,39 +14,29 @@ # under the License. from collections import defaultdict import fnmatch -import hashlib import itertools import json import operator import pkg_resources import threading -import uuid from gnocchiclient import exceptions as gnocchi_exc from keystoneauth1 import exceptions as ka_exceptions -import oslo_cache from oslo_log import log from oslo_utils import timeutils from stevedore import extension from urllib import parse as urlparse +from ceilometer import cache_utils from ceilometer import declarative from ceilometer import gnocchi_client from ceilometer.i18n import _ from ceilometer import keystone_client from ceilometer import publisher -NAME_ENCODED = __name__.encode('utf-8') -CACHE_NAMESPACE = uuid.UUID(bytes=hashlib.md5(NAME_ENCODED).digest()) LOG = log.getLogger(__name__) -def cache_key_mangler(key): - """Construct an opaque cache key.""" - - return uuid.uuid5(CACHE_NAMESPACE, key).hex - - EVENT_CREATE, EVENT_UPDATE, EVENT_DELETE = ("create", "update", "delete") @@ -213,20 +203,11 @@ class GnocchiPublisher(publisher.ConfigPublisherBase): timeout = options.get('timeout', [6.05])[-1] self._ks_client = keystone_client.get_client(conf) - self.cache = None - try: - oslo_cache.configure(conf) - # NOTE(cdent): The default cache backend is a real but - # noop backend. We don't want to use that here because - # we want to avoid the cache pathways entirely if the - # cache has not been configured explicitly. - if conf.cache.enabled: - cache_region = oslo_cache.create_region() - self.cache = oslo_cache.configure_cache_region( - conf, cache_region) - self.cache.key_mangler = cache_key_mangler - except oslo_cache.exception.ConfigurationError as exc: - LOG.warning('unable to configure oslo_cache: %s', exc) + # NOTE(cdent): The default cache backend is a real but + # noop backend. We don't want to use that here because + # we want to avoid the cache pathways entirely if the + # cache has not been configured explicitly. + self.cache = cache_utils.get_client(conf) self._gnocchi_project_id = None self._gnocchi_project_id_lock = threading.Lock() diff --git a/ceilometer/tests/unit/polling/test_non_openstack_credentials_discovery.py b/ceilometer/tests/unit/polling/test_non_openstack_credentials_discovery.py index c1fffd87..4e257415 100644 --- a/ceilometer/tests/unit/polling/test_non_openstack_credentials_discovery.py +++ b/ceilometer/tests/unit/polling/test_non_openstack_credentials_discovery.py @@ -95,8 +95,8 @@ class TestNonOpenStackCredentialsDiscovery(base.BaseTestCase): @mock.patch('keystoneclient.v2_0.client.Client') def test_discover_response_ok(self, client_mock): - def discover_mock(self, manager, param=None): - return ["barbican_url"] + discover_mock = mock.MagicMock() + discover_mock.return_value = ["barbican_url"] original_discover_method = EndpointDiscovery.discover EndpointDiscovery.discover = discover_mock @@ -108,9 +108,11 @@ class TestNonOpenStackCredentialsDiscovery(base.BaseTestCase): client_mock.session.get.return_value = return_value - response = self.discovery.discover( - manager=self.FakeManager(client_mock), param="param") + fake_manager = self.FakeManager(client_mock) + response = self.discovery.discover(manager=fake_manager, param="param") self.assertEqual(["content"], response) + discover_mock.assert_has_calls([ + mock.call(fake_manager, "key-manager")]) EndpointDiscovery.discover = original_discover_method diff --git a/ceilometer/tests/unit/test_cache_utils.py b/ceilometer/tests/unit/test_cache_utils.py new file mode 100644 index 00000000..245eaa34 --- /dev/null +++ b/ceilometer/tests/unit/test_cache_utils.py @@ -0,0 +1,65 @@ +# +# Copyright 2022 Red Hat, Inc +# +# 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 import cache_utils +from ceilometer import service as ceilometer_service +from oslo_cache import core as cache +from oslo_config import fixture as config_fixture +from oslotest import base + + +class CacheConfFixture(config_fixture.Config): + def setUp(self): + super(CacheConfFixture, self).setUp() + self.conf = ceilometer_service.\ + prepare_service(argv=[], config_files=[]) + cache.configure(self.conf) + self.config(enabled=True, group='cache') + + +class TestOsloCache(base.BaseTestCase): + def setUp(self): + super(TestOsloCache, self).setUp() + + conf = ceilometer_service.prepare_service(argv=[], config_files=[]) + + dict_conf_fixture = CacheConfFixture(conf) + self.useFixture(dict_conf_fixture) + dict_conf_fixture.config(expiration_time=600, + backend='oslo_cache.dict', + group='cache') + self.dict_conf = dict_conf_fixture.conf + + # enable_retry_client is only supported by + # 'dogpile.cache.pymemcache' backend which makes this + # incorrect config + faulty_conf_fixture = CacheConfFixture(conf) + self.useFixture(faulty_conf_fixture) + faulty_conf_fixture.config(expiration_time=600, + backend='dogpile.cache.memcached', + group='cache', + enable_retry_client='true') + self.faulty_cache_conf = faulty_conf_fixture.conf + + self.no_cache_conf = ceilometer_service.\ + prepare_service(argv=[], config_files=[]) + + def test_get_cache_region(self): + self.assertIsNotNone(cache_utils.get_cache_region(self.dict_conf)) + + def test_get_client(self): + self.assertIsNotNone(cache_utils.get_client(self.dict_conf)) + self.assertIsNone(cache_utils.get_client(self.no_cache_conf)) + self.assertIsNone(cache_utils.get_client(self.faulty_cache_conf)) |