summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2013-06-03 21:04:21 +0000
committerGerrit Code Review <review@openstack.org>2013-06-03 21:04:21 +0000
commit5fcd5fe8055ee3457bafacb2f4785661af02830a (patch)
tree698cb8b8c0f47086a9b11868d4f937a6cf229f7b
parentd0cbff778838c16dbd449fc01ef84e1223327794 (diff)
parentbb36650f87dd4b30e9ebbbb4409444b4482338b5 (diff)
downloadnova-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.sample29
-rw-r--r--nova/api/openstack/__init__.py50
-rw-r--r--nova/test.py2
-rw-r--r--nova/tests/api/openstack/compute/test_v3_extensions.py72
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)