From 6e87d4fd407546ab151d39934a4cec3bf6fb82e8 Mon Sep 17 00:00:00 2001 From: Eylon Malin Date: Tue, 29 Mar 2016 10:57:52 +0000 Subject: [PATCH] enable loading of external plugins with different base path Change-Id: I2ef561aac446e2f3b9788c50f4822390775a6a40 --- vitrage/service.py | 24 ++++++++++++------- vitrage/synchronizer/plugins/__init__.py | 3 +++ .../evaluator/test_action_executor.py | 3 ++- vitrage/tests/unit/entity_graph/base.py | 7 +++++- .../entity_graph/states/test_state_manager.py | 7 +++++- .../entity_graph/test_transformer_manager.py | 7 +++++- 6 files changed, 39 insertions(+), 12 deletions(-) diff --git a/vitrage/service.py b/vitrage/service.py index 5c9ffecb4..99a690191 100644 --- a/vitrage/service.py +++ b/vitrage/service.py @@ -22,7 +22,6 @@ from vitrage import keystone_client from vitrage import messaging from vitrage import opts -PLUGINS_PATH = 'vitrage.synchronizer.plugins.' LOG = log.getLogger(__name__) @@ -36,13 +35,14 @@ def prepare_service(args=None, conf=None, config_files=None): conf.register_opts(list(options), group=None if group == 'DEFAULT' else group) - for plugin_name in conf.synchronizer_plugins.plugin_type: - load_plugin(conf, plugin_name) - - keystone_client.register_keystoneauth_opts(conf) conf(args, project='vitrage', validate_default_values=True, default_config_files=config_files) + for plugin_name in conf.synchronizer_plugins.plugin_type: + load_plugin(conf, plugin_name, conf.synchronizer_plugins.plugin_path) + + keystone_client.register_keystoneauth_opts(conf) + keystone_client.setup_keystoneauth(conf) log.setup(conf, 'vitrage') conf.log_opt_values(LOG, logging.DEBUG) @@ -51,6 +51,14 @@ def prepare_service(args=None, conf=None, config_files=None): return conf -def load_plugin(conf, name): - opt = importutils.import_module(PLUGINS_PATH + name).OPTS - conf.register_opts(list(opt), group=None if name == 'DEFAULT' else name) +def load_plugin(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/synchronizer/plugins/__init__.py b/vitrage/synchronizer/plugins/__init__.py index 2697578d7..cb2641447 100644 --- a/vitrage/synchronizer/plugins/__init__.py +++ b/vitrage/synchronizer/plugins/__init__.py @@ -36,4 +36,7 @@ OPTS = [ AODH_PLUGIN, CINDER_VOLUME_PLUGIN], help='Names of supported plugins'), + cfg.ListOpt('plugin_path', + default=['vitrage.synchronizer.plugins'], + help='base path for plugins') ] diff --git a/vitrage/tests/functional/evaluator/test_action_executor.py b/vitrage/tests/functional/evaluator/test_action_executor.py index d683a7312..5356f7e2c 100644 --- a/vitrage/tests/functional/evaluator/test_action_executor.py +++ b/vitrage/tests/functional/evaluator/test_action_executor.py @@ -49,7 +49,8 @@ class TestActionExecutor(TestEntityGraphFunctionalBase): cls.conf.register_opts(cls.PLUGINS_OPTS, group='synchronizer_plugins') for plugin_name in cls.conf.synchronizer_plugins.plugin_type: - load_plugin(cls.conf, plugin_name) + load_plugin(cls.conf, plugin_name, + cls.conf.synchronizer_plugins.plugin_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 f02a2c2ea..4b0c6439e 100644 --- a/vitrage/tests/unit/entity_graph/base.py +++ b/vitrage/tests/unit/entity_graph/base.py @@ -45,6 +45,10 @@ class TestEntityGraphUnitBase(base.BaseTest): NOVA_INSTANCE_PLUGIN, NOVA_ZONE_PLUGIN], help='Names of supported synchronizer plugins'), + + cfg.ListOpt('plugin_path', + default=['vitrage.synchronizer.plugins'], + help='base path for plugins') ] NUM_NODES = 1 @@ -55,7 +59,8 @@ class TestEntityGraphUnitBase(base.BaseTest): @staticmethod def load_plugins(conf): for plugin_name in conf.synchronizer_plugins.plugin_type: - load_plugin(conf, plugin_name) + load_plugin(conf, plugin_name, + conf.synchronizer_plugins.plugin_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_state_manager.py b/vitrage/tests/unit/entity_graph/states/test_state_manager.py index 4792aefd5..e91598add 100644 --- a/vitrage/tests/unit/entity_graph/states/test_state_manager.py +++ b/vitrage/tests/unit/entity_graph/states/test_state_manager.py @@ -43,12 +43,17 @@ class TestStateManager(base.BaseTest): NOVA_INSTANCE_PLUGIN, NOVA_ZONE_PLUGIN], help='Names of supported synchronizer plugins'), + + cfg.ListOpt('plugin_path', + default=['vitrage.synchronizer.plugins'], + help='base path for plugins') ] @staticmethod def _load_plugins(conf): for plugin_name in conf.synchronizer_plugins.plugin_type: - load_plugin(conf, plugin_name) + load_plugin(conf, plugin_name, + conf.synchronizer_plugins.plugin_path) # noinspection PyAttributeOutsideInit def setUp(self): diff --git a/vitrage/tests/unit/entity_graph/test_transformer_manager.py b/vitrage/tests/unit/entity_graph/test_transformer_manager.py index 11bb4d1e8..3a85d03e4 100644 --- a/vitrage/tests/unit/entity_graph/test_transformer_manager.py +++ b/vitrage/tests/unit/entity_graph/test_transformer_manager.py @@ -43,6 +43,10 @@ class TransformerManagerTest(base.BaseTest): NOVA_INSTANCE_PLUGIN, NOVA_ZONE_PLUGIN], help='Names of supported synchronizer plugins'), + + cfg.ListOpt('plugin_path', + default=['vitrage.synchronizer.plugins'], + help='base path for plugins') ] # noinspection PyPep8Naming @@ -51,7 +55,8 @@ class TransformerManagerTest(base.BaseTest): cls.conf = cfg.ConfigOpts() cls.conf.register_opts(cls.OPTS, group='synchronizer_plugins') for plugin_name in cls.conf.synchronizer_plugins.plugin_type: - load_plugin(cls.conf, plugin_name) + load_plugin(cls.conf, plugin_name, + cls.conf.synchronizer_plugins.plugin_path) cls.manager = TransformerManager(cls.conf) def test_transformer_registration_nagios(self):