From e1a743a7eab1aaa8686873fc94249cefebd90e7c Mon Sep 17 00:00:00 2001 From: Mark Washenberger Date: Wed, 19 Oct 2011 14:12:23 -0400 Subject: Use UUIDs instead of IDs for OSAPI servers. Continues to support both UUIDs and IDs in the compute and db layers, but only exposes UUIDs in the ID fields of OSAPI responses. Technically, old ID-based URIs still work, but you likely can't find them any longer. This only affects servers--images and flavors still use integer IDs. Fixes bug 804093 Change-Id: Iecf25c5402f355dd3f227b87a936fcc1b81371b6 --- nova/api/openstack/common.py | 36 ++++++++++++------- nova/api/openstack/contrib/volumes.py | 11 +++--- nova/api/openstack/schemas/v1.1/server.rng | 1 - nova/api/openstack/servers.py | 57 ++++-------------------------- nova/api/openstack/views/servers.py | 9 +++-- 5 files changed, 41 insertions(+), 73 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py index 4a26ee42f..45987d40e 100644 --- a/nova/api/openstack/common.py +++ b/nova/api/openstack/common.py @@ -113,21 +113,31 @@ def get_pagination_params(request): """ params = {} - for param in ['marker', 'limit']: - if not param in request.GET: - continue - try: - params[param] = int(request.GET[param]) - except ValueError: - msg = _('%s param must be an integer') % param - raise webob.exc.HTTPBadRequest(explanation=msg) - if params[param] < 0: - msg = _('%s param must be positive') % param - raise webob.exc.HTTPBadRequest(explanation=msg) - + if 'limit' in request.GET: + params['limit'] = _get_limit_param(request) + if 'marker' in request.GET: + params['marker'] = _get_marker_param(request) return params +def _get_limit_param(request): + """Extract integer limit from request or fail""" + try: + limit = int(request.GET['limit']) + except ValueError: + msg = _('limit param must be an integer') + raise webob.exc.HTTPBadRequest(explanation=msg) + if limit < 0: + msg = _('limit param must be positive') + raise webob.exc.HTTPBadRequest(explanation=msg) + return limit + + +def _get_marker_param(request): + """Extract marker id from request or fail""" + return request.GET['marker'] + + def limited(items, request, max_limit=FLAGS.osapi_max_limit): """ Return a slice of items according to requested offset and limit. @@ -178,7 +188,7 @@ def limited_by_marker(items, request, max_limit=FLAGS.osapi_max_limit): if marker: start_index = -1 for i, item in enumerate(items): - if item['id'] == marker: + if item['id'] == marker or item.get('uuid') == marker: start_index = i + 1 break if start_index < 0: diff --git a/nova/api/openstack/contrib/volumes.py b/nova/api/openstack/contrib/volumes.py index f706ebfe1..da856b4a1 100644 --- a/nova/api/openstack/contrib/volumes.py +++ b/nova/api/openstack/contrib/volumes.py @@ -19,6 +19,7 @@ from webob import exc import webob from nova import compute +from nova import db from nova import exception from nova import flags from nova import log as logging @@ -200,8 +201,8 @@ def _translate_attachment_summary_view(_context, vol): d['id'] = volume_id d['volumeId'] = volume_id - if vol.get('instance_id'): - d['serverId'] = vol['instance_id'] + if vol.get('instance'): + d['serverId'] = vol['instance']['uuid'] if vol.get('mountpoint'): d['device'] = vol['mountpoint'] @@ -245,7 +246,8 @@ class VolumeAttachmentController(object): LOG.debug("volume_id not found") return faults.Fault(exc.HTTPNotFound()) - if str(vol['instance_id']) != server_id: + instance = vol['instance'] + if instance is None or str(instance['uuid']) != server_id: LOG.debug("instance_id != server_id") return faults.Fault(exc.HTTPNotFound()) @@ -307,7 +309,8 @@ class VolumeAttachmentController(object): except exception.NotFound: return faults.Fault(exc.HTTPNotFound()) - if str(vol['instance_id']) != server_id: + instance = vol['instance'] + if instance is None or str(instance['uuid']) != server_id: LOG.debug("instance_id != server_id") return faults.Fault(exc.HTTPNotFound()) diff --git a/nova/api/openstack/schemas/v1.1/server.rng b/nova/api/openstack/schemas/v1.1/server.rng index 4eb1a0b85..2e86ccffe 100644 --- a/nova/api/openstack/schemas/v1.1/server.rng +++ b/nova/api/openstack/schemas/v1.1/server.rng @@ -4,7 +4,6 @@ - diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 23acfe66d..f4844e0e7 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -204,7 +204,7 @@ class Controller(object): return kernel_id, ramdisk_id @staticmethod - def _do_get_kernel_ramdisk_from_image(image_meta): + def _do_get_kernel_ramdisk_from_image(image_meta): """Given an ImageService image_meta, return kernel and ramdisk image ids if present. @@ -585,6 +585,7 @@ class Controller(object): rotation factor to be deleted. """ + context = req.environ["nova.context"] entity = input_dict["createBackup"] try: @@ -607,13 +608,10 @@ class Controller(object): raise exc.HTTPBadRequest(explanation=msg) # preserve link to server in image properties - server_ref = os.path.join(req.application_url, - 'servers', - str(instance_id)) + server_ref = os.path.join(req.application_url, 'servers', instance_id) props = {'instance_ref': server_ref} metadata = entity.get('metadata', {}) - context = req.environ["nova.context"] common.check_img_metadata_quota_limit(context, metadata) try: props.update(metadata) @@ -678,44 +676,6 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) - @exception.novaclient_converter - @scheduler_api.redirect_handler - def get_lock(self, req, id): - """ - return the boolean state of (instance with id)'s lock - - """ - context = req.environ['nova.context'] - try: - self.compute_api.get_lock(context, id) - except Exception: - readable = traceback.format_exc() - LOG.exception(_("Compute.api::get_lock %s"), readable) - raise exc.HTTPUnprocessableEntity() - return webob.Response(status_int=202) - - @exception.novaclient_converter - @scheduler_api.redirect_handler - def get_ajax_console(self, req, id): - """Returns a url to an instance's ajaxterm console.""" - try: - self.compute_api.get_ajax_console(req.environ['nova.context'], - int(id)) - except exception.NotFound: - raise exc.HTTPNotFound() - return webob.Response(status_int=202) - - @exception.novaclient_converter - @scheduler_api.redirect_handler - def get_vnc_console(self, req, id): - """Returns a url to an instance's ajaxterm console.""" - try: - self.compute_api.get_vnc_console(req.environ['nova.context'], - int(id)) - except exception.NotFound: - raise exc.HTTPNotFound() - return webob.Response(status_int=202) - @exception.novaclient_converter @scheduler_api.redirect_handler def diagnostics(self, req, id): @@ -737,7 +697,7 @@ class Controller(object): error=item.error)) return dict(actions=actions) - def resize(self, req, instance_id, flavor_id): + def _resize(self, req, instance_id, flavor_id): """Begin the resize process with given instance/flavor.""" context = req.environ["nova.context"] @@ -870,7 +830,7 @@ class Controller(object): msg = _("Resize requests require 'flavorRef' attribute.") raise exc.HTTPBadRequest(explanation=msg) - return self.resize(req, id, flavor_ref) + return self._resize(req, id, flavor_ref) def _action_rebuild(self, info, request, instance_id): context = request.environ['nova.context'] @@ -915,6 +875,7 @@ class Controller(object): @common.check_snapshots_enabled def _action_create_image(self, input_dict, req, instance_id): """Snapshot a server instance.""" + context = req.environ['nova.context'] entity = input_dict.get("createImage", {}) try: @@ -929,13 +890,10 @@ class Controller(object): raise exc.HTTPBadRequest(explanation=msg) # preserve link to server in image properties - server_ref = os.path.join(req.application_url, - 'servers', - str(instance_id)) + server_ref = os.path.join(req.application_url, 'servers', instance_id) props = {'instance_ref': server_ref} metadata = entity.get('metadata', {}) - context = req.environ['nova.context'] common.check_img_metadata_quota_limit(context, metadata) try: props.update(metadata) @@ -998,7 +956,6 @@ def make_server(elem, detailed=False): elem.set('id') if detailed: - elem.set('uuid') elem.set('userId', 'user_id') elem.set('tenantId', 'tenant_id') elem.set('updated') diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index d756ec04f..288730efe 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -52,13 +52,12 @@ class ViewBuilder(object): server = self._build_simple(inst) self._build_links(server['server'], inst) - server['server']['uuid'] = inst['uuid'] return server def _build_simple(self, inst): """Return a simple model of a server.""" - return dict(server=dict(id=inst['id'], name=inst['display_name'])) + return dict(server=dict(id=inst['uuid'], name=inst['display_name'])) def _build_detail(self, inst): """Returns a detailed model of a server.""" @@ -66,7 +65,7 @@ class ViewBuilder(object): task_state = inst.get('task_state') inst_dict = { - 'id': inst['id'], + 'id': inst['uuid'], 'name': inst['display_name'], 'user_id': inst.get('user_id', ''), 'tenant_id': inst.get('project_id', ''), @@ -137,8 +136,8 @@ class ViewBuilder(object): } def _build_links(self, response, inst): - href = self.generate_href(inst["id"]) - bookmark = self.generate_bookmark(inst["id"]) + href = self.generate_href(inst["uuid"]) + bookmark = self.generate_bookmark(inst["uuid"]) links = [ { -- cgit