Merge "Added validation for rescue image ref" into stable/mitaka

This commit is contained in:
Jenkins 2016-06-09 05:50:54 +00:00 committed by Gerrit Code Review
commit 73820214bf
4 changed files with 46 additions and 7 deletions

View File

@ -14,6 +14,7 @@
"""The rescue mode extension."""
from oslo_utils import uuidutils
import webob
from webob import exc
@ -22,6 +23,7 @@ from nova.api.openstack import extensions as exts
from nova.api.openstack import wsgi
from nova import compute
from nova import exception
from nova.i18n import _
from nova import utils
@ -34,6 +36,15 @@ class RescueController(wsgi.Controller):
self.compute_api = compute.API()
self.ext_mgr = ext_mgr
def _rescue_image_validation(self, image_ref):
image_uuid = image_ref.split('/').pop()
if not uuidutils.is_uuid_like(image_uuid):
msg = _("Invalid rescue_image_ref provided.")
raise exc.HTTPBadRequest(explanation=msg)
return image_uuid
@wsgi.action('rescue')
def _rescue(self, req, id, body):
"""Rescue an instance."""
@ -50,7 +61,8 @@ class RescueController(wsgi.Controller):
rescue_image_ref = None
if self.ext_mgr.is_loaded("os-extended-rescue-with-image"):
if body['rescue'] and 'rescue_image_ref' in body['rescue']:
rescue_image_ref = body['rescue']['rescue_image_ref']
rescue_image_ref = self._rescue_image_validation(
body['rescue']['rescue_image_ref'])
self.compute_api.rescue(context, instance,
rescue_password=password, rescue_image_ref=rescue_image_ref)
except exception.InstanceIsLocked as e:

View File

@ -15,6 +15,7 @@
"""The rescue mode extension."""
from oslo_config import cfg
from oslo_utils import uuidutils
from webob import exc
from nova.api.openstack import common
@ -24,6 +25,7 @@ from nova.api.openstack import wsgi
from nova.api import validation
from nova import compute
from nova import exception
from nova.i18n import _
from nova import utils
@ -40,6 +42,15 @@ class RescueController(wsgi.Controller):
super(RescueController, self).__init__(*args, **kwargs)
self.compute_api = compute.API(skip_policy_check=True)
def _rescue_image_validation(self, image_ref):
image_uuid = image_ref.split('/').pop()
if not uuidutils.is_uuid_like(image_uuid):
msg = _("Invalid rescue_image_ref provided.")
raise exc.HTTPBadRequest(explanation=msg)
return image_uuid
# TODO(cyeoh): Should be responding here with 202 Accept
# because rescue is an async call, but keep to 200
# for backwards compatibility reasons.
@ -59,7 +70,8 @@ class RescueController(wsgi.Controller):
instance = common.get_instance(self.compute_api, context, id)
rescue_image_ref = None
if body['rescue'] and 'rescue_image_ref' in body['rescue']:
rescue_image_ref = body['rescue']['rescue_image_ref']
rescue_image_ref = self._rescue_image_validation(
body['rescue']['rescue_image_ref'])
try:
self.compute_api.rescue(context, instance,

View File

@ -54,7 +54,8 @@ class ExtendedRescueWithImageTest(test.NoDBTestCase):
rescue_password=mock.ANY, rescue_image_ref=rescue_image_ref)
def test_rescue_with_image_specified(self):
body = dict(rescue={"rescue_image_ref": "image-ref"})
body = dict(rescue={
"rescue_image_ref": "76fa36fc-c930-4bf3-8c8a-ea2a2420deb6"})
self._make_rescue_request_with_image_ref(body)
def test_rescue_without_image_specified(self):

View File

@ -44,6 +44,10 @@ def fake_compute_get(*args, **kwargs):
class RescueTestV21(test.NoDBTestCase):
image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
image_href = 'http://localhost/v2/fake/images/%s' % image_uuid
def setUp(self):
super(RescueTestV21, self).setUp()
@ -138,17 +142,27 @@ class RescueTestV21(test.NoDBTestCase):
self.controller._rescue,
self.fake_req, UUID, body=body)
@mock.patch('nova.compute.api.API.rescue')
def test_rescue_with_bad_image_specified(self, mock_compute_api_rescue):
body = {"rescue": {"adminPass": "ABC123",
"rescue_image_ref": "img-id"}}
self.assertRaises(webob.exc.HTTPBadRequest,
self.controller._rescue,
self.fake_req, UUID, body=body)
@mock.patch('nova.compute.api.API.rescue')
def test_rescue_with_image_specified(self, mock_compute_api_rescue):
instance = fake_compute_get()
body = {"rescue": {"adminPass": "ABC123",
"rescue_image_ref": "img-id"}}
"rescue_image_ref": self.image_href}}
resp_json = self.controller._rescue(self.fake_req, UUID, body=body)
self.assertEqual("ABC123", resp_json['adminPass'])
mock_compute_api_rescue.assert_called_with(mock.ANY, instance,
rescue_password=u'ABC123',
rescue_image_ref=u'img-id')
mock_compute_api_rescue.assert_called_with(
mock.ANY,
instance,
rescue_password=u'ABC123',
rescue_image_ref=self.image_uuid)
@mock.patch('nova.compute.api.API.rescue')
def test_rescue_without_image_specified(self, mock_compute_api_rescue):