Handle InstanceNotFound when setting password via metadata

When setting an instance password via the metadata service, if the
instance is not found it results in a 500 response to the caller.

This change handles the InstanceNotFound error and returns it as
a 400. Note it's a 400 since the instance uuid is part of the POST
request body, not on the URL path so it's not a 404 response.

Change-Id: I4aa99b563e1a5a87aa3e3dfb28800f107676df92
Partial-Bug: #1696848
(cherry picked from commit c91ee68d49)
This commit is contained in:
Matt Riedemann 2017-06-10 09:24:48 -04:00
parent 67caff67a9
commit a2653ac0d0
2 changed files with 19 additions and 1 deletions

View File

@ -18,6 +18,7 @@ from six.moves import range
from webob import exc
from nova import context
from nova import exception
from nova.i18n import _
from nova import objects
from nova import utils
@ -69,7 +70,10 @@ def handle_password(req, meta_data):
im = objects.InstanceMapping.get_by_instance_uuid(ctxt, meta_data.uuid)
with context.target_cell(ctxt, im.cell_mapping) as cctxt:
instance = objects.Instance.get_by_uuid(cctxt, meta_data.uuid)
try:
instance = objects.Instance.get_by_uuid(cctxt, meta_data.uuid)
except exception.InstanceNotFound as e:
raise exc.HTTPBadRequest(explanation=e.format_message())
instance.system_metadata.update(convert_password(ctxt, req.body))
instance.save()
else:

View File

@ -1635,6 +1635,20 @@ class MetadataPasswordTestCase(test.TestCase):
result = password.handle_password(request, self.mdinst)
self.assertEqual(result, 'foo')
@mock.patch.object(objects.InstanceMapping, 'get_by_instance_uuid',
return_value=objects.InstanceMapping(cell_mapping=None))
@mock.patch.object(objects.Instance, 'get_by_uuid')
def test_set_password_instance_not_found(self, get_by_uuid, get_mapping):
"""Tests that a 400 is returned if the instance can not be found."""
get_by_uuid.side_effect = exception.InstanceNotFound(
instance_id=self.instance.uuid)
request = webob.Request.blank('')
request.method = 'POST'
request.val = b'foo'
request.content_length = len(request.body)
self.assertRaises(webob.exc.HTTPBadRequest, password.handle_password,
request, self.mdinst)
def test_bad_method(self):
request = webob.Request.blank('')
request.method = 'PUT'