From b6198396ba8599b5a9c5d8177c44feed9faf4128 Mon Sep 17 00:00:00 2001 From: Rafael Folco Date: Fri, 10 Mar 2017 17:01:32 +0000 Subject: [PATCH] [placement] Raising http codes on old microversion Currently only HTTP 404 can be raised. This enables other HTTP status to be raised if microversion does not match with the minimum required. This is useful for new methods created to raise other http status code for older placement microversions, like 405 HTTPMethodNotAllowed. Change-Id: I2b684fcfd93fc70fe385a93346ee255279909489 --- .../openstack/placement/handlers/aggregate.py | 4 ++-- nova/api/openstack/placement/microversion.py | 17 ++++++++++++--- .../openstack/placement/test_microversion.py | 21 +++++++++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/nova/api/openstack/placement/handlers/aggregate.py b/nova/api/openstack/placement/handlers/aggregate.py index 271159fe1..c48cd450c 100644 --- a/nova/api/openstack/placement/handlers/aggregate.py +++ b/nova/api/openstack/placement/handlers/aggregate.py @@ -52,7 +52,7 @@ def get_aggregates(req): On success return a 200 with an application/json body containing a list of aggregate uuids. """ - microversion.raise_404_if_not_version(req, (1, 1)) + microversion.raise_http_status_code_if_not_version(req, 404, (1, 1)) context = req.environ['placement.context'] uuid = util.wsgi_path_item(req.environ, 'uuid') resource_provider = objects.ResourceProvider.get_by_uuid( @@ -65,7 +65,7 @@ def get_aggregates(req): @webob.dec.wsgify @util.require_content('application/json') def set_aggregates(req): - microversion.raise_404_if_not_version(req, (1, 1)) + microversion.raise_http_status_code_if_not_version(req, 404, (1, 1)) context = req.environ['placement.context'] uuid = util.wsgi_path_item(req.environ, 'uuid') resource_provider = objects.ResourceProvider.get_by_uuid( diff --git a/nova/api/openstack/placement/microversion.py b/nova/api/openstack/placement/microversion.py index 45a3f1193..847127bbf 100644 --- a/nova/api/openstack/placement/microversion.py +++ b/nova/api/openstack/placement/microversion.py @@ -73,11 +73,22 @@ def parse_version_string(version_string): version_string, exc)) -def raise_404_if_not_version(req, min_version, max_version=None): - """Utility to raise a 404 if the wanted microversion does not match.""" +def raise_http_status_code_if_not_version(req, status_code, min_version, + max_version=None): + """Utility to raise a http status code if the wanted microversion does not + match. + + :param req: The HTTP request for the placement api + :param status_code: HTTP status code (integer value) to be raised + :param min_version: Minimum placement microversion level + :param max_version: Maximum placement microversion level + :returns: None + :raises: HTTP status code if the specified microversion does not match + :raises: KeyError if status_code is not a valid HTTP status code + """ want_version = req.environ[MICROVERSION_ENVIRON] if not want_version.matches(min_version, max_version): - raise webob.exc.HTTPNotFound + raise webob.exc.status_map[status_code] class MicroversionMiddleware(object): diff --git a/nova/tests/unit/api/openstack/placement/test_microversion.py b/nova/tests/unit/api/openstack/placement/test_microversion.py index 4c5d96c4a..88b019d38 100644 --- a/nova/tests/unit/api/openstack/placement/test_microversion.py +++ b/nova/tests/unit/api/openstack/placement/test_microversion.py @@ -16,6 +16,7 @@ import collections import operator import mock +import webob # import the handlers to load up handler decorators import nova.api.openstack.placement.handler # noqa @@ -106,3 +107,23 @@ class TestMicroversionIntersection(test.NoDBTestCase): self.assertFalse( self._check_intersection(method_info), 'method %s has intersecting versioned handlers' % method_name) + + +class TestMicroversionUtility(test.NoDBTestCase): + + req = webob.Request.blank('/', method="GET") + req.accept = 'application/json' + + def test_raise_405_out_of_date_version(self): + version_obj = microversion.parse_version_string('1.4') + self.req.environ['placement.microversion'] = version_obj + self.assertRaises(webob.exc.HTTPMethodNotAllowed, + microversion.raise_http_status_code_if_not_version, + self.req, 405, (1, 5)) + + def test_raise_keyerror_out_of_date_version(self): + version_obj = microversion.parse_version_string('1.4') + self.req.environ['placement.microversion'] = version_obj + self.assertRaises(KeyError, + microversion.raise_http_status_code_if_not_version, + self.req, 999, (1, 5))