Consolidate image_href to image uuid validation code
The server rebuild and rescue APIs were using very similar helper methods for parsing the image uuid out of the image_href request parameter and also validating an image uuid was provided. This moves that into a common utility method so we don't have the copy/paste everywhere. Change-Id: I7c38d576bbfc459f40eba75452cdfc97bdd9e724
This commit is contained in:
@@ -21,6 +21,7 @@ import re
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import strutils
|
||||
from oslo_utils import uuidutils
|
||||
import six
|
||||
import six.moves.urllib.parse as urlparse
|
||||
import webob
|
||||
@@ -567,3 +568,41 @@ def is_all_tenants(search_opts):
|
||||
# The empty string is considered enabling all_tenants
|
||||
all_tenants = 'all_tenants' in search_opts
|
||||
return all_tenants
|
||||
|
||||
|
||||
def image_uuid_from_href(image_href, key):
|
||||
"""If the image href was generated by nova api, strip image_href down to an
|
||||
id and use the default glance connection params
|
||||
|
||||
:param image_href: URL or UUID for an image.
|
||||
:param key: The request body key for the image_href value. This is used in
|
||||
error messages.
|
||||
:returns: The parsed image UUID.
|
||||
:raises: webob.exc.HTTPBadRequest if the image_href does not have a valid
|
||||
image UUID in it.
|
||||
"""
|
||||
if not image_href:
|
||||
# NOTE(mriedem): This error message is copied from how our jsonschema
|
||||
# validation error looks.
|
||||
msg = _("Invalid input for field/attribute %(path)s. "
|
||||
"Value: %(value)s. %(message)s") % {
|
||||
'path': key, 'value': image_href,
|
||||
'message': (
|
||||
'Invalid image reference format. Specify the image '
|
||||
'reference by UUID or full URL.')
|
||||
}
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
image_uuid = image_href.split('/').pop()
|
||||
|
||||
if not uuidutils.is_uuid_like(image_uuid):
|
||||
msg = _("Invalid input for field/attribute %(path)s. "
|
||||
"Value: %(value)s. %(message)s") % {
|
||||
'path': key, 'value': image_href,
|
||||
'message': (
|
||||
'Invalid image reference format. Specify the image '
|
||||
'reference by UUID or full URL.')
|
||||
}
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
return image_uuid
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
"""The rescue mode extension."""
|
||||
|
||||
from oslo_utils import uuidutils
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
@@ -23,7 +22,6 @@ 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
|
||||
|
||||
|
||||
@@ -36,15 +34,6 @@ 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."""
|
||||
@@ -61,8 +50,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 = self._rescue_image_validation(
|
||||
body['rescue']['rescue_image_ref'])
|
||||
rescue_image_ref = common.image_uuid_from_href(
|
||||
body['rescue']['rescue_image_ref'], 'rescue_image_ref')
|
||||
self.compute_api.rescue(context, instance,
|
||||
rescue_password=password, rescue_image_ref=rescue_image_ref)
|
||||
except exception.InstanceIsLocked as e:
|
||||
|
||||
@@ -864,21 +864,6 @@ class Controller(wsgi.Controller):
|
||||
msg = _("Missing imageRef attribute")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
def _image_uuid_from_href(self, image_href):
|
||||
if not image_href:
|
||||
msg = _("Invalid imageRef provided.")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
# If the image href was generated by nova api, strip image_href
|
||||
# down to an id and use the default glance connection params
|
||||
image_uuid = image_href.split('/').pop()
|
||||
|
||||
if not uuidutils.is_uuid_like(image_uuid):
|
||||
msg = _("Invalid imageRef provided.")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
return image_uuid
|
||||
|
||||
def _image_from_req_data(self, data):
|
||||
"""Get image data from the request or raise appropriate
|
||||
exceptions
|
||||
@@ -897,7 +882,7 @@ class Controller(wsgi.Controller):
|
||||
return ''
|
||||
else:
|
||||
image_href = self._image_ref_from_req_data(data)
|
||||
image_uuid = self._image_uuid_from_href(image_href)
|
||||
image_uuid = common.image_uuid_from_href(image_href, 'imageRef')
|
||||
return image_uuid
|
||||
|
||||
def _flavor_id_from_req_data(self, data):
|
||||
@@ -975,7 +960,7 @@ class Controller(wsgi.Controller):
|
||||
msg = _("Could not parse imageRef from request.")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
image_href = self._image_uuid_from_href(image_href)
|
||||
image_href = common.image_uuid_from_href(image_href, 'imageRef')
|
||||
|
||||
password = self._get_server_admin_password(body)
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
"""The rescue mode extension."""
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_utils import uuidutils
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack import common
|
||||
@@ -25,7 +24,6 @@ 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
|
||||
|
||||
|
||||
@@ -42,15 +40,6 @@ 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.
|
||||
@@ -70,8 +59,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 = self._rescue_image_validation(
|
||||
body['rescue']['rescue_image_ref'])
|
||||
rescue_image_ref = common.image_uuid_from_href(
|
||||
body['rescue']['rescue_image_ref'], 'rescue_image_ref')
|
||||
|
||||
try:
|
||||
self.compute_api.rescue(context, instance,
|
||||
|
||||
@@ -952,17 +952,6 @@ class ServersController(wsgi.Controller):
|
||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'delete', id)
|
||||
|
||||
def _image_uuid_from_href(self, image_href):
|
||||
# If the image href was generated by nova api, strip image_href
|
||||
# down to an id and use the default glance connection params
|
||||
image_uuid = image_href.split('/').pop()
|
||||
|
||||
if not uuidutils.is_uuid_like(image_uuid):
|
||||
msg = _("Invalid imageRef provided.")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
return image_uuid
|
||||
|
||||
def _image_from_req_data(self, server_dict, create_kwargs):
|
||||
"""Get image data from the request or raise appropriate
|
||||
exceptions.
|
||||
@@ -975,7 +964,8 @@ class ServersController(wsgi.Controller):
|
||||
if not image_href and create_kwargs.get('block_device_mapping'):
|
||||
return ''
|
||||
elif image_href:
|
||||
return self._image_uuid_from_href(six.text_type(image_href))
|
||||
return common.image_uuid_from_href(six.text_type(image_href),
|
||||
'imageRef')
|
||||
else:
|
||||
msg = _("Missing imageRef attribute")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
@@ -1012,7 +1002,7 @@ class ServersController(wsgi.Controller):
|
||||
rebuild_dict = body['rebuild']
|
||||
|
||||
image_href = rebuild_dict["imageRef"]
|
||||
image_href = self._image_uuid_from_href(image_href)
|
||||
image_href = common.image_uuid_from_href(image_href, 'imageRef')
|
||||
|
||||
password = self._get_server_admin_password(rebuild_dict)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user