From 2363058cd397bddeeef940bb4cadde5b580c0456 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Mon, 26 Aug 2013 07:31:27 +0800 Subject: [PATCH] Support for wildcard in pipeline This patch will support for wildcard in pipeline.yaml so we can exclude things like !storage.objects.* This patch is dedicated to Fei Long Wang who triggered my thought on the subject and proposed a first implementation. docImpact Fixes bug 1209128 Change-Id: I09a805ea7c9313b45152672a63981d5d4c263601 --- ceilometer/pipeline.py | 28 +++++++++++++++++++++------- tests/test_pipeline.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/ceilometer/pipeline.py b/ceilometer/pipeline.py index 69679b9d3..379d73886 100644 --- a/ceilometer/pipeline.py +++ b/ceilometer/pipeline.py @@ -16,6 +16,7 @@ # License for the specific language governing permissions and limitations # under the License. +import fnmatch import itertools import os import operator @@ -241,14 +242,27 @@ class Pipeline(object): def support_meter(self, meter_name): meter_name = self._variable_meter_name(meter_name) - if ('!' + meter_name) in self.meters: - return False - if '*' in self.meters: - return True - elif self.meters[0][0] == '!': - return not ('!' + meter_name) in self.meters + + # Special case: if we only have negation, we suppose the default it + # allow + if all(meter.startswith('!') for meter in self.meters): + default = True else: - return meter_name in self.meters + default = False + + # Support wildcard like storage.* and !disk.* + # Start with negation, we consider that the order is deny, allow + if any(fnmatch.fnmatch(meter_name, meter[1:]) + for meter in self.meters + if meter[0] == '!'): + return False + + if any(fnmatch.fnmatch(meter_name, meter) + for meter in self.meters + if meter[0] != '!'): + return True + + return default def flush(self, ctxt): """Flush data after all samples have been injected to pipeline.""" diff --git a/tests/test_pipeline.py b/tests/test_pipeline.py index ceee6b6fb..7afdc58fa 100644 --- a/tests/test_pipeline.py +++ b/tests/test_pipeline.py @@ -325,6 +325,37 @@ class TestPipeline(base.TestCase): self.assertTrue(pipeline_manager.pipelines[0].support_meter('b')) self.assertFalse(pipeline_manager.pipelines[0].support_meter('c')) + def test_wildcard_and_excluded_wildcard_counters(self): + counter_cfg = ['*', '!disk.*'] + self.pipeline_cfg[0]['counters'] = counter_cfg + pipeline_manager = pipeline.PipelineManager(self.pipeline_cfg, + self.transformer_manager) + self.assertFalse(pipeline_manager.pipelines[0]. + support_meter('disk.read.bytes')) + self.assertTrue(pipeline_manager.pipelines[0].support_meter('cpu')) + + def test_included_counter_and_wildcard_counters(self): + counter_cfg = ['cpu', 'disk.*'] + self.pipeline_cfg[0]['counters'] = counter_cfg + pipeline_manager = pipeline.PipelineManager(self.pipeline_cfg, + self.transformer_manager) + self.assertTrue(pipeline_manager.pipelines[0]. + support_meter('disk.read.bytes')) + self.assertTrue(pipeline_manager.pipelines[0].support_meter('cpu')) + self.assertFalse(pipeline_manager.pipelines[0]. + support_meter('instance')) + + def test_excluded_counter_and_excluded_wildcard_counters(self): + counter_cfg = ['!cpu', '!disk.*'] + self.pipeline_cfg[0]['counters'] = counter_cfg + pipeline_manager = pipeline.PipelineManager(self.pipeline_cfg, + self.transformer_manager) + self.assertFalse(pipeline_manager.pipelines[0]. + support_meter('disk.read.bytes')) + self.assertFalse(pipeline_manager.pipelines[0].support_meter('cpu')) + self.assertTrue(pipeline_manager.pipelines[0]. + support_meter('instance')) + def test_multiple_pipeline(self): self.pipeline_cfg.append({ 'name': 'second_pipeline',