Use plain routes list for '/servers' endpoint instead of stevedore
This patch add '/servers' related routes by a plain list, instead of using stevedore. After all the Nova API endpoints moves to the plain routes list, the usage of stevedore for loading the API will be removed from Nova. To remove the servers extension from stevedore, all the extensions which depend on servers needs to be removed together. Those extensions are about the servers API response extension and the action extension. Also note that the original 'ProjectMapper' use the 'routes.Mapper.resource' to create a set of routes for a resource which comform to the Atom publishing protocol. It includes some of URL mappings we didn't document before. This patch will remove those URL mappings, also remove the corresponding URL mappings for 'os-volumes_boot' endpoint. For the detail, please reference: http://lists.openstack.org/pipermail/openstack-dev/2017-March/114736.html Partial-implement-blueprint api-no-more-extensions-pike Change-Id: I76c384c10bd804fc2049aef305044149bb55d0dc
This commit is contained in:
parent
658ee87995
commit
874ba55a49
@ -152,7 +152,7 @@ class APIMapper(routes.Mapper):
|
|||||||
|
|
||||||
|
|
||||||
class ProjectMapper(APIMapper):
|
class ProjectMapper(APIMapper):
|
||||||
def resource(self, member_name, collection_name, **kwargs):
|
def _get_project_id_token(self):
|
||||||
# NOTE(sdague): project_id parameter is only valid if its hex
|
# NOTE(sdague): project_id parameter is only valid if its hex
|
||||||
# or hex + dashes (note, integers are a subset of this). This
|
# or hex + dashes (note, integers are a subset of this). This
|
||||||
# is required to hand our overlaping routes issues.
|
# is required to hand our overlaping routes issues.
|
||||||
@ -160,7 +160,10 @@ class ProjectMapper(APIMapper):
|
|||||||
if CONF.osapi_v21.project_id_regex:
|
if CONF.osapi_v21.project_id_regex:
|
||||||
project_id_regex = CONF.osapi_v21.project_id_regex
|
project_id_regex = CONF.osapi_v21.project_id_regex
|
||||||
|
|
||||||
project_id_token = '{project_id:%s}' % project_id_regex
|
return '{project_id:%s}' % project_id_regex
|
||||||
|
|
||||||
|
def resource(self, member_name, collection_name, **kwargs):
|
||||||
|
project_id_token = self._get_project_id_token()
|
||||||
if 'parent_resource' not in kwargs:
|
if 'parent_resource' not in kwargs:
|
||||||
kwargs['path_prefix'] = '%s/' % project_id_token
|
kwargs['path_prefix'] = '%s/' % project_id_token
|
||||||
else:
|
else:
|
||||||
@ -191,6 +194,20 @@ class ProjectMapper(APIMapper):
|
|||||||
collection_name,
|
collection_name,
|
||||||
**kwargs)
|
**kwargs)
|
||||||
|
|
||||||
|
def create_route(self, path, method, controller, action):
|
||||||
|
project_id_token = self._get_project_id_token()
|
||||||
|
|
||||||
|
# while we transition away from project IDs in the API URIs, create
|
||||||
|
# additional routes that include the project_id
|
||||||
|
self.connect('/%s%s' % (project_id_token, path),
|
||||||
|
conditions=dict(method=[method]),
|
||||||
|
controller=controller,
|
||||||
|
action=action)
|
||||||
|
self.connect(path,
|
||||||
|
conditions=dict(method=[method]),
|
||||||
|
controller=controller,
|
||||||
|
action=action)
|
||||||
|
|
||||||
|
|
||||||
class PlainMapper(APIMapper):
|
class PlainMapper(APIMapper):
|
||||||
def resource(self, member_name, collection_name, **kwargs):
|
def resource(self, member_name, collection_name, **kwargs):
|
||||||
|
@ -14,25 +14,8 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
"""
|
# The APIRouterV21 moves down to the 'nova.api.openstack.compute.routes' for
|
||||||
WSGI middleware for OpenStack Compute API.
|
# circle reference problem. Import the APIRouterV21 is for the api-paste.ini
|
||||||
"""
|
# works correctly without modification. We still looking for a chance to move
|
||||||
|
# the APIRouterV21 back to here after cleanups.
|
||||||
import nova.api.openstack
|
from nova.api.openstack.compute.routes import APIRouterV21 # noqa
|
||||||
from nova.api.openstack.compute import extension_info
|
|
||||||
|
|
||||||
|
|
||||||
class APIRouterV21(nova.api.openstack.APIRouterV21):
|
|
||||||
"""Routes requests on the OpenStack API to the appropriate controller
|
|
||||||
and method.
|
|
||||||
"""
|
|
||||||
def __init__(self):
|
|
||||||
self._loaded_extension_info = extension_info.LoadedExtensionInfo()
|
|
||||||
super(APIRouterV21, self).__init__()
|
|
||||||
|
|
||||||
def _register_extension(self, ext):
|
|
||||||
return self.loaded_extension_info.register_extension(ext.obj)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def loaded_extension_info(self):
|
|
||||||
return self._loaded_extension_info
|
|
||||||
|
@ -18,6 +18,28 @@ from oslo_log import log as logging
|
|||||||
|
|
||||||
import webob.exc
|
import webob.exc
|
||||||
|
|
||||||
|
from nova.api.openstack.compute import admin_actions
|
||||||
|
from nova.api.openstack.compute import admin_password
|
||||||
|
from nova.api.openstack.compute import config_drive
|
||||||
|
from nova.api.openstack.compute import console_output
|
||||||
|
from nova.api.openstack.compute import create_backup
|
||||||
|
from nova.api.openstack.compute import deferred_delete
|
||||||
|
from nova.api.openstack.compute import evacuate
|
||||||
|
from nova.api.openstack.compute import extended_availability_zone
|
||||||
|
from nova.api.openstack.compute import extended_server_attributes
|
||||||
|
from nova.api.openstack.compute import extended_status
|
||||||
|
from nova.api.openstack.compute import extended_volumes
|
||||||
|
from nova.api.openstack.compute import hide_server_addresses
|
||||||
|
from nova.api.openstack.compute import lock_server
|
||||||
|
from nova.api.openstack.compute import migrate_server
|
||||||
|
from nova.api.openstack.compute import multinic
|
||||||
|
from nova.api.openstack.compute import pause_server
|
||||||
|
from nova.api.openstack.compute import rescue
|
||||||
|
from nova.api.openstack.compute import scheduler_hints
|
||||||
|
from nova.api.openstack.compute import server_usage
|
||||||
|
from nova.api.openstack.compute import servers
|
||||||
|
from nova.api.openstack.compute import shelve
|
||||||
|
from nova.api.openstack.compute import suspend_server
|
||||||
from nova.api.openstack import extensions
|
from nova.api.openstack import extensions
|
||||||
from nova.api.openstack import wsgi
|
from nova.api.openstack import wsgi
|
||||||
from nova import exception
|
from nova import exception
|
||||||
@ -163,6 +185,36 @@ hardcoded_extensions = [
|
|||||||
'alias': 'os-personality'},
|
'alias': 'os-personality'},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# TODO(alex_xu): This is a list of unused extension objs. Add those
|
||||||
|
# extension objs here for building a compatible extension API. Finally,
|
||||||
|
# we should remove those extension objs, and add corresponding entries
|
||||||
|
# in the 'hardcoded_extensions'.
|
||||||
|
unused_extension_objs = [
|
||||||
|
admin_actions.AdminActions,
|
||||||
|
admin_password.AdminPassword,
|
||||||
|
config_drive.ConfigDrive,
|
||||||
|
console_output.ConsoleOutput,
|
||||||
|
create_backup.CreateBackup,
|
||||||
|
deferred_delete.DeferredDelete,
|
||||||
|
evacuate.Evacuate,
|
||||||
|
extended_availability_zone.ExtendedAvailabilityZone,
|
||||||
|
extended_server_attributes.ExtendedServerAttributes,
|
||||||
|
extended_status.ExtendedStatus,
|
||||||
|
extended_volumes.ExtendedVolumes,
|
||||||
|
hide_server_addresses.HideServerAddresses,
|
||||||
|
lock_server.LockServer,
|
||||||
|
migrate_server.MigrateServer,
|
||||||
|
multinic.Multinic,
|
||||||
|
pause_server.PauseServer,
|
||||||
|
rescue.Rescue,
|
||||||
|
scheduler_hints.SchedulerHints,
|
||||||
|
server_usage.ServerUsage,
|
||||||
|
servers.Servers,
|
||||||
|
shelve.Shelve,
|
||||||
|
suspend_server.SuspendServer
|
||||||
|
]
|
||||||
|
|
||||||
# V2.1 does not support XML but we need to keep an entry in the
|
# V2.1 does not support XML but we need to keep an entry in the
|
||||||
# /extensions information returned to the user for backwards
|
# /extensions information returned to the user for backwards
|
||||||
# compatibility
|
# compatibility
|
||||||
@ -219,6 +271,16 @@ class ExtensionInfoController(wsgi.Controller):
|
|||||||
item['description']
|
item['description']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
for ext_cls in unused_extension_objs:
|
||||||
|
ext = ext_cls(None)
|
||||||
|
action = ':'.join([
|
||||||
|
base_policies.COMPUTE_API, ext.alias, 'discoverable'])
|
||||||
|
if context.can(action, fatal=False):
|
||||||
|
discoverable_extensions[ext.alias] = ext
|
||||||
|
else:
|
||||||
|
LOG.debug("Filter out extension %s from discover list",
|
||||||
|
ext.alias)
|
||||||
|
|
||||||
for alias, ext in self.extension_info.get_extensions().items():
|
for alias, ext in self.extension_info.get_extensions().items():
|
||||||
action = ':'.join([
|
action = ':'.join([
|
||||||
base_policies.COMPUTE_API, alias, 'discoverable'])
|
base_policies.COMPUTE_API, alias, 'discoverable'])
|
||||||
|
@ -338,6 +338,4 @@ class FloatingIps(extensions.V21APIExtensionBase):
|
|||||||
return resource
|
return resource
|
||||||
|
|
||||||
def get_controller_extensions(self):
|
def get_controller_extensions(self):
|
||||||
controller = FloatingIPActionController()
|
return []
|
||||||
extension = extensions.ControllerExtension(self, 'servers', controller)
|
|
||||||
return [extension]
|
|
||||||
|
@ -195,9 +195,7 @@ class RemoteConsoles(extensions.V21APIExtensionBase):
|
|||||||
version = 1
|
version = 1
|
||||||
|
|
||||||
def get_controller_extensions(self):
|
def get_controller_extensions(self):
|
||||||
controller = RemoteConsolesController()
|
return []
|
||||||
extension = extensions.ControllerExtension(self, 'servers', controller)
|
|
||||||
return [extension]
|
|
||||||
|
|
||||||
def get_resources(self):
|
def get_resources(self):
|
||||||
parent = {'member_name': 'server',
|
parent = {'member_name': 'server',
|
||||||
|
177
nova/api/openstack/compute/routes.py
Normal file
177
nova/api/openstack/compute/routes.py
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
# Copyright 2010 United States Government as represented by the
|
||||||
|
# Administrator of the National Aeronautics and Space Administration.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import functools
|
||||||
|
|
||||||
|
import nova.api.openstack
|
||||||
|
from nova.api.openstack.compute import admin_actions
|
||||||
|
from nova.api.openstack.compute import admin_password
|
||||||
|
from nova.api.openstack.compute import config_drive
|
||||||
|
from nova.api.openstack.compute import console_output
|
||||||
|
from nova.api.openstack.compute import create_backup
|
||||||
|
from nova.api.openstack.compute import deferred_delete
|
||||||
|
from nova.api.openstack.compute import evacuate
|
||||||
|
from nova.api.openstack.compute import extended_availability_zone
|
||||||
|
from nova.api.openstack.compute import extended_server_attributes
|
||||||
|
from nova.api.openstack.compute import extended_status
|
||||||
|
from nova.api.openstack.compute import extended_volumes
|
||||||
|
from nova.api.openstack.compute import extension_info
|
||||||
|
from nova.api.openstack.compute import floating_ips
|
||||||
|
from nova.api.openstack.compute import hide_server_addresses
|
||||||
|
from nova.api.openstack.compute import keypairs
|
||||||
|
from nova.api.openstack.compute import lock_server
|
||||||
|
from nova.api.openstack.compute import migrate_server
|
||||||
|
from nova.api.openstack.compute import multinic
|
||||||
|
from nova.api.openstack.compute import pause_server
|
||||||
|
from nova.api.openstack.compute import remote_consoles
|
||||||
|
from nova.api.openstack.compute import rescue
|
||||||
|
from nova.api.openstack.compute import security_groups
|
||||||
|
from nova.api.openstack.compute import server_usage
|
||||||
|
from nova.api.openstack.compute import servers
|
||||||
|
from nova.api.openstack.compute import shelve
|
||||||
|
from nova.api.openstack.compute import suspend_server
|
||||||
|
from nova.api.openstack import wsgi
|
||||||
|
import nova.conf
|
||||||
|
|
||||||
|
|
||||||
|
CONF = nova.conf.CONF
|
||||||
|
|
||||||
|
|
||||||
|
def _create_controller(main_controller, controller_list,
|
||||||
|
action_controller_list):
|
||||||
|
"""This is a helper method to create controller with a
|
||||||
|
list of extended controller. This is for backward compatible
|
||||||
|
with old extension interface. Finally, the controller for the
|
||||||
|
same resource will be merged into single one controller.
|
||||||
|
"""
|
||||||
|
|
||||||
|
controller = wsgi.ResourceV21(main_controller())
|
||||||
|
for ctl in controller_list:
|
||||||
|
controller.register_extensions(ctl())
|
||||||
|
for ctl in action_controller_list:
|
||||||
|
controller.register_actions(ctl())
|
||||||
|
return controller
|
||||||
|
|
||||||
|
|
||||||
|
server_controller = functools.partial(_create_controller,
|
||||||
|
servers.ServersController,
|
||||||
|
[
|
||||||
|
config_drive.ConfigDriveController,
|
||||||
|
extended_availability_zone.ExtendedAZController,
|
||||||
|
extended_server_attributes.ExtendedServerAttributesController,
|
||||||
|
extended_status.ExtendedStatusController,
|
||||||
|
extended_volumes.ExtendedVolumesController,
|
||||||
|
hide_server_addresses.Controller,
|
||||||
|
keypairs.Controller,
|
||||||
|
security_groups.SecurityGroupsOutputController,
|
||||||
|
server_usage.ServerUsageController,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
admin_actions.AdminActionsController,
|
||||||
|
admin_password.AdminPasswordController,
|
||||||
|
console_output.ConsoleOutputController,
|
||||||
|
create_backup.CreateBackupController,
|
||||||
|
deferred_delete.DeferredDeleteController,
|
||||||
|
evacuate.EvacuateController,
|
||||||
|
floating_ips.FloatingIPActionController,
|
||||||
|
lock_server.LockServerController,
|
||||||
|
migrate_server.MigrateServerController,
|
||||||
|
multinic.MultinicController,
|
||||||
|
pause_server.PauseServerController,
|
||||||
|
remote_consoles.RemoteConsolesController,
|
||||||
|
rescue.RescueController,
|
||||||
|
security_groups.SecurityGroupActionController,
|
||||||
|
shelve.ShelveController,
|
||||||
|
suspend_server.SuspendServerController
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# NOTE(alex_xu): This is structure of this route list as below:
|
||||||
|
# (
|
||||||
|
# ('Route path': {
|
||||||
|
# 'HTTP method: [
|
||||||
|
# 'Controller',
|
||||||
|
# 'The method of controller is used to handle this route'
|
||||||
|
# ],
|
||||||
|
# ...
|
||||||
|
# }),
|
||||||
|
# ...
|
||||||
|
# )
|
||||||
|
#
|
||||||
|
# Also note that this is ordered tuple. For example, the '/servers/detail'
|
||||||
|
# should be in the front of '/servers/{id}', otherwise the request to
|
||||||
|
# '/servers/detail' always matches to '/servers/{id}' as the id is 'detail'.
|
||||||
|
ROUTE_LIST = (
|
||||||
|
# NOTE: '/os-volumes_boot' is a clone of '/servers'. We may want to
|
||||||
|
# deprecate it in the future.
|
||||||
|
('/os-volumes_boot', {
|
||||||
|
'GET': [server_controller, 'index'],
|
||||||
|
'POST': [server_controller, 'create']
|
||||||
|
}),
|
||||||
|
('/os-volumes_boot/detail', {
|
||||||
|
'GET': [server_controller, 'detail']
|
||||||
|
}),
|
||||||
|
('/os-volumes_boot/{id}', {
|
||||||
|
'GET': [server_controller, 'show'],
|
||||||
|
'PUT': [server_controller, 'update'],
|
||||||
|
'DELETE': [server_controller, 'delete']
|
||||||
|
}),
|
||||||
|
('/os-volumes_boot/{id}/action', {
|
||||||
|
'POST': [server_controller, 'action']
|
||||||
|
}),
|
||||||
|
('/servers', {
|
||||||
|
'GET': [server_controller, 'index'],
|
||||||
|
'POST': [server_controller, 'create']
|
||||||
|
}),
|
||||||
|
('/servers/detail', {
|
||||||
|
'GET': [server_controller, 'detail']
|
||||||
|
}),
|
||||||
|
('/servers/{id}', {
|
||||||
|
'GET': [server_controller, 'show'],
|
||||||
|
'PUT': [server_controller, 'update'],
|
||||||
|
'DELETE': [server_controller, 'delete']
|
||||||
|
}),
|
||||||
|
('/servers/{id}/action', {
|
||||||
|
'POST': [server_controller, 'action']
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class APIRouterV21(nova.api.openstack.APIRouterV21):
|
||||||
|
"""Routes requests on the OpenStack API to the appropriate controller
|
||||||
|
and method. The URL mapping based on the plain list `ROUTE_LIST` is built
|
||||||
|
at here. The stevedore based API loading will be replaced by this.
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
self._loaded_extension_info = extension_info.LoadedExtensionInfo()
|
||||||
|
super(APIRouterV21, self).__init__()
|
||||||
|
|
||||||
|
for path, methods in ROUTE_LIST:
|
||||||
|
for method, controller_info in methods.items():
|
||||||
|
# TODO(alex_xu): In the end, I want to create single controller
|
||||||
|
# instance instead of create controller instance for each
|
||||||
|
# route.
|
||||||
|
controller = controller_info[0]()
|
||||||
|
action = controller_info[1]
|
||||||
|
self.map.create_route(path, method, controller, action)
|
||||||
|
|
||||||
|
def _register_extension(self, ext):
|
||||||
|
return self.loaded_extension_info.register_extension(ext.obj)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def loaded_extension_info(self):
|
||||||
|
return self._loaded_extension_info
|
@ -503,11 +503,7 @@ class SecurityGroups(extensions.V21APIExtensionBase):
|
|||||||
version = 1
|
version = 1
|
||||||
|
|
||||||
def get_controller_extensions(self):
|
def get_controller_extensions(self):
|
||||||
secgrp_output_ext = extensions.ControllerExtension(
|
return []
|
||||||
self, 'servers', SecurityGroupsOutputController())
|
|
||||||
secgrp_act_ext = extensions.ControllerExtension(
|
|
||||||
self, 'servers', SecurityGroupActionController())
|
|
||||||
return [secgrp_output_ext, secgrp_act_ext]
|
|
||||||
|
|
||||||
def get_resources(self):
|
def get_resources(self):
|
||||||
secgrp_ext = extensions.ResourceExtension(ALIAS,
|
secgrp_ext = extensions.ResourceExtension(ALIAS,
|
||||||
|
@ -608,10 +608,6 @@ class Volumes(extensions.V21APIExtensionBase):
|
|||||||
ALIAS, VolumeController(), collection_actions={'detail': 'GET'})
|
ALIAS, VolumeController(), collection_actions={'detail': 'GET'})
|
||||||
resources.append(res)
|
resources.append(res)
|
||||||
|
|
||||||
res = extensions.ResourceExtension('os-volumes_boot',
|
|
||||||
inherits='servers')
|
|
||||||
resources.append(res)
|
|
||||||
|
|
||||||
res = extensions.ResourceExtension('os-volume_attachments',
|
res = extensions.ResourceExtension('os-volume_attachments',
|
||||||
VolumeAttachmentController(),
|
VolumeAttachmentController(),
|
||||||
parent=dict(
|
parent=dict(
|
||||||
|
@ -13,10 +13,8 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import mock
|
|
||||||
import webob.exc
|
import webob.exc
|
||||||
|
|
||||||
from nova.api.openstack import compute
|
|
||||||
from nova.api.openstack.compute import extension_info
|
from nova.api.openstack.compute import extension_info
|
||||||
from nova.api.openstack import extensions
|
from nova.api.openstack import extensions
|
||||||
from nova import exception
|
from nova import exception
|
||||||
@ -30,29 +28,10 @@ class fake_bad_extension(object):
|
|||||||
|
|
||||||
class ExtensionLoadingTestCase(test.NoDBTestCase):
|
class ExtensionLoadingTestCase(test.NoDBTestCase):
|
||||||
|
|
||||||
def test_extensions_loaded(self):
|
|
||||||
app = compute.APIRouterV21()
|
|
||||||
self.assertIn('servers', app._loaded_extension_info.extensions)
|
|
||||||
|
|
||||||
def test_check_bad_extension(self):
|
def test_check_bad_extension(self):
|
||||||
loaded_ext_info = extension_info.LoadedExtensionInfo()
|
loaded_ext_info = extension_info.LoadedExtensionInfo()
|
||||||
self.assertFalse(loaded_ext_info._check_extension(fake_bad_extension))
|
self.assertFalse(loaded_ext_info._check_extension(fake_bad_extension))
|
||||||
|
|
||||||
@mock.patch('nova.api.openstack.APIRouterV21._register_resources_list')
|
|
||||||
def test_extensions_inherit(self, mock_register):
|
|
||||||
app = compute.APIRouterV21()
|
|
||||||
self.assertIn('servers', app._loaded_extension_info.extensions)
|
|
||||||
self.assertIn('os-volumes', app._loaded_extension_info.extensions)
|
|
||||||
|
|
||||||
mock_register.assert_called_with(mock.ANY, mock.ANY)
|
|
||||||
ext_no_inherits = mock_register.call_args_list[0][0][0]
|
|
||||||
ext_has_inherits = mock_register.call_args_list[1][0][0]
|
|
||||||
# os-volumes inherits from servers
|
|
||||||
name_list = [ext.obj.alias for ext in ext_has_inherits]
|
|
||||||
self.assertIn('os-volumes', name_list)
|
|
||||||
name_list = [ext.obj.alias for ext in ext_no_inherits]
|
|
||||||
self.assertIn('servers', name_list)
|
|
||||||
|
|
||||||
def test_extensions_expected_error(self):
|
def test_extensions_expected_error(self):
|
||||||
@extensions.expected_errors(404)
|
@extensions.expected_errors(404)
|
||||||
def fake_func():
|
def fake_func():
|
||||||
|
22
setup.cfg
22
setup.cfg
@ -71,8 +71,6 @@ wsgi_scripts =
|
|||||||
nova-placement-api = nova.api.openstack.placement.wsgi:init_application
|
nova-placement-api = nova.api.openstack.placement.wsgi:init_application
|
||||||
|
|
||||||
nova.api.v21.extensions =
|
nova.api.v21.extensions =
|
||||||
admin_actions = nova.api.openstack.compute.admin_actions:AdminActions
|
|
||||||
admin_password = nova.api.openstack.compute.admin_password:AdminPassword
|
|
||||||
agents = nova.api.openstack.compute.agents:Agents
|
agents = nova.api.openstack.compute.agents:Agents
|
||||||
aggregates = nova.api.openstack.compute.aggregates:Aggregates
|
aggregates = nova.api.openstack.compute.aggregates:Aggregates
|
||||||
assisted_volume_snapshots = nova.api.openstack.compute.assisted_volume_snapshots:AssistedVolumeSnapshots
|
assisted_volume_snapshots = nova.api.openstack.compute.assisted_volume_snapshots:AssistedVolumeSnapshots
|
||||||
@ -83,17 +81,8 @@ nova.api.v21.extensions =
|
|||||||
cells = nova.api.openstack.compute.cells:Cells
|
cells = nova.api.openstack.compute.cells:Cells
|
||||||
certificates = nova.api.openstack.compute.certificates:Certificates
|
certificates = nova.api.openstack.compute.certificates:Certificates
|
||||||
cloudpipe = nova.api.openstack.compute.cloudpipe:Cloudpipe
|
cloudpipe = nova.api.openstack.compute.cloudpipe:Cloudpipe
|
||||||
config_drive = nova.api.openstack.compute.config_drive:ConfigDrive
|
|
||||||
console_auth_tokens = nova.api.openstack.compute.console_auth_tokens:ConsoleAuthTokens
|
console_auth_tokens = nova.api.openstack.compute.console_auth_tokens:ConsoleAuthTokens
|
||||||
console_output = nova.api.openstack.compute.console_output:ConsoleOutput
|
|
||||||
consoles = nova.api.openstack.compute.consoles:Consoles
|
consoles = nova.api.openstack.compute.consoles:Consoles
|
||||||
create_backup = nova.api.openstack.compute.create_backup:CreateBackup
|
|
||||||
deferred_delete = nova.api.openstack.compute.deferred_delete:DeferredDelete
|
|
||||||
evacuate = nova.api.openstack.compute.evacuate:Evacuate
|
|
||||||
extended_availability_zone = nova.api.openstack.compute.extended_availability_zone:ExtendedAvailabilityZone
|
|
||||||
extended_server_attributes = nova.api.openstack.compute.extended_server_attributes:ExtendedServerAttributes
|
|
||||||
extended_status = nova.api.openstack.compute.extended_status:ExtendedStatus
|
|
||||||
extended_volumes = nova.api.openstack.compute.extended_volumes:ExtendedVolumes
|
|
||||||
extension_info = nova.api.openstack.compute.extension_info:ExtensionInfo
|
extension_info = nova.api.openstack.compute.extension_info:ExtensionInfo
|
||||||
fixed_ips = nova.api.openstack.compute.fixed_ips:FixedIps
|
fixed_ips = nova.api.openstack.compute.fixed_ips:FixedIps
|
||||||
flavors = nova.api.openstack.compute.flavors:Flavors
|
flavors = nova.api.openstack.compute.flavors:Flavors
|
||||||
@ -106,7 +95,6 @@ nova.api.v21.extensions =
|
|||||||
floating_ips = nova.api.openstack.compute.floating_ips:FloatingIps
|
floating_ips = nova.api.openstack.compute.floating_ips:FloatingIps
|
||||||
floating_ips_bulk = nova.api.openstack.compute.floating_ips_bulk:FloatingIpsBulk
|
floating_ips_bulk = nova.api.openstack.compute.floating_ips_bulk:FloatingIpsBulk
|
||||||
fping = nova.api.openstack.compute.fping:Fping
|
fping = nova.api.openstack.compute.fping:Fping
|
||||||
hide_server_addresses = nova.api.openstack.compute.hide_server_addresses:HideServerAddresses
|
|
||||||
hosts = nova.api.openstack.compute.hosts:Hosts
|
hosts = nova.api.openstack.compute.hosts:Hosts
|
||||||
hypervisors = nova.api.openstack.compute.hypervisors:Hypervisors
|
hypervisors = nova.api.openstack.compute.hypervisors:Hypervisors
|
||||||
images = nova.api.openstack.compute.images:Images
|
images = nova.api.openstack.compute.images:Images
|
||||||
@ -117,19 +105,13 @@ nova.api.v21.extensions =
|
|||||||
ips = nova.api.openstack.compute.ips:IPs
|
ips = nova.api.openstack.compute.ips:IPs
|
||||||
keypairs = nova.api.openstack.compute.keypairs:Keypairs
|
keypairs = nova.api.openstack.compute.keypairs:Keypairs
|
||||||
limits = nova.api.openstack.compute.limits:Limits
|
limits = nova.api.openstack.compute.limits:Limits
|
||||||
lock_server = nova.api.openstack.compute.lock_server:LockServer
|
|
||||||
migrate_server = nova.api.openstack.compute.migrate_server:MigrateServer
|
|
||||||
migrations = nova.api.openstack.compute.migrations:Migrations
|
migrations = nova.api.openstack.compute.migrations:Migrations
|
||||||
multinic = nova.api.openstack.compute.multinic:Multinic
|
|
||||||
multiple_create = nova.api.openstack.compute.multiple_create:MultipleCreate
|
multiple_create = nova.api.openstack.compute.multiple_create:MultipleCreate
|
||||||
networks = nova.api.openstack.compute.networks:Networks
|
networks = nova.api.openstack.compute.networks:Networks
|
||||||
networks_associate = nova.api.openstack.compute.networks_associate:NetworksAssociate
|
networks_associate = nova.api.openstack.compute.networks_associate:NetworksAssociate
|
||||||
pause_server = nova.api.openstack.compute.pause_server:PauseServer
|
|
||||||
quota_classes = nova.api.openstack.compute.quota_classes:QuotaClasses
|
quota_classes = nova.api.openstack.compute.quota_classes:QuotaClasses
|
||||||
quota_sets = nova.api.openstack.compute.quota_sets:QuotaSets
|
quota_sets = nova.api.openstack.compute.quota_sets:QuotaSets
|
||||||
remote_consoles = nova.api.openstack.compute.remote_consoles:RemoteConsoles
|
remote_consoles = nova.api.openstack.compute.remote_consoles:RemoteConsoles
|
||||||
rescue = nova.api.openstack.compute.rescue:Rescue
|
|
||||||
scheduler_hints = nova.api.openstack.compute.scheduler_hints:SchedulerHints
|
|
||||||
security_group_default_rules = nova.api.openstack.compute.security_group_default_rules:SecurityGroupDefaultRules
|
security_group_default_rules = nova.api.openstack.compute.security_group_default_rules:SecurityGroupDefaultRules
|
||||||
security_groups = nova.api.openstack.compute.security_groups:SecurityGroups
|
security_groups = nova.api.openstack.compute.security_groups:SecurityGroups
|
||||||
server_diagnostics = nova.api.openstack.compute.server_diagnostics:ServerDiagnostics
|
server_diagnostics = nova.api.openstack.compute.server_diagnostics:ServerDiagnostics
|
||||||
@ -138,13 +120,9 @@ nova.api.v21.extensions =
|
|||||||
server_migrations = nova.api.openstack.compute.server_migrations:ServerMigrations
|
server_migrations = nova.api.openstack.compute.server_migrations:ServerMigrations
|
||||||
server_password = nova.api.openstack.compute.server_password:ServerPassword
|
server_password = nova.api.openstack.compute.server_password:ServerPassword
|
||||||
server_tags = nova.api.openstack.compute.server_tags:ServerTags
|
server_tags = nova.api.openstack.compute.server_tags:ServerTags
|
||||||
server_usage = nova.api.openstack.compute.server_usage:ServerUsage
|
|
||||||
server_groups = nova.api.openstack.compute.server_groups:ServerGroups
|
server_groups = nova.api.openstack.compute.server_groups:ServerGroups
|
||||||
servers = nova.api.openstack.compute.servers:Servers
|
|
||||||
services = nova.api.openstack.compute.services:Services
|
services = nova.api.openstack.compute.services:Services
|
||||||
shelve = nova.api.openstack.compute.shelve:Shelve
|
|
||||||
simple_tenant_usage = nova.api.openstack.compute.simple_tenant_usage:SimpleTenantUsage
|
simple_tenant_usage = nova.api.openstack.compute.simple_tenant_usage:SimpleTenantUsage
|
||||||
suspend_server = nova.api.openstack.compute.suspend_server:SuspendServer
|
|
||||||
tenant_networks = nova.api.openstack.compute.tenant_networks:TenantNetworks
|
tenant_networks = nova.api.openstack.compute.tenant_networks:TenantNetworks
|
||||||
used_limits = nova.api.openstack.compute.used_limits:UsedLimits
|
used_limits = nova.api.openstack.compute.used_limits:UsedLimits
|
||||||
user_data = nova.api.openstack.compute.user_data:UserData
|
user_data = nova.api.openstack.compute.user_data:UserData
|
||||||
|
Loading…
Reference in New Issue
Block a user