summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ceilometer/polling/manager.py23
-rw-r--r--ceilometer/tests/unit/polling/test_manager.py70
-rw-r--r--doc/source/admin/telemetry-dynamic-pollster.rst5
3 files changed, 96 insertions, 2 deletions
diff --git a/ceilometer/polling/manager.py b/ceilometer/polling/manager.py
index 6b9289d1..717d1426 100644
--- a/ceilometer/polling/manager.py
+++ b/ceilometer/polling/manager.py
@@ -253,7 +253,8 @@ class AgentManager(cotyledon.Service):
for namespace in namespaces)
# Create dynamic pollsters
- extensions_dynamic_pollsters = self.create_dynamic_pollsters()
+ extensions_dynamic_pollsters = self.create_dynamic_pollsters(
+ namespaces)
self.extensions = list(itertools.chain(*list(extensions))) + list(
itertools.chain(*list(extensions_fb))) + list(
@@ -291,15 +292,18 @@ class AgentManager(cotyledon.Service):
self._keystone = None
self._keystone_last_exception = None
- def create_dynamic_pollsters(self):
+ def create_dynamic_pollsters(self, namespaces):
"""Creates dynamic pollsters
This method Creates dynamic pollsters based on configurations placed on
'pollsters_definitions_dirs'
+ :param namespaces: The namespaces we are running on to validate if
+ the pollster should be instantiated or not.
:return: a list with the dynamic pollsters defined by the operator.
"""
+ namespaces_set = set(namespaces)
pollsters_definitions_dirs = self.conf.pollsters_definitions_dirs
if not pollsters_definitions_dirs:
LOG.info("Variable 'pollsters_definitions_dirs' not defined.")
@@ -333,6 +337,21 @@ class AgentManager(cotyledon.Service):
for pollster_cfg in pollsters_cfg:
pollster_name = pollster_cfg['name']
+ pollster_namespaces = pollster_cfg.get(
+ 'namespaces', ['central'])
+ if isinstance(pollster_namespaces, list):
+ pollster_namespaces = set(pollster_namespaces)
+ else:
+ pollster_namespaces = {pollster_namespaces}
+
+ if not bool(namespaces_set & pollster_namespaces):
+ LOG.info("The pollster [%s] is not configured to run in "
+ "these namespaces %s, the configured namespaces "
+ "for this pollster are %s. Therefore, we are "
+ "skipping it.", pollster_name, namespaces_set,
+ pollster_namespaces)
+ continue
+
if pollster_name not in pollsters_definitions:
LOG.info("Loading dynamic pollster [%s] from file [%s].",
pollster_name, pollsters_definitions_file)
diff --git a/ceilometer/tests/unit/polling/test_manager.py b/ceilometer/tests/unit/polling/test_manager.py
index e805b9be..c9a1e1e1 100644
--- a/ceilometer/tests/unit/polling/test_manager.py
+++ b/ceilometer/tests/unit/polling/test_manager.py
@@ -422,6 +422,76 @@ class TestPollingAgent(BaseAgent):
self.assertIn(60, polling_tasks.keys())
self.assertNotIn(10, polling_tasks.keys())
+ @mock.patch('glob.glob')
+ @mock.patch('ceilometer.declarative.load_definitions')
+ def test_setup_polling_dynamic_pollster_namespace(self, load_mock,
+ glob_mock):
+ glob_mock.return_value = ['test.yml']
+ load_mock.return_value = [{
+ 'name': "test.dynamic.pollster",
+ 'namespaces': "dynamic",
+ 'sample_type': 'gauge',
+ 'unit': 'test',
+ 'endpoint_type': 'test',
+ 'url_path': 'test',
+ 'value_attribute': 'test'
+ }, {
+ 'name': "test.compute.central.pollster",
+ 'sample_type': 'gauge',
+ 'namespaces': ["compute", "central"],
+ 'unit': 'test',
+ 'endpoint_type': 'test',
+ 'url_path': 'test',
+ 'value_attribute': 'test'
+ }, {
+ 'name': "test.compute.pollster",
+ 'namespaces': ["compute"],
+ 'sample_type': 'gauge',
+ 'unit': 'test',
+ 'endpoint_type': 'test',
+ 'url_path': 'test',
+ 'value_attribute': 'test'
+ }, {
+ 'name': "test.central.pollster",
+ 'sample_type': 'gauge',
+ 'unit': 'test',
+ 'endpoint_type': 'test',
+ 'url_path': 'test',
+ 'value_attribute': 'test'
+ }]
+ mgr = manager.AgentManager(0, self.CONF, namespaces=['dynamic'])
+ self.assertEqual(len(mgr.extensions), 1)
+ self.assertEqual(
+ mgr.extensions[0].definitions.configurations['name'],
+ 'test.dynamic.pollster')
+
+ mgr = manager.AgentManager(0, self.CONF)
+ self.assertEqual(
+ mgr.extensions[-3].definitions.configurations['name'],
+ 'test.compute.central.pollster')
+ self.assertEqual(
+ mgr.extensions[-2].definitions.configurations['name'],
+ 'test.compute.pollster')
+ self.assertEqual(
+ mgr.extensions[-1].definitions.configurations['name'],
+ 'test.central.pollster')
+
+ mgr = manager.AgentManager(0, self.CONF, namespaces=['compute'])
+ self.assertEqual(
+ mgr.extensions[-2].definitions.configurations['name'],
+ 'test.compute.central.pollster')
+ self.assertEqual(
+ mgr.extensions[-1].definitions.configurations['name'],
+ 'test.compute.pollster')
+
+ mgr = manager.AgentManager(0, self.CONF, ['central'])
+ self.assertEqual(
+ mgr.extensions[-2].definitions.configurations['name'],
+ 'test.compute.central.pollster')
+ self.assertEqual(
+ mgr.extensions[-1].definitions.configurations['name'],
+ 'test.central.pollster')
+
def test_setup_polling_task_same_interval(self):
self.polling_cfg['sources'].append({
'name': 'test_polling_1',
diff --git a/doc/source/admin/telemetry-dynamic-pollster.rst b/doc/source/admin/telemetry-dynamic-pollster.rst
index d861c07f..e60c04e8 100644
--- a/doc/source/admin/telemetry-dynamic-pollster.rst
+++ b/doc/source/admin/telemetry-dynamic-pollster.rst
@@ -198,6 +198,11 @@ attributes to define a dynamic pollster:
executed serially, one after the other. Therefore, if the request hangs,
all pollsters (including the non-dynamic ones) will stop executing.
+* ``namespaces``: optional parameter. Defines the namespaces (running
+ ceilometer instances) where the pollster will be instantiated. This
+ parameter accepts a single string value or a list of strings. The
+ default value is `central`.
+
The complete YAML configuration to gather data from Magnum (that has been used
as an example) is the following: