From f6964aadc5b073152d221bb0a4e899c2b17d174c Mon Sep 17 00:00:00 2001 From: Rick Harris Date: Thu, 23 Jun 2011 14:27:13 -0500 Subject: Small refactoring around getting params --- nova/api/openstack/images.py | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index 5ffd8e96a..54f8e05a9 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -88,28 +88,53 @@ class Controller(object): return webob.exc.HTTPNoContent() def create(self, req, body): - """Snapshot a server instance and save the image. + """Snapshot or backup a server instance and save the image. + + Images now have an `image_type` associated with them, which can be + 'snapshot' or the backup type, like 'daily' or 'weekly'. + + If the image_type is backup-like, then the rotation factor can be + included and that will cause the oldest backups that exceed the + rotation factor to be deleted. :param req: `wsgi.Request` object """ + def get_param(param): + try: + return body["image"][param] + except KeyError: + raise webob.exc.HTTPBadRequest() + context = req.environ['nova.context'] content_type = req.get_content_type() if not body: raise webob.exc.HTTPBadRequest() + image_type = body["image"].get("image_type", "snapshot") + try: server_id = self._server_id_from_req_data(body) - image_name = body["image"]["name"] except KeyError: raise webob.exc.HTTPBadRequest() - image = self._compute_service.snapshot(context, server_id, image_name) + if image_type == "snapshot": + image_name = get_param("name") + image = self._compute_service.snapshot(context, server_id, + image_name) + else: + if not FLAGS.allow_admin_api: + raise webob.exc.HTTPBadRequest() + + rotation = get_param("rotation") + image = self._compute_service.backup(context, server_id, + image_type, rotation) + return dict(image=self.get_builder(req).build(image, detail=True)) def get_builder(self, request): """Indicates that you must use a Controller subclass.""" - raise NotImplementedError + raise NotImplementedError() def _server_id_from_req_data(self, data): raise NotImplementedError() -- cgit From 2d0d1e179dd8870967ebf00a82fbc7d21bed6116 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Thu, 23 Jun 2011 16:28:59 -0500 Subject: Cast rotation to int. --- nova/api/openstack/images.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index 54f8e05a9..d8dbd2360 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -126,7 +126,7 @@ class Controller(object): if not FLAGS.allow_admin_api: raise webob.exc.HTTPBadRequest() - rotation = get_param("rotation") + rotation = int(get_param("rotation")) image = self._compute_service.backup(context, server_id, image_type, rotation) -- cgit From cbf9f1bef113d54be57e2bb9a79990226afcd90f Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Fri, 24 Jun 2011 11:55:43 -0500 Subject: Adding tests for backup no rotation, invalid image type --- nova/api/openstack/images.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index d8dbd2360..2287ca0f7 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -122,13 +122,17 @@ class Controller(object): image_name = get_param("name") image = self._compute_service.snapshot(context, server_id, image_name) - else: + elif image_type in ("daily", "weekly"): if not FLAGS.allow_admin_api: raise webob.exc.HTTPBadRequest() rotation = int(get_param("rotation")) image = self._compute_service.backup(context, server_id, image_type, rotation) + else: + LOG.error(_("Invalid image_type '%s' passed" % image_type)) + raise webob.exc.HTTPBadRequest() + return dict(image=self.get_builder(req).build(image, detail=True)) -- cgit From 1d3960e3b76e3f75c68f919278a2a227e1f96e48 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Fri, 24 Jun 2011 11:56:15 -0500 Subject: Pep8 fix --- nova/api/openstack/images.py | 1 - 1 file changed, 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index 2287ca0f7..5f88ede96 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -133,7 +133,6 @@ class Controller(object): LOG.error(_("Invalid image_type '%s' passed" % image_type)) raise webob.exc.HTTPBadRequest() - return dict(image=self.get_builder(req).build(image, detail=True)) def get_builder(self, request): -- cgit From 594d5c7a98f2b4e6ea2d866f10c67cbdaa88ce0c Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Fri, 24 Jun 2011 15:03:01 -0500 Subject: Refactored backup rotate. --- nova/api/openstack/images.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index 5f88ede96..c535e4e26 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -118,19 +118,25 @@ class Controller(object): except KeyError: raise webob.exc.HTTPBadRequest() + image_name = get_param("name") + if image_type == "snapshot": - image_name = get_param("name") - image = self._compute_service.snapshot(context, server_id, - image_name) - elif image_type in ("daily", "weekly"): + image = self._compute_service.snapshot( + context, server_id, image_name) + elif image_type == "backup": + # NOTE(sirp): Unlike snapshot, backup is not a customer facing + # API call; rather, it's used by the internal backup scheduler if not FLAGS.allow_admin_api: raise webob.exc.HTTPBadRequest() + backup_type = get_param("backup_type") rotation = int(get_param("rotation")) - image = self._compute_service.backup(context, server_id, - image_type, rotation) + + image = self._compute_service.backup( + context, server_id, image_name, + backup_type, rotation) else: - LOG.error(_("Invalid image_type '%s' passed" % image_type)) + LOG.error(_("Invalid image_type '%s' passed") % image_type) raise webob.exc.HTTPBadRequest() return dict(image=self.get_builder(req).build(image, detail=True)) -- cgit From 2916aa40f6dc0b06217ff7d3750ecdd3bb03e4fd Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Tue, 28 Jun 2011 16:03:41 -0500 Subject: Review feedback. --- nova/api/openstack/images.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index 44d8c94a4..7ebf58023 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -105,7 +105,8 @@ class Controller(object): try: return body["image"][param] except KeyError: - raise webob.exc.HTTPBadRequest() + raise webob.exc.HTTPBadRequest(explanation="Missing required " + "param: %s" % param) context = req.environ['nova.context'] content_type = req.get_content_type() @@ -131,7 +132,8 @@ class Controller(object): # NOTE(sirp): Unlike snapshot, backup is not a customer facing # API call; rather, it's used by the internal backup scheduler if not FLAGS.allow_admin_api: - raise webob.exc.HTTPBadRequest() + raise webob.exc.HTTPBadRequest( + explanation="Admin API Required") backup_type = get_param("backup_type") rotation = int(get_param("rotation")) @@ -141,7 +143,8 @@ class Controller(object): backup_type, rotation, extra_properties=props) else: LOG.error(_("Invalid image_type '%s' passed") % image_type) - raise webob.exc.HTTPBadRequest() + raise webob.exc.HTTPBadRequest(explanation="Invalue image_type: " + "%s" % image_type) return dict(image=self.get_builder(req).build(image, detail=True)) -- cgit From 74c222b6b4042053cc8c2d0038f37b3f8ee8b9fc Mon Sep 17 00:00:00 2001 From: Mark Washenberger Date: Wed, 29 Jun 2011 14:52:56 -0400 Subject: don't pass zero in to glance image service if no limit or marker are present --- nova/api/openstack/common.py | 37 +++++++++++++++++-------------------- nova/api/openstack/images.py | 12 ++++++------ 2 files changed, 23 insertions(+), 26 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py index 4da7ec0ef..aa8911b62 100644 --- a/nova/api/openstack/common.py +++ b/nova/api/openstack/common.py @@ -45,23 +45,20 @@ def get_pagination_params(request): exc.HTTPBadRequest() exceptions to be raised. """ - try: - marker = int(request.GET.get('marker', 0)) - except ValueError: - raise webob.exc.HTTPBadRequest(_('marker param must be an integer')) - - try: - limit = int(request.GET.get('limit', 0)) - except ValueError: - raise webob.exc.HTTPBadRequest(_('limit param must be an integer')) - - if limit < 0: - raise webob.exc.HTTPBadRequest(_('limit param must be positive')) - - if marker < 0: - raise webob.exc.HTTPBadRequest(_('marker param must be positive')) - - return(marker, limit) + 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(msg) + if params[param] < 0: + msg = _('%s param must be positive') % param + raise webob.exc.HTTPBadRequest(msg) + + return params def limited(items, request, max_limit=FLAGS.osapi_max_limit): @@ -100,10 +97,10 @@ def limited(items, request, max_limit=FLAGS.osapi_max_limit): def limited_by_marker(items, request, max_limit=FLAGS.osapi_max_limit): """Return a slice of items according to the requested marker and limit.""" - (marker, limit) = get_pagination_params(request) + params = get_pagination_params(request) - if limit == 0: - limit = max_limit + limit = params.get('limit', max_limit) + marker = params.get('marker') limit = min(max_limit, limit) start_index = 0 diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index d43340e10..64d003a0f 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -181,9 +181,9 @@ class ControllerV11(Controller): """ context = req.environ['nova.context'] filters = self._get_filters(req) - (marker, limit) = common.get_pagination_params(req) - images = self._image_service.index( - context, filters=filters, marker=marker, limit=limit) + page_params = common.get_pagination_params(req) + images = self._image_service.index(context, filters=filters, + **page_params) builder = self.get_builder(req).build return dict(images=[builder(image, detail=False) for image in images]) @@ -195,9 +195,9 @@ class ControllerV11(Controller): """ context = req.environ['nova.context'] filters = self._get_filters(req) - (marker, limit) = common.get_pagination_params(req) - images = self._image_service.detail( - context, filters=filters, marker=marker, limit=limit) + page_params = common.get_pagination_params(req) + images = self._image_service.detail(context, filters=filters, + **page_params) builder = self.get_builder(req).build return dict(images=[builder(image, detail=True) for image in images]) -- cgit