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
This commit is contained in:
		@@ -18,6 +18,7 @@ from six.moves import range
 | 
				
			|||||||
from webob import exc
 | 
					from webob import exc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from nova import context
 | 
					from nova import context
 | 
				
			||||||
 | 
					from nova import exception
 | 
				
			||||||
from nova.i18n import _
 | 
					from nova.i18n import _
 | 
				
			||||||
from nova import objects
 | 
					from nova import objects
 | 
				
			||||||
from nova import utils
 | 
					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)
 | 
					        im = objects.InstanceMapping.get_by_instance_uuid(ctxt, meta_data.uuid)
 | 
				
			||||||
        with context.target_cell(ctxt, im.cell_mapping) as cctxt:
 | 
					        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.system_metadata.update(convert_password(ctxt, req.body))
 | 
				
			||||||
        instance.save()
 | 
					        instance.save()
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1635,6 +1635,20 @@ class MetadataPasswordTestCase(test.TestCase):
 | 
				
			|||||||
        result = password.handle_password(request, self.mdinst)
 | 
					        result = password.handle_password(request, self.mdinst)
 | 
				
			||||||
        self.assertEqual(result, 'foo')
 | 
					        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):
 | 
					    def test_bad_method(self):
 | 
				
			||||||
        request = webob.Request.blank('')
 | 
					        request = webob.Request.blank('')
 | 
				
			||||||
        request.method = 'PUT'
 | 
					        request.method = 'PUT'
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user