def test_microversion_406_handling(self): body = '' status = '400 Bad Request' title = '' # Not a 406, no version info required. result = util.json_error_formatter( body, status, title, self.environ) self.assertNotIn('max_version', result['errors'][0]) self.assertNotIn('min_version', result['errors'][0]) # A 406 but not because of microversions (microversion # parsing was successful), no version info # required. status = '406 Not Acceptable' version_obj = microversion.parse_version_string('2.3') self.environ[microversion.MICROVERSION_ENVIRON] = version_obj result = util.json_error_formatter( body, status, title, self.environ) self.assertNotIn('max_version', result['errors'][0]) self.assertNotIn('min_version', result['errors'][0]) # Microversion parsing failed, status is 406, send version info. del self.environ[microversion.MICROVERSION_ENVIRON] result = util.json_error_formatter( body, status, title, self.environ) self.assertEqual(microversion.max_version_string(), result['errors'][0]['max_version']) self.assertEqual(microversion.min_version_string(), result['errors'][0]['min_version'])
def json_error_formatter(body, status, title, environ): """A json_formatter for webob exceptions. Follows API-WG guidelines at http://specs.openstack.org/openstack/api-wg/guidelines/errors.html """ # Clear out the html that webob sneaks in. body = webob.exc.strip_tags(body) # Get status code out of status message. webob's error formatter # only passes entire status string. status_code = int(status.split(None, 1)[0]) error_dict = { 'status': status_code, 'title': title, 'detail': body } # If the request id middleware has had a chance to add an id, # put it in the error response. if request_id.ENV_REQUEST_ID in environ: error_dict['request_id'] = environ[request_id.ENV_REQUEST_ID] # When there is a no microversion in the environment and a 406, # microversion parsing failed so we need to include microversion # min and max information in the error response. microversion = nova.api.openstack.placement.microversion if status_code == 406 and microversion.MICROVERSION_ENVIRON not in environ: error_dict['max_version'] = microversion.max_version_string() error_dict['min_version'] = microversion.min_version_string() return {'errors': [error_dict]}
def json_error_formatter(body, status, title, environ): """A json_formatter for webob exceptions. Follows API-WG guidelines at http://specs.openstack.org/openstack/api-wg/guidelines/errors.html """ # Clear out the html that webob sneaks in. body = webob.exc.strip_tags(body) # Get status code out of status message. webob's error formatter # only passes entire status string. status_code = int(status.split(None, 1)[0]) error_dict = {'status': status_code, 'title': title, 'detail': body} # If the request id middleware has had a chance to add an id, # put it in the error response. if request_id.ENV_REQUEST_ID in environ: error_dict['request_id'] = environ[request_id.ENV_REQUEST_ID] # When there is a no microversion in the environment and a 406, # microversion parsing failed so we need to include microversion # min and max information in the error response. microversion = nova.api.openstack.placement.microversion if status_code == 406 and microversion.MICROVERSION_ENVIRON not in environ: error_dict['max_version'] = microversion.max_version_string() error_dict['min_version'] = microversion.min_version_string() return {'errors': [error_dict]}
def home(req): want_version = req.environ[microversion.MICROVERSION_ENVIRON] min_version = microversion.min_version_string() max_version = microversion.max_version_string() # NOTE(cdent): As sections of the api are added, links can be # added to this output to align with the guidelines at # http://specs.openstack.org/openstack/api-wg/guidelines/microversion_specification.html#version-discovery version_data = { 'id': 'v%s' % min_version, 'max_version': max_version, 'min_version': min_version, # for now there is only ever one version, so it must be CURRENT 'status': 'CURRENT', 'links': [{ # Point back to this same URL as the root of this version. # NOTE(cdent): We explicitly want this to be a relative-URL # representation of "this same URL", otherwise placement needs # to keep track of proxy addresses and the like, which we have # avoided thus far, in order to construct full URLs. Placement # is much easier to scale if we never track that stuff. 'rel': 'self', 'href': '', }], } version_json = jsonutils.dumps({'versions': [version_data]}) req.response.body = encodeutils.to_utf8(version_json) req.response.content_type = 'application/json' if want_version.matches((1, 15)): req.response.cache_control = 'no-cache' req.response.last_modified = timeutils.utcnow(with_timezone=True) return req.response
def do_parse(qstring, version=(1, 18)): """Converts a querystring to a MultiDict, mimicking request.GET, and runs parse_qs_request_groups on it. """ req = webob.Request.blank('?' + qstring) mv_parsed = microversion_parse.Version(*version) mv_parsed.max_version = microversion_parse.parse_version_string( microversion.max_version_string()) mv_parsed.min_version = microversion_parse.parse_version_string( microversion.min_version_string()) req.environ['placement.microversion'] = mv_parsed return util.parse_qs_request_groups(req)
def do_parse(qstring, version=(1, 18)): """Converts a querystring to a MultiDict, mimicking request.GET, and runs parse_qs_request_groups on it. """ req = webob.Request.blank('?' + qstring) mv_parsed = microversion_parse.Version(*version) mv_parsed.max_version = microversion_parse.parse_version_string( microversion.max_version_string()) mv_parsed.min_version = microversion_parse.parse_version_string( microversion.min_version_string()) req.environ['placement.microversion'] = mv_parsed d = util.parse_qs_request_groups(req) # Sort for easier testing return [d[suff] for suff in sorted(d)]
def setUp(self): super(TestEnsureConsumer, self).setUp() self.mock_project_get = self.useFixture(fixtures.MockPatch( 'nova.api.openstack.placement.objects.project.' 'Project.get_by_external_id')).mock self.mock_user_get = self.useFixture(fixtures.MockPatch( 'nova.api.openstack.placement.objects.user.' 'User.get_by_external_id')).mock self.mock_consumer_get = self.useFixture(fixtures.MockPatch( 'nova.api.openstack.placement.objects.consumer.' 'Consumer.get_by_uuid')).mock self.mock_project_create = self.useFixture(fixtures.MockPatch( 'nova.api.openstack.placement.objects.project.' 'Project.create')).mock self.mock_user_create = self.useFixture(fixtures.MockPatch( 'nova.api.openstack.placement.objects.user.' 'User.create')).mock self.mock_consumer_create = self.useFixture(fixtures.MockPatch( 'nova.api.openstack.placement.objects.consumer.' 'Consumer.create')).mock self.ctx = mock.sentinel.ctx self.consumer_id = uuidsentinel.consumer self.project_id = uuidsentinel.project self.user_id = uuidsentinel.user mv_parsed = microversion_parse.Version(1, 27) mv_parsed.max_version = microversion_parse.parse_version_string( microversion.max_version_string()) mv_parsed.min_version = microversion_parse.parse_version_string( microversion.min_version_string()) self.before_version = mv_parsed mv_parsed = microversion_parse.Version(1, 28) mv_parsed.max_version = microversion_parse.parse_version_string( microversion.max_version_string()) mv_parsed.min_version = microversion_parse.parse_version_string( microversion.min_version_string()) self.after_version = mv_parsed
def home(req): min_version = microversion.min_version_string() max_version = microversion.max_version_string() # NOTE(cdent): As sections of the api are added, links can be # added to this output to align with the guidelines at # http://specs.openstack.org/openstack/api-wg/guidelines/microversion_specification.html#version-discovery version_data = { 'id': 'v%s' % min_version, 'max_version': max_version, 'min_version': min_version, } version_json = jsonutils.dumps({'versions': [version_data]}) req.response.body = encodeutils.to_utf8(version_json) req.response.content_type = 'application/json' return req.response
def home(req): min_version = microversion.min_version_string() max_version = microversion.max_version_string() # NOTE(cdent): As sections of the api are added, links can be # added to this output to align with the guidelines at # http://specs.openstack.org/openstack/api-wg/guidelines/microversion_specification.html#version-discovery version_data = { 'id': 'v%s' % min_version, 'max_version': max_version, 'min_version': min_version, } version_json = jsonutils.dumps({'versions': [version_data]}) req.response.body = version_json req.response.content_type = 'application/json' return req.response
def setUp(self): super(TestEnsureConsumer, self).setUp() self.mock_project_get = self.useFixture( fixtures.MockPatch('nova.api.openstack.placement.objects.project.' 'Project.get_by_external_id')).mock self.mock_user_get = self.useFixture( fixtures.MockPatch('nova.api.openstack.placement.objects.user.' 'User.get_by_external_id')).mock self.mock_consumer_get = self.useFixture( fixtures.MockPatch('nova.api.openstack.placement.objects.consumer.' 'Consumer.get_by_uuid')).mock self.mock_project_create = self.useFixture( fixtures.MockPatch('nova.api.openstack.placement.objects.project.' 'Project.create')).mock self.mock_user_create = self.useFixture( fixtures.MockPatch('nova.api.openstack.placement.objects.user.' 'User.create')).mock self.mock_consumer_create = self.useFixture( fixtures.MockPatch('nova.api.openstack.placement.objects.consumer.' 'Consumer.create')).mock self.ctx = mock.sentinel.ctx self.consumer_id = uuidsentinel.consumer self.project_id = uuidsentinel.project self.user_id = uuidsentinel.user mv_parsed = microversion_parse.Version(1, 27) mv_parsed.max_version = microversion_parse.parse_version_string( microversion.max_version_string()) mv_parsed.min_version = microversion_parse.parse_version_string( microversion.min_version_string()) self.before_version = mv_parsed mv_parsed = microversion_parse.Version(1, 28) mv_parsed.max_version = microversion_parse.parse_version_string( microversion.max_version_string()) mv_parsed.min_version = microversion_parse.parse_version_string( microversion.min_version_string()) self.after_version = mv_parsed
def home(req): want_version = req.environ[microversion.MICROVERSION_ENVIRON] min_version = microversion.min_version_string() max_version = microversion.max_version_string() # NOTE(cdent): As sections of the api are added, links can be # added to this output to align with the guidelines at # http://specs.openstack.org/openstack/api-wg/guidelines/microversion_specification.html#version-discovery version_data = { 'id': 'v%s' % min_version, 'max_version': max_version, 'min_version': min_version, } version_json = jsonutils.dumps({'versions': [version_data]}) req.response.body = encodeutils.to_utf8(version_json) req.response.content_type = 'application/json' if want_version.matches((1, 15)): req.response.cache_control = 'no-cache' req.response.last_modified = timeutils.utcnow(with_timezone=True) return req.response