api: deprecate the concept of extensions in v2.1

We want to remove the extension infrastructure in the v2.1 API during
the next release. To make that possible, we must deprecate the
configuration now.

Also deprecating the osapi_v3 group, and moving to osapi_v21.

UpgradeImpact
DocImpact

Part of blueprint nova-api-deprecate-extensions

Change-Id: I084444b11dceda7cf8f88c157aa67d36490fce49
This commit is contained in:
John Garbutt 2015-08-19 13:46:52 +01:00 committed by John Garbutt
parent 19810750b4
commit 11507eeceb
17 changed files with 70 additions and 52 deletions

View File

@ -43,20 +43,26 @@ from nova import wsgi as base_wsgi
api_opts = [
cfg.BoolOpt('enabled',
default=True,
help='DEPRECATED: Whether the V3 API is enabled or not. '
'This option will be removed in the 14.0.0 "N" release.',
deprecated_for_removal=True),
help='DEPRECATED: Whether the V2.1 API is enabled or not. '
'This option will be removed in the near future.',
deprecated_for_removal=True, deprecated_group='osapi_v21'),
cfg.ListOpt('extensions_blacklist',
default=[],
help='A list of v3 API extensions to never load. '
'Specify the extension aliases here.'),
help='DEPRECATED: A list of v2.1 API extensions to never '
'load. Specify the extension aliases here. '
'This option will be removed in the near future. '
'After that point you have to run all of the API.',
deprecated_for_removal=True, deprecated_group='osapi_v21'),
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.')
help='DEPRECATED: If the list is not empty then a v2.1 '
'API extension will only be loaded if it exists in this '
'list. Specify the extension aliases here. '
'This option will be removed in the near future. '
'After that point you have to run all of the API.',
deprecated_for_removal=True, deprecated_group='osapi_v21')
]
api_opts_group = cfg.OptGroup(name='osapi_v3', title='API v3 Options')
api_opts_group = cfg.OptGroup(name='osapi_v21', title='API v2.1 Options')
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
@ -323,27 +329,36 @@ class APIRouterV21(base_wsgi.Router):
# 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):
if (not CONF.osapi_v21.extensions_whitelist or
ext.obj.alias in CONF.osapi_v21.extensions_whitelist):
# Check the extension is not in the blacklist
if ext.obj.alias not in CONF.osapi_v3.extensions_blacklist:
blacklist = CONF.osapi_v21.extensions_blacklist
if ext.obj.alias not in blacklist:
return self._register_extension(ext)
return False
if not CONF.osapi_v3.enabled:
if not CONF.osapi_v21.enabled:
LOG.info(_LI("V3 API has been disabled by configuration"))
LOG.warning(_LW("In the M release you must run the v2.1 API."))
return
if (CONF.osapi_v21.extensions_blacklist or
CONF.osapi_v21.extensions_whitelist):
LOG.warning(
_LW('In the M release you must run all of the API. '
'The concept of API extensions will be removed from '
'the codebase to ensure there is a single Compute API.'))
self.init_only = init_only
LOG.debug("v3 API Extension Blacklist: %s",
CONF.osapi_v3.extensions_blacklist)
CONF.osapi_v21.extensions_blacklist)
LOG.debug("v3 API Extension Whitelist: %s",
CONF.osapi_v3.extensions_whitelist)
CONF.osapi_v21.extensions_whitelist)
in_blacklist_and_whitelist = set(
CONF.osapi_v3.extensions_whitelist).intersection(
CONF.osapi_v3.extensions_blacklist)
CONF.osapi_v21.extensions_whitelist).intersection(
CONF.osapi_v21.extensions_blacklist)
if len(in_blacklist_and_whitelist) != 0:
LOG.warning(_LW("Extensions in both blacklist and whitelist: %s"),
list(in_blacklist_and_whitelist))

View File

@ -51,8 +51,10 @@ CONF.import_opt('enable_instance_password',
'nova.api.openstack.compute.legacy_v2.servers')
CONF.import_opt('network_api_class', 'nova.network')
CONF.import_opt('reclaim_instance_interval', 'nova.compute.manager')
CONF.import_opt('extensions_blacklist', 'nova.api.openstack', group='osapi_v3')
CONF.import_opt('extensions_whitelist', 'nova.api.openstack', group='osapi_v3')
CONF.import_opt('extensions_blacklist', 'nova.api.openstack',
group='osapi_v21')
CONF.import_opt('extensions_whitelist', 'nova.api.openstack',
group='osapi_v21')
LOG = logging.getLogger(__name__)
authorize = extensions.os_compute_authorizer(ALIAS)
@ -100,11 +102,12 @@ class ServersController(wsgi.Controller):
def check_whiteblack_lists(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):
if (not CONF.osapi_v21.extensions_whitelist or
ext.obj.alias in CONF.osapi_v21.extensions_whitelist):
# Check the extension is not in the blacklist
if ext.obj.alias not in CONF.osapi_v3.extensions_blacklist:
extensions_blacklist = CONF.osapi_v21.extensions_blacklist
if ext.obj.alias not in extensions_blacklist:
return True
else:
LOG.warning(_LW("Not loading %s because it is "

View File

@ -21,7 +21,7 @@ from nova.api.openstack import wsgi
CONF = cfg.CONF
CONF.import_opt('enabled', 'nova.api.openstack', group='osapi_v3')
CONF.import_opt('enabled', 'nova.api.openstack', group='osapi_v21')
LINKS = {
'v2.0': {
@ -80,7 +80,7 @@ VERSIONS = {
class Versions(wsgi.Resource):
def __init__(self):
super(Versions, self).__init__(None)
if not CONF.osapi_v3.enabled:
if not CONF.osapi_v21.enabled:
del VERSIONS["v2.1"]
def index(self, req, body=None):

View File

@ -143,5 +143,5 @@ def list_opts():
nova.api.openstack.compute.legacy_v2.servers.server_opts,
)),
('neutron', nova.api.metadata.handler.metadata_proxy_opts),
('osapi_v3', nova.api.openstack.api_opts),
('osapi_v21', nova.api.openstack.api_opts),
]

View File

@ -55,7 +55,7 @@ from nova import utils
CONF = cfg.CONF
CONF.import_opt('enabled', 'nova.api.openstack', group='osapi_v3')
CONF.import_opt('enabled', 'nova.api.openstack', group='osapi_v21')
logging.register_options(CONF)
CONF.set_override('use_stderr', False)

View File

@ -54,7 +54,7 @@ class ApiSampleTestBaseV3(testscenarios.WithScenarios,
whitelist.update(set(self.extra_extensions_to_load))
CONF.set_override('extensions_whitelist', whitelist,
'osapi_v3')
'osapi_v21')
expected_middleware = []
if (not hasattr(self, '_test') or (self._test == 'v2.1')):
# NOTE(gmann)For v2.1 API testing, override /v2 endpoint with v2.1

View File

@ -241,7 +241,7 @@ class ServersControllerCreateTestV21(test.TestCase):
extension_info=ext_info)
CONF.set_override('extensions_blacklist',
'os-availability-zone',
'osapi_v3')
'osapi_v21')
self.no_availability_zone_controller = servers_v21.ServersController(
extension_info=ext_info)

View File

@ -45,10 +45,10 @@ class BlockDeviceMappingTestV21(test.TestCase):
self.controller = servers_v21.ServersController(
extension_info=ext_info)
CONF.set_override('extensions_blacklist', 'os-block-device-mapping',
'osapi_v3')
'osapi_v21')
self.no_bdm_v2_controller = servers_v21.ServersController(
extension_info=ext_info)
CONF.set_override('extensions_blacklist', '', 'osapi_v3')
CONF.set_override('extensions_blacklist', '', 'osapi_v21')
def setUp(self):
super(BlockDeviceMappingTestV21, self).setUp()

View File

@ -40,16 +40,16 @@ class BlockDeviceMappingTestV21(test.TestCase):
def _setup_controller(self):
ext_info = extension_info.LoadedExtensionInfo()
CONF.set_override('extensions_blacklist', 'os-block-device-mapping',
'osapi_v3')
'osapi_v21')
self.controller = servers_v21.ServersController(
extension_info=ext_info)
CONF.set_override('extensions_blacklist',
['os-block-device-mapping-v1',
'os-block-device-mapping'],
'osapi_v3')
'osapi_v21')
self.no_volumes_controller = servers_v21.ServersController(
extension_info=ext_info)
CONF.set_override('extensions_blacklist', '', 'osapi_v3')
CONF.set_override('extensions_blacklist', '', 'osapi_v21')
def setUp(self):
super(BlockDeviceMappingTestV21, self).setUp()
@ -299,7 +299,7 @@ class BlockDeviceMappingTestV21(test.TestCase):
CONF.set_override('extensions_blacklist',
['os-block-device-mapping',
'os-block-device-mapping-v1'],
'osapi_v3')
'osapi_v21')
controller = servers_v21.ServersController(extension_info=ext_info)
bdm = [{'device_name': 'foo1',
'volume_id': fakes.FAKE_UUID,
@ -328,7 +328,7 @@ class BlockDeviceMappingTestV21(test.TestCase):
def test_create_instance_both_bdm_formats(self):
ext_info = extension_info.LoadedExtensionInfo()
CONF.set_override('extensions_blacklist', '', 'osapi_v3')
CONF.set_override('extensions_blacklist', '', 'osapi_v21')
both_controllers = servers_v21.ServersController(
extension_info=ext_info)
bdm = [{'device_name': 'foo'}]

View File

@ -98,7 +98,7 @@ class ServersControllerCreateTestV21(test.TestCase):
extension_info=ext_info)
CONF.set_override('extensions_blacklist',
'os-config-drive',
'osapi_v3')
'osapi_v21')
self.no_config_drive_controller = servers_v21.ServersController(
extension_info=ext_info)

View File

@ -73,7 +73,7 @@ class ExtensionLoadingTestCase(test.NoDBTestCase):
def test_extensions_blacklist(self):
app = compute.APIRouterV21()
self.assertIn('os-hosts', app._loaded_extension_info.extensions)
CONF.set_override('extensions_blacklist', ['os-hosts'], 'osapi_v3')
CONF.set_override('extensions_blacklist', ['os-hosts'], 'osapi_v21')
app = compute.APIRouterV21()
self.assertNotIn('os-hosts', app._loaded_extension_info.extensions)
@ -102,7 +102,7 @@ class ExtensionLoadingTestCase(test.NoDBTestCase):
app = compute.APIRouterV21()
self.assertIn('os-hosts', app._loaded_extension_info.extensions)
CONF.set_override('extensions_whitelist', ['servers', 'os-hosts'],
'osapi_v3')
'osapi_v21')
app = compute.APIRouterV21()
self.assertIn('os-hosts', app._loaded_extension_info.extensions)
@ -115,7 +115,7 @@ class ExtensionLoadingTestCase(test.NoDBTestCase):
app = compute.APIRouterV21()
self.assertIn('os-hosts', app._loaded_extension_info.extensions)
CONF.set_override('extensions_whitelist', ['servers'], 'osapi_v3')
CONF.set_override('extensions_whitelist', ['servers'], 'osapi_v21')
app = compute.APIRouterV21()
self.assertNotIn('os-hosts', app._loaded_extension_info.extensions)
@ -129,8 +129,8 @@ class ExtensionLoadingTestCase(test.NoDBTestCase):
app = compute.APIRouterV21()
self.assertIn('os-hosts', app._loaded_extension_info.extensions)
CONF.set_override('extensions_whitelist', ['servers', 'os-hosts'],
'osapi_v3')
CONF.set_override('extensions_blacklist', ['os-hosts'], 'osapi_v3')
'osapi_v21')
CONF.set_override('extensions_blacklist', ['os-hosts'], 'osapi_v21')
app = compute.APIRouterV21()
self.assertNotIn('os-hosts', app._loaded_extension_info.extensions)
self.assertIn('servers', app._loaded_extension_info.extensions)

View File

@ -65,7 +65,7 @@ class MultiCreateExtensionTestV21(test.TestCase):
self.controller = servers_v21.ServersController(
extension_info=ext_info)
CONF.set_override('extensions_blacklist', 'os-multiple-create',
'osapi_v3')
'osapi_v21')
self.no_mult_create_controller = servers_v21.ServersController(
extension_info=ext_info)

View File

@ -181,7 +181,7 @@ class ServersControllerCreateTestV21(test.TestCase):
def _set_up_controller(self):
ext_info = extension_info.LoadedExtensionInfo()
CONF.set_override('extensions_blacklist', 'os-scheduler-hints',
'osapi_v3')
'osapi_v21')
self.no_scheduler_hints_controller = servers_v21.ServersController(
extension_info=ext_info)

View File

@ -3546,7 +3546,7 @@ class TestServersExtensionPoint(test.NoDBTestCase):
def setUp(self):
super(TestServersExtensionPoint, self).setUp()
CONF.set_override('extensions_whitelist', ['os-disk-config'],
'osapi_v3')
'osapi_v21')
self.stubs.Set(disk_config, 'DiskConfig', FakeExt)
def _test_load_extension_point(self, name):
@ -3576,7 +3576,7 @@ class TestServersExtensionPoint(test.NoDBTestCase):
class TestServersExtensionSchema(test.NoDBTestCase):
def setUp(self):
super(TestServersExtensionSchema, self).setUp()
CONF.set_override('extensions_whitelist', ['disk_config'], 'osapi_v3')
CONF.set_override('extensions_whitelist', ['disk_config'], 'osapi_v21')
def _test_load_extension_schema(self, name):
setattr(FakeExt, 'get_server_%s_schema' % name,

View File

@ -62,7 +62,7 @@ class ServersControllerCreateTest(test.TestCase):
ext_info = extension_info.LoadedExtensionInfo()
self.controller = servers.ServersController(extension_info=ext_info)
CONF.set_override('extensions_blacklist', 'os-user-data',
'osapi_v3')
'osapi_v21')
self.no_user_data_controller = servers.ServersController(
extension_info=ext_info)

View File

@ -71,7 +71,7 @@ class ExtensionLoadingTestCase(test.NoDBTestCase):
def test_extensions_blacklist(self):
app = compute.APIRouterV3()
self.assertIn('os-hosts', app._loaded_extension_info.extensions)
CONF.set_override('extensions_blacklist', ['os-hosts'], 'osapi_v3')
CONF.set_override('extensions_blacklist', ['os-hosts'], 'osapi_v21')
app = compute.APIRouterV3()
self.assertNotIn('os-hosts', app._loaded_extension_info.extensions)
@ -85,7 +85,7 @@ class ExtensionLoadingTestCase(test.NoDBTestCase):
app = compute.APIRouterV3()
self.assertIn('os-hosts', app._loaded_extension_info.extensions)
CONF.set_override('extensions_whitelist', ['servers', 'os-hosts'],
'osapi_v3')
'osapi_v21')
app = compute.APIRouterV3()
self.assertIn('os-hosts', app._loaded_extension_info.extensions)
@ -98,7 +98,7 @@ class ExtensionLoadingTestCase(test.NoDBTestCase):
app = compute.APIRouterV3()
self.assertIn('os-hosts', app._loaded_extension_info.extensions)
CONF.set_override('extensions_whitelist', ['servers'], 'osapi_v3')
CONF.set_override('extensions_whitelist', ['servers'], 'osapi_v21')
app = compute.APIRouterV3()
self.assertNotIn('os-hosts', app._loaded_extension_info.extensions)
@ -112,8 +112,8 @@ class ExtensionLoadingTestCase(test.NoDBTestCase):
app = compute.APIRouterV3()
self.assertIn('os-hosts', app._loaded_extension_info.extensions)
CONF.set_override('extensions_whitelist', ['servers', 'os-hosts'],
'osapi_v3')
CONF.set_override('extensions_blacklist', ['os-hosts'], 'osapi_v3')
'osapi_v21')
CONF.set_override('extensions_blacklist', ['os-hosts'], 'osapi_v21')
app = compute.APIRouterV3()
self.assertNotIn('os-hosts', app._loaded_extension_info.extensions)
self.assertIn('servers', app._loaded_extension_info.extensions)

View File

@ -63,7 +63,7 @@ class ConfFixture(config_fixture.Config):
self.conf.set_default('sqlite_synchronous', False,
group='api_database')
self.conf.set_default('fatal_exception_format_errors', True)
self.conf.set_default('enabled', True, 'osapi_v3')
self.conf.set_default('enabled', True, 'osapi_v21')
self.conf.set_default('force_dhcp_release', False)
self.conf.set_default('periodic_enable', False)
self.addCleanup(utils.cleanup_dns_managers)