diff options
-rw-r--r-- | ceilometer/polling/manager.py | 23 | ||||
-rw-r--r-- | ceilometer/tests/unit/polling/test_manager.py | 70 | ||||
-rw-r--r-- | doc/source/admin/telemetry-dynamic-pollster.rst | 5 |
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: |