diff options
| author | Jenkins <jenkins@review.openstack.org> | 2013-06-03 21:04:21 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2013-06-03 21:04:21 +0000 |
| commit | 5fcd5fe8055ee3457bafacb2f4785661af02830a (patch) | |
| tree | 698cb8b8c0f47086a9b11868d4f937a6cf229f7b | |
| parent | d0cbff778838c16dbd449fc01ef84e1223327794 (diff) | |
| parent | bb36650f87dd4b30e9ebbbb4409444b4482338b5 (diff) | |
| download | nova-5fcd5fe8055ee3457bafacb2f4785661af02830a.tar.gz nova-5fcd5fe8055ee3457bafacb2f4785661af02830a.tar.xz nova-5fcd5fe8055ee3457bafacb2f4785661af02830a.zip | |
Merge "Adds ability to black/whitelist v3 API extensions"
| -rw-r--r-- | etc/nova/nova.conf.sample | 29 | ||||
| -rw-r--r-- | nova/api/openstack/__init__.py | 50 | ||||
| -rw-r--r-- | nova/test.py | 2 | ||||
| -rw-r--r-- | nova/tests/api/openstack/compute/test_v3_extensions.py | 72 |
4 files changed, 139 insertions, 14 deletions
diff --git a/etc/nova/nova.conf.sample b/etc/nova/nova.conf.sample index 569c2d391..29778a556 100644 --- a/etc/nova/nova.conf.sample +++ b/etc/nova/nova.conf.sample @@ -413,14 +413,6 @@ # -# Options defined in nova.api.openstack -# - -# Whether the V3 API is enabled or not -#osapi_v3_enabled=False - - -# # Options defined in nova.api.openstack.common # @@ -2880,4 +2872,25 @@ #keymap=en-us +[osapi_v3] + +# +# Options defined in nova.api.openstack +# + +# Whether the V3 API is enabled or not +#enabled=False + +# If the list is not empty then a v3 API extension +# will only be loaded if it exists in this list. +# Specify the extension aliases here +#extensions_whitelist= + +# A list of v3 API extensions to never load. +# Specify the extension aliases here. +# Note that if an extension is in both the blacklist and +# and whitelist then it will not be loaded +#extensions_blacklist= + + # Total option count: 584 diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index c5181dd0b..96b9f5781 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -35,14 +35,25 @@ from nova import wsgi as base_wsgi api_opts = [ - cfg.BoolOpt('osapi_v3_enabled', + cfg.BoolOpt('enabled', default=False, - help='Whether the V3 API is enabled or not') + help='Whether the V3 API is enabled or not'), + cfg.ListOpt('extensions_blacklist', + default=[], + help='A list of v3 API extensions to never load. ' + 'Specify the extension aliases here.'), + cfg.ListOpt('extensions_whitelist', + default=[], + help='If the list is not empty then a v3 API extension ' + 'will only be loaded if it exists in this list. Specify ' + 'the extension aliases here.') ] +api_opts_group = cfg.OptGroup(name='osapi_v3', title='API v3 Options') LOG = logging.getLogger(__name__) CONF = cfg.CONF -CONF.register_opts(api_opts) +CONF.register_group(api_opts_group) +CONF.register_opts(api_opts, api_opts_group) class FaultWrapper(base_wsgi.Middleware): @@ -239,15 +250,44 @@ class APIRouterV3(base_wsgi.Router): if (self.init_only is None or ext.obj.alias in self.init_only) and isinstance(ext.obj, extensions.V3APIExtensionBase): - return self._register_extension(ext) + + # Check whitelist is either empty or if not then the extension + # is in the whitelist + if (not CONF.osapi_v3.extensions_whitelist or + ext.obj.alias in CONF.osapi_v3.extensions_whitelist): + + # Check the extension is not in the blacklist + if ext.obj.alias not in CONF.osapi_v3.extensions_blacklist: + return self._register_extension(ext) + else: + LOG.warning(_("Not loading %s because it is " + "in the blacklist"), ext.obj.alias) + return False + else: + LOG.warning( + _("Not loading %s because it is not in the whitelist"), + ext.obj.alias) + return False else: return False - if not CONF.osapi_v3_enabled: + if not CONF.osapi_v3.enabled: LOG.warning("V3 API has been disabled by configuration") return self.init_only = init_only + LOG.debug(_("v3 API Extension Blacklist: %s"), + CONF.osapi_v3.extensions_blacklist) + LOG.debug(_("v3 API Extension Whitelist: %s"), + CONF.osapi_v3.extensions_whitelist) + + in_blacklist_and_whitelist = set( + CONF.osapi_v3.extensions_whitelist).intersection( + CONF.osapi_v3.extensions_blacklist) + if len(in_blacklist_and_whitelist) != 0: + LOG.warning(_("Extensions in both blacklist and whitelist: %s"), + list(in_blacklist_and_whitelist)) + self.api_extension_manager = stevedore.enabled.EnabledExtensionManager( namespace=self.API_EXTENSION_NAMESPACE, check_func=_check_load_extension, diff --git a/nova/test.py b/nova/test.py index d9a7e7494..41ef26c81 100644 --- a/nova/test.py +++ b/nova/test.py @@ -231,7 +231,7 @@ class TestCase(testtools.TestCase): self.useFixture(fixtures.EnvironmentVariable('http_proxy')) self.policy = self.useFixture(policy_fixture.PolicyFixture()) CONF.set_override('fatal_exception_format_errors', True) - CONF.set_override('osapi_v3_enabled', True) + CONF.set_override('enabled', True, 'osapi_v3') def _clear_attrs(self): # Delete attributes that don't start with _ so they don't pin diff --git a/nova/tests/api/openstack/compute/test_v3_extensions.py b/nova/tests/api/openstack/compute/test_v3_extensions.py new file mode 100644 index 000000000..f7c1bf39c --- /dev/null +++ b/nova/tests/api/openstack/compute/test_v3_extensions.py @@ -0,0 +1,72 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 IBM 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 oslo.config import cfg + +from nova.api.openstack import compute +from nova.api.openstack.compute import plugins +from nova import test + +CONF = cfg.CONF + + +class fake_bad_extension(object): + name = "fake_bad_extension" + alias = "fake-bad" + + +class ExtensionLoadingTestCase(test.TestCase): + + def test_extensions_loaded(self): + app = compute.APIRouterV3() + self.assertIn('servers', app._loaded_extension_info.extensions) + + def test_check_bad_extension(self): + extension_info = plugins.LoadedExtensionInfo() + self.assertFalse(extension_info._check_extension(fake_bad_extension)) + + def test_extensions_blacklist(self): + app = compute.APIRouterV3() + self.assertIn('os-fixed-ips', app._loaded_extension_info.extensions) + CONF.set_override('extensions_blacklist', 'os-fixed-ips', 'osapi_v3') + app = compute.APIRouterV3() + self.assertNotIn('os-fixed-ips', app._loaded_extension_info.extensions) + + def test_extensions_whitelist_accept(self): + app = compute.APIRouterV3() + self.assertIn('os-fixed-ips', app._loaded_extension_info.extensions) + CONF.set_override('extensions_whitelist', 'servers,os-fixed-ips', + 'osapi_v3') + app = compute.APIRouterV3() + self.assertIn('os-fixed-ips', app._loaded_extension_info.extensions) + + def test_extensions_whitelist_block(self): + app = compute.APIRouterV3() + self.assertIn('os-fixed-ips', app._loaded_extension_info.extensions) + CONF.set_override('extensions_whitelist', 'servers', 'osapi_v3') + app = compute.APIRouterV3() + self.assertNotIn('os-fixed-ips', app._loaded_extension_info.extensions) + + def test_blacklist_overrides_whitelist(self): + app = compute.APIRouterV3() + self.assertIn('os-fixed-ips', app._loaded_extension_info.extensions) + CONF.set_override('extensions_whitelist', 'servers,os-fixed-ips', + 'osapi_v3') + CONF.set_override('extensions_blacklist', 'os-fixed-ips', 'osapi_v3') + app = compute.APIRouterV3() + self.assertNotIn('os-fixed-ips', app._loaded_extension_info.extensions) + self.assertIn('servers', app._loaded_extension_info.extensions) + self.assertEqual(len(app._loaded_extension_info.extensions), 1) |
