... according to the versions currently supported. Change-Id: I8513dd1116f4f8afe2287908444c947728188d35 Signed-off-by: Takashi Kajinami <kajinamit@oss.nttdata.com>
		
			
				
	
	
		
			117 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#
 | 
						|
# Copyright 2013 Intel Corp.
 | 
						|
# Copyright 2014 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.
 | 
						|
import fnmatch
 | 
						|
import os
 | 
						|
 | 
						|
from oslo_log import log
 | 
						|
import yaml
 | 
						|
 | 
						|
LOG = log.getLogger(__name__)
 | 
						|
 | 
						|
 | 
						|
class ConfigException(Exception):
 | 
						|
    def __init__(self, cfg_type, message, cfg):
 | 
						|
        self.cfg_type = cfg_type
 | 
						|
        self.msg = message
 | 
						|
        self.cfg = cfg
 | 
						|
 | 
						|
    def __str__(self):
 | 
						|
        return f'{self.cfg_type} {self.cfg}: {self.msg}'
 | 
						|
 | 
						|
 | 
						|
class SourceException(Exception):
 | 
						|
    def __init__(self, message, cfg):
 | 
						|
        self.msg = message
 | 
						|
        self.cfg = cfg
 | 
						|
 | 
						|
    def __str__(self):
 | 
						|
        return f'Source definition invalid: {self.msg} ({self.cfg})'
 | 
						|
 | 
						|
 | 
						|
class ConfigManagerBase:
 | 
						|
    """Base class for managing configuration file refresh"""
 | 
						|
 | 
						|
    def __init__(self, conf):
 | 
						|
        self.conf = conf
 | 
						|
 | 
						|
    def load_config(self, cfg_file):
 | 
						|
        """Load a configuration file and set its refresh values."""
 | 
						|
        if os.path.exists(cfg_file):
 | 
						|
            cfg_loc = cfg_file
 | 
						|
        else:
 | 
						|
            cfg_loc = self.conf.find_file(cfg_file)
 | 
						|
            if not cfg_loc:
 | 
						|
                LOG.debug("No pipeline definitions configuration file found! "
 | 
						|
                          "Using default config.")
 | 
						|
                cfg_loc = os.path.join(
 | 
						|
                    os.path.dirname(os.path.abspath(__file__)),
 | 
						|
                    'pipeline', 'data', cfg_file)
 | 
						|
        with open(cfg_loc) as fap:
 | 
						|
            conf = yaml.safe_load(fap)
 | 
						|
        LOG.debug("Config file: %s", conf)
 | 
						|
        return conf
 | 
						|
 | 
						|
 | 
						|
class Source:
 | 
						|
    """Represents a generic source"""
 | 
						|
 | 
						|
    def __init__(self, cfg):
 | 
						|
        self.cfg = cfg
 | 
						|
        try:
 | 
						|
            self.name = cfg['name']
 | 
						|
        except KeyError as err:
 | 
						|
            raise SourceException(
 | 
						|
                "Required field %s not specified" % err.args[0], cfg)
 | 
						|
 | 
						|
    def __str__(self):
 | 
						|
        return self.name
 | 
						|
 | 
						|
    def check_source_filtering(self, data, d_type):
 | 
						|
        """Source data rules checking
 | 
						|
 | 
						|
        - At least one meaningful datapoint exist
 | 
						|
        - Included type and excluded type can't co-exist on the same pipeline
 | 
						|
        - Included type meter and wildcard can't co-exist at same pipeline
 | 
						|
        """
 | 
						|
        if not data:
 | 
						|
            raise SourceException('No %s specified' % d_type, self.cfg)
 | 
						|
 | 
						|
        if (any(x for x in data if x[0] not in '!*') and
 | 
						|
           any(x for x in data if x[0] == '!')):
 | 
						|
            raise SourceException(
 | 
						|
                'Both included and excluded %s specified' % d_type,
 | 
						|
                self.cfg)
 | 
						|
 | 
						|
        if '*' in data and any(x for x in data if x[0] not in '!*'):
 | 
						|
            raise SourceException(
 | 
						|
                'Included %s specified with wildcard' % d_type,
 | 
						|
                self.cfg)
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def is_supported(dataset, data_name):
 | 
						|
        # Support wildcard like storage.* and !disk.*
 | 
						|
        # Start with negation, we consider that the order is deny, allow
 | 
						|
        if any(fnmatch.fnmatch(data_name, datapoint[1:])
 | 
						|
               for datapoint in dataset if datapoint[0] == '!'):
 | 
						|
            return False
 | 
						|
 | 
						|
        if any(fnmatch.fnmatch(data_name, datapoint)
 | 
						|
               for datapoint in dataset if datapoint[0] != '!'):
 | 
						|
            return True
 | 
						|
 | 
						|
        # if we only have negation, we suppose the default is allow
 | 
						|
        return all(datapoint.startswith('!') for datapoint in dataset)
 |