Load custom drivers from config option
This commit adds support to load custom driver endpoints from config file. New option 'custom_driver_endpoints' is added for the same. Eg: custom_driver_endpoints = 'test=congress.datasources.test_driver:TestDriver' Implements blueprint enable-drivers-by-default Change-Id: I465301213734b9d4d7e5f7d67bae1d08767d9f16
This commit is contained in:
parent
7863b03d0d
commit
6e2f8449c1
|
@ -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'),
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue