summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorTushar Patil <tushar.vitthal.patil@gmail.com>2011-08-19 10:08:46 -0700
committerTushar Patil <tushar.vitthal.patil@gmail.com>2011-08-19 10:08:46 -0700
commit10fdf234039d1c5e21037a17809186152f1d718d (patch)
tree6fe6088425c668b2b0ca4cf34810585092ccbe8f /nova/api
parent69c26210dd821df0d2160e51b10f147db2a40249 (diff)
parentba079e5ccfa6b5f9fdfa036842f3e5ba51df4b75 (diff)
Merged from trunk
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/openstack/common.py3
-rw-r--r--nova/api/openstack/contrib/rescue.py83
-rw-r--r--nova/api/openstack/contrib/virtual_interfaces.py108
-rw-r--r--nova/api/openstack/create_instance_helper.py15
-rw-r--r--nova/api/openstack/server_metadata.py3
-rw-r--r--nova/api/openstack/servers.py6
-rw-r--r--nova/api/openstack/views/servers.py8
7 files changed, 217 insertions, 9 deletions
diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py
index b2a675653..d9eb832f2 100644
--- a/nova/api/openstack/common.py
+++ b/nova/api/openstack/common.py
@@ -241,7 +241,8 @@ def check_img_metadata_quota_limit(context, metadata):
quota_metadata = quota.allowed_metadata_items(context, num_metadata)
if quota_metadata < num_metadata:
expl = _("Image metadata limit exceeded")
- raise webob.exc.HTTPBadRequest(explanation=expl)
+ raise webob.exc.HTTPRequestEntityTooLarge(explanation=expl,
+ headers={'Retry-After': 0})
class MetadataXMLDeserializer(wsgi.XMLDeserializer):
diff --git a/nova/api/openstack/contrib/rescue.py b/nova/api/openstack/contrib/rescue.py
new file mode 100644
index 000000000..3de128895
--- /dev/null
+++ b/nova/api/openstack/contrib/rescue.py
@@ -0,0 +1,83 @@
+# Copyright 2011 Openstack, LLC.
+#
+# 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.
+
+"""The rescue mode extension."""
+
+import webob
+from webob import exc
+
+from nova import compute
+from nova import log as logging
+from nova.api.openstack import extensions as exts
+from nova.api.openstack import faults
+
+
+LOG = logging.getLogger("nova.api.contrib.rescue")
+
+
+def wrap_errors(fn):
+ """"Ensure errors are not passed along."""
+ def wrapped(*args):
+ try:
+ fn(*args)
+ except Exception, e:
+ return faults.Fault(exc.HTTPInternalServerError())
+ return wrapped
+
+
+class Rescue(exts.ExtensionDescriptor):
+ """The Rescue controller for the OpenStack API."""
+ def __init__(self):
+ super(Rescue, self).__init__()
+ self.compute_api = compute.API()
+
+ @wrap_errors
+ def _rescue(self, input_dict, req, instance_id):
+ """Rescue an instance."""
+ context = req.environ["nova.context"]
+ self.compute_api.rescue(context, instance_id)
+
+ return webob.Response(status_int=202)
+
+ @wrap_errors
+ def _unrescue(self, input_dict, req, instance_id):
+ """Unrescue an instance."""
+ context = req.environ["nova.context"]
+ self.compute_api.unrescue(context, instance_id)
+
+ return webob.Response(status_int=202)
+
+ def get_name(self):
+ return "Rescue"
+
+ def get_alias(self):
+ return "os-rescue"
+
+ def get_description(self):
+ return "Instance rescue mode"
+
+ def get_namespace(self):
+ return "http://docs.openstack.org/ext/rescue/api/v1.1"
+
+ def get_updated(self):
+ return "2011-08-18T00:00:00+00:00"
+
+ def get_actions(self):
+ """Return the actions the extension adds, as required by contract."""
+ actions = [
+ exts.ActionExtension("servers", "rescue", self._rescue),
+ exts.ActionExtension("servers", "unrescue", self._unrescue),
+ ]
+
+ return actions
diff --git a/nova/api/openstack/contrib/virtual_interfaces.py b/nova/api/openstack/contrib/virtual_interfaces.py
new file mode 100644
index 000000000..dab61efc8
--- /dev/null
+++ b/nova/api/openstack/contrib/virtual_interfaces.py
@@ -0,0 +1,108 @@
+# Copyright (C) 2011 Midokura KK
+# 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.
+
+"""The virtual interfaces extension."""
+
+from webob import exc
+import webob
+
+from nova import compute
+from nova import exception
+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.api.openstack import wsgi
+
+
+LOG = logging.getLogger("nova.api.virtual_interfaces")
+
+
+def _translate_vif_summary_view(_context, vif):
+ """Maps keys for VIF summary view."""
+ d = {}
+ d['id'] = vif['uuid']
+ d['mac_address'] = vif['address']
+ return d
+
+
+def _get_metadata():
+ metadata = {
+ "attributes": {
+ 'virtual_interface': ["id", "mac_address"]}}
+ return metadata
+
+
+class ServerVirtualInterfaceController(object):
+ """The instance VIF API controller for the Openstack API.
+ """
+
+ def __init__(self):
+ self.compute_api = compute.API()
+ super(ServerVirtualInterfaceController, self).__init__()
+
+ def _items(self, req, server_id, entity_maker):
+ """Returns a list of VIFs, transformed through entity_maker."""
+ context = req.environ['nova.context']
+
+ try:
+ instance = self.compute_api.get(context, server_id)
+ except exception.NotFound:
+ return faults.Fault(exc.HTTPNotFound())
+
+ vifs = instance['virtual_interfaces']
+ limited_list = common.limited(vifs, req)
+ res = [entity_maker(context, vif) for vif in limited_list]
+ return {'virtual_interfaces': res}
+
+ def index(self, req, server_id):
+ """Returns the list of VIFs for a given instance."""
+ return self._items(req, server_id,
+ entity_maker=_translate_vif_summary_view)
+
+
+class Virtual_interfaces(extensions.ExtensionDescriptor):
+
+ def get_name(self):
+ return "VirtualInterfaces"
+
+ def get_alias(self):
+ return "virtual_interfaces"
+
+ def get_description(self):
+ return "Virtual interface support"
+
+ def get_namespace(self):
+ return "http://docs.openstack.org/ext/virtual_interfaces/api/v1.1"
+
+ def get_updated(self):
+ return "2011-08-17T00:00:00+00:00"
+
+ def get_resources(self):
+ resources = []
+
+ metadata = _get_metadata()
+ body_serializers = {
+ 'application/xml': wsgi.XMLDictSerializer(metadata=metadata,
+ xmlns=wsgi.XMLNS_V11)}
+ serializer = wsgi.ResponseSerializer(body_serializers, None)
+ res = extensions.ResourceExtension(
+ 'os-virtual-interfaces',
+ controller=ServerVirtualInterfaceController(),
+ parent=dict(member_name='server', collection_name='servers'),
+ serializer=serializer)
+ resources.append(res)
+
+ return resources
diff --git a/nova/api/openstack/create_instance_helper.py b/nova/api/openstack/create_instance_helper.py
index 8d5a9d2a3..42b553674 100644
--- a/nova/api/openstack/create_instance_helper.py
+++ b/nova/api/openstack/create_instance_helper.py
@@ -128,6 +128,7 @@ class CreateInstanceHelper(object):
raise exc.HTTPBadRequest(explanation=msg)
zone_blob = server_dict.get('blob')
+ user_data = server_dict.get('user_data')
availability_zone = server_dict.get('availability_zone')
name = server_dict['name']
self._validate_server_name(name)
@@ -170,6 +171,7 @@ class CreateInstanceHelper(object):
min_count=min_count,
max_count=max_count,
requested_networks=requested_networks,
+ user_data=user_data,
availability_zone=availability_zone))
except quota.QuotaError as error:
self._handle_quota_error(error)
@@ -191,13 +193,20 @@ class CreateInstanceHelper(object):
"""
if error.code == "OnsetFileLimitExceeded":
expl = _("Personality file limit exceeded")
- raise exc.HTTPBadRequest(explanation=expl)
+ raise exc.HTTPRequestEntityTooLarge(explanation=error.message,
+ headers={'Retry-After': 0})
if error.code == "OnsetFilePathLimitExceeded":
expl = _("Personality file path too long")
- raise exc.HTTPBadRequest(explanation=expl)
+ raise exc.HTTPRequestEntityTooLarge(explanation=error.message,
+ headers={'Retry-After': 0})
if error.code == "OnsetFileContentLimitExceeded":
expl = _("Personality file content too long")
- raise exc.HTTPBadRequest(explanation=expl)
+ raise exc.HTTPRequestEntityTooLarge(explanation=error.message,
+ headers={'Retry-After': 0})
+ if error.code == "InstanceLimitExceeded":
+ expl = _("Instance quotas have been exceeded")
+ raise exc.HTTPRequestEntityTooLarge(explanation=error.message,
+ headers={'Retry-After': 0})
# if the original error is okay, just reraise it
raise error
diff --git a/nova/api/openstack/server_metadata.py b/nova/api/openstack/server_metadata.py
index 2b235f79a..8ac3319c9 100644
--- a/nova/api/openstack/server_metadata.py
+++ b/nova/api/openstack/server_metadata.py
@@ -151,7 +151,8 @@ class Controller(object):
def _handle_quota_error(self, error):
"""Reraise quota errors as api-specific http exceptions."""
if error.code == "MetadataLimitExceeded":
- raise exc.HTTPBadRequest(explanation=error.message)
+ raise exc.HTTPRequestEntityTooLarge(explanation=error.message,
+ headers={'Retry-After': 0})
raise error
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py
index 5c34e28fd..b814bc24f 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/servers.py
@@ -923,6 +923,12 @@ class ServerXMLSerializer(wsgi.XMLDictSerializer):
node.setAttribute('adminPass', server_dict['server']['adminPass'])
return self.to_xml_string(node, True)
+ def update(self, server_dict):
+ xml_doc = minidom.Document()
+ node = self._server_to_xml_detailed(xml_doc,
+ server_dict['server'])
+ return self.to_xml_string(node, True)
+
def create_resource(version='1.0'):
controller = {
diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py
index 8222f6766..edc328129 100644
--- a/nova/api/openstack/views/servers.py
+++ b/nova/api/openstack/views/servers.py
@@ -111,14 +111,14 @@ class ViewBuilderV10(ViewBuilder):
response['uuid'] = inst['uuid']
def _build_image(self, response, inst):
- if 'image_ref' in dict(inst):
+ if inst.get('image_ref', None):
image_ref = inst['image_ref']
if str(image_ref).startswith('http'):
raise exception.ListingImageRefsNotSupported()
response['imageId'] = int(image_ref)
def _build_flavor(self, response, inst):
- if 'instance_type' in dict(inst):
+ if inst.get('instance_type', None):
response['flavorId'] = inst['instance_type']['flavorid']
def _build_addresses(self, response, inst):
@@ -146,7 +146,7 @@ class ViewBuilderV11(ViewBuilder):
return response
def _build_image(self, response, inst):
- if 'image_ref' in dict(inst):
+ if inst.get("image_ref", None):
image_href = inst['image_ref']
image_id = str(common.get_id_from_href(image_href))
_bookmark = self.image_builder.generate_bookmark(image_id)
@@ -161,7 +161,7 @@ class ViewBuilderV11(ViewBuilder):
}
def _build_flavor(self, response, inst):
- if "instance_type" in dict(inst):
+ if inst.get("instance_type", None):
flavor_id = inst["instance_type"]['flavorid']
flavor_ref = self.flavor_builder.generate_href(flavor_id)
flavor_bookmark = self.flavor_builder.generate_bookmark(flavor_id)