summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorBrian Waldon <brian.waldon@rackspace.com>2011-11-11 13:26:13 -0500
committerBrian Waldon <brian.waldon@rackspace.com>2011-11-17 10:09:15 -0800
commitde635fc882caebd5d5c9701e755a7174e37a05c5 (patch)
tree7f7414caef497db6b0c7710569391f52c246b8cc /nova/api
parentf14ec8a9e2ef9d7869e9834bd054e9c0e271ec31 (diff)
downloadnova-de635fc882caebd5d5c9701e755a7174e37a05c5.tar.gz
nova-de635fc882caebd5d5c9701e755a7174e37a05c5.tar.xz
nova-de635fc882caebd5d5c9701e755a7174e37a05c5.zip
Creating new v2 namespace in nova.api.openstack
Related to blueprint separate-nova-adminapi Change-Id: Ida35372b7263c4a4efdafd35faa1325c4436459b
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/openstack/__init__.py187
-rw-r--r--nova/api/openstack/faults.py116
-rw-r--r--nova/api/openstack/v2/__init__.py186
-rw-r--r--nova/api/openstack/v2/accounts.py (renamed from nova/api/openstack/accounts.py)10
-rw-r--r--nova/api/openstack/v2/auth.py (renamed from nova/api/openstack/auth.py)30
-rw-r--r--nova/api/openstack/v2/consoles.py (renamed from nova/api/openstack/consoles.py)6
-rw-r--r--nova/api/openstack/v2/contrib/__init__.py (renamed from nova/api/openstack/contrib/__init__.py)2
-rw-r--r--nova/api/openstack/v2/contrib/admin_actions.py (renamed from nova/api/openstack/contrib/admin_actions.py)4
-rw-r--r--nova/api/openstack/v2/contrib/createserverext.py (renamed from nova/api/openstack/contrib/createserverext.py)6
-rw-r--r--nova/api/openstack/v2/contrib/deferred_delete.py (renamed from nova/api/openstack/contrib/deferred_delete.py)6
-rw-r--r--nova/api/openstack/v2/contrib/disk_config.py (renamed from nova/api/openstack/contrib/disk_config.py)6
-rw-r--r--nova/api/openstack/v2/contrib/extended_status.py (renamed from nova/api/openstack/contrib/extended_status.py)7
-rw-r--r--nova/api/openstack/v2/contrib/flavorextradata.py (renamed from nova/api/openstack/contrib/flavorextradata.py)6
-rw-r--r--nova/api/openstack/v2/contrib/flavorextraspecs.py (renamed from nova/api/openstack/contrib/flavorextraspecs.py)3
-rw-r--r--nova/api/openstack/v2/contrib/floating_ips.py (renamed from nova/api/openstack/contrib/floating_ips.py)5
-rw-r--r--nova/api/openstack/v2/contrib/hosts.py (renamed from nova/api/openstack/contrib/hosts.py)7
-rw-r--r--nova/api/openstack/v2/contrib/keypairs.py (renamed from nova/api/openstack/contrib/keypairs.py)2
-rw-r--r--nova/api/openstack/v2/contrib/multinic.py (renamed from nova/api/openstack/contrib/multinic.py)4
-rw-r--r--nova/api/openstack/v2/contrib/quotas.py (renamed from nova/api/openstack/contrib/quotas.py)2
-rw-r--r--nova/api/openstack/v2/contrib/rescue.py (renamed from nova/api/openstack/contrib/rescue.py)5
-rw-r--r--nova/api/openstack/v2/contrib/security_groups.py (renamed from nova/api/openstack/contrib/security_groups.py)14
-rw-r--r--nova/api/openstack/v2/contrib/simple_tenant_usage.py (renamed from nova/api/openstack/contrib/simple_tenant_usage.py)13
-rw-r--r--nova/api/openstack/v2/contrib/virtual_interfaces.py (renamed from nova/api/openstack/contrib/virtual_interfaces.py)8
-rw-r--r--nova/api/openstack/v2/contrib/virtual_storage_arrays.py (renamed from nova/api/openstack/contrib/virtual_storage_arrays.py)20
-rw-r--r--nova/api/openstack/v2/contrib/volumes.py (renamed from nova/api/openstack/contrib/volumes.py)8
-rw-r--r--nova/api/openstack/v2/contrib/volumetypes.py (renamed from nova/api/openstack/contrib/volumetypes.py)4
-rw-r--r--nova/api/openstack/v2/contrib/zones.py (renamed from nova/api/openstack/contrib/zones.py)4
-rw-r--r--nova/api/openstack/v2/extensions.py (renamed from nova/api/openstack/extensions.py)12
-rw-r--r--nova/api/openstack/v2/flavors.py (renamed from nova/api/openstack/flavors.py)4
-rw-r--r--nova/api/openstack/v2/image_metadata.py (renamed from nova/api/openstack/image_metadata.py)4
-rw-r--r--nova/api/openstack/v2/images.py (renamed from nova/api/openstack/images.py)12
-rw-r--r--nova/api/openstack/v2/ips.py (renamed from nova/api/openstack/ips.py)5
-rw-r--r--nova/api/openstack/v2/limits.py (renamed from nova/api/openstack/limits.py)18
-rw-r--r--nova/api/openstack/v2/ratelimiting/__init__.py (renamed from nova/api/openstack/ratelimiting/__init__.py)5
-rw-r--r--nova/api/openstack/v2/schemas/atom-link.rng (renamed from nova/api/openstack/schemas/atom-link.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/atom.rng (renamed from nova/api/openstack/schemas/atom.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/v1.1/addresses.rng (renamed from nova/api/openstack/schemas/v1.1/addresses.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/v1.1/extension.rng (renamed from nova/api/openstack/schemas/v1.1/extension.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/v1.1/extensions.rng (renamed from nova/api/openstack/schemas/v1.1/extensions.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/v1.1/flavor.rng (renamed from nova/api/openstack/schemas/v1.1/flavor.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/v1.1/flavors.rng (renamed from nova/api/openstack/schemas/v1.1/flavors.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/v1.1/flavors_index.rng (renamed from nova/api/openstack/schemas/v1.1/flavors_index.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/v1.1/image.rng (renamed from nova/api/openstack/schemas/v1.1/image.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/v1.1/images.rng (renamed from nova/api/openstack/schemas/v1.1/images.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/v1.1/images_index.rng (renamed from nova/api/openstack/schemas/v1.1/images_index.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/v1.1/limits.rng (renamed from nova/api/openstack/schemas/v1.1/limits.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/v1.1/metadata.rng (renamed from nova/api/openstack/schemas/v1.1/metadata.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/v1.1/server.rng (renamed from nova/api/openstack/schemas/v1.1/server.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/v1.1/servers.rng (renamed from nova/api/openstack/schemas/v1.1/servers.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/v1.1/servers_index.rng (renamed from nova/api/openstack/schemas/v1.1/servers_index.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/v1.1/version.rng (renamed from nova/api/openstack/schemas/v1.1/version.rng)0
-rw-r--r--nova/api/openstack/v2/schemas/v1.1/versions.rng (renamed from nova/api/openstack/schemas/v1.1/versions.rng)0
-rw-r--r--nova/api/openstack/v2/server_metadata.py (renamed from nova/api/openstack/server_metadata.py)2
-rw-r--r--nova/api/openstack/v2/servers.py (renamed from nova/api/openstack/servers.py)13
-rw-r--r--nova/api/openstack/v2/urlmap.py (renamed from nova/api/openstack/urlmap.py)2
-rw-r--r--nova/api/openstack/v2/users.py (renamed from nova/api/openstack/users.py)8
-rw-r--r--nova/api/openstack/v2/versions.py (renamed from nova/api/openstack/versions.py)7
-rw-r--r--nova/api/openstack/v2/views/__init__.py (renamed from nova/api/openstack/views/__init__.py)0
-rw-r--r--nova/api/openstack/v2/views/addresses.py (renamed from nova/api/openstack/views/addresses.py)2
-rw-r--r--nova/api/openstack/v2/views/flavors.py (renamed from nova/api/openstack/views/flavors.py)1
-rw-r--r--nova/api/openstack/v2/views/images.py (renamed from nova/api/openstack/views/images.py)0
-rw-r--r--nova/api/openstack/v2/views/limits.py (renamed from nova/api/openstack/views/limits.py)0
-rw-r--r--nova/api/openstack/v2/views/servers.py (renamed from nova/api/openstack/views/servers.py)11
-rw-r--r--nova/api/openstack/v2/views/versions.py (renamed from nova/api/openstack/views/versions.py)0
-rw-r--r--nova/api/openstack/v2/zones.py (renamed from nova/api/openstack/zones.py)14
-rw-r--r--nova/api/openstack/wsgi.py107
-rw-r--r--nova/api/openstack/xmlutil.py4
67 files changed, 430 insertions, 472 deletions
diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py
index 07911221d..e69de29bb 100644
--- a/nova/api/openstack/__init__.py
+++ b/nova/api/openstack/__init__.py
@@ -1,187 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# 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.
-
-"""
-WSGI middleware for OpenStack API controllers.
-"""
-
-import routes
-import webob.dec
-import webob.exc
-
-from nova.api.openstack import accounts
-from nova.api.openstack import faults
-from nova.api.openstack import consoles
-from nova.api.openstack import flavors
-from nova.api.openstack import images
-from nova.api.openstack import image_metadata
-from nova.api.openstack import ips
-from nova.api.openstack import limits
-from nova.api.openstack import servers
-from nova.api.openstack import server_metadata
-from nova.api.openstack import users
-from nova.api.openstack import versions
-from nova.api.openstack import wsgi
-from nova.api.openstack import zones
-from nova import flags
-from nova import log as logging
-from nova import wsgi as base_wsgi
-
-
-LOG = logging.getLogger('nova.api.openstack')
-FLAGS = flags.FLAGS
-flags.DEFINE_bool('allow_admin_api',
- False,
- 'When True, this API service will accept admin operations.')
-flags.DEFINE_bool('allow_instance_snapshots',
- True,
- 'When True, this API service will permit instance snapshot operations.')
-
-
-class FaultWrapper(base_wsgi.Middleware):
- """Calls down the middleware stack, making exceptions into faults."""
-
- @webob.dec.wsgify(RequestClass=wsgi.Request)
- def __call__(self, req):
- try:
- return req.get_response(self.application)
- except Exception as ex:
- LOG.exception(_("Caught error: %s"), unicode(ex))
- exc = webob.exc.HTTPInternalServerError()
- return faults.Fault(exc)
-
-
-class APIMapper(routes.Mapper):
- def routematch(self, url=None, environ=None):
- if url is "":
- result = self._match("", environ)
- return result[0], result[1]
- return routes.Mapper.routematch(self, url, environ)
-
-
-class ProjectMapper(APIMapper):
-
- def resource(self, member_name, collection_name, **kwargs):
- if not ('parent_resource' in kwargs):
- kwargs['path_prefix'] = '{project_id}/'
- else:
- parent_resource = kwargs['parent_resource']
- p_collection = parent_resource['collection_name']
- p_member = parent_resource['member_name']
- kwargs['path_prefix'] = '{project_id}/%s/:%s_id' % (p_collection,
- p_member)
- routes.Mapper.resource(self, member_name,
- collection_name,
- **kwargs)
-
-
-class APIRouter(base_wsgi.Router):
- """
- Routes requests on the OpenStack API to the appropriate controller
- and method.
- """
-
- @classmethod
- def factory(cls, global_config, **local_config):
- """Simple paste factory, :class:`nova.wsgi.Router` doesn't have one"""
- return cls()
-
- def __init__(self, ext_mgr=None):
- self.server_members = {}
- mapper = ProjectMapper()
- self._setup_routes(mapper)
- super(APIRouter, self).__init__(mapper)
-
- def _setup_routes(self, mapper):
- server_members = self.server_members
- server_members['action'] = 'POST'
- if FLAGS.allow_admin_api:
- LOG.debug(_("Including admin operations in API."))
-
- server_members['diagnostics'] = 'GET'
- server_members['actions'] = 'GET'
-
- mapper.resource("user", "users",
- controller=users.create_resource(),
- collection={'detail': 'GET'})
-
- mapper.resource("account", "accounts",
- controller=accounts.create_resource(),
- collection={'detail': 'GET'})
-
- mapper.resource("zone", "zones",
- controller=zones.create_resource(),
- collection={'detail': 'GET',
- 'info': 'GET',
- 'select': 'POST'})
-
- mapper.connect("versions", "/",
- controller=versions.create_resource(),
- action='show')
-
- mapper.redirect("", "/")
-
- mapper.resource("console", "consoles",
- controller=consoles.create_resource(),
- parent_resource=dict(member_name='server',
- collection_name='servers'))
-
- mapper.resource("server", "servers",
- controller=servers.create_resource(),
- collection={'detail': 'GET'},
- member=self.server_members)
-
- mapper.resource("ip", "ips", controller=ips.create_resource(),
- parent_resource=dict(member_name='server',
- collection_name='servers'))
-
- mapper.resource("image", "images",
- controller=images.create_resource(),
- collection={'detail': 'GET'})
-
- mapper.resource("limit", "limits",
- controller=limits.create_resource())
-
- mapper.resource("flavor", "flavors",
- controller=flavors.create_resource(),
- collection={'detail': 'GET'})
-
- image_metadata_controller = image_metadata.create_resource()
-
- mapper.resource("image_meta", "metadata",
- controller=image_metadata_controller,
- parent_resource=dict(member_name='image',
- collection_name='images'))
-
- mapper.connect("metadata", "/{project_id}/images/{image_id}/metadata",
- controller=image_metadata_controller,
- action='update_all',
- conditions={"method": ['PUT']})
-
- server_metadata_controller = server_metadata.create_resource()
-
- mapper.resource("server_meta", "metadata",
- controller=server_metadata_controller,
- parent_resource=dict(member_name='server',
- collection_name='servers'))
-
- mapper.connect("metadata",
- "/{project_id}/servers/{server_id}/metadata",
- controller=server_metadata_controller,
- action='update_all',
- conditions={"method": ['PUT']})
diff --git a/nova/api/openstack/faults.py b/nova/api/openstack/faults.py
deleted file mode 100644
index 83381d755..000000000
--- a/nova/api/openstack/faults.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 OpenStack LLC.
-# 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 webob.dec
-import webob.exc
-
-from nova.api.openstack import common
-from nova.api.openstack import wsgi
-
-
-class Fault(webob.exc.HTTPException):
- """Wrap webob.exc.HTTPException to provide API friendly response."""
-
- _fault_names = {
- 400: "badRequest",
- 401: "unauthorized",
- 403: "resizeNotAllowed",
- 404: "itemNotFound",
- 405: "badMethod",
- 409: "inProgress",
- 413: "overLimit",
- 415: "badMediaType",
- 501: "notImplemented",
- 503: "serviceUnavailable"}
-
- def __init__(self, exception):
- """Create a Fault for the given webob.exc.exception."""
- self.wrapped_exc = exception
- self.status_int = exception.status_int
-
- @webob.dec.wsgify(RequestClass=wsgi.Request)
- def __call__(self, req):
- """Generate a WSGI response based on the exception passed to ctor."""
- # Replace the body with fault details.
- code = self.wrapped_exc.status_int
- fault_name = self._fault_names.get(code, "cloudServersFault")
- fault_data = {
- fault_name: {
- 'code': code,
- 'message': self.wrapped_exc.explanation}}
- if code == 413:
- retry = self.wrapped_exc.headers['Retry-After']
- fault_data[fault_name]['retryAfter'] = retry
-
- # 'code' is an attribute on the fault tag itself
- metadata = {'attributes': {fault_name: 'code'}}
-
- xml_serializer = wsgi.XMLDictSerializer(metadata, wsgi.XMLNS_V11)
-
- content_type = req.best_match_content_type()
- serializer = {
- 'application/xml': xml_serializer,
- 'application/json': wsgi.JSONDictSerializer(),
- }[content_type]
-
- self.wrapped_exc.body = serializer.serialize(fault_data)
- self.wrapped_exc.content_type = content_type
-
- return self.wrapped_exc
-
- def __str__(self):
- return self.wrapped_exc.__str__()
-
-
-class OverLimitFault(webob.exc.HTTPException):
- """
- Rate-limited request response.
- """
-
- def __init__(self, message, details, retry_time):
- """
- Initialize new `OverLimitFault` with relevant information.
- """
- self.wrapped_exc = webob.exc.HTTPRequestEntityTooLarge()
- self.content = {
- "overLimitFault": {
- "code": self.wrapped_exc.status_int,
- "message": message,
- "details": details,
- },
- }
-
- @webob.dec.wsgify(RequestClass=wsgi.Request)
- def __call__(self, request):
- """
- Return the wrapped exception with a serialized body conforming to our
- error format.
- """
- content_type = request.best_match_content_type()
- metadata = {"attributes": {"overLimitFault": "code"}}
-
- xml_serializer = wsgi.XMLDictSerializer(metadata, wsgi.XMLNS_V11)
- serializer = {
- 'application/xml': xml_serializer,
- 'application/json': wsgi.JSONDictSerializer(),
- }[content_type]
-
- content = serializer.serialize(self.content)
- self.wrapped_exc.body = content
-
- return self.wrapped_exc
diff --git a/nova/api/openstack/v2/__init__.py b/nova/api/openstack/v2/__init__.py
new file mode 100644
index 000000000..1ea2ba250
--- /dev/null
+++ b/nova/api/openstack/v2/__init__.py
@@ -0,0 +1,186 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# 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.
+
+"""
+WSGI middleware for OpenStack API controllers.
+"""
+
+import routes
+import webob.dec
+import webob.exc
+
+from nova.api.openstack.v2 import accounts
+from nova.api.openstack.v2 import consoles
+from nova.api.openstack.v2 import flavors
+from nova.api.openstack.v2 import images
+from nova.api.openstack.v2 import image_metadata
+from nova.api.openstack.v2 import ips
+from nova.api.openstack.v2 import limits
+from nova.api.openstack.v2 import servers
+from nova.api.openstack.v2 import server_metadata
+from nova.api.openstack.v2 import users
+from nova.api.openstack.v2 import versions
+from nova.api.openstack.v2 import zones
+from nova.api.openstack import wsgi
+from nova import flags
+from nova import log as logging
+from nova import wsgi as base_wsgi
+
+
+LOG = logging.getLogger('nova.api.openstack.v2')
+FLAGS = flags.FLAGS
+flags.DEFINE_bool('allow_admin_api',
+ False,
+ 'When True, this API service will accept admin operations.')
+flags.DEFINE_bool('allow_instance_snapshots',
+ True,
+ 'When True, this API service will permit instance snapshot operations.')
+
+
+class FaultWrapper(base_wsgi.Middleware):
+ """Calls down the middleware stack, making exceptions into faults."""
+
+ @webob.dec.wsgify(RequestClass=wsgi.Request)
+ def __call__(self, req):
+ try:
+ return req.get_response(self.application)
+ except Exception as ex:
+ LOG.exception(_("Caught error: %s"), unicode(ex))
+ exc = webob.exc.HTTPInternalServerError()
+ return wsgi.Fault(exc)
+
+
+class APIMapper(routes.Mapper):
+ def routematch(self, url=None, environ=None):
+ if url is "":
+ result = self._match("", environ)
+ return result[0], result[1]
+ return routes.Mapper.routematch(self, url, environ)
+
+
+class ProjectMapper(APIMapper):
+
+ def resource(self, member_name, collection_name, **kwargs):
+ if not ('parent_resource' in kwargs):
+ kwargs['path_prefix'] = '{project_id}/'
+ else:
+ parent_resource = kwargs['parent_resource']
+ p_collection = parent_resource['collection_name']
+ p_member = parent_resource['member_name']
+ kwargs['path_prefix'] = '{project_id}/%s/:%s_id' % (p_collection,
+ p_member)
+ routes.Mapper.resource(self, member_name,
+ collection_name,
+ **kwargs)
+
+
+class APIRouter(base_wsgi.Router):
+ """
+ Routes requests on the OpenStack API to the appropriate controller
+ and method.
+ """
+
+ @classmethod
+ def factory(cls, global_config, **local_config):
+ """Simple paste factory, :class:`nova.wsgi.Router` doesn't have one"""
+ return cls()
+
+ def __init__(self, ext_mgr=None):
+ self.server_members = {}
+ mapper = ProjectMapper()
+ self._setup_routes(mapper)
+ super(APIRouter, self).__init__(mapper)
+
+ def _setup_routes(self, mapper):
+ server_members = self.server_members
+ server_members['action'] = 'POST'
+ if FLAGS.allow_admin_api:
+ LOG.debug(_("Including admin operations in API."))
+
+ server_members['diagnostics'] = 'GET'
+ server_members['actions'] = 'GET'
+
+ mapper.resource("user", "users",
+ controller=users.create_resource(),
+ collection={'detail': 'GET'})
+
+ mapper.resource("account", "accounts",
+ controller=accounts.create_resource(),
+ collection={'detail': 'GET'})
+
+ mapper.resource("zone", "zones",
+ controller=zones.create_resource(),
+ collection={'detail': 'GET',
+ 'info': 'GET',
+ 'select': 'POST'})
+
+ mapper.connect("versions", "/",
+ controller=versions.create_resource(),
+ action='show')
+
+ mapper.redirect("", "/")
+
+ mapper.resource("console", "consoles",
+ controller=consoles.create_resource(),
+ parent_resource=dict(member_name='server',
+ collection_name='servers'))
+
+ mapper.resource("server", "servers",
+ controller=servers.create_resource(),
+ collection={'detail': 'GET'},
+ member=self.server_members)
+
+ mapper.resource("ip", "ips", controller=ips.create_resource(),
+ parent_resource=dict(member_name='server',
+ collection_name='servers'))
+
+ mapper.resource("image", "images",
+ controller=images.create_resource(),
+ collection={'detail': 'GET'})
+
+ mapper.resource("limit", "limits",
+ controller=limits.create_resource())
+
+ mapper.resource("flavor", "flavors",
+ controller=flavors.create_resource(),
+ collection={'detail': 'GET'})
+
+ image_metadata_controller = image_metadata.create_resource()
+
+ mapper.resource("image_meta", "metadata",
+ controller=image_metadata_controller,
+ parent_resource=dict(member_name='image',
+ collection_name='images'))
+
+ mapper.connect("metadata", "/{project_id}/images/{image_id}/metadata",
+ controller=image_metadata_controller,
+ action='update_all',
+ conditions={"method": ['PUT']})
+
+ server_metadata_controller = server_metadata.create_resource()
+
+ mapper.resource("server_meta", "metadata",
+ controller=server_metadata_controller,
+ parent_resource=dict(member_name='server',
+ collection_name='servers'))
+
+ mapper.connect("metadata",
+ "/{project_id}/servers/{server_id}/metadata",
+ controller=server_metadata_controller,
+ action='update_all',
+ conditions={"method": ['PUT']})
diff --git a/nova/api/openstack/accounts.py b/nova/api/openstack/v2/accounts.py
index 3a19d5c89..0f1584261 100644
--- a/nova/api/openstack/accounts.py
+++ b/nova/api/openstack/v2/accounts.py
@@ -15,18 +15,16 @@
import webob.exc
+from nova.api.openstack import wsgi
+from nova.api.openstack import xmlutil
+from nova.auth import manager
from nova import exception
from nova import flags
from nova import log as logging
-from nova.auth import manager
-from nova.api.openstack import faults
-from nova.api.openstack import wsgi
-from nova.api.openstack import xmlutil
-
FLAGS = flags.FLAGS
-LOG = logging.getLogger('nova.api.openstack')
+LOG = logging.getLogger('nova.api.openstack.v2.accounts')
def _translate_keys(account):
diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/v2/auth.py
index d435f8318..c0ea30671 100644
--- a/nova/api/openstack/auth.py
+++ b/nova/api/openstack/v2/auth.py
@@ -19,25 +19,25 @@ import hashlib
import os
import time
-import webob.exc
import webob.dec
+import webob.exc
+from nova.api.openstack import common
+from nova.api.openstack import wsgi
from nova import auth
from nova import context
from nova import exception
from nova import flags
from nova import log as logging
from nova import utils
-from nova import wsgi
-from nova.api.openstack import common
-from nova.api.openstack import faults
+from nova import wsgi as base_wsgi
-LOG = logging.getLogger('nova.api.openstack')
+LOG = logging.getLogger('nova.api.openstack.v2.auth')
FLAGS = flags.FLAGS
flags.DECLARE('use_forwarded_for', 'nova.api.auth')
-class NoAuthMiddleware(wsgi.Middleware):
+class NoAuthMiddleware(base_wsgi.Middleware):
"""Return a fake token if one isn't specified."""
@webob.dec.wsgify(RequestClass=wsgi.Request)
@@ -73,7 +73,7 @@ class NoAuthMiddleware(wsgi.Middleware):
return self.application
-class AuthMiddleware(wsgi.Middleware):
+class AuthMiddleware(base_wsgi.Middleware):
"""Authorize the openstack API request or return an HTTP Forbidden."""
def __init__(self, application, db_driver=None):
@@ -92,12 +92,12 @@ class AuthMiddleware(wsgi.Middleware):
token = req.headers["X-Auth-Token"]
msg = _("%(user_id)s could not be found with token '%(token)s'")
LOG.warn(msg % locals())
- return faults.Fault(webob.exc.HTTPUnauthorized())
+ return wsgi.Fault(webob.exc.HTTPUnauthorized())
# Get all valid projects for the user
projects = self.auth.get_projects(user_id)
if not projects:
- return faults.Fault(webob.exc.HTTPUnauthorized())
+ return wsgi.Fault(webob.exc.HTTPUnauthorized())
project_id = ""
path_parts = req.path.split('/')
@@ -110,9 +110,9 @@ class AuthMiddleware(wsgi.Middleware):
try:
project = self.auth.get_project(project_id)
except exception.ProjectNotFound:
- return faults.Fault(webob.exc.HTTPUnauthorized())
+ return wsgi.Fault(webob.exc.HTTPUnauthorized())
if project_id not in [p.id for p in projects]:
- return faults.Fault(webob.exc.HTTPUnauthorized())
+ return wsgi.Fault(webob.exc.HTTPUnauthorized())
else:
# As a fallback, set project_id from the headers, which is the v1.0
# behavior. As a last resort, be forgiving to the user and set
@@ -137,7 +137,7 @@ class AuthMiddleware(wsgi.Middleware):
msg = _("%(user_id)s must be an admin or a "
"member of %(project_id)s")
LOG.warn(msg % locals())
- return faults.Fault(webob.exc.HTTPUnauthorized())
+ return wsgi.Fault(webob.exc.HTTPUnauthorized())
return self.application
@@ -155,7 +155,7 @@ class AuthMiddleware(wsgi.Middleware):
msg = _("Authentication requests must be made against a version "
"root (e.g. /v1.0 or /v1.1).")
LOG.warn(msg)
- return faults.Fault(webob.exc.HTTPUnauthorized(explanation=msg))
+ return wsgi.Fault(webob.exc.HTTPUnauthorized(explanation=msg))
def _get_auth_header(key):
"""Ensures that the KeyError returned is meaningful."""
@@ -169,7 +169,7 @@ class AuthMiddleware(wsgi.Middleware):
except KeyError as ex:
msg = _("Could not find %s in request.") % ex
LOG.warn(msg)
- return faults.Fault(webob.exc.HTTPUnauthorized(explanation=msg))
+ return wsgi.Fault(webob.exc.HTTPUnauthorized(explanation=msg))
token, user = self._authorize_user(username, key, req)
if user and token:
@@ -184,7 +184,7 @@ class AuthMiddleware(wsgi.Middleware):
LOG.debug(_("Successfully authenticated '%s'") % username)
return res
else:
- return faults.Fault(webob.exc.HTTPUnauthorized())
+ return wsgi.Fault(webob.exc.HTTPUnauthorized())
def authorize_token(self, token_hash):
""" retrieves user information from the datastore given a token
diff --git a/nova/api/openstack/consoles.py b/nova/api/openstack/v2/consoles.py
index 7d8c0523e..ad0d8cbb4 100644
--- a/nova/api/openstack/consoles.py
+++ b/nova/api/openstack/v2/consoles.py
@@ -15,13 +15,13 @@
# License for the specific language governing permissions and limitations
# under the License.
-from webob import exc
import webob
+from webob import exc
-from nova import console
-from nova import exception
from nova.api.openstack import wsgi
from nova.api.openstack import xmlutil
+from nova import console
+from nova import exception
def _translate_keys(cons):
diff --git a/nova/api/openstack/contrib/__init__.py b/nova/api/openstack/v2/contrib/__init__.py
index b3d4df69b..d361dac9c 100644
--- a/nova/api/openstack/contrib/__init__.py
+++ b/nova/api/openstack/v2/contrib/__init__.py
@@ -28,7 +28,7 @@ from nova import log as logging
from nova import utils
-LOG = logging.getLogger('nova.api.openstack.contrib')
+LOG = logging.getLogger('nova.api.openstack.v2.contrib')
def standard_extensions(ext_mgr):
diff --git a/nova/api/openstack/contrib/admin_actions.py b/nova/api/openstack/v2/contrib/admin_actions.py
index 81b23a8a0..632a8dc0e 100644
--- a/nova/api/openstack/contrib/admin_actions.py
+++ b/nova/api/openstack/v2/contrib/admin_actions.py
@@ -19,16 +19,16 @@ import traceback
import webob
from webob import exc
+from nova.api.openstack.v2 import extensions
from nova import compute
from nova import exception
from nova import flags
from nova import log as logging
-from nova.api.openstack import extensions
from nova.scheduler import api as scheduler_api
FLAGS = flags.FLAGS
-LOG = logging.getLogger("nova.api.openstack.contrib.admin_actions")
+LOG = logging.getLogger("nova.api.openstack.v2.contrib.admin_actions")
class Admin_actions(extensions.ExtensionDescriptor):
diff --git a/nova/api/openstack/contrib/createserverext.py b/nova/api/openstack/v2/contrib/createserverext.py
index 4e6556f5d..a207d1bc5 100644
--- a/nova/api/openstack/contrib/createserverext.py
+++ b/nova/api/openstack/v2/contrib/createserverext.py
@@ -14,9 +14,9 @@
# License for the specific language governing permissions and limitations
# under the License
-from nova.api.openstack import extensions
-from nova.api.openstack import servers
-from nova.api.openstack import views
+from nova.api.openstack.v2 import extensions
+from nova.api.openstack.v2 import servers
+from nova.api.openstack.v2 import views
from nova.api.openstack import wsgi
diff --git a/nova/api/openstack/contrib/deferred_delete.py b/nova/api/openstack/v2/contrib/deferred_delete.py
index 8415ca4b3..95eb8f42c 100644
--- a/nova/api/openstack/contrib/deferred_delete.py
+++ b/nova/api/openstack/v2/contrib/deferred_delete.py
@@ -17,13 +17,13 @@
import webob
+from nova.api.openstack.v2 import extensions
+from nova.api.openstack.v2 import servers
from nova import compute
from nova import log as logging
-from nova.api.openstack import extensions
-from nova.api.openstack import servers
-LOG = logging.getLogger("nova.api.contrib.deferred-delete")
+LOG = logging.getLogger("nova.api.openstack.v2.contrib.deferred-delete")
class Deferred_delete(extensions.ExtensionDescriptor):
diff --git a/nova/api/openstack/contrib/disk_config.py b/nova/api/openstack/v2/contrib/disk_config.py
index 20da999a7..6e26c1daa 100644
--- a/nova/api/openstack/contrib/disk_config.py
+++ b/nova/api/openstack/v2/contrib/disk_config.py
@@ -16,11 +16,11 @@
"""Disk Config extension."""
-from webob import exc
from xml.dom import minidom
-from nova.api.openstack import extensions
-from nova.api.openstack import servers
+from webob import exc
+
+from nova.api.openstack.v2 import extensions
from nova.api.openstack import xmlutil
from nova import compute
from nova import log as logging
diff --git a/nova/api/openstack/contrib/extended_status.py b/nova/api/openstack/v2/contrib/extended_status.py
index 625f3ab2b..5e0a69780 100644
--- a/nova/api/openstack/contrib/extended_status.py
+++ b/nova/api/openstack/v2/contrib/extended_status.py
@@ -19,17 +19,16 @@ import traceback
import webob
from webob import exc
+from nova.api.openstack.v2 import extensions
+from nova.api.openstack import xmlutil
from nova import compute
from nova import exception
from nova import flags
from nova import log as logging
-from nova.api.openstack import extensions
-from nova.api.openstack import faults
-from nova.api.openstack import xmlutil
FLAGS = flags.FLAGS
-LOG = logging.getLogger("nova.api.openstack.contrib.extendedstatus")
+LOG = logging.getLogger("nova.api.openstack.v2.contrib.extendedstatus")
class Extended_status(extensions.ExtensionDescriptor):
diff --git a/nova/api/openstack/contrib/flavorextradata.py b/nova/api/openstack/v2/contrib/flavorextradata.py
index f696d161b..0b0938054 100644
--- a/nova/api/openstack/contrib/flavorextradata.py
+++ b/nova/api/openstack/v2/contrib/flavorextradata.py
@@ -1,3 +1,5 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
# Copyright 2011 Canonical Ltd.
# All Rights Reserved.
#
@@ -22,7 +24,7 @@ attributes. This extension adds to that list:
swap
"""
-from nova.api.openstack import extensions
+from nova.api.openstack.v2 import extensions
class Flavorextradata(extensions.ExtensionDescriptor):
@@ -32,5 +34,3 @@ class Flavorextradata(extensions.ExtensionDescriptor):
alias = "os-flavor-extra-data"
namespace = "http://docs.openstack.org/ext/flavor_extra_data/api/v1.1"
updated = "2011-09-14T00:00:00+00:00"
-
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
diff --git a/nova/api/openstack/contrib/flavorextraspecs.py b/nova/api/openstack/v2/contrib/flavorextraspecs.py
index d71e9cf8b..bb38ea64e 100644
--- a/nova/api/openstack/contrib/flavorextraspecs.py
+++ b/nova/api/openstack/v2/contrib/flavorextraspecs.py
@@ -19,10 +19,9 @@
from webob import exc
+from nova.api.openstack.v2 import extensions
from nova import db
from nova import exception
-from nova.api.openstack import extensions
-from nova.api.openstack import wsgi
class FlavorExtraSpecsController(object):
diff --git a/nova/api/openstack/contrib/floating_ips.py b/nova/api/openstack/v2/contrib/floating_ips.py
index b64251e53..9689eac48 100644
--- a/nova/api/openstack/contrib/floating_ips.py
+++ b/nova/api/openstack/v2/contrib/floating_ips.py
@@ -15,17 +15,18 @@
# 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 webob
+from nova.api.openstack.v2 import extensions
from nova import compute
from nova import exception
from nova import log as logging
from nova import network
from nova import rpc
-from nova.api.openstack import extensions
-LOG = logging.getLogger('nova.api.openstack.contrib.floating_ips')
+LOG = logging.getLogger('nova.api.openstack.v2.contrib.floating_ips')
def _translate_floating_ip_view(floating_ip):
diff --git a/nova/api/openstack/contrib/hosts.py b/nova/api/openstack/v2/contrib/hosts.py
index 736843c3d..eb5074520 100644
--- a/nova/api/openstack/contrib/hosts.py
+++ b/nova/api/openstack/v2/contrib/hosts.py
@@ -17,17 +17,16 @@
import webob.exc
+from nova.api.openstack import common
+from nova.api.openstack.v2 import extensions
from nova import compute
from nova import exception
from nova import flags
from nova import log as logging
-from nova.api.openstack import common
-from nova.api.openstack import extensions
-from nova.api.openstack import faults
from nova.scheduler import api as scheduler_api
-LOG = logging.getLogger("nova.api.hosts")
+LOG = logging.getLogger("nova.api.openstack.v2.contrib.hosts")
FLAGS = flags.FLAGS
diff --git a/nova/api/openstack/contrib/keypairs.py b/nova/api/openstack/v2/contrib/keypairs.py
index ee5cad530..e57d40001 100644
--- a/nova/api/openstack/contrib/keypairs.py
+++ b/nova/api/openstack/v2/contrib/keypairs.py
@@ -24,10 +24,10 @@ import tempfile
import webob
from webob import exc
+from nova.api.openstack.v2 import extensions
from nova import crypto
from nova import db
from nova import exception
-from nova.api.openstack import extensions
class KeypairController(object):
diff --git a/nova/api/openstack/contrib/multinic.py b/nova/api/openstack/v2/contrib/multinic.py
index 26968646d..561e246b5 100644
--- a/nova/api/openstack/contrib/multinic.py
+++ b/nova/api/openstack/v2/contrib/multinic.py
@@ -18,13 +18,13 @@
import webob
from webob import exc
-from nova.api.openstack import extensions
+from nova.api.openstack.v2 import extensions
from nova import compute
from nova import exception
from nova import log as logging
-LOG = logging.getLogger("nova.api.multinic")
+LOG = logging.getLogger("nova.api.openstack.v2.contrib.multinic")
# Note: The class name is as it has to be for this to be loaded as an
diff --git a/nova/api/openstack/contrib/quotas.py b/nova/api/openstack/v2/contrib/quotas.py
index 184b4d12f..7ad426c44 100644
--- a/nova/api/openstack/contrib/quotas.py
+++ b/nova/api/openstack/v2/contrib/quotas.py
@@ -17,10 +17,10 @@
import webob
+from nova.api.openstack.v2 import extensions
from nova import db
from nova import exception
from nova import quota
-from nova.api.openstack import extensions
class QuotaSetsController(object):
diff --git a/nova/api/openstack/contrib/rescue.py b/nova/api/openstack/v2/contrib/rescue.py
index d3f38b200..b63bf9ec5 100644
--- a/nova/api/openstack/contrib/rescue.py
+++ b/nova/api/openstack/v2/contrib/rescue.py
@@ -17,8 +17,7 @@
import webob
from webob import exc
-from nova.api.openstack import extensions as exts
-from nova.api.openstack import faults
+from nova.api.openstack.v2 import extensions as exts
from nova import compute
from nova import exception
from nova import flags
@@ -27,7 +26,7 @@ from nova import utils
FLAGS = flags.FLAGS
-LOG = logging.getLogger("nova.api.contrib.rescue")
+LOG = logging.getLogger("nova.api.openstack.v2.contrib.rescue")
class Rescue(exts.ExtensionDescriptor):
diff --git a/nova/api/openstack/contrib/security_groups.py b/nova/api/openstack/v2/contrib/security_groups.py
index fd1187629..50f129bd6 100644
--- a/nova/api/openstack/contrib/security_groups.py
+++ b/nova/api/openstack/v2/contrib/security_groups.py
@@ -16,25 +16,23 @@
"""The security groups extension."""
import urllib
+from xml.dom import minidom
+
from webob import exc
import webob
+from nova.api.openstack import common
+from nova.api.openstack.v2 import extensions
+from nova.api.openstack import wsgi
from nova import compute
from nova import db
from nova import exception
from nova import flags
from nova import log as logging
-from nova import rpc
from nova import utils
-from nova.api.openstack import common
-from nova.api.openstack import extensions
-from nova.api.openstack import wsgi
-from nova.compute import power_state
-
-from xml.dom import minidom
-LOG = logging.getLogger("nova.api.contrib.security_groups")
+LOG = logging.getLogger("nova.api.openstack.v2.contrib.security_groups")
FLAGS = flags.FLAGS
diff --git a/nova/api/openstack/contrib/simple_tenant_usage.py b/nova/api/openstack/v2/contrib/simple_tenant_usage.py
index 3399ac2be..e896371ed 100644
--- a/nova/api/openstack/contrib/simple_tenant_usage.py
+++ b/nova/api/openstack/v2/contrib/simple_tenant_usage.py
@@ -15,17 +15,18 @@
# License for the specific language governing permissions and limitations
# under the License.
+from datetime import datetime
import urlparse
+
import webob
+from webob import exc
-from datetime import datetime
-from nova import exception
-from nova import flags
+from nova.api.openstack.v2 import extensions
+from nova.api.openstack.v2 import views
from nova.compute import api
-from nova.api.openstack import extensions
-from nova.api.openstack import views
from nova.db.sqlalchemy.session import get_session
-from webob import exc
+from nova import exception
+from nova import flags
FLAGS = flags.FLAGS
diff --git a/nova/api/openstack/contrib/virtual_interfaces.py b/nova/api/openstack/v2/contrib/virtual_interfaces.py
index 0afd2119d..1975a8dc0 100644
--- a/nova/api/openstack/contrib/virtual_interfaces.py
+++ b/nova/api/openstack/v2/contrib/virtual_interfaces.py
@@ -15,14 +15,14 @@
"""The virtual interfaces extension."""
-from nova import log as logging
-from nova import network
from nova.api.openstack import common
-from nova.api.openstack import extensions
+from nova.api.openstack.v2 import extensions
from nova.api.openstack import wsgi
+from nova import log as logging
+from nova import network
-LOG = logging.getLogger("nova.api.virtual_interfaces")
+LOG = logging.getLogger("nova.api.openstack.v2.contrib.virtual_interfaces")
def _translate_vif_summary_view(_context, vif):
diff --git a/nova/api/openstack/contrib/virtual_storage_arrays.py b/nova/api/openstack/v2/contrib/virtual_storage_arrays.py
index a6bf72960..f3a7831d5 100644
--- a/nova/api/openstack/contrib/virtual_storage_arrays.py
+++ b/nova/api/openstack/v2/contrib/virtual_storage_arrays.py
@@ -21,25 +21,25 @@
import webob
from webob import exc
-from nova import vsa
-from nova import volume
+from nova.api.openstack import common
+from nova.api.openstack.v2.contrib import volumes
+from nova.api.openstack.v2 import extensions
+from nova.api.openstack.v2 import servers
+from nova.api.openstack import wsgi
from nova import compute
+from nova.compute import instance_types
from nova import network
from nova import db
from nova import quota
from nova import exception
+from nova import flags
from nova import log as logging
-from nova.api.openstack import common
-from nova.api.openstack import extensions
-from nova.api.openstack import wsgi
-from nova.api.openstack import servers
-from nova.api.openstack.contrib import volumes
-from nova.compute import instance_types
+from nova import vsa
+from nova import volume
-from nova import flags
FLAGS = flags.FLAGS
-LOG = logging.getLogger("nova.api.vsa")
+LOG = logging.getLogger("nova.api.openstack.v2.contrib.vsa")
def _vsa_view(context, vsa, details=False, instances=None):
diff --git a/nova/api/openstack/contrib/volumes.py b/nova/api/openstack/v2/contrib/volumes.py
index 917cfc61b..5d86282f2 100644
--- a/nova/api/openstack/contrib/volumes.py
+++ b/nova/api/openstack/v2/contrib/volumes.py
@@ -18,6 +18,9 @@
from webob import exc
import webob
+from nova.api.openstack import common
+from nova.api.openstack.v2 import extensions
+from nova.api.openstack.v2 import servers
from nova import compute
from nova import db
from nova import exception
@@ -26,12 +29,9 @@ from nova import log as logging
from nova import quota
from nova import volume
from nova.volume import volume_types
-from nova.api.openstack import common
-from nova.api.openstack import extensions
-from nova.api.openstack import servers
-LOG = logging.getLogger("nova.api.volumes")
+LOG = logging.getLogger("nova.api.openstack.v2.contrib.volumes")
FLAGS = flags.FLAGS
diff --git a/nova/api/openstack/contrib/volumetypes.py b/nova/api/openstack/v2/contrib/volumetypes.py
index 64a9e0f02..ca3866c99 100644
--- a/nova/api/openstack/contrib/volumetypes.py
+++ b/nova/api/openstack/v2/contrib/volumetypes.py
@@ -19,11 +19,11 @@
from webob import exc
+from nova.api.openstack.v2 import extensions
+from nova.api.openstack import wsgi
from nova import db
from nova import exception
from nova.volume import volume_types
-from nova.api.openstack import extensions
-from nova.api.openstack import wsgi
class VolumeTypesController(object):
diff --git a/nova/api/openstack/contrib/zones.py b/nova/api/openstack/v2/contrib/zones.py
index 628b8182f..76a235713 100644
--- a/nova/api/openstack/contrib/zones.py
+++ b/nova/api/openstack/v2/contrib/zones.py
@@ -20,10 +20,10 @@
from nova import flags
from nova import log as logging
-from nova.api.openstack import extensions
+from nova.api.openstack.v2 import extensions
-LOG = logging.getLogger("nova.api.zones")
+LOG = logging.getLogger("nova.api.openstack.v2.contrib.zones")
FLAGS = flags.FLAGS
diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/v2/extensions.py
index 7da10513e..a5cf863ed 100644
--- a/nova/api/openstack/extensions.py
+++ b/nova/api/openstack/v2/extensions.py
@@ -27,18 +27,18 @@ import routes
import webob.dec
import webob.exc
+import nova.api.openstack.v2
+from nova.api.openstack import common
+from nova.api.openstack import wsgi
+from nova.api.openstack import xmlutil
from nova import exception
from nova import flags
from nova import log as logging
from nova import utils
from nova import wsgi as base_wsgi
-import nova.api.openstack
-from nova.api.openstack import common
-from nova.api.openstack import wsgi
-from nova.api.openstack import xmlutil
-LOG = logging.getLogger('nova.api.openstack.extensions')
+LOG = logging.getLogger('nova.api.openstack.v2.extensions')
FLAGS = flags.FLAGS
@@ -273,7 +273,7 @@ class ExtensionMiddleware(base_wsgi.Middleware):
ext_mgr = ExtensionManager()
self.ext_mgr = ext_mgr
- mapper = nova.api.openstack.ProjectMapper()
+ mapper = nova.api.openstack.v2.ProjectMapper()
serializer = wsgi.ResponseSerializer(
{'application/xml': ExtensionsXMLSerializer()})
diff --git a/nova/api/openstack/flavors.py b/nova/api/openstack/v2/flavors.py
index 7680ef1ca..d5b673c7f 100644
--- a/nova/api/openstack/flavors.py
+++ b/nova/api/openstack/v2/flavors.py
@@ -15,10 +15,10 @@
# License for the specific language governing permissions and limitations
# under the License.
-import webob
from lxml import etree
+import webob
-from nova.api.openstack.views import flavors as flavors_view
+from nova.api.openstack.v2.views import flavors as flavors_view
from nova.api.openstack import wsgi
from nova.api.openstack import xmlutil
from nova.compute import instance_types
diff --git a/nova/api/openstack/image_metadata.py b/nova/api/openstack/v2/image_metadata.py
index adb6bee4b..e3cfac4e0 100644
--- a/nova/api/openstack/image_metadata.py
+++ b/nova/api/openstack/v2/image_metadata.py
@@ -17,12 +17,12 @@
from webob import exc
+from nova.api.openstack import common
+from nova.api.openstack import wsgi
from nova import exception
from nova import flags
from nova import image
from nova import utils
-from nova.api.openstack import common
-from nova.api.openstack import wsgi
FLAGS = flags.FLAGS
diff --git a/nova/api/openstack/images.py b/nova/api/openstack/v2/images.py
index f3ef63b49..84b7b17db 100644
--- a/nova/api/openstack/images.py
+++ b/nova/api/openstack/v2/images.py
@@ -18,20 +18,18 @@ import os.path
from lxml import etree
import webob.exc
+from nova.api.openstack import common
+from nova.api.openstack.v2.views import images as views_images
+from nova.api.openstack import wsgi
+from nova.api.openstack import xmlutil
from nova import compute
from nova import exception
from nova import flags
import nova.image
from nova import log
-from nova.api.openstack import common
-from nova.api.openstack import image_metadata
-from nova.api.openstack import servers
-from nova.api.openstack import wsgi
-from nova.api.openstack import xmlutil
-from nova.api.openstack.views import images as views_images
-LOG = log.getLogger('nova.api.openstack.images')
+LOG = log.getLogger('nova.api.openstack.v2.images')
FLAGS = flags.FLAGS
SUPPORTED_FILTERS = {
diff --git a/nova/api/openstack/ips.py b/nova/api/openstack/v2/ips.py
index 2bef453a2..705754665 100644
--- a/nova/api/openstack/ips.py
+++ b/nova/api/openstack/v2/ips.py
@@ -16,19 +16,18 @@
# under the License.
from lxml import etree
-
from webob import exc
import nova
from nova.api.openstack import common
+from nova.api.openstack.v2.views import addresses as view_addresses
from nova.api.openstack import wsgi
from nova.api.openstack import xmlutil
-from nova.api.openstack.views import addresses as view_addresses
from nova import log as logging
from nova import flags
-LOG = logging.getLogger('nova.api.openstack.ips')
+LOG = logging.getLogger('nova.api.openstack.v2.ips')
FLAGS = flags.FLAGS
diff --git a/nova/api/openstack/limits.py b/nova/api/openstack/v2/limits.py
index 56e839526..04ff9e647 100644
--- a/nova/api/openstack/limits.py
+++ b/nova/api/openstack/v2/limits.py
@@ -17,28 +17,26 @@
Module dedicated functions/classes dealing with rate limiting requests.
"""
+from collections import defaultdict
import copy
import httplib
import json
-from lxml import etree
import math
import re
import time
import urllib
-import webob.exc
-
-from collections import defaultdict
+from lxml import etree
from webob.dec import wsgify
+import webob.exc
-from nova import quota
-from nova import utils
-from nova import wsgi as base_wsgi
from nova.api.openstack import common
-from nova.api.openstack import faults
-from nova.api.openstack.views import limits as limits_views
+from nova.api.openstack.v2.views import limits as limits_views
from nova.api.openstack import wsgi
from nova.api.openstack import xmlutil
+from nova import quota
+from nova import utils
+from nova import wsgi as base_wsgi
# Convenience constants for the limits dictionary passed to Limiter().
@@ -275,7 +273,7 @@ class RateLimitingMiddleware(base_wsgi.Middleware):
if delay:
msg = _("This request was rate-limited.")
retry = time.time() + delay
- return faults.OverLimitFault(msg, error, retry)
+ return wsgi.OverLimitFault(msg, error, retry)
req.environ["nova.limits"] = self._limiter.get_limits(username)
diff --git a/nova/api/openstack/ratelimiting/__init__.py b/nova/api/openstack/v2/ratelimiting/__init__.py
index 9ede548c2..78dc465a7 100644
--- a/nova/api/openstack/ratelimiting/__init__.py
+++ b/nova/api/openstack/v2/ratelimiting/__init__.py
@@ -20,11 +20,12 @@
import httplib
import time
import urllib
+
import webob.dec
import webob.exc
from nova import wsgi
-from nova.api.openstack import faults
+from nova.api.openstack import wsgi as os_wsgi
# Convenience constants for the limits dictionary passed to Limiter().
PER_SECOND = 1
@@ -83,7 +84,7 @@ class RateLimitingMiddleware(wsgi.Middleware):
exc = webob.exc.HTTPRequestEntityTooLarge(
explanation=('Too many requests.'),
headers={'Retry-After': time.time() + delay})
- raise faults.Fault(exc)
+ raise os_wsgi.Fault(exc)
return application
def get_delay(self, action_name, username):
diff --git a/nova/api/openstack/schemas/atom-link.rng b/nova/api/openstack/v2/schemas/atom-link.rng
index edba5eee6..edba5eee6 100644
--- a/nova/api/openstack/schemas/atom-link.rng
+++ b/nova/api/openstack/v2/schemas/atom-link.rng
diff --git a/nova/api/openstack/schemas/atom.rng b/nova/api/openstack/v2/schemas/atom.rng
index c2df4e410..c2df4e410 100644
--- a/nova/api/openstack/schemas/atom.rng
+++ b/nova/api/openstack/v2/schemas/atom.rng
diff --git a/nova/api/openstack/schemas/v1.1/addresses.rng b/nova/api/openstack/v2/schemas/v1.1/addresses.rng
index b498e8a63..b498e8a63 100644
--- a/nova/api/openstack/schemas/v1.1/addresses.rng
+++ b/nova/api/openstack/v2/schemas/v1.1/addresses.rng
diff --git a/nova/api/openstack/schemas/v1.1/extension.rng b/nova/api/openstack/v2/schemas/v1.1/extension.rng
index 336659755..336659755 100644
--- a/nova/api/openstack/schemas/v1.1/extension.rng
+++ b/nova/api/openstack/v2/schemas/v1.1/extension.rng
diff --git a/nova/api/openstack/schemas/v1.1/extensions.rng b/nova/api/openstack/v2/schemas/v1.1/extensions.rng
index 4d8bff646..4d8bff646 100644
--- a/nova/api/openstack/schemas/v1.1/extensions.rng
+++ b/nova/api/openstack/v2/schemas/v1.1/extensions.rng
diff --git a/nova/api/openstack/schemas/v1.1/flavor.rng b/nova/api/openstack/v2/schemas/v1.1/flavor.rng
index 6d3adc8dc..6d3adc8dc 100644
--- a/nova/api/openstack/schemas/v1.1/flavor.rng
+++ b/nova/api/openstack/v2/schemas/v1.1/flavor.rng
diff --git a/nova/api/openstack/schemas/v1.1/flavors.rng b/nova/api/openstack/v2/schemas/v1.1/flavors.rng
index b7a3acc01..b7a3acc01 100644
--- a/nova/api/openstack/schemas/v1.1/flavors.rng
+++ b/nova/api/openstack/v2/schemas/v1.1/flavors.rng
diff --git a/nova/api/openstack/schemas/v1.1/flavors_index.rng b/nova/api/openstack/v2/schemas/v1.1/flavors_index.rng
index d1a4fedb1..d1a4fedb1 100644
--- a/nova/api/openstack/schemas/v1.1/flavors_index.rng
+++ b/nova/api/openstack/v2/schemas/v1.1/flavors_index.rng
diff --git a/nova/api/openstack/schemas/v1.1/image.rng b/nova/api/openstack/v2/schemas/v1.1/image.rng
index 505081fba..505081fba 100644
--- a/nova/api/openstack/schemas/v1.1/image.rng
+++ b/nova/api/openstack/v2/schemas/v1.1/image.rng
diff --git a/nova/api/openstack/schemas/v1.1/images.rng b/nova/api/openstack/v2/schemas/v1.1/images.rng
index 064d4d9cc..064d4d9cc 100644
--- a/nova/api/openstack/schemas/v1.1/images.rng
+++ b/nova/api/openstack/v2/schemas/v1.1/images.rng
diff --git a/nova/api/openstack/schemas/v1.1/images_index.rng b/nova/api/openstack/v2/schemas/v1.1/images_index.rng
index 3db0b2672..3db0b2672 100644
--- a/nova/api/openstack/schemas/v1.1/images_index.rng
+++ b/nova/api/openstack/v2/schemas/v1.1/images_index.rng
diff --git a/nova/api/openstack/schemas/v1.1/limits.rng b/nova/api/openstack/v2/schemas/v1.1/limits.rng
index 1af8108ec..1af8108ec 100644
--- a/nova/api/openstack/schemas/v1.1/limits.rng
+++ b/nova/api/openstack/v2/schemas/v1.1/limits.rng
diff --git a/nova/api/openstack/schemas/v1.1/metadata.rng b/nova/api/openstack/v2/schemas/v1.1/metadata.rng
index b2f5d702a..b2f5d702a 100644
--- a/nova/api/openstack/schemas/v1.1/metadata.rng
+++ b/nova/api/openstack/v2/schemas/v1.1/metadata.rng
diff --git a/nova/api/openstack/schemas/v1.1/server.rng b/nova/api/openstack/v2/schemas/v1.1/server.rng
index 2e86ccffe..2e86ccffe 100644
--- a/nova/api/openstack/schemas/v1.1/server.rng
+++ b/nova/api/openstack/v2/schemas/v1.1/server.rng
diff --git a/nova/api/openstack/schemas/v1.1/servers.rng b/nova/api/openstack/v2/schemas/v1.1/servers.rng
index 4e2bb8853..4e2bb8853 100644
--- a/nova/api/openstack/schemas/v1.1/servers.rng
+++ b/nova/api/openstack/v2/schemas/v1.1/servers.rng
diff --git a/nova/api/openstack/schemas/v1.1/servers_index.rng b/nova/api/openstack/v2/schemas/v1.1/servers_index.rng
index 023e4b66a..023e4b66a 100644
--- a/nova/api/openstack/schemas/v1.1/servers_index.rng
+++ b/nova/api/openstack/v2/schemas/v1.1/servers_index.rng
diff --git a/nova/api/openstack/schemas/v1.1/version.rng b/nova/api/openstack/v2/schemas/v1.1/version.rng
index ae76270ba..ae76270ba 100644
--- a/nova/api/openstack/schemas/v1.1/version.rng
+++ b/nova/api/openstack/v2/schemas/v1.1/version.rng
diff --git a/nova/api/openstack/schemas/v1.1/versions.rng b/nova/api/openstack/v2/schemas/v1.1/versions.rng
index 8b2cc7f71..8b2cc7f71 100644
--- a/nova/api/openstack/schemas/v1.1/versions.rng
+++ b/nova/api/openstack/v2/schemas/v1.1/versions.rng
diff --git a/nova/api/openstack/server_metadata.py b/nova/api/openstack/v2/server_metadata.py
index 4145898c1..47dbe2fbd 100644
--- a/nova/api/openstack/server_metadata.py
+++ b/nova/api/openstack/v2/server_metadata.py
@@ -17,9 +17,9 @@
from webob import exc
-from nova import compute
from nova.api.openstack import common
from nova.api.openstack import wsgi
+from nova import compute
from nova import exception
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/v2/servers.py
index 8b11b30f6..1ae7f80bf 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/v2/servers.py
@@ -23,13 +23,12 @@ from webob import exc
import webob
from xml.dom import minidom
-import nova.api.openstack
from nova.api.openstack import common
-from nova.api.openstack import ips
-from nova.api.openstack.views import addresses as views_addresses
-from nova.api.openstack.views import flavors as views_flavors
-from nova.api.openstack.views import images as views_images
-from nova.api.openstack.views import servers as views_servers
+from nova.api.openstack.v2 import ips
+from nova.api.openstack.v2.views import addresses as views_addresses
+from nova.api.openstack.v2.views import flavors as views_flavors
+from nova.api.openstack.v2.views import images as views_images
+from nova.api.openstack.v2.views import servers as views_servers
from nova.api.openstack import wsgi
from nova.api.openstack import xmlutil
from nova import compute
@@ -45,7 +44,7 @@ from nova.scheduler import api as scheduler_api
from nova import utils
-LOG = logging.getLogger('nova.api.openstack.servers')
+LOG = logging.getLogger('nova.api.openstack.v2.servers')
FLAGS = flags.FLAGS
diff --git a/nova/api/openstack/urlmap.py b/nova/api/openstack/v2/urlmap.py
index 199fa6130..bae69198e 100644
--- a/nova/api/openstack/urlmap.py
+++ b/nova/api/openstack/v2/urlmap.py
@@ -28,7 +28,7 @@ _option_header_piece_re = re.compile(r';\s*([^\s;=]+|%s)\s*'
r'(?:=\s*([^;]+|%s))?\s*' %
(_quoted_string_re, _quoted_string_re))
-LOG = logging.getLogger('nova.api.openstack.map')
+LOG = logging.getLogger('nova.api.openstack.v2.map')
def unquote_header_value(value):
diff --git a/nova/api/openstack/users.py b/nova/api/openstack/v2/users.py
index 9fac45763..9dba79e03 100644
--- a/nova/api/openstack/users.py
+++ b/nova/api/openstack/v2/users.py
@@ -15,17 +15,17 @@
from webob import exc
-from nova import exception
-from nova import flags
-from nova import log as logging
from nova.api.openstack import common
from nova.api.openstack import wsgi
from nova.api.openstack import xmlutil
from nova.auth import manager
+from nova import exception
+from nova import flags
+from nova import log as logging
FLAGS = flags.FLAGS
-LOG = logging.getLogger('nova.api.openstack')
+LOG = logging.getLogger('nova.api.openstack.users')
def _translate_keys(user):
diff --git a/nova/api/openstack/versions.py b/nova/api/openstack/v2/versions.py
index 5461ffce2..3c3d4068c 100644
--- a/nova/api/openstack/versions.py
+++ b/nova/api/openstack/v2/versions.py
@@ -16,11 +16,12 @@
# under the License.
from datetime import datetime
+
from lxml import etree
import webob
import webob.dec
-import nova.api.openstack.views.versions
+from nova.api.openstack.v2.views import versions as views_versions
from nova.api.openstack import wsgi
from nova.api.openstack import xmlutil
@@ -84,7 +85,7 @@ class Versions(wsgi.Resource):
def dispatch(self, request, *args):
"""Respond to a request for all OpenStack API versions."""
- builder = nova.api.openstack.views.versions.get_view_builder(request)
+ builder = views_versions.get_view_builder(request)
if request.path == '/':
# List Versions
return builder.build_versions(VERSIONS)
@@ -95,7 +96,7 @@ class Versions(wsgi.Resource):
class VersionV11(object):
def show(self, req):
- builder = nova.api.openstack.views.versions.get_view_builder(req)
+ builder = views_versions.get_view_builder(req)
return builder.build_version(VERSIONS['v1.1'])
diff --git a/nova/api/openstack/views/__init__.py b/nova/api/openstack/v2/views/__init__.py
index e69de29bb..e69de29bb 100644
--- a/nova/api/openstack/views/__init__.py
+++ b/nova/api/openstack/v2/views/__init__.py
diff --git a/nova/api/openstack/views/addresses.py b/nova/api/openstack/v2/views/addresses.py
index 1dbcaffe0..6f518b11a 100644
--- a/nova/api/openstack/views/addresses.py
+++ b/nova/api/openstack/v2/views/addresses.py
@@ -23,7 +23,7 @@ from nova import log as logging
FLAGS = flags.FLAGS
-LOG = logging.getLogger('nova.api.openstack.views.addresses')
+LOG = logging.getLogger('nova.api.openstack.v2.views.addresses')
class ViewBuilder(common.ViewBuilder):
diff --git a/nova/api/openstack/views/flavors.py b/nova/api/openstack/v2/views/flavors.py
index f84ae5987..7b170a6b2 100644
--- a/nova/api/openstack/views/flavors.py
+++ b/nova/api/openstack/v2/views/flavors.py
@@ -17,7 +17,6 @@
import os.path
-
from nova.api.openstack import common
diff --git a/nova/api/openstack/views/images.py b/nova/api/openstack/v2/views/images.py
index c4cfe8031..c4cfe8031 100644
--- a/nova/api/openstack/views/images.py
+++ b/nova/api/openstack/v2/views/images.py
diff --git a/nova/api/openstack/views/limits.py b/nova/api/openstack/v2/views/limits.py
index 138a40cb8..138a40cb8 100644
--- a/nova/api/openstack/views/limits.py
+++ b/nova/api/openstack/v2/views/limits.py
diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/v2/views/servers.py
index e6f4bc2c4..979be930f 100644
--- a/nova/api/openstack/views/servers.py
+++ b/nova/api/openstack/v2/views/servers.py
@@ -17,19 +17,16 @@
# under the License.
import hashlib
-import os
from nova.api.openstack import common
-from nova.api.openstack.views import addresses as views_addresses
-from nova.api.openstack.views import flavors as views_flavors
-from nova.api.openstack.views import images as views_images
-from nova.compute import vm_states
-from nova import exception
+from nova.api.openstack.v2.views import addresses as views_addresses
+from nova.api.openstack.v2.views import flavors as views_flavors
+from nova.api.openstack.v2.views import images as views_images
from nova import log as logging
from nova import utils
-LOG = logging.getLogger('nova.api.openstack.views.servers')
+LOG = logging.getLogger('nova.api.openstack.v2.views.servers')
class ViewBuilder(common.ViewBuilder):
diff --git a/nova/api/openstack/views/versions.py b/nova/api/openstack/v2/views/versions.py
index 1ac398706..1ac398706 100644
--- a/nova/api/openstack/views/versions.py
+++ b/nova/api/openstack/v2/views/versions.py
diff --git a/nova/api/openstack/zones.py b/nova/api/openstack/v2/zones.py
index 2a95cd0a4..8c5add2d1 100644
--- a/nova/api/openstack/zones.py
+++ b/nova/api/openstack/v2/zones.py
@@ -16,25 +16,23 @@
import json
import urlparse
+from nova.api.openstack import common
+from nova.api.openstack.v2 import servers
+from nova.api.openstack import xmlutil
+from nova.api.openstack import wsgi
+from nova.compute import api as compute
from nova import crypto
from nova import db
from nova import exception
from nova import flags
from nova import log as logging
-
-from nova.compute import api as compute
from nova.scheduler import api
-from nova.api.openstack import common
-from nova.api.openstack import servers
-from nova.api.openstack import xmlutil
-from nova.api.openstack import wsgi
-
FLAGS = flags.FLAGS
-LOG = logging.getLogger('nova.api.openstack.zones')
+LOG = logging.getLogger('nova.api.openstack.v2.zones')
def _filter_keys(item, keys):
diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py
index 8c6b30ca9..7e4875066 100644
--- a/nova/api/openstack/wsgi.py
+++ b/nova/api/openstack/wsgi.py
@@ -15,13 +15,11 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
from lxml import etree
import webob
from xml.dom import minidom
from xml.parsers import expat
-import faults
from nova import exception
from nova import log as logging
from nova import utils
@@ -528,7 +526,7 @@ class Resource(wsgi.Application):
serialized by requested content type.
Exceptions derived from webob.exc.HTTPException will be automatically
- wrapped in faults.Fault() to provide API friendly error responses.
+ wrapped in Fault() to provide API friendly error responses.
"""
@@ -556,10 +554,10 @@ class Resource(wsgi.Application):
action, args, accept = self.deserializer.deserialize(request)
except exception.InvalidContentType:
msg = _("Unsupported Content-Type")
- return faults.Fault(webob.exc.HTTPBadRequest(explanation=msg))
+ return Fault(webob.exc.HTTPBadRequest(explanation=msg))
except exception.MalformedRequestBody:
msg = _("Malformed request body")
- return faults.Fault(webob.exc.HTTPBadRequest(explanation=msg))
+ return Fault(webob.exc.HTTPBadRequest(explanation=msg))
project_id = args.pop("project_id", None)
if 'nova.context' in request.environ and project_id:
@@ -567,12 +565,12 @@ class Resource(wsgi.Application):
try:
action_result = self.dispatch(request, action, args)
- except faults.Fault as ex:
+ except Fault as ex:
LOG.info(_("Fault thrown: %s"), unicode(ex))
action_result = ex
except webob.exc.HTTPException as ex:
LOG.info(_("HTTP exception thrown: %s"), unicode(ex))
- action_result = faults.Fault(ex)
+ action_result = Fault(ex)
if type(action_result) is dict or action_result is None:
response = self.serializer.serialize(request,
@@ -601,7 +599,7 @@ class Resource(wsgi.Application):
return controller_method(req=request, **action_args)
except TypeError as exc:
LOG.exception(exc)
- return faults.Fault(webob.exc.HTTPBadRequest())
+ return Fault(webob.exc.HTTPBadRequest())
class Controller(object):
@@ -612,3 +610,96 @@ class Controller(object):
def __init__(self, view_builder=None):
"""Initialize controller with a view builder instance."""
self._view_builder = view_builder or self._view_builder_class()
+
+
+class Fault(webob.exc.HTTPException):
+ """Wrap webob.exc.HTTPException to provide API friendly response."""
+
+ _fault_names = {
+ 400: "badRequest",
+ 401: "unauthorized",
+ 403: "resizeNotAllowed",
+ 404: "itemNotFound",
+ 405: "badMethod",
+ 409: "inProgress",
+ 413: "overLimit",
+ 415: "badMediaType",
+ 501: "notImplemented",
+ 503: "serviceUnavailable"}
+
+ def __init__(self, exception):
+ """Create a Fault for the given webob.exc.exception."""
+ self.wrapped_exc = exception
+ self.status_int = exception.status_int
+
+ @webob.dec.wsgify(RequestClass=Request)
+ def __call__(self, req):
+ """Generate a WSGI response based on the exception passed to ctor."""
+ # Replace the body with fault details.
+ code = self.wrapped_exc.status_int
+ fault_name = self._fault_names.get(code, "cloudServersFault")
+ fault_data = {
+ fault_name: {
+ 'code': code,
+ 'message': self.wrapped_exc.explanation}}
+ if code == 413:
+ retry = self.wrapped_exc.headers['Retry-After']
+ fault_data[fault_name]['retryAfter'] = retry
+
+ # 'code' is an attribute on the fault tag itself
+ metadata = {'attributes': {fault_name: 'code'}}
+
+ xml_serializer = XMLDictSerializer(metadata, XMLNS_V11)
+
+ content_type = req.best_match_content_type()
+ serializer = {
+ 'application/xml': xml_serializer,
+ 'application/json': JSONDictSerializer(),
+ }[content_type]
+
+ self.wrapped_exc.body = serializer.serialize(fault_data)
+ self.wrapped_exc.content_type = content_type
+
+ return self.wrapped_exc
+
+ def __str__(self):
+ return self.wrapped_exc.__str__()
+
+
+class OverLimitFault(webob.exc.HTTPException):
+ """
+ Rate-limited request response.
+ """
+
+ def __init__(self, message, details, retry_time):
+ """
+ Initialize new `OverLimitFault` with relevant information.
+ """
+ self.wrapped_exc = webob.exc.HTTPRequestEntityTooLarge()
+ self.content = {
+ "overLimitFault": {
+ "code": self.wrapped_exc.status_int,
+ "message": message,
+ "details": details,
+ },
+ }
+
+ @webob.dec.wsgify(RequestClass=Request)
+ def __call__(self, request):
+ """
+ Return the wrapped exception with a serialized body conforming to our
+ error format.
+ """
+ content_type = request.best_match_content_type()
+ metadata = {"attributes": {"overLimitFault": "code"}}
+
+ xml_serializer = XMLDictSerializer(metadata, XMLNS_V11)
+ serializer = {
+ 'application/xml': xml_serializer,
+ 'application/json': JSONDictSerializer(),
+ }[content_type]
+
+ content = serializer.serialize(self.content)
+ self.wrapped_exc.body = content
+
+ return self.wrapped_exc
diff --git a/nova/api/openstack/xmlutil.py b/nova/api/openstack/xmlutil.py
index 5779849b3..db490e652 100644
--- a/nova/api/openstack/xmlutil.py
+++ b/nova/api/openstack/xmlutil.py
@@ -31,9 +31,9 @@ XMLNS_ATOM = 'http://www.w3.org/2005/Atom'
def validate_schema(xml, schema_name):
if type(xml) is str:
xml = etree.fromstring(xml)
- base_path = 'nova/api/openstack/schemas/v1.1/'
+ base_path = 'nova/api/openstack/v2/schemas/v1.1/'
if schema_name in ('atom', 'atom-link'):
- base_path = 'nova/api/openstack/schemas/'
+ base_path = 'nova/api/openstack/v2/schemas/'
schema_path = os.path.join(utils.novadir(),
'%s%s.rng' % (base_path, schema_name))
schema_doc = etree.parse(schema_path)