Provide plugins an oslo_config group for their setup
The plugin implementations need to be isolated from the entity that is using os-vif. Plugins should be allowed to define their own custom config parameters, without needing the user of os-vif to pass further options into the os_vif.initialize() method. This change introduces a CONFIG_OPTS attribute on the Plugin class. This provides a list of oslo_config options that are to be used by the plugin. os_vif will register these options into a group 'os_vif_$PLUGIN' eg 'os_vif_linux_bridge'. This gives the plugin impls the ability to have config options in the main project conf (ie /etc/nova/nova.conf) without exposing them directly to all of nova's own config options. Change-Id: I9634b474cd0d3fda09aef5800020c9415c28e3d8
This commit is contained in:
parent
1ff6526c3d
commit
72d5dfbf48
13
README.rst
13
README.rst
@ -14,19 +14,12 @@ Usage
|
||||
-----
|
||||
|
||||
The interface to the `os_vif` library is very simple. To begin using the
|
||||
library, first call the `os_vif.initialize()` function, supplying a set of
|
||||
keyword arguments for configuration options::
|
||||
library, first call the `os_vif.initialize()` function. This will load
|
||||
all installed plugins and register the object model::
|
||||
|
||||
import os_vif
|
||||
|
||||
os_vif.initialize(libvirt_virt_type='kvm',
|
||||
network_device_mtu=1500,
|
||||
vlan_interface='eth1',
|
||||
use_ipv6=False,
|
||||
iptables_top_regex='',
|
||||
iptables_bottom_regex='',
|
||||
iptables_drop_action='DROP',
|
||||
forward_bridge_interface=['all'])
|
||||
os_vif.initialize()
|
||||
|
||||
Once the `os_vif` library is initialized, there are only two other library
|
||||
functions: `os_vif.plug()` and `os_vif.unplug()`. Both methods accept a single
|
||||
|
@ -24,7 +24,7 @@ _EXT_MANAGER = None
|
||||
LOG = logging.getLogger('os_vif')
|
||||
|
||||
|
||||
def initialize(reset=False, **config):
|
||||
def initialize(reset=False):
|
||||
"""
|
||||
Loads all os_vif plugins and initializes them with a dictionary of
|
||||
configuration options. These configuration options are passed as-is
|
||||
@ -32,38 +32,16 @@ def initialize(reset=False, **config):
|
||||
|
||||
:param reset: Recreate and load the VIF plugin extensions.
|
||||
|
||||
The following configuration options are currently known to be
|
||||
used by the VIF plugins, however this list may change and you
|
||||
should check the documentation of individual plugins for a complete
|
||||
list of configuration options that the plugin understands or uses.
|
||||
|
||||
:param **config: Configuration option dictionary.
|
||||
|
||||
`use_ipv6`: Default: False. For plugins that configure IPv6 iptables
|
||||
rules or functionality, set this option to True if you want
|
||||
to support IPv6.
|
||||
`disable_rootwrap`: Default: False. Set to True to force plugins to use
|
||||
sudoers files instead of any `oslo.rootwrap` functionality.
|
||||
`use_rootwrap_daemon`: Default: False. Set to True to use the optional
|
||||
`oslo.rootwrap` daemon for better performance of root-run
|
||||
commands.
|
||||
`rootwrap_config`: Default: /etc/nova/rootwrap.conf. Path to the
|
||||
rootwrap configuration file.
|
||||
`iptables_top_regex`: Default: ''. Override top filters in iptables
|
||||
rules construction.
|
||||
`iptables_bottom_regex`: Default: ''. Override bottom filters in
|
||||
iptables rules construction.
|
||||
`iptables_drop_action`: Default: DROP. Override the name of the drop
|
||||
action in iptables rules.
|
||||
`forward_bridge_interface`: Default: ['all'].
|
||||
`network_device_mtu`: Default: 1500. Override the MTU of network
|
||||
devices created by a VIF plugin.
|
||||
"""
|
||||
global _EXT_MANAGER
|
||||
if reset or (_EXT_MANAGER is None):
|
||||
_EXT_MANAGER = extension.ExtensionManager(namespace='os_vif',
|
||||
invoke_on_load=True,
|
||||
invoke_args=config)
|
||||
invoke_on_load=False)
|
||||
for plugin_name in _EXT_MANAGER.keys():
|
||||
cls = _EXT_MANAGER[plugin_name].plugin
|
||||
obj = cls.load(plugin_name)
|
||||
_EXT_MANAGER[plugin_name].obj = obj
|
||||
|
||||
os_vif.objects.register_all()
|
||||
|
||||
|
||||
|
@ -11,10 +11,13 @@
|
||||
# under the License.
|
||||
|
||||
import abc
|
||||
|
||||
from oslo_config import cfg
|
||||
import six
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class PluginVIFInfo(object):
|
||||
"""
|
||||
Class describing the plugin and the versions of VIF object it understands.
|
||||
@ -54,10 +57,15 @@ class PluginInfo(object):
|
||||
class PluginBase(object):
|
||||
"""Base class for all VIF plugins."""
|
||||
|
||||
def __init__(self, **config):
|
||||
# Override to provide a tuple of oslo_config.Opt instances for
|
||||
# the plugin config parameters
|
||||
CONFIG_OPTS = ()
|
||||
|
||||
def __init__(self, config):
|
||||
"""
|
||||
Sets up the plugin using supplied kwargs representing configuration
|
||||
options.
|
||||
Initialize the plugin object with the provided config
|
||||
|
||||
:param config: `oslo_config.ConfigOpts.GroupAttr` instance:
|
||||
"""
|
||||
self.config = config
|
||||
|
||||
@ -93,3 +101,24 @@ class PluginBase(object):
|
||||
this method should let `processutils.ProcessExecutionError`
|
||||
bubble up.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def load(cls, plugin_name):
|
||||
"""
|
||||
Load a plugin, registering its configuration options
|
||||
|
||||
:param plugin_name: the name of the plugin extension
|
||||
|
||||
:returns: an initialized instance of the class
|
||||
"""
|
||||
cfg_group_name = "os_vif_" + plugin_name
|
||||
cfg_opts = getattr(cls, "CONFIG_OPTS")
|
||||
cfg_vals = None
|
||||
if cfg_opts and len(cfg_opts) > 0:
|
||||
cfg_group = cfg.OptGroup(
|
||||
cfg_group_name,
|
||||
"os-vif plugin %s options" % plugin_name)
|
||||
CONF.register_opts(cfg_opts, group=cfg_group)
|
||||
|
||||
cfg_vals = getattr(CONF, cfg_group_name)
|
||||
return cls(cfg_vals)
|
||||
|
@ -11,6 +11,7 @@
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
from stevedore import extension
|
||||
|
||||
import os_vif
|
||||
@ -22,13 +23,34 @@ from os_vif.tests import base
|
||||
|
||||
class DemoPlugin(plugin.PluginBase):
|
||||
|
||||
CONFIG_OPTS = (
|
||||
cfg.BoolOpt("make_it_work",
|
||||
default=False,
|
||||
help="Make everything work correctly by setting this"),
|
||||
cfg.IntOpt("sleep_time",
|
||||
default=0,
|
||||
help="How long to artifically sleep")
|
||||
)
|
||||
|
||||
def describe(self):
|
||||
pass
|
||||
|
||||
def plug(self, vif, instance_info):
|
||||
def plug(self, vif, instance_info, config):
|
||||
pass
|
||||
|
||||
def unplug(self, vif, instance_info):
|
||||
def unplug(self, vif, instance_info, config):
|
||||
pass
|
||||
|
||||
|
||||
class DemoPluginNoConfig(plugin.PluginBase):
|
||||
|
||||
def describe(self):
|
||||
pass
|
||||
|
||||
def plug(self, vif, instance_info, config):
|
||||
pass
|
||||
|
||||
def unplug(self, vif, instance_info, config):
|
||||
pass
|
||||
|
||||
|
||||
@ -46,9 +68,25 @@ class TestOSVIF(base.TestCase):
|
||||
os_vif.initialize()
|
||||
os_vif.initialize()
|
||||
mock_EM.assert_called_once_with(
|
||||
invoke_args={}, invoke_on_load=True, namespace='os_vif')
|
||||
invoke_on_load=False, namespace='os_vif')
|
||||
self.assertIsNotNone(os_vif._EXT_MANAGER)
|
||||
|
||||
def test_load_plugin(self):
|
||||
obj = DemoPlugin.load("demo")
|
||||
self.assertTrue(hasattr(cfg.CONF, "os_vif_demo"))
|
||||
self.assertTrue(hasattr(cfg.CONF.os_vif_demo, "make_it_work"))
|
||||
self.assertTrue(hasattr(cfg.CONF.os_vif_demo, "sleep_time"))
|
||||
self.assertEqual(cfg.CONF.os_vif_demo.make_it_work, False)
|
||||
self.assertEqual(cfg.CONF.os_vif_demo.sleep_time, 0)
|
||||
|
||||
self.assertEqual(obj.config, cfg.CONF.os_vif_demo)
|
||||
|
||||
def test_load_plugin_no_config(self):
|
||||
obj = DemoPluginNoConfig.load("demonocfg")
|
||||
self.assertFalse(hasattr(cfg.CONF, "os_vif_demonocfg"))
|
||||
|
||||
self.assertIsNone(obj.config)
|
||||
|
||||
def test_plug_not_initialized(self):
|
||||
self.assertRaises(
|
||||
exception.LibraryNotInitialized,
|
||||
@ -63,8 +101,8 @@ class TestOSVIF(base.TestCase):
|
||||
def test_plug(self, mock_plug):
|
||||
plg = extension.Extension(name="demo",
|
||||
entry_point="os-vif",
|
||||
plugin="DemoPlugin",
|
||||
obj=DemoPlugin())
|
||||
plugin=DemoPlugin,
|
||||
obj=None)
|
||||
with mock.patch('stevedore.extension.ExtensionManager',
|
||||
return_value={'foobar': plg}):
|
||||
os_vif.initialize()
|
||||
@ -78,8 +116,8 @@ class TestOSVIF(base.TestCase):
|
||||
def test_unplug(self, mock_unplug):
|
||||
plg = extension.Extension(name="demo",
|
||||
entry_point="os-vif",
|
||||
plugin="DemoPlugin",
|
||||
obj=DemoPlugin())
|
||||
plugin=DemoPlugin,
|
||||
obj=None)
|
||||
with mock.patch('stevedore.extension.ExtensionManager',
|
||||
return_value={'foobar': plg}):
|
||||
os_vif.initialize()
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
pbr>=1.6
|
||||
netaddr>=0.7.12,!=0.7.16
|
||||
oslo.config>=3.4.0 # Apache-2.0
|
||||
oslo.log>=1.14.0 # Apache-2.0
|
||||
oslo.i18n>=1.5.0 # Apache-2.0
|
||||
oslo.versionedobjects>=0.13.0
|
||||
|
Loading…
Reference in New Issue
Block a user