Merge "Load custom drivers from config option"

This commit is contained in:
Zuul 2018-04-17 00:29:47 +00:00 committed by Gerrit Code Review
commit 5072473f60
5 changed files with 87 additions and 10 deletions

View File

@ -59,6 +59,11 @@ core_opts = [
default=[],
help=_('List of driver names to be disabled. For example, '
'disabled_drivers=nova, plexxi')),
cfg.ListOpt('custom_driver_endpoints',
default=[],
help=_("List of third party endpoints to be loaded seperated "
"by comma. For example custom_driver_endpoints = "
"'test=congress.datasources.test_driver:TestDriver',")),
cfg.IntOpt('datasource_sync_period', default=60,
help='The number of seconds to wait between synchronizing '
'datasource config from the database'),

View File

@ -24,6 +24,7 @@ from oslo_messaging import exceptions as messaging_exceptions
from oslo_messaging.rpc import dispatcher
from oslo_utils import strutils
from oslo_utils import uuidutils
import pkg_resources
import stevedore
from congress.datalog import compile as datalog_compile
@ -116,8 +117,6 @@ class DseNode(object):
# Note(ekcs): A little strange that _control_bus starts before self?
self._control_bus = control_bus.DseNodeControlBus(self)
self.register_service(self._control_bus)
# load configured drivers
# self.loaded_drivers = self.load_drivers()
self.periodic_tasks = None
self.sync_thread = None
self.start()
@ -513,12 +512,33 @@ class DseNode(object):
namespace='congress.datasource.drivers',
invoke_on_load=False)
# Load third party drivers from config if any
if cfg.CONF.custom_driver_endpoints:
custom_extensions = cls.load_custom_drivers()
if custom_extensions:
mgr.extensions.extend(custom_extensions)
for driver in mgr:
if driver.name not in cfg.CONF.disabled_drivers:
result[driver.name] = driver
cls.loaded_drivers = result
@classmethod
def load_custom_drivers(cls):
cdist = pkg_resources.get_distribution('congress')
ext_list = []
for driver in cfg.CONF.custom_driver_endpoints:
try:
ep = pkg_resources.EntryPoint.parse(driver, dist=cdist)
ep_plugin = ep.load()
ext = stevedore.extension.Extension(
name=ep.name, entry_point=ep, plugin=ep_plugin, obj=None)
ext_list.append(ext)
except Exception:
LOG.exception("Failed to load driver endpoint %s", driver)
return ext_list
@classmethod
def get_driver_info(cls, driver_name):
driver = cls.loaded_drivers.get(driver_name)
@ -646,14 +666,7 @@ class DseNode(object):
def create_datasource_service(self, datasource):
"""Create a new DataService on this node.
:param: name is the name of the service. Must be unique across all
services
:param: classPath is a string giving the path to the class name, e.g.
congress.datasources.fake_datasource.FakeDataSource
:param: args is the list of arguments to give the DataService
constructor
:param: type\_ is the kind of service
:param: id\_ is an optional parameter for specifying the uuid.
:param: datasource: datsource object.
"""
# get the driver info for the datasource
ds_dict = self.make_datasource_dict(datasource)

View File

@ -32,6 +32,9 @@ from congress.tests import helper
class TestDatasourceModel(base.SqlTestCase):
def setUp(self):
super(TestDatasourceModel, self).setUp()
cfg.CONF.set_override(
'custom_driver_endpoints',
'test=congress.tests.test_custom_driver:TestCustomDriver')
services = api_base.setup_config(with_fake_datasource=False)
self.datasource_model = services['api']['api-datasource']
self.data = services['data']
@ -78,6 +81,17 @@ class TestDatasourceModel(base.SqlTestCase):
self.assertEqual('datasource_test_3', obj.name)
self.assertIsNotNone(ds_obj)
def test_add_datasource_with_custom_driver(self):
datasource4 = self._get_datasource_request()
datasource4['name'] = 'datasource_test_4'
datasource4['driver'] = 'test'
self.datasource_model.add_item(datasource4, {})
ds_obj = self.node.service_object('datasource_test_4')
obj = self.engine.policy_object('datasource_test_4')
self.assertIsNotNone(obj.schema)
self.assertEqual('datasource_test_4', obj.name)
self.assertIsNotNone(ds_obj)
def test_add_item_duplicate(self):
self.assertRaises(webservice.DataModelException,
self.datasource_model.add_item,

View File

@ -52,6 +52,15 @@ class TestDriverModel(base.SqlTestCase):
ret = [d['id'] for d in driver_api.get_items({}, {})['results']]
self.assertEqual(sorted(drivers), sorted(ret))
def test_drivers_list_with_custom_drivers(self):
cfg.CONF.set_override(
'custom_driver_endpoints',
'test=congress.tests.test_custom_driver:TestCustomDriver')
services = api_base.setup_config(node_id='test-node-2')
driver_api = services['api']['api-system']
ret = [d['id'] for d in driver_api.get_items({}, {})['results']]
self.assertIn('test', ret)
def test_driver_details(self):
context = {
"driver_id": "fake_datasource"

View File

@ -0,0 +1,36 @@
# Copyright (c) 2018 NEC, Corp
#
# 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.
#
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from congress.datasources import datasource_driver
from congress.datasources import datasource_utils
class TestCustomDriver(datasource_driver.PollingDataSourceDriver):
def __init__(self, name='', args=None):
super(TestCustomDriver, self).__init__(name, args)
@staticmethod
def get_datasource_info():
result = {}
result['id'] = 'test'
result['description'] = 'This is a fake driver used for testing'
result['config'] = datasource_utils.get_openstack_required_config()
result['secret'] = ['password']
return result