[placement] Mark HTTP error responses for translation

The HTTP responses that are errors and provided messages to the
client should be marked for translation. This change does that.

Change-Id: If22270768c2e6cdb810e0e08b3a4ab7a42bf828d
Closes-Bug: #1621888
This commit is contained in:
Chris Dent 2016-09-12 20:00:08 +00:00 committed by Matt Riedemann
parent 5b207f9a13
commit a4b5b0c859
6 changed files with 70 additions and 48 deletions

View File

@ -35,7 +35,7 @@ from nova.api.openstack.placement.handlers import root
from nova.api.openstack.placement.handlers import usage from nova.api.openstack.placement.handlers import usage
from nova.api.openstack.placement import util from nova.api.openstack.placement import util
from nova import exception from nova import exception
from nova.i18n import _LE from nova.i18n import _, _LE
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -109,7 +109,7 @@ def handle_405(environ, start_response):
if _methods: if _methods:
headers['allow'] = _methods headers['allow'] = _methods
raise webob.exc.HTTPMethodNotAllowed( raise webob.exc.HTTPMethodNotAllowed(
'The method specified is not allowed for this resource.', _('The method specified is not allowed for this resource.'),
headers=headers, json_formatter=util.json_error_formatter) headers=headers, json_formatter=util.json_error_formatter)
@ -152,7 +152,7 @@ class PlacementHandler(object):
# integrated yet. # integrated yet.
if 'admin' not in context.to_policy_values()['roles']: if 'admin' not in context.to_policy_values()['roles']:
raise webob.exc.HTTPForbidden( raise webob.exc.HTTPForbidden(
'admin required', _('admin required'),
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
try: try:
return dispatch(environ, start_response, self._map) return dispatch(environ, start_response, self._map)

View File

@ -20,7 +20,7 @@ import webob
from nova.api.openstack.placement import util from nova.api.openstack.placement import util
from nova import exception from nova import exception
from nova.i18n import _LE from nova.i18n import _, _LE
from nova import objects from nova import objects
@ -96,14 +96,14 @@ def _extract_allocations(body, schema):
data = jsonutils.loads(body) data = jsonutils.loads(body)
except ValueError as exc: except ValueError as exc:
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
'Malformed JSON: %s' % exc, _('Malformed JSON: %(error)s') % {'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
try: try:
jsonschema.validate(data, schema, jsonschema.validate(data, schema,
format_checker=jsonschema.FormatChecker()) format_checker=jsonschema.FormatChecker())
except jsonschema.ValidationError as exc: except jsonschema.ValidationError as exc:
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
'JSON does not validate: %s' % exc, _('JSON does not validate: %(error)s') % {'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
return data return data
@ -197,7 +197,8 @@ def list_for_resource_provider(req):
context, uuid) context, uuid)
except exception.NotFound as exc: except exception.NotFound as exc:
raise webob.exc.HTTPNotFound( raise webob.exc.HTTPNotFound(
"Resource provider '%s' not found: %s" % (uuid, exc), _("Resource provider '%(rp_uuid)s' not found: %(error)s") %
{'rp_uuid': uuid, 'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
allocations = objects.AllocationList.get_all_by_resource_provider_uuid( allocations = objects.AllocationList.get_all_by_resource_provider_uuid(
@ -232,8 +233,9 @@ def set_allocations(req):
context, resource_provider_uuid) context, resource_provider_uuid)
except exception.NotFound: except exception.NotFound:
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
"Allocation for resource provider '%s' " _("Allocation for resource provider '%(rp_uuid)s' "
"that does not exist." % resource_provider_uuid, "that does not exist.") %
{'rp_uuid': resource_provider_uuid},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
resources = allocation['resources'] resources = allocation['resources']
@ -246,9 +248,10 @@ def set_allocations(req):
used=resources[resource_class]) used=resources[resource_class])
except ValueError as exc: except ValueError as exc:
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
"Allocation of class '%s' for " _("Allocation of class '%(class)s' for "
"resource provider '%s' invalid: " "resource provider '%(rp_uuid)s' invalid: %(error)s") %
"%s" % (resource_class, resource_provider_uuid, exc)) {'class': resource_class, 'rp_uuid':
resource_provider_uuid, 'error': exc})
allocation_objects.append(allocation) allocation_objects.append(allocation)
allocations = objects.AllocationList(context, objects=allocation_objects) allocations = objects.AllocationList(context, objects=allocation_objects)
@ -262,12 +265,13 @@ def set_allocations(req):
except exception.InvalidInventory as exc: except exception.InvalidInventory as exc:
LOG.exception(_LE("Bad inventory")) LOG.exception(_LE("Bad inventory"))
raise webob.exc.HTTPConflict( raise webob.exc.HTTPConflict(
'Unable to allocate inventory: %s' % exc, _('Unable to allocate inventory: %(error)s') % {'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
except exception.ConcurrentUpdateDetected as exc: except exception.ConcurrentUpdateDetected as exc:
LOG.exception(_LE("Concurrent Update")) LOG.exception(_LE("Concurrent Update"))
raise webob.exc.HTTPConflict( raise webob.exc.HTTPConflict(
'Inventory changed while attempting to allocate: %s' % exc, _('Inventory changed while attempting to allocate: %(error)s') %
{'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
req.response.status = 204 req.response.status = 204
@ -284,7 +288,8 @@ def delete_allocations(req):
context, consumer_uuid) context, consumer_uuid)
if not allocations: if not allocations:
raise webob.exc.HTTPNotFound( raise webob.exc.HTTPNotFound(
"No allocations for consumer '%s'" % consumer_uuid, _("No allocations for consumer '%(consumer_uuid)s'") %
{'consumer_uuid': consumer_uuid},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
allocations.delete_all() allocations.delete_all()
LOG.debug("Successfully deleted allocations %s", allocations) LOG.debug("Successfully deleted allocations %s", allocations)

View File

@ -20,6 +20,7 @@ import webob
from nova.api.openstack.placement import util from nova.api.openstack.placement import util
from nova import exception from nova import exception
from nova.i18n import _
from nova import objects from nova import objects
RESOURCE_CLASS_IDENTIFIER = "^[A-Z0-9_]+$" RESOURCE_CLASS_IDENTIFIER = "^[A-Z0-9_]+$"
@ -109,13 +110,13 @@ def _extract_json(body, schema):
data = jsonutils.loads(body) data = jsonutils.loads(body)
except ValueError as exc: except ValueError as exc:
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
'Malformed JSON: %s' % exc, _('Malformed JSON: %(error)s') % {'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
try: try:
jsonschema.validate(data, schema) jsonschema.validate(data, schema)
except jsonschema.ValidationError as exc: except jsonschema.ValidationError as exc:
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
'JSON does not validate: %s' % exc, _('JSON does not validate: %(error)s') % {'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
return data return data
@ -156,8 +157,10 @@ def _make_inventory_object(resource_provider, resource_class, **data):
resource_class=resource_class, **data) resource_class=resource_class, **data)
except (ValueError, TypeError) as exc: except (ValueError, TypeError) as exc:
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
'Bad inventory %s for resource provider %s: %s' _('Bad inventory %(class)s for resource provider '
% (resource_class, resource_provider.uuid, exc), '%(rp_uuid)s: %(error)s') % {'class': resource_class,
'rp_uuid': resource_provider.uuid,
'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
return inventory return inventory
@ -226,12 +229,13 @@ def create_inventory(req):
except (exception.ConcurrentUpdateDetected, except (exception.ConcurrentUpdateDetected,
db_exc.DBDuplicateEntry) as exc: db_exc.DBDuplicateEntry) as exc:
raise webob.exc.HTTPConflict( raise webob.exc.HTTPConflict(
'Update conflict: %s' % exc, _('Update conflict: %(error)s') % {'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
except exception.InvalidInventoryCapacity as exc: except exception.InvalidInventoryCapacity as exc:
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
'Unable to create inventory for resource provider %s: %s' _('Unable to create inventory for resource provider '
% (resource_provider.uuid, exc), '%(rp_uuid)s: %(error)s') % {'rp_uuid': resource_provider.uuid,
'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
response = req.response response = req.response
@ -261,8 +265,8 @@ def delete_inventory(req):
except (exception.ConcurrentUpdateDetected, except (exception.ConcurrentUpdateDetected,
exception.InventoryInUse) as exc: exception.InventoryInUse) as exc:
raise webob.exc.HTTPConflict( raise webob.exc.HTTPConflict(
'Unable to delete inventory of class %s: %s' % ( _('Unable to delete inventory of class %(class)s: %(error)s') %
resource_class, exc), {'class': resource_class, 'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
response = req.response response = req.response
@ -308,8 +312,8 @@ def get_inventory(req):
if not inventory: if not inventory:
raise webob.exc.HTTPNotFound( raise webob.exc.HTTPNotFound(
'No inventory of class %s for %s' _('No inventory of class %(class)s for %(rp_uuid)s') %
% (resource_class, resource_provider.uuid), {'class': resource_class, 'rp_uuid': resource_provider.uuid},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
return _send_inventory(req.response, resource_provider, inventory) return _send_inventory(req.response, resource_provider, inventory)
@ -339,7 +343,7 @@ def set_inventories(req):
data = _extract_inventories(req.body, PUT_INVENTORY_SCHEMA) data = _extract_inventories(req.body, PUT_INVENTORY_SCHEMA)
if data['resource_provider_generation'] != resource_provider.generation: if data['resource_provider_generation'] != resource_provider.generation:
raise webob.exc.HTTPConflict( raise webob.exc.HTTPConflict(
'resource provider generation conflict', _('resource provider generation conflict'),
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
inv_list = [] inv_list = []
@ -355,12 +359,13 @@ def set_inventories(req):
exception.InventoryInUse, exception.InventoryInUse,
db_exc.DBDuplicateEntry) as exc: db_exc.DBDuplicateEntry) as exc:
raise webob.exc.HTTPConflict( raise webob.exc.HTTPConflict(
'update conflict: %s' % exc, _('update conflict: %(error)s') % {'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
except exception.InvalidInventoryCapacity as exc: except exception.InvalidInventoryCapacity as exc:
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
'Unable to update inventory for resource provider %s: %s' _('Unable to update inventory for resource provider '
% (resource_provider.uuid, exc), '%(rp_uuid)s: %(error)s') % {'rp_uuid': resource_provider.uuid,
'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
return _send_inventories(req.response, resource_provider, inventories) return _send_inventories(req.response, resource_provider, inventories)
@ -388,7 +393,7 @@ def update_inventory(req):
data = _extract_inventory(req.body, BASE_INVENTORY_SCHEMA) data = _extract_inventory(req.body, BASE_INVENTORY_SCHEMA)
if data['resource_provider_generation'] != resource_provider.generation: if data['resource_provider_generation'] != resource_provider.generation:
raise webob.exc.HTTPConflict( raise webob.exc.HTTPConflict(
'resource provider generation conflict', _('resource provider generation conflict'),
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
inventory = _make_inventory_object(resource_provider, inventory = _make_inventory_object(resource_provider,
@ -400,12 +405,13 @@ def update_inventory(req):
except (exception.ConcurrentUpdateDetected, except (exception.ConcurrentUpdateDetected,
db_exc.DBDuplicateEntry) as exc: db_exc.DBDuplicateEntry) as exc:
raise webob.exc.HTTPConflict( raise webob.exc.HTTPConflict(
'update conflict: %s' % exc, _('update conflict: %(error)s') % {'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
except exception.InvalidInventoryCapacity as exc: except exception.InvalidInventoryCapacity as exc:
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
'Unable to update inventory for resource provider %s: %s' _('Unable to update inventory for resource provider '
% (resource_provider.uuid, exc), '%(rp_uuid)s: %(error)s') % {'rp_uuid': resource_provider.uuid,
'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
return _send_inventory(req.response, resource_provider, inventory) return _send_inventory(req.response, resource_provider, inventory)

View File

@ -21,6 +21,7 @@ import webob
from nova.api.openstack.placement import util from nova.api.openstack.placement import util
from nova import exception from nova import exception
from nova.i18n import _
from nova import objects from nova import objects
@ -51,14 +52,14 @@ def _extract_resource_provider(body, schema):
data = jsonutils.loads(body) data = jsonutils.loads(body)
except ValueError as exc: except ValueError as exc:
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
'Malformed JSON: %s' % exc, _('Malformed JSON: %(error)s') % {'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
try: try:
jsonschema.validate(data, schema, jsonschema.validate(data, schema,
format_checker=jsonschema.FormatChecker()) format_checker=jsonschema.FormatChecker())
except jsonschema.ValidationError as exc: except jsonschema.ValidationError as exc:
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
'JSON does not validate: %s' % exc, _('JSON does not validate: %(error)s') % {'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
return data return data
@ -109,11 +110,13 @@ def create_resource_provider(req):
resource_provider.create() resource_provider.create()
except db_exc.DBDuplicateEntry as exc: except db_exc.DBDuplicateEntry as exc:
raise webob.exc.HTTPConflict( raise webob.exc.HTTPConflict(
'Conflicting resource provider already exists: %s' % exc, _('Conflicting resource provider already exists: %(error)s') %
{'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
except exception.ObjectActionError as exc: except exception.ObjectActionError as exc:
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
'Unable to create resource provider %s: %s' % (uuid, exc), _('Unable to create resource provider %(rp_uuid)s: %(error)s') %
{'rp_uuid': uuid, 'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
req.response.location = util.resource_provider_url( req.response.location = util.resource_provider_url(
@ -138,7 +141,8 @@ def delete_resource_provider(req):
resource_provider.destroy() resource_provider.destroy()
except exception.ResourceProviderInUse as exc: except exception.ResourceProviderInUse as exc:
raise webob.exc.HTTPConflict( raise webob.exc.HTTPConflict(
'Unable to delete resource provider %s: %s' % (uuid, exc), _('Unable to delete resource provider %(rp_uuid)s: %(error)s') %
{'rp_uuid': uuid, 'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
req.response.status = 204 req.response.status = 204
req.response.content_type = None req.response.content_type = None
@ -181,12 +185,13 @@ def list_resource_providers(req):
invalid_filters = passed_filters - allowed_filters invalid_filters = passed_filters - allowed_filters
if invalid_filters: if invalid_filters:
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
'Invalid filters: %s' % ', '.join(invalid_filters), _('Invalid filters: %(filters)s') %
{'filters': ', '.join(invalid_filters)},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
if 'uuid' in req.GET and not uuidutils.is_uuid_like(req.GET['uuid']): if 'uuid' in req.GET and not uuidutils.is_uuid_like(req.GET['uuid']):
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
'Invalid uuid value: %s' % req.GET['uuid'], _('Invalid uuid value: %(uuid)s') % {'uuid': req.GET['uuid']},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
filters = {} filters = {}
@ -227,11 +232,13 @@ def update_resource_provider(req):
resource_provider.save() resource_provider.save()
except db_exc.DBDuplicateEntry as exc: except db_exc.DBDuplicateEntry as exc:
raise webob.exc.HTTPConflict( raise webob.exc.HTTPConflict(
'Conflicting resource provider already exists: %s' % exc, _('Conflicting resource provider already exists: %(error)s') %
{'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
except exception.ObjectActionError as exc: except exception.ObjectActionError as exc:
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
'Unable to save resource provider %s: %s' % (uuid, exc), _('Unable to save resource provider %(rp_uuid)s: %(error)s') %
{'rp_uuid': uuid, 'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
req.response.body = jsonutils.dumps( req.response.body = jsonutils.dumps(

View File

@ -24,6 +24,7 @@ import webob
# NOTE(cdent): avoid cyclical import conflict between util and # NOTE(cdent): avoid cyclical import conflict between util and
# microversion # microversion
import nova.api.openstack.placement.util import nova.api.openstack.placement.util
from nova.i18n import _
SERVICE_TYPE = 'placement' SERVICE_TYPE = 'placement'
@ -78,11 +79,11 @@ class MicroversionMiddleware(object):
microversion = extract_version(req.headers) microversion = extract_version(req.headers)
except ValueError as exc: except ValueError as exc:
raise webob.exc.HTTPNotAcceptable( raise webob.exc.HTTPNotAcceptable(
'Invalid microversion: %s' % exc, _('Invalid microversion: %(error)s') % {'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
except TypeError as exc: except TypeError as exc:
raise webob.exc.HTTPBadRequest( raise webob.exc.HTTPBadRequest(
'Invalid microversion: %s' % exc, _('Invalid microversion: %(error)s') % {'error': exc},
json_formatter=util.json_error_formatter) json_formatter=util.json_error_formatter)
req.environ[MICROVERSION_ENVIRON] = microversion req.environ[MICROVERSION_ENVIRON] = microversion

View File

@ -20,6 +20,7 @@ import webob
# NOTE(cdent): avoid cyclical import conflict between util and # NOTE(cdent): avoid cyclical import conflict between util and
# microversion # microversion
import nova.api.openstack.placement.microversion import nova.api.openstack.placement.microversion
from nova.i18n import _
# NOTE(cdent): This registers a FormatChecker on the jsonschema # NOTE(cdent): This registers a FormatChecker on the jsonschema
@ -51,7 +52,7 @@ def check_accept(*types):
if not best_match: if not best_match:
type_string = ', '.join(types) type_string = ', '.join(types)
raise webob.exc.HTTPNotAcceptable( raise webob.exc.HTTPNotAcceptable(
'Only %s is provided' % type_string, _('Only %(type)s is provided') % {'type': type_string},
json_formatter=json_error_formatter) json_formatter=json_error_formatter)
return f(req) return f(req)
return decorated_function return decorated_function
@ -107,8 +108,10 @@ def require_content(content_type):
# set it the error message content to 'None' to make # set it the error message content to 'None' to make
# a useful message in that case. # a useful message in that case.
raise webob.exc.HTTPUnsupportedMediaType( raise webob.exc.HTTPUnsupportedMediaType(
'The media type %s is not supported, use %s' _('The media type %(bad_type)s is not supported, '
% (req.content_type or 'None', content_type), 'use %(good_type)s') %
{'bad_type': req.content_type or 'None',
'good_type': content_type},
json_formatter=json_error_formatter) json_formatter=json_error_formatter)
else: else:
return f(req) return f(req)