diff --git a/vitrage/notifier/__init__.py b/vitrage/notifier/__init__.py index a464c2ff1..660c18a17 100644 --- a/vitrage/notifier/__init__.py +++ b/vitrage/notifier/__init__.py @@ -17,4 +17,7 @@ from oslo_config import cfg OPTS = [ cfg.ListOpt('notifiers', help='Names of enabled notifiers (example aodh, nova)'), + cfg.ListOpt('notifiers_path', + default=['vitrage.notifier.plugins'], + help='list of base path for notifiers'), ] diff --git a/vitrage/notifier/plugins/aodh/__init__.py b/vitrage/notifier/plugins/aodh/__init__.py index 70097d786..90c771c73 100644 --- a/vitrage/notifier/plugins/aodh/__init__.py +++ b/vitrage/notifier/plugins/aodh/__init__.py @@ -12,4 +12,12 @@ # License for the specific language governing permissions and limitations # under the License. -pass +from oslo_config import cfg + +OPTS = [ + cfg.StrOpt('notifier', + default='vitrage.notifier.plugins.aodh.' + 'aodh_notifier.AodhNotifier', + help='aodh notifier class path', + required=True), +] diff --git a/vitrage/notifier/plugins/nova/__init__.py b/vitrage/notifier/plugins/nova/__init__.py index 70097d786..9575afbd1 100644 --- a/vitrage/notifier/plugins/nova/__init__.py +++ b/vitrage/notifier/plugins/nova/__init__.py @@ -12,4 +12,12 @@ # License for the specific language governing permissions and limitations # under the License. -pass +from oslo_config import cfg + +OPTS = [ + cfg.StrOpt('notifier', + default='vitrage.notifier.plugins.nova.' + 'nova_notifier.NovaNotifier', + help='nova notifier class path', + required=True), +] diff --git a/vitrage/notifier/service.py b/vitrage/notifier/service.py index 109b773fb..ea6c9d466 100644 --- a/vitrage/notifier/service.py +++ b/vitrage/notifier/service.py @@ -15,11 +15,10 @@ from oslo_log import log import oslo_messaging from oslo_service import service as os_service +from oslo_utils import importutils from vitrage import messaging -from vitrage.notifier.plugins.aodh.aodh_notifier import AodhNotifier -from vitrage.notifier.plugins.nova.nova_notifier import NovaNotifier - +from vitrage.opts import register_opts LOG = log.getLogger(__name__) @@ -60,11 +59,12 @@ class VitrageNotifierService(os_service.Service): if not conf_notifier_names: LOG.info('There are no notifier plugins in configuration') return [] - for plugin in [AodhNotifier, NovaNotifier]: - plugin_name = plugin.get_notifier_name() - if plugin_name in conf_notifier_names: - LOG.info('Notifier plugin %s started', plugin_name) - notifiers.append(plugin(conf)) + for notifier_name in conf_notifier_names: + register_opts(conf, notifier_name, conf.notifiers_path) + LOG.info('Notifier plugin %s started', notifier_name) + notifiers.append(importutils.import_object( + conf[notifier_name].notifier, + conf)) return notifiers diff --git a/vitrage/opts.py b/vitrage/opts.py index ebf6f0c7a..3156f62aa 100644 --- a/vitrage/opts.py +++ b/vitrage/opts.py @@ -15,6 +15,7 @@ import itertools import os +from oslo_log import log from oslo_utils import importutils import vitrage.api @@ -26,6 +27,8 @@ import vitrage.keystone_client import vitrage.notifier import vitrage.rpc +LOG = log.getLogger(__name__) + DATASOURCES_PATH = 'vitrage.datasources.' DATASOURCE_FS_PATH = os.path.join('vitrage', 'datasources') DRIVER_FILE = 'driver.py' @@ -76,3 +79,20 @@ def _filter_folders_containing_transformer(folders): def _normalize_path_to_datasource_name(path_list, top=os.getcwd()): return [os.path.relpath(path, os.path.join(top, DATASOURCE_FS_PATH)) .replace(os.sep, '.') for path in path_list] + + +def register_opts(conf, package_name, paths): + """register opts of package package_name, with base path in paths""" + for path in paths: + try: + opt = importutils.import_module( + "%s.%s" % (path, package_name)).OPTS + conf.register_opts( + list(opt), + group=None if package_name == 'DEFAULT' else package_name + ) + return + except ImportError: + pass + + LOG.error("Failed to register config options for %s" % package_name) diff --git a/vitrage/service.py b/vitrage/service.py index 2d62fc61f..a401a1cdf 100644 --- a/vitrage/service.py +++ b/vitrage/service.py @@ -16,11 +16,10 @@ import logging from oslo_config import cfg from oslo_log import log from oslo_policy import opts as policy_opts -from oslo_utils import importutils - from vitrage import keystone_client from vitrage import messaging from vitrage import opts +from vitrage.opts import register_opts LOG = log.getLogger(__name__) @@ -39,7 +38,7 @@ def prepare_service(args=None, conf=None, config_files=None): default_config_files=config_files) for datasource in conf.datasources.types: - load_datasource(conf, datasource, conf.datasources.path) + register_opts(conf, datasource, conf.datasources.path) keystone_client.register_keystoneauth_opts(conf) @@ -49,16 +48,3 @@ def prepare_service(args=None, conf=None, config_files=None): messaging.setup() return conf - - -def load_datasource(conf, name, paths): - for path in paths: - try: - opt = importutils.import_module("%s.%s" % (path, name)).OPTS - conf.register_opts(list(opt), - group=None if name == 'DEFAULT' else name) - return - except ImportError: - pass - - LOG.error("Failed to register config options for plugin %s" % name) diff --git a/vitrage/tests/functional/evaluator/test_action_executor.py b/vitrage/tests/functional/evaluator/test_action_executor.py index 430974923..c490d45c7 100644 --- a/vitrage/tests/functional/evaluator/test_action_executor.py +++ b/vitrage/tests/functional/evaluator/test_action_executor.py @@ -31,7 +31,7 @@ from vitrage.evaluator.actions.base import ActionType from vitrage.evaluator.actions.evaluator_event_transformer import VITRAGE_TYPE from vitrage.evaluator.template_data import ActionSpecs from vitrage.evaluator.template_fields import TemplateFields as TFields -from vitrage.service import load_datasource +from vitrage.opts import register_opts from vitrage.tests.functional.base import TestFunctionalBase LOG = logging.getLogger(__name__) @@ -47,9 +47,7 @@ class TestActionExecutor(TestFunctionalBase): cls.conf.register_opts(cls.DATASOURCES_OPTS, group='datasources') for datasource_name in cls.conf.datasources.types: - load_datasource(cls.conf, - datasource_name, - cls.conf.datasources.path) + register_opts(cls.conf, datasource_name, cls.conf.datasources.path) def test_execute_update_vertex(self): diff --git a/vitrage/tests/unit/entity_graph/base.py b/vitrage/tests/unit/entity_graph/base.py index e5310bbeb..b8859dd11 100644 --- a/vitrage/tests/unit/entity_graph/base.py +++ b/vitrage/tests/unit/entity_graph/base.py @@ -25,7 +25,7 @@ from vitrage.datasources.nova.zone import NOVA_ZONE_DATASOURCE from vitrage.entity_graph.initialization_status import InitializationStatus from vitrage.entity_graph.processor import processor as proc import vitrage.graph.utils as graph_utils -from vitrage.service import load_datasource +from vitrage.opts import register_opts from vitrage.tests import base from vitrage.tests.mocks import mock_driver as mock_sync from vitrage.tests.mocks import utils @@ -63,7 +63,7 @@ class TestEntityGraphUnitBase(base.BaseTest): @staticmethod def load_datasources(conf): for datasource in conf.datasources.types: - load_datasource(conf, datasource, conf.datasources.path) + register_opts(conf, datasource, conf.datasources.path) def _create_processor_with_graph(self, conf, processor=None): events = self._create_mock_events() diff --git a/vitrage/tests/unit/entity_graph/states/test_datasource_info_mapper.py b/vitrage/tests/unit/entity_graph/states/test_datasource_info_mapper.py index f3d9f6276..68a2e859a 100644 --- a/vitrage/tests/unit/entity_graph/states/test_datasource_info_mapper.py +++ b/vitrage/tests/unit/entity_graph/states/test_datasource_info_mapper.py @@ -25,7 +25,7 @@ from vitrage.entity_graph.mappings.datasource_info_mapper import \ from vitrage.entity_graph.mappings.operational_resource_state import \ OperationalResourceState from vitrage.graph.utils import create_vertex -from vitrage.service import load_datasource +from vitrage.opts import register_opts from vitrage.tests import base from vitrage.tests.mocks import utils @@ -53,7 +53,7 @@ class TestDatasourceInfoMapper(base.BaseTest): @staticmethod def _load_datasources(conf): for datasource_name in conf.datasources.types: - load_datasource(conf, datasource_name, conf.datasources.path) + register_opts(conf, datasource_name, conf.datasources.path) # noinspection PyAttributeOutsideInit,PyPep8Naming @classmethod diff --git a/vitrage/tests/unit/entity_graph/test_transformer_manager.py b/vitrage/tests/unit/entity_graph/test_transformer_manager.py index 5dbb1f717..0ae71cfec 100644 --- a/vitrage/tests/unit/entity_graph/test_transformer_manager.py +++ b/vitrage/tests/unit/entity_graph/test_transformer_manager.py @@ -24,7 +24,7 @@ from vitrage.datasources.nova.instance.transformer import InstanceTransformer from vitrage.datasources.nova.zone import NOVA_ZONE_DATASOURCE from vitrage.datasources.nova.zone.transformer import ZoneTransformer from vitrage.entity_graph.transformer_manager import TransformerManager -from vitrage.service import load_datasource +from vitrage.opts import register_opts from vitrage.tests import base LOG = logging.getLogger(__name__) @@ -52,7 +52,7 @@ class TransformerManagerTest(base.BaseTest): cls.conf.register_opts(cls.OPTS, group='datasources') for datasource in cls.conf.datasources.types: - load_datasource(cls.conf, datasource, cls.conf.datasources.path) + register_opts(cls.conf, datasource, cls.conf.datasources.path) cls.manager = TransformerManager(cls.conf)