From 70e4d73778d448cb7f122bc0a2a0c43a78fff46a Mon Sep 17 00:00:00 2001 From: John Tran Date: Wed, 8 Jun 2011 15:23:33 -0700 Subject: added a test for allocate_address & added error handling for api instead of returning 'UnknownError', will give information 'AllocateAddressError: NoMoreAddresses --- nova/api/ec2/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'nova/api') diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py index 1915d007d..459ecb442 100644 --- a/nova/api/ec2/__init__.py +++ b/nova/api/ec2/__init__.py @@ -348,6 +348,12 @@ class Executor(wsgi.Application): LOG.debug(_('KeyPairExists raised: %s'), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) + except rpc.RemoteError as ex: + LOG.debug(_('RemoteError raised: %s'), ex.exc_type, + context=context) + if ex.exc_type == 'NoMoreAddresses': + return self._error(req, context, 'AllocateAddressError', + ex.exc_type) except Exception as ex: extra = {'environment': req.environ} LOG.exception(_('Unexpected error raised: %s'), unicode(ex), -- cgit From 3764be9d65483a9e431b69f37e3516fa20961362 Mon Sep 17 00:00:00 2001 From: John Tran Date: Wed, 8 Jun 2011 17:15:35 -0700 Subject: raises exception.NoFloatingIpsDefined instead of UnknownError --- nova/api/ec2/cloud.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 316298c39..6c5dba8ed 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -39,6 +39,7 @@ from nova import flags from nova import ipv6 from nova import log as logging from nova import network +from nova import rpc from nova import utils from nova import volume from nova.api.ec2 import ec2utils @@ -872,8 +873,11 @@ class CloudController(object): def allocate_address(self, context, **kwargs): LOG.audit(_("Allocate address"), context=context) - public_ip = self.network_api.allocate_floating_ip(context) - return {'publicIp': public_ip} + try: + public_ip = self.network_api.allocate_floating_ip(context) + return {'publicIp': public_ip} + except rpc.RemoteError: + raise exception.NoFloatingIpsDefined def release_address(self, context, public_ip, **kwargs): LOG.audit(_("Release address %s"), public_ip, context=context) -- cgit From b11cf9bc7b1b9792bdab77aa72dc6163f3e44ca1 Mon Sep 17 00:00:00 2001 From: John Tran Date: Wed, 8 Jun 2011 17:17:40 -0700 Subject: removing custom exception, instead using NoFloatingIpsDefined --- nova/api/ec2/__init__.py | 6 ------ 1 file changed, 6 deletions(-) (limited to 'nova/api') diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py index 459ecb442..1915d007d 100644 --- a/nova/api/ec2/__init__.py +++ b/nova/api/ec2/__init__.py @@ -348,12 +348,6 @@ class Executor(wsgi.Application): LOG.debug(_('KeyPairExists raised: %s'), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) - except rpc.RemoteError as ex: - LOG.debug(_('RemoteError raised: %s'), ex.exc_type, - context=context) - if ex.exc_type == 'NoMoreAddresses': - return self._error(req, context, 'AllocateAddressError', - ex.exc_type) except Exception as ex: extra = {'environment': req.environ} LOG.exception(_('Unexpected error raised: %s'), unicode(ex), -- cgit From 463e0388308760dbf3bf2b3fa901d8076d002f91 Mon Sep 17 00:00:00 2001 From: John Tran Date: Thu, 9 Jun 2011 00:01:42 -0700 Subject: matched the inner exception specifically, instead of catching all RemoteError exceptions --- nova/api/ec2/cloud.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 6c5dba8ed..84a83d8e6 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -876,8 +876,11 @@ class CloudController(object): try: public_ip = self.network_api.allocate_floating_ip(context) return {'publicIp': public_ip} - except rpc.RemoteError: - raise exception.NoFloatingIpsDefined + except rpc.RemoteError as ex: + if ex.exc_type == 'NoMoreAddresses': + raise exception.NoFloatingIpsDefined + else: + raise def release_address(self, context, public_ip, **kwargs): LOG.audit(_("Release address %s"), public_ip, context=context) -- cgit From 0e7a2042cc5922bb014a77080ec0bdb93bbf575c Mon Sep 17 00:00:00 2001 From: John Tran Date: Fri, 10 Jun 2011 10:28:03 -0700 Subject: raise instance instead of class --- nova/api/ec2/cloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 84a83d8e6..5ed473b73 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -878,7 +878,7 @@ class CloudController(object): return {'publicIp': public_ip} except rpc.RemoteError as ex: if ex.exc_type == 'NoMoreAddresses': - raise exception.NoFloatingIpsDefined + raise exception.NoFloatingIpsDefined() else: raise -- cgit From 05fecdf873a5c02dcb13c841304df872411d4183 Mon Sep 17 00:00:00 2001 From: John Tran Date: Fri, 10 Jun 2011 11:10:58 -0700 Subject: added new exception more descriptive of not having available floating addresses avail for allocation --- nova/api/ec2/cloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 5ed473b73..e1c65ae40 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -878,7 +878,7 @@ class CloudController(object): return {'publicIp': public_ip} except rpc.RemoteError as ex: if ex.exc_type == 'NoMoreAddresses': - raise exception.NoFloatingIpsDefined() + raise exception.NoMoreFloatingIps() else: raise -- cgit From e986887d513855d5a5fd6ca90998860f67fcb1d3 Mon Sep 17 00:00:00 2001 From: William Wolf Date: Fri, 10 Jun 2011 15:28:17 -0400 Subject: force utf-8 encoding on toprettyxml call for XMLDictSerializer --- nova/api/openstack/wsgi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py index ddf4e6fa9..6760735c4 100644 --- a/nova/api/openstack/wsgi.py +++ b/nova/api/openstack/wsgi.py @@ -225,7 +225,7 @@ class XMLDictSerializer(DictSerializer): if not xmlns and self.xmlns: node.setAttribute('xmlns', self.xmlns) - return node.toprettyxml(indent=' ') + return node.toprettyxml(indent=' ', encoding='utf-8') def _to_xml_node(self, doc, metadata, nodename, data): """Recursive method to convert data members to XML nodes.""" -- cgit From 92423564aa24124b0144264d6cd1c57c78eaf5dd Mon Sep 17 00:00:00 2001 From: William Wolf Date: Fri, 10 Jun 2011 16:41:14 -0400 Subject: return body correctly as object instead of a string, with tests, also check for empty body on requests that need a body --- nova/api/openstack/server_metadata.py | 11 +++++++++-- nova/api/openstack/wsgi.py | 4 ++++ 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/server_metadata.py b/nova/api/openstack/server_metadata.py index b38b84a2a..c17d77d46 100644 --- a/nova/api/openstack/server_metadata.py +++ b/nova/api/openstack/server_metadata.py @@ -37,12 +37,18 @@ class Controller(object): meta_dict[key] = value return dict(metadata=meta_dict) + def _check_body(self, body): + if not body: + expl = _('No Request Body') + raise exc.HTTPBadRequest(explanation=expl) + def index(self, req, server_id): """ Returns the list of metadata for a given instance """ context = req.environ['nova.context'] return self._get_metadata(context, server_id) def create(self, req, server_id, body): + self._check_body(body) context = req.environ['nova.context'] metadata = body.get('metadata') try: @@ -51,9 +57,10 @@ class Controller(object): metadata) except quota.QuotaError as error: self._handle_quota_error(error) - return req.body + return body def update(self, req, server_id, id, body): + self._check_body(body) context = req.environ['nova.context'] if not id in body: expl = _('Request body and URI mismatch') @@ -68,7 +75,7 @@ class Controller(object): except quota.QuotaError as error: self._handle_quota_error(error) - return req.body + return body def show(self, req, server_id, id): """ Return a single metadata item """ diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py index ddf4e6fa9..8c30cdeb9 100644 --- a/nova/api/openstack/wsgi.py +++ b/nova/api/openstack/wsgi.py @@ -348,16 +348,20 @@ class Resource(wsgi.Application): LOG.debug("%(method)s %(url)s" % {"method": request.method, "url": request.url}) + print "CALL" try: action, action_args, accept = self.deserializer.deserialize( request) except exception.InvalidContentType: return webob.exc.HTTPBadRequest(_("Unsupported Content-Type")) + print "CALL2" action_result = self.dispatch(request, action, action_args) + print "ACTION RESULT:", action_result, isinstance(action_result, str) #TODO(bcwaldon): find a more elegant way to pass through non-dict types if type(action_result) is dict: + print "DICT" response = self.serializer.serialize(action_result, accept) else: response = action_result -- cgit From cbaa94ac255cde729bae3257da6657a114755224 Mon Sep 17 00:00:00 2001 From: William Wolf Date: Fri, 10 Jun 2011 16:43:13 -0400 Subject: got rid of prints for debugging --- nova/api/openstack/wsgi.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py index 8c30cdeb9..ddf4e6fa9 100644 --- a/nova/api/openstack/wsgi.py +++ b/nova/api/openstack/wsgi.py @@ -348,20 +348,16 @@ class Resource(wsgi.Application): LOG.debug("%(method)s %(url)s" % {"method": request.method, "url": request.url}) - print "CALL" try: action, action_args, accept = self.deserializer.deserialize( request) except exception.InvalidContentType: return webob.exc.HTTPBadRequest(_("Unsupported Content-Type")) - print "CALL2" action_result = self.dispatch(request, action, action_args) - print "ACTION RESULT:", action_result, isinstance(action_result, str) #TODO(bcwaldon): find a more elegant way to pass through non-dict types if type(action_result) is dict: - print "DICT" response = self.serializer.serialize(action_result, accept) else: response = action_result -- cgit From 8146b92f7d81eada6408f939ef25cb5393650008 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 10 Jun 2011 18:39:58 -0400 Subject: adding support for cusom serialization methods --- nova/api/openstack/wsgi.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py index ddf4e6fa9..e71b80e2c 100644 --- a/nova/api/openstack/wsgi.py +++ b/nova/api/openstack/wsgi.py @@ -189,7 +189,10 @@ class DictSerializer(object): def serialize(self, data, action='default'): """Find local serialization method and encode response body.""" - action_method = getattr(self, action, self.default) + if action is None: + action_method = self.default + else: + action_method = getattr(self, action, self.default) return action_method(data) def default(self, data): @@ -296,7 +299,7 @@ class ResponseSerializer(object): } self.serializers.update(serializers or {}) - def serialize(self, response_data, content_type): + def serialize(self, response_data, content_type, action='default'): """Serialize a dict into a string and wrap in a wsgi.Request object. :param response_data: dict produced by the Controller @@ -307,7 +310,7 @@ class ResponseSerializer(object): response.headers['Content-Type'] = content_type serializer = self.get_serializer(content_type) - response.body = serializer.serialize(response_data) + response.body = serializer.serialize(response_data, action) return response @@ -358,7 +361,7 @@ class Resource(wsgi.Application): #TODO(bcwaldon): find a more elegant way to pass through non-dict types if type(action_result) is dict: - response = self.serializer.serialize(action_result, accept) + response = self.serializer.serialize(action_result, accept, action) else: response = action_result -- cgit From bd31a85575ce53dfa80f414dd359b3bdb2855292 Mon Sep 17 00:00:00 2001 From: William Wolf Date: Mon, 13 Jun 2011 08:53:34 -0400 Subject: check for none and empty string, this way empty dicts/lists will be ok --- nova/api/openstack/server_metadata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/openstack/server_metadata.py b/nova/api/openstack/server_metadata.py index c17d77d46..57666f6b7 100644 --- a/nova/api/openstack/server_metadata.py +++ b/nova/api/openstack/server_metadata.py @@ -38,7 +38,7 @@ class Controller(object): return dict(metadata=meta_dict) def _check_body(self, body): - if not body: + if body == None or body == "": expl = _('No Request Body') raise exc.HTTPBadRequest(explanation=expl) -- cgit From f2ca12fc5ea236bb8940acce80065a3bcbe37d2a Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Mon, 13 Jun 2011 15:03:26 -0400 Subject: wsgi can now handle dispatching action None more elegantly --- nova/api/openstack/wsgi.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py index e71b80e2c..385ae4625 100644 --- a/nova/api/openstack/wsgi.py +++ b/nova/api/openstack/wsgi.py @@ -60,8 +60,9 @@ class TextDeserializer(object): def deserialize(self, datastring, action='default'): """Find local deserialization method and parse request body.""" - action_method = getattr(self, action, self.default) - return action_method(datastring) + action_method = getattr(self, str(action), self.default) + output = action_method(datastring) + return output def default(self, datastring): """Default deserialization code should live here""" @@ -189,11 +190,9 @@ class DictSerializer(object): def serialize(self, data, action='default'): """Find local serialization method and encode response body.""" - if action is None: - action_method = self.default - else: - action_method = getattr(self, action, self.default) - return action_method(data) + action_method = getattr(self, str(action), self.default) + output = action_method(data) + return output def default(self, data): """Default serialization code should live here""" -- cgit From 83df6e50fa90620dd7510e1a06d9128d4de7cb29 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Mon, 13 Jun 2011 15:08:00 -0400 Subject: removing unnecessary lines --- nova/api/openstack/wsgi.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py index 385ae4625..6cb73d8bf 100644 --- a/nova/api/openstack/wsgi.py +++ b/nova/api/openstack/wsgi.py @@ -61,8 +61,7 @@ class TextDeserializer(object): def deserialize(self, datastring, action='default'): """Find local deserialization method and parse request body.""" action_method = getattr(self, str(action), self.default) - output = action_method(datastring) - return output + return action_method(datastring) def default(self, datastring): """Default deserialization code should live here""" @@ -191,8 +190,7 @@ class DictSerializer(object): def serialize(self, data, action='default'): """Find local serialization method and encode response body.""" action_method = getattr(self, str(action), self.default) - output = action_method(data) - return output + return action_method(data) def default(self, data): """Default serialization code should live here""" -- cgit From f3381ee03355d8800d229efb7f799df9e6c915e2 Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Mon, 13 Jun 2011 21:14:26 -0400 Subject: pep8 --- nova/api/openstack/limits.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/openstack/limits.py b/nova/api/openstack/limits.py index dc2bc6bbc..fede96e33 100644 --- a/nova/api/openstack/limits.py +++ b/nova/api/openstack/limits.py @@ -99,7 +99,7 @@ def create_resource(version='1.0'): serializers = { 'application/xml': wsgi.XMLDictSerializer(xmlns=xmlns, - metadata=metadata) + metadata=metadata), } return wsgi.Resource(controller, serializers=serializers) -- cgit From 9ef64c8ccbcdacfef642b2c203ffcc45b2deaf36 Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Tue, 14 Jun 2011 17:52:49 -0500 Subject: fixed instance[fixed_ip] in ec2 api, removed fixed_ip shim --- nova/api/ec2/cloud.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 14a18c330..e74256dfa 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -121,8 +121,8 @@ class CloudController(object): result = {} for instance in self.compute_api.get_all(context, project_id=project_id): - if instance['fixed_ip']: - line = '%s slots=%d' % (instance['fixed_ip']['address'], + if instance['fixed_ips']: + line = '%s slots=%d' % (instance['fixed_ips'][0]['address'], instance['vcpus']) key = str(instance['key_name']) if key in result: @@ -793,15 +793,15 @@ class CloudController(object): 'name': instance['state_description']} fixed_addr = None floating_addr = None - if instance['fixed_ip']: - fixed_addr = instance['fixed_ip']['address'] - if instance['fixed_ip']['floating_ips']: - fixed = instance['fixed_ip'] + if instance['fixed_ips']: + fixed = instance['fixed_ips'][0] + fixed_addr = fixed['address'] + if fixed['floating_ips']: floating_addr = fixed['floating_ips'][0]['address'] - if instance['fixed_ip']['network'] and 'use_v6' in kwargs: + if fixed['network'] and 'use_v6' in kwargs: i['dnsNameV6'] = ipv6.to_global( - instance['fixed_ip']['network']['cidr_v6'], - instance['fixed_ip']['virtual_interface']['address'], + fixed['network']['cidr_v6'], + fixed['virtual_interface']['address'], instance['project_id']) i['privateDnsName'] = fixed_addr -- cgit