예제 #1
0
    def validate_integer(value, name, min_value=None, max_value=None):
        """Make sure that value is a valid integer, potentially within range.

        :param value: the value of the integer
        :param name: the name of the integer
        :param min_length: the min_length of the integer
        :param max_length: the max_length of the integer
        :returns: integer
        """
        try:
            value = int(value)
        except (TypeError, ValueError, UnicodeEncodeError):
            raise webob.exc.HTTPBadRequest(explanation=(
                _('%s must be an integer.') % name))

        if min_value is not None and value < min_value:
            raise webob.exc.HTTPBadRequest(
                explanation=(_('%(value_name)s must be >= %(min_value)d') %
                             {'value_name': name, 'min_value': min_value}))
        if max_value is not None and value > max_value:
            raise webob.exc.HTTPBadRequest(
                explanation=(_('%(value_name)s must be <= %(max_value)d') %
                             {'value_name': name, 'max_value': max_value}))

        return value
예제 #2
0
    def __call__(self, environ, start_response):
        r"""Subclasses will probably want to implement __call__ like this:

        @webob.dec.wsgify(RequestClass=Request)
        def __call__(self, req):
          # Any of the following objects work as responses:

          # Option 1: simple string
          res = 'message\n'

          # Option 2: a nicely formatted HTTP exception page
          res = exc.HTTPForbidden(explanation='Nice try')

          # Option 3: a webob Response object (in case you need to play with
          # headers, or you want to be treated like an iterable)
          res = Response();
          res.app_iter = open('somefile')

          # Option 4: any wsgi app to be run next
          res = self.application

          # Option 5: you can get a Response object for a wsgi app, too, to
          # play with headers etc
          res = req.get_response(self.application)

          # You can then just return your response...
          return res
          # ... or set req.response and return None.
          req.response = res

        See the end of http://pythonpaste.org/webob/modules/dec.html
        for more info.

        """
        raise NotImplementedError(_('You must implement __call__'))
예제 #3
0
def db_sync(engine, version=None):
    """Migrate the database to `version` or the most recent version."""
    if version is not None and int(version) < db_version(engine):
        raise exception.CoriolisException(
            _("Cannot migrate to lower schema version."))

    return migration.db_sync(engine, version=version)
예제 #4
0
def action_peek_json(body):
    """Determine action to invoke."""

    try:
        decoded = jsonutils.loads(body)
    except ValueError:
        msg = _("cannot understand JSON")
        raise exception.MalformedRequestBody(reason=msg)

    # Make sure there's exactly one key...
    if len(decoded) != 1:
        msg = _("too many body keys")
        raise exception.MalformedRequestBody(reason=msg)

    # Return the action and the decoded body...
    return list(decoded.keys())[0]
예제 #5
0
def _check_string_length(value, name, min_length=0, max_length=None):
    """Check the length of specified string.
    :param value: the value of the string
    :param name: the name of the string
    :param min_length: the min_length of the string
    :param max_length: the max_length of the string
    """
    if not isinstance(value, six.string_types):
        msg = _("%s is not a string or unicode") % name
        raise exception.InvalidInput(message=msg)

    if len(value) < min_length:
        msg = _("%(name)s has a minimum character requirement of "
                "%(min_length)s.") % {'name': name, 'min_length': min_length}
        raise exception.InvalidInput(message=msg)

    if max_length and len(value) > max_length:
        msg = _("%(name)s has more than %(max_length)s "
                "characters.") % {'name': name, 'max_length': max_length}
        raise exception.InvalidInput(message=msg)
예제 #6
0
 def assert_valid_body(body, entity_name):
     # NOTE: After v1 api is deprecated need to merge 'is_valid_body' and
     #       'assert_valid_body' in to one method. Right now it is not
     #       possible to modify 'is_valid_body' to raise exception because
     #       in case of V1 api when 'is_valid_body' return False,
     #       'HTTPUnprocessableEntity' exception is getting raised and in
     #       V2 api 'HTTPBadRequest' exception is getting raised.
     if not Controller.is_valid_body(body, entity_name):
         raise webob.exc.HTTPBadRequest(
             explanation=_("Missing required element '%s' in "
                           "request body.") % entity_name)
예제 #7
0
    def __call__(self, req):
        user = req.headers.get('X_USER')
        user = req.headers.get('X_USER_ID', user)
        if user is None:
            LOG.debug("Neither X_USER_ID nor X_USER found in request")
            return webob.exc.HTTPUnauthorized()

        # get the roles
        roles = [r.strip() for r in req.headers.get('X_ROLE', '').split(',')]
        if 'X_TENANT_ID' in req.headers:
            # This is the new header since Keystone went to ID/Name
            tenant = req.headers['X_TENANT_ID']
        else:
            # This is for legacy compatibility
            tenant = req.headers['X_TENANT']

        project_name = req.headers.get('X_TENANT_NAME')
        project_domain_name = req.headers.get('X-Project-Domain-Name')
        user_domain_name = req.headers.get('X-User-Domain-Name')

        req_id = req.environ.get(request_id.ENV_REQUEST_ID)
        # TODO(alexpilotti): Check why it's not str
        if isinstance(req_id, bytes):
            req_id = req_id.decode()

        # Get the auth token
        auth_token = req.headers.get('X_AUTH_TOKEN')

        # Build a context, including the auth_token...
        remote_address = req.remote_addr

        service_catalog = None
        if req.headers.get('X_SERVICE_CATALOG') is not None:
            try:
                catalog_header = req.headers.get('X_SERVICE_CATALOG')
                service_catalog = jsonutils.loads(catalog_header)
            except ValueError:
                raise webob.exc.HTTPInternalServerError(
                    explanation=_('Invalid service catalog json.'))

        ctx = context.RequestContext(user,
                                     tenant,
                                     project_name=project_name,
                                     project_domain=project_domain_name,
                                     user_domain=user_domain_name,
                                     roles=roles,
                                     auth_token=auth_token,
                                     remote_address=remote_address,
                                     service_catalog=service_catalog,
                                     request_id=req_id)

        req.environ['coriolis.context'] = ctx
        return self.application
예제 #8
0
    def __init__(self, ext_mgr=None):
        if ext_mgr is None:
            if self.ExtensionManager:
                ext_mgr = self.ExtensionManager()
            else:
                raise exception.CoriolisException(
                    _("Must specify an ExtensionManager class"))

        mapper = ProjectMapper()
        self.resources = {}
        self._setup_routes(mapper, ext_mgr)
        self._setup_ext_routes(mapper, ext_mgr)
        self._setup_extensions(ext_mgr)
        super(APIRouter, self).__init__(mapper)
예제 #9
0
파일: fault.py 프로젝트: cloudbase/coriolis
    def _error(self, inner, req):
        LOG.exception(_LE("Caught error: %(type)s %(error)s"),
                      {'type': type(inner),
                       'error': inner})
        safe = getattr(inner, 'safe', False)
        headers = getattr(inner, 'headers', None)
        status = getattr(inner, 'code', 500)
        if status is None:
            status = 500

        msg_dict = dict(url=req.url, status=status)
        LOG.info(_LI("%(url)s returned with HTTP %(status)d"), msg_dict)
        outer = self.status_to_type(status)
        if headers:
            outer.headers = headers
        if safe:
            msg = (inner.msg if isinstance(inner, exception.CoriolisException)
                   else six.text_type(inner))
            params = {'exception': inner.__class__.__name__,
                      'explanation': msg}
            outer.explanation = _('%(exception)s: %(explanation)s') % params
        return wsgi.Fault(outer)
예제 #10
0
class MalformedRequestBody(CoriolisException):
    message = _("Malformed message body: %(reason)s")
    code = 400
    safe = True
예제 #11
0
class FloatingIPPoolNotFound(NotFound):
    message = _("Floating IP pool \"%(pool_name)s\" could not be found.")
예제 #12
0
class VolumeSnapshotNotFound(NotFound):
    message = _("Volume snapshot \"%(snapshot_id)s\" could not be found.")
예제 #13
0
class DiskStorageMappingNotFound(NotFound):
    message = _('No storage mapping for disk with ID "%(id)s" could be found.')
예제 #14
0
class ImageNotFound(NotFound):
    message = _("Image \"%(image_name)s\" could not be found.")
예제 #15
0
class OSMorphingToolsNotFound(NotFound):
    message = _("Couldn't find any morphing tools for this OS.")
예제 #16
0
class InstanceNotFound(NotFound):
    message = _("Instance \"%(instance_name)s\" could not be found.")
예제 #17
0
class APITimeout(APIException):
    message = _("Timeout while requesting %(service)s API.")
예제 #18
0
class InvalidReplicaState(Invalid):
    message = _("Invalid replica state: %(reason)s")
예제 #19
0
class InvalidActionTasksExecutionState(Invalid):
    message = _("Invalid tasks execution state: %(reason)s")
예제 #20
0
    def _process_stack(self, request, action, action_args,
                       content_type, body, accept):
        """Implement the processing stack."""

        # Get the implementing method
        try:
            meth, extensions = self.get_method(request, action,
                                               content_type, body)
        except (AttributeError, TypeError):
            return Fault(webob.exc.HTTPNotFound())
        except KeyError as ex:
            msg = _("There is no such action: %s") % ex.args[0]
            return Fault(webob.exc.HTTPBadRequest(explanation=msg))
        except exception.MalformedRequestBody:
            msg = _("Malformed request body")
            return Fault(webob.exc.HTTPBadRequest(explanation=msg))

        # Now, deserialize the request body...
        try:
            if content_type:
                contents = self.deserialize(meth, content_type, body)
            else:
                contents = {}
        except exception.InvalidContentType:
            msg = _("Unsupported Content-Type")
            return Fault(webob.exc.HTTPBadRequest(explanation=msg))
        except exception.MalformedRequestBody:
            msg = _("Malformed request body")
            return Fault(webob.exc.HTTPBadRequest(explanation=msg))

        # Update the action args
        action_args.update(contents)

        project_id = action_args.pop("project_id", None)
        context = request.environ.get('coriolis.context')
        if (context and project_id and (project_id != context.tenant)):
            msg = _("Malformed request url")
            return Fault(webob.exc.HTTPBadRequest(explanation=msg))

        # Run pre-processing extensions
        response, post = self.pre_process_extensions(extensions,
                                                     request, action_args)

        if not response:
            try:
                with ResourceExceptionHandler():
                    action_result = self.dispatch(meth, request, action_args)
            except Fault as ex:
                response = ex

        if not response:
            # No exceptions; convert action_result into a
            # ResponseObject
            resp_obj = None
            if type(action_result) is dict or action_result is None:
                resp_obj = ResponseObject(action_result)
            elif isinstance(action_result, ResponseObject):
                resp_obj = action_result
            else:
                response = action_result

            # Run post-processing extensions
            if resp_obj:
                _set_request_id_header(request, resp_obj)
                # Do a preserialize to set up the response object
                serializers = getattr(meth, 'wsgi_serializers', {})
                resp_obj._bind_method_serializers(serializers)
                if hasattr(meth, 'wsgi_code'):
                    resp_obj._default_code = meth.wsgi_code
                resp_obj.preserialize(accept, self.default_serializers)

                # Process post-processing extensions
                response = self.post_process_extensions(post, resp_obj,
                                                        request, action_args)

            if resp_obj and not response:
                response = resp_obj.serialize(request, accept,
                                              self.default_serializers)

        try:
            msg_dict = dict(url=request.url, status=response.status_int)
            msg = _LI("%(url)s returned with HTTP %(status)d")
        except AttributeError as e:
            msg_dict = dict(url=request.url, e=e)
            msg = _LI("%(url)s returned a fault: %(e)s")

        LOG.info(msg, msg_dict)

        return response
예제 #21
0
 def _from_json(self, datastring):
     try:
         return jsonutils.loads(datastring)
     except ValueError:
         msg = _("cannot understand JSON")
         raise exception.MalformedRequestBody(reason=msg)
예제 #22
0
class InvalidMigrationState(Invalid):
    message = _("Invalid migration state: %(reason)s")
예제 #23
0
class InvalidInput(Invalid):
    message = _("Invalid input received: %(reason)s")
예제 #24
0
class ServiceUnavailable(Invalid):
    message = _("Service is unavailable at this time.")
예제 #25
0
class InvalidContentType(Invalid):
    message = _("Invalid content type %(content_type)s.")
예제 #26
0
class NotFound(CoriolisException):
    message = _("Resource could not be found.")
    code = 404
    safe = True
예제 #27
0
class InvalidHost(Invalid):
    message = _("Invalid host: %(reason)s")
예제 #28
0
class FileNotFound(NotFound):
    message = _("File %(file_path)s could not be found.")
예제 #29
0
class SameDestination(Invalid):
    message = _("Origin and destination cannot be the same")
예제 #30
0
class NetworkNotFound(NotFound):
    message = _("Network \"%(network_name)s\" could not be found.")
예제 #31
0
class InvalidParameterValue(Invalid):
    message = _("%(err)s")
예제 #32
0
class StorageBackendNotFound(NotFound):
    message = _(
        'Storage backend with name "%(storage_name)s" could not be found.')
예제 #33
0
class InvalidAuthKey(Invalid):
    message = _("Invalid auth key: %(reason)s")
예제 #34
0
class FlavorNotFound(NotFound):
    message = _("Flavor \"%(flavor_name)s\" could not be found.")
예제 #35
0
class InvalidConfigurationValue(Invalid):
    message = _('Value "%(value)s" is not valid for '
                'configuration option "%(option)s"')
예제 #36
0
class VolumeNotFound(NotFound):
    message = _("Volume \"%(volume_id)s\" could not be found.")
예제 #37
0
class InvalidTaskState(Invalid):
    message = _('Task "%(task_id)s" in in an invalid state: %(task_state)s')
예제 #38
0
class VolumeBackupNotFound(NotFound):
    message = _("Volume backup \"%(backup_id)s\" could not be found.")
예제 #39
0
class TaskIsCancelling(InvalidTaskState):
    message = _(TASK_ALREADY_CANCELLING_EXCEPTION_FMT)
예제 #40
0
class ConfigNotFound(NotFound):
    message = _("Could not find config at %(path)s")
예제 #41
0
class InvalidTaskResult(InvalidTaskState):
    message = _('Task returned an invalid result.')