示例#1
0
    def _migrate(self, req, id, body):
        """Permit admins to migrate a server to a new host."""
        context = req.environ['nova.context']
        authorize(context, 'migrate')

        instance = common.get_instance(self.compute_api,
                                       context,
                                       id,
                                       want_objects=True)
        try:
            self.compute_api.resize(req.environ['nova.context'], instance)
        except exception.TooManyInstances as e:
            raise exc.HTTPRequestEntityTooLarge(explanation=e.format_message())
        except exception.QuotaError as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.format_message(), headers={'Retry-After': 0})
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'migrate')
        except exception.InstanceNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.NoValidHost as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        return webob.Response(status_int=202)
示例#2
0
    def _update_instance_metadata(self, context, server_id, metadata,
                                  delete=False):
        try:
            server = self.compute_api.get(context, server_id)
            return self.compute_api.update_instance_metadata(context,
                                                             server,
                                                             metadata,
                                                             delete)

        except exception.InstanceNotFound:
            msg = _('Server does not exist')
            raise exc.HTTPNotFound(explanation=msg)

        except (ValueError, AttributeError):
            msg = _("Malformed request body")
            raise exc.HTTPBadRequest(explanation=msg)

        except exception.InvalidMetadata as error:
            raise exc.HTTPBadRequest(explanation=unicode(error))

        except exception.InvalidMetadataSize as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=unicode(error))

        except exception.QuotaError as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=unicode(error),
                                                headers={'Retry-After': 0})
示例#3
0
    def _update_instance_metadata(self,
                                  context,
                                  server_id,
                                  metadata,
                                  delete=False):
        try:
            server = self.compute_api.get(context, server_id)
            return self.compute_api.update_instance_metadata(
                context, server, metadata, delete)

        except exception.InstanceNotFound:
            msg = _('Server does not exist')
            raise exc.HTTPNotFound(explanation=msg)

        except exception.InvalidMetadata as error:
            raise exc.HTTPBadRequest(explanation=error.format_message())

        except exception.InvalidMetadataSize as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.format_message())

        except exception.QuotaError as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.format_message(), headers={'Retry-After': 0})

        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'update metadata')
示例#4
0
    def restore(self, req, id):
        """Restore an existing backupjobrun"""
        backupjobrun_id = id
        LOG.debug(_('Restoring backupjobrun %(backupjobrun_id)s') % locals())
        context = req.environ['raksha.context']
        LOG.audit(_("Restoring backupjobrun %(backupjobrun_id)s"),
                  locals(),
                  context=context)

        try:
            self.backupjob_api.backupjobrun_restore(
                context, backupjobrun_id=backupjobrun_id)
        except exception.InvalidInput as error:
            raise exc.HTTPBadRequest(explanation=unicode(error))
        except exception.InvalidVolume as error:
            raise exc.HTTPBadRequest(explanation=unicode(error))
        except exception.InvalidBackupJob as error:
            raise exc.HTTPBadRequest(explanation=unicode(error))
        except exception.BackupJobNotFound as error:
            raise exc.HTTPNotFound(explanation=unicode(error))
        except exception.VolumeNotFound as error:
            raise exc.HTTPNotFound(explanation=unicode(error))
        except exception.VolumeSizeExceedsAvailableQuota as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=error.message,
                                                headers={'Retry-After': 0})
        except exception.VolumeLimitExceeded as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=error.message,
                                                headers={'Retry-After': 0})

        return webob.Response(status_int=202)
示例#5
0
    def _update_instance_metadata(self,
                                  context,
                                  server_id,
                                  metadata,
                                  delete=False):
        try:
            server = common.get_instance(self.compute_api,
                                         context,
                                         server_id,
                                         want_objects=True)
            return self.compute_api.update_instance_metadata(
                context, server, metadata, delete)

        except exception.InvalidMetadata as error:
            raise exc.HTTPBadRequest(explanation=error.format_message())

        except exception.InvalidMetadataSize as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.format_message())

        except exception.QuotaError as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.format_message(), headers={'Retry-After': 0})

        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())

        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'update metadata')
    def restore(self, req, id, body):
        """Restore an existing backup to a volume."""
        LOG.debug('Restoring backup %(backup_id)s (%(body)s)', {
            'backup_id': id,
            'body': body
        })
        if not self.is_valid_body(body, 'restore'):
            msg = _("Incorrect request body format")
            raise exc.HTTPBadRequest(explanation=msg)

        context = req.environ['cinder.context']
        restore = body['restore']
        volume_id = restore.get('volume_id', None)
        # code begin by luobin
        availability_zone = restore.get('availability_zone', None)
        # code end by luobin
        description = restore.get('description', None)

        LOG.info(_("Restoring backup %(backup_id)s to volume %(volume_id)s"), {
            'backup_id': id,
            'volume_id': volume_id
        },
                 context=context)

        try:
            # code begin by luobin
            new_restore = self.backup_api.restore(
                context,
                backup_id=id,
                volume_id=volume_id,
                availability_zone=availability_zone,
                description=description)
            # code end by luobin

        except exception.InvalidInput as error:
            raise exc.HTTPBadRequest(explanation=error.msg)
        except exception.InvalidVolume as error:
            raise exc.HTTPBadRequest(explanation=error.msg)
        except exception.InvalidBackup as error:
            raise exc.HTTPBadRequest(explanation=error.msg)
        except exception.BackupNotFound as error:
            raise exc.HTTPNotFound(explanation=error.msg)
        except exception.VolumeNotFound as error:
            raise exc.HTTPNotFound(explanation=error.msg)
        except exception.VolumeSizeExceedsAvailableQuota as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=error.msg,
                                                headers={'Retry-After': 0})
        except exception.VolumeLimitExceeded as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=error.msg,
                                                headers={'Retry-After': 0})

        retval = self._view_builder.restore_summary(
            req, dict(new_restore.iteritems()))
        return retval
示例#7
0
    def restore(self, req, id, body):
        """Restore an existing backup to a volume."""
        LOG.debug(_('Restoring backup %(backup_id)s (%(body)s)'), {
            'backup_id': id,
            'body': body
        })
        if not self.is_valid_body(body, 'restore'):
            raise exc.HTTPBadRequest()

        context = req.environ['cinder.context']

        try:
            restore = body['restore']
        except KeyError:
            msg = _("Incorrect request body format")
            raise exc.HTTPBadRequest(explanation=msg)
        volume_id = restore.get('volume_id', None)

        LOG.audit(_("Restoring backup %(backup_id)s to volume %(volume_id)s"),
                  {
                      'backup_id': id,
                      'volume_id': volume_id
                  },
                  context=context)

        try:
            new_restore = self.backup_api.restore(context,
                                                  backup_id=id,
                                                  volume_id=volume_id)
        except exception.InvalidInput as error:
            raise exc.HTTPBadRequest(explanation=unicode(error))
        except exception.InvalidVolume as error:
            raise exc.HTTPBadRequest(explanation=unicode(error))
        except exception.InvalidBackup as error:
            raise exc.HTTPBadRequest(explanation=unicode(error))
        except exception.BackupNotFound as error:
            raise exc.HTTPNotFound(explanation=unicode(error))
        except exception.VolumeNotFound as error:
            raise exc.HTTPNotFound(explanation=unicode(error))
        except exception.VolumeSizeExceedsAvailableQuota as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=error.message,
                                                headers={'Retry-After': 0})
        except exception.VolumeLimitExceeded as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=error.message,
                                                headers={'Retry-After': 0})

        retval = self._view_builder.restore_summary(
            req, dict(new_restore.iteritems()))
        return retval
示例#8
0
    def _update_instance_metadata(self,
                                  context,
                                  server_id,
                                  metadata,
                                  delete=False):
        try:
            server = common.get_instance(self.compute_api, context, server_id)
            return self.compute_api.update_instance_metadata(
                context, server, metadata, delete)

        except exception.InstanceNotFound:
            msg = _('Server does not exist')
            raise exc.HTTPNotFound(explanation=msg)

        except (ValueError, AttributeError):
            msg = _("Malformed request body")
            raise exc.HTTPBadRequest(explanation=msg)

        except exception.InvalidMetadata as error:
            raise exc.HTTPBadRequest(explanation=error.format_message())

        except exception.InvalidMetadataSize as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.format_message())

        except exception.QuotaError as error:
            raise exc.HTTPForbidden(explanation=error.format_message())

        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())

        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'update metadata', server_id)
示例#9
0
文件: app.py 项目: ushahidi/SiCDS
 def __call__(self, req):
     resp = None
     success = False
     try:
         if req.path_info not in self._routes:
             raise exc.HTTPNotFound
         if req.method != 'POST':
             raise exc.HTTPMethodNotAllowed(explanation='Only POST allowed')
         if req.content_length > self.REQMAXBYTES:
             req.logged_body = req.body_file.read(self.REQMAXBYTES) + '...'
             raise exc.HTTPRequestEntityTooLarge(explanation='Request max '
                 'size is {0} bytes'.format(self.REQMAXBYTES))
         reqjson = loads(req.body)
         req.logged_body = reqjson
         handler = self._routes[req.path_info]
         respjson = handler(self, reqjson)
         resp = Response(body=dumps(respjson), content_type='application/json')
         resp.logged_body = respjson
         success = True
     except Exception as e:
         if isinstance(e, exc.HTTPException):
             resp = e
         elif isinstance(e, (JSONDecodeError, SchemaError)):
             resp = exc.HTTPBadRequest(explanation=repr(e))
         else:
             resp = exc.HTTPInternalServerError(explanation=repr(e))
         resp.logged_body = resp.explanation
     finally:
         try:
             self.log(req, resp, success)
         except Exception as e:
             resp = exc.HTTPInternalServerError(explanation='Log failure: {0}\n'
                 'req: {1}\nresp: {2}'.format(repr(e), getattr(req, 'logged_body', None),
                 getattr(resp, 'logged_body', None)))
         return resp
示例#10
0
    def restore(self, req, id, body):
        """Restore an existing backup to a volume."""
        LOG.debug('Restoring backup %(backup_id)s (%(body)s)',
                  {'backup_id': id, 'body': body})

        context = req.environ['cinder.context']
        restore = body['restore']
        volume_id = restore.get('volume_id', None)
        name = restore.get('name', None)

        LOG.info("Restoring backup %(backup_id)s to volume %(volume_id)s.",
                 {'backup_id': id, 'volume_id': volume_id},
                 context=context)

        try:
            new_restore = self.backup_api.restore(context,
                                                  backup_id=id,
                                                  volume_id=volume_id,
                                                  name=name)
        # Not found exception will be handled at the wsgi level
        except (exception.InvalidInput,
                exception.InvalidVolume,
                exception.InvalidBackup) as error:
            raise exc.HTTPBadRequest(explanation=error.msg)
        except (exception.VolumeSizeExceedsAvailableQuota,
                exception.VolumeLimitExceeded) as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.msg, headers={'Retry-After': '0'})

        retval = self._view_builder.restore_summary(
            req, dict(new_restore))
        return retval
示例#11
0
    def accept(self, req, id, body):
        """Accept a new volume transfer."""
        transfer_id = id
        LOG.debug(_('Accepting volume transfer %s'), transfer_id)
        if not self.is_valid_body(body, 'accept'):
            raise exc.HTTPBadRequest()

        context = req.environ['cinder.context']

        try:
            accept = body['accept']
            auth_key = accept['auth_key']
        except KeyError:
            msg = _("Incorrect request body format")
            raise exc.HTTPBadRequest(explanation=msg)

        LOG.audit(_("Accepting transfer %s"), transfer_id, context=context)

        try:
            accepted_transfer = self.transfer_api.accept(
                context, transfer_id, auth_key)
        except exception.VolumeSizeExceedsAvailableQuota as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=error.message,
                                                headers={'Retry-After': 0})
        except exception.InvalidVolume as error:
            raise exc.HTTPBadRequest(explanation=unicode(error))

        transfer = \
            self._view_builder.summary(req,
                                       dict(accepted_transfer.iteritems()))
        return transfer
示例#12
0
    def accept(self, req, id, body):
        """Accept a new volume transfer."""
        transfer_id = id
        LOG.debug('Accepting volume transfer %s', transfer_id)
        self.assert_valid_body(body, 'accept')

        context = req.environ['storage.context']
        accept = body['accept']

        try:
            auth_key = accept['auth_key']
        except KeyError:
            msg = _("Incorrect request body format")
            raise exc.HTTPBadRequest(explanation=msg)

        LOG.info(_LI("Accepting transfer %s"), transfer_id, context=context)

        try:
            accepted_transfer = self.transfer_api.accept(
                context, transfer_id, auth_key)
        except exception.VolumeSizeExceedsAvailableQuota as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=error.msg,
                                                headers={'Retry-After': '0'})
        except exception.InvalidVolume as error:
            raise exc.HTTPBadRequest(explanation=error.msg)

        transfer = \
            self._view_builder.summary(req,
                                       dict(accepted_transfer))
        return transfer
示例#13
0
    def _resize(self, req, instance_id, flavor_id, **kwargs):
        """Begin the resize process with given instance/flavor."""
        context = req.environ["nova.context"]
        instance = self._get_server(context, req, instance_id)

        try:
            self.compute_api.resize(context, instance, flavor_id, **kwargs)
        except exception.QuotaError as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.format_message(), headers={'Retry-After': 0})
        except exception.FlavorNotFound:
            msg = _("Unable to locate requested flavor.")
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.CannotResizeToSameFlavor:
            msg = _("Resize requires a flavor change.")
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'resize')
        except exception.ImageNotAuthorized:
            msg = _("You are not authorized to access the image "
                    "the instance was started with.")
            raise exc.HTTPUnauthorized(explanation=msg)
        except exception.ImageNotFound:
            msg = _("Image that the instance was started "
                    "with could not be found.")
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.Invalid:
            msg = _("Invalid instance image.")
            raise exc.HTTPBadRequest(explanation=msg)

        return webob.Response(status_int=202)
示例#14
0
    def _migrate(self, req, id, body):
        """Permit admins to migrate a server to a new host."""
        context = req.environ['nova.context']
        authorize(context, 'migrate')

        #ADD by zhjh 2014-12-03 migrate instance to a selected host.
        host = body["migrate"]["host"] if (isinstance(body['migrate'], dict) and 'host' in body['migrate']) else None

        try:
            instance = self.compute_api.get(context, id, want_objects=True)
            #MOD by zhjh 2014-12-04 migrate instance to a selected host.
            #self.compute_api.resize(req.environ['nova.context'], instance)
            self.compute_api.resize(req.environ['nova.context'], instance, host=host)
        except exception.QuotaError as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.format_message(),
                headers={'Retry-After': 0})
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'migrate')
        except exception.InstanceNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except Exception as e:
            LOG.exception(_("Error in migrate %s"), e)
            raise exc.HTTPBadRequest()
        return webob.Response(status_int=202)
示例#15
0
    def restore(self, req, id, body):
        """Restore an existing backup to a volume."""
        LOG.debug('Restoring backup %(backup_id)s (%(body)s)', {
            'backup_id': id,
            'body': body
        })
        self.assert_valid_body(body, 'restore')

        context = req.environ['cinder.context']
        restore = body['restore']
        volume_id = restore.get('volume_id', None)
        name = restore.get('name', None)

        LOG.info(_LI("Restoring backup %(backup_id)s to volume %(volume_id)s"),
                 {
                     'backup_id': id,
                     'volume_id': volume_id
                 },
                 context=context)

        try:
            new_restore = self.backup_api.restore(context,
                                                  backup_id=id,
                                                  volume_id=volume_id,
                                                  name=name)
        except exception.InvalidInput as error:
            raise exc.HTTPBadRequest(explanation=error.msg)
        except exception.InvalidVolume as error:
            raise exc.HTTPBadRequest(explanation=error.msg)
        except exception.InvalidBackup as error:
            raise exc.HTTPBadRequest(explanation=error.msg)
        except exception.BackupNotFound as error:
            raise exc.HTTPNotFound(explanation=error.msg)
        except exception.VolumeNotFound as error:
            raise exc.HTTPNotFound(explanation=error.msg)
        except exception.VolumeSizeExceedsAvailableQuota as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=error.msg,
                                                headers={'Retry-After': 0})
        except exception.VolumeLimitExceeded as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=error.msg,
                                                headers={'Retry-After': 0})

        retval = self._view_builder.restore_summary(req, dict(new_restore))
        return retval
示例#16
0
def code2exception(code, detail):
    """Transforms a code + detail into a WebOb exception"""
    if code == 400:
        return exc.HTTPBadRequest(detail)
    if code == 401:
        return exc.HTTPUnauthorized(detail)
    if code == 402:
        return exc.HTTPPaymentRequired(detail)
    if code == 403:
        return exc.HTTPForbidden(detail)
    if code == 404:
        return exc.HTTPNotFound(detail)
    if code == 405:
        return exc.HTTPMethodNotAllowed(detail)
    if code == 406:
        return exc.HTTPNotAcceptable(detail)
    if code == 407:
        return exc.HTTPProxyAuthenticationRequired(detail)
    if code == 408:
        return exc.HTTPRequestTimeout(detail)
    if code == 409:
        return exc.HTTPConflict(detail)
    if code == 410:
        return exc.HTTPGone(detail)
    if code == 411:
        return exc.HTTPLengthRequired(detail)
    if code == 412:
        return exc.HTTPPreconditionFailed(detail)
    if code == 413:
        return exc.HTTPRequestEntityTooLarge(detail)
    if code == 414:
        return exc.HTTPRequestURITooLong(detail)
    if code == 415:
        return exc.HTTPUnsupportedMediaType(detail)
    if code == 416:
        return exc.HTTPRequestRangeNotSatisfiable(detail)
    if code == 417:
        return exc.HTTPExpectationFailed(detail)
    if code == 500:
        return exc.HTTPInternalServerError(detail)
    if code == 501:
        return exc.HTTPNotImplemented(detail)
    if code == 502:
        return exc.HTTPBadGateway(detail)
    if code == 503:
        return exc.HTTPServiceUnavailable(detail)
    if code == 504:
        return exc.HTTPGatewayTimeout(detail)
    if code == 505:
        return exc.HTTPVersionNotSupported(detail)

    raise NotImplementedError(code)
 def _handle_quota_error(self, error):
     """
     Reraise quota errors as api-specific http exceptions
     """
     if error.code == "OnsetFileLimitExceeded":
         expl = _("Personality file limit exceeded")
         raise exc.HTTPRequestEntityTooLarge(explanation=error.message,
                                             headers={'Retry-After': 0})
     if error.code == "OnsetFilePathLimitExceeded":
         expl = _("Personality file path too long")
         raise exc.HTTPRequestEntityTooLarge(explanation=error.message,
                                             headers={'Retry-After': 0})
     if error.code == "OnsetFileContentLimitExceeded":
         expl = _("Personality file content too long")
         raise exc.HTTPRequestEntityTooLarge(explanation=error.message,
                                             headers={'Retry-After': 0})
     if error.code == "InstanceLimitExceeded":
         expl = _("Instance quotas have been exceeded")
         raise exc.HTTPRequestEntityTooLarge(explanation=error.message,
                                             headers={'Retry-After': 0})
     # if the original error is okay, just reraise it
     raise error
示例#18
0
    def _update_instance_metadata(self,
                                  context,
                                  server_id,
                                  metadata,
                                  delete=False):
        try:
            # This is very ugly! But because the key/value pairs of metadata
            # must be a string and we must make 5.1API be consistent with
            # 5.0API, we can only compromise.
            # And, there is a bug in 5.0, that is, if we set boot order to
            # network,hd via updating metadata, when we migrate or hard reboot
            # the vm, the boot order would be changed to hd.
            if ('__bootDev' in metadata
                    and isinstance(metadata['__bootDev'], list)):
                str_boot_dev = ''
                for boot_dev in metadata['__bootDev']:
                    str_boot_dev = str_boot_dev + str(boot_dev) + ','
                str_boot_dev = str_boot_dev[:len(str_boot_dev) - 1]
                metadata['__bootDev'] = str_boot_dev

            server = self.compute_api.get(context,
                                          server_id,
                                          want_objects=True)
            return self.compute_api.update_instance_metadata(
                context, server, metadata, delete)

        except exception.InstanceNotFound:
            msg = _('Server does not exist')
            raise exc.HTTPNotFound(explanation=msg)

        except (ValueError, AttributeError):
            msg = _("Malformed request body")
            raise exc.HTTPBadRequest(explanation=msg)

        except exception.InvalidMetadata as error:
            raise exc.HTTPBadRequest(explanation=error.format_message())

        except exception.InvalidMetadataSize as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.format_message())

        except exception.QuotaError as error:
            raise exc.HTTPForbidden(explanation=error.format_message())

        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())

        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'update metadata')
示例#19
0
文件: servers.py 项目: xtoddx/nova
    def _handle_quota_error(self, error):
        """
        Reraise quota errors as api-specific http exceptions
        """

        code_mappings = {
            "OnsetFileLimitExceeded": _("Personality file limit exceeded"),
            "OnsetFilePathLimitExceeded": _("Personality file path too long"),
            "OnsetFileContentLimitExceeded":
            _("Personality file content too long"),

            # NOTE(bcwaldon): expose the message generated below in order
            # to better explain how the quota was exceeded
            "InstanceLimitExceeded": error.message,
        }

        expl = code_mappings.get(error.code)
        if expl:
            raise exc.HTTPRequestEntityTooLarge(explanation=expl,
                                                headers={'Retry-After': 0})
        # if the original error is okay, just reraise it
        raise exc.HTTPRequestEntityTooLarge(explanation=error.msg,
                                            headers={'Retry-After': 0})
示例#20
0
def translate_exceptions():
    """Translate nova exceptions to http exceptions."""
    try:
        yield
    except exception.Invalid as exp:
        msg = exp.format_message()
        raise exc.HTTPBadRequest(explanation=msg)
    except exception.SecurityGroupNotFound as exp:
        msg = exp.format_message()
        raise exc.HTTPNotFound(explanation=msg)
    except exception.InstanceNotFound as exp:
        msg = exp.format_message()
        raise exc.HTTPNotFound(explanation=msg)
    except exception.SecurityGroupLimitExceeded as exp:
        msg = exp.format_message()
        raise exc.HTTPRequestEntityTooLarge(explanation=msg)
示例#21
0
    def _update_snapshot_metadata(self,
                                  context,
                                  snapshot_id,
                                  metadata,
                                  delete=False):
        try:
            snapshot = self.volume_api.get_snapshot(context, snapshot_id)
            return self.volume_api.update_snapshot_metadata(
                context, snapshot, metadata, delete)
        # Not found exception will be handled at the wsgi level
        except (ValueError, AttributeError):
            msg = _("Malformed request body")
            raise exc.HTTPBadRequest(explanation=msg)

        except exception.InvalidVolumeMetadata as error:
            raise exc.HTTPBadRequest(explanation=error.msg)

        except exception.InvalidVolumeMetadataSize as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=error.msg)
    def __call__(self, request):
        if len(request.path_info + request.query_string) > 4096:
            return exc.HTTPRequestURITooLong()
        
        if request.method in ['PUT', 'POST']:
            if 'Content-Length' in request.headers and\
                    int(request.headers['Content-Length']) > 3145728:
                return exc.HTTPRequestEntityTooLarge()

            elif 'Content-Length' not in request.headers:
                return exc.HTTPLengthRequired()

        if not request.path_info in _SERVICES_PATHS:
            return exc.HTTPNotFound()

        func = _ROUTES.get((request.path_info, request.method))
        if func is not None:
            return func(request)
        else:
            return exc.HTTPMethodNotAllowed()
示例#23
0
 def _migrate(self, req, id, body):
     """Permit admins to migrate a server to a new host."""
     context = req.environ['nova.context']
     authorize(context, 'migrate')
     try:
         instance = self.compute_api.get(context, id, want_objects=True)
         self.compute_api.resize(req.environ['nova.context'], instance)
     except exception.InstanceIsLocked as e:
         raise exc.HTTPConflict(explanation=e.format_message())
     except exception.InstanceInvalidState as state_error:
         common.raise_http_conflict_for_instance_invalid_state(
             state_error, 'migrate')
     except exception.InstanceNotFound as e:
         raise exc.HTTPNotFound(explanation=e.format_message())
     except exception.FlavorNotFound as e:
         raise exc.HTTPNotFound(explanation=e.format_message())
     except exception.CannotResizeToSameFlavor as e:
         raise exc.HTTPBadRequest(explanation=e.format_message())
     except exception.TooManyInstances as e:
         raise exc.HTTPRequestEntityTooLarge(explanation=e.format_message())
     return webob.Response(status_int=202)
示例#24
0
    def _update_snapshot_metadata(self,
                                  context,
                                  snapshot_id,
                                  metadata,
                                  delete=False):
        try:
            snapshot = self.volume_api.get_snapshot(context, snapshot_id)
            return self.volume_api.update_snapshot_metadata(
                context, snapshot, metadata, delete)
        except exception.SnapshotNotFound:
            msg = _('snapshot does not exist')
            raise exc.HTTPNotFound(explanation=msg)

        except (ValueError, AttributeError):
            msg = _("Malformed request body")
            raise exc.HTTPBadRequest(explanation=msg)

        except exception.InvalidVolumeMetadata as error:
            raise exc.HTTPBadRequest(explanation=error.msg)

        except exception.InvalidVolumeMetadataSize as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=error.msg)
示例#25
0
    def _update_volume_metadata(self,
                                context,
                                volume_id,
                                metadata,
                                delete=False):
        try:
            volume = self.volume_api.get(context, volume_id)
            return self.volume_api.update_volume_metadata(
                context, volume, metadata, delete)
        except exception.VolumeNotFound:
            msg = _('volume does not exist')
            raise exc.HTTPNotFound(explanation=msg)

        except (ValueError, AttributeError):
            msg = _("Malformed request body")
            raise exc.HTTPBadRequest(explanation=msg)

        except exception.InvalidVolumeMetadata as error:
            raise exc.HTTPBadRequest(explanation=unicode(error))

        except exception.InvalidVolumeMetadataSize as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=unicode(error))
示例#26
0
    def accept(self, req, id, body):
        """Accept a new volume transfer."""
        transfer_id = id
        LOG.debug('Accepting volume transfer %s', transfer_id)

        context = req.environ['cinder.context']
        accept = body['accept']
        auth_key = accept['auth_key']

        LOG.info("Accepting transfer %s", transfer_id)

        try:
            accepted_transfer = self.transfer_api.accept(
                context, transfer_id, auth_key)
        except exception.VolumeSizeExceedsAvailableQuota as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=error.msg,
                                                headers={'Retry-After': '0'})
        except exception.InvalidVolume as error:
            raise exc.HTTPBadRequest(explanation=error.msg)

        transfer = \
            self._view_builder.summary(req,
                                       dict(accepted_transfer))
        return transfer
示例#27
0
文件: servers.py 项目: Drooids/nova
    def _action_rebuild(self, req, id, body):
        """Rebuild an instance with the given attributes."""
        body = body['rebuild']

        try:
            image_href = body["imageRef"]
        except (KeyError, TypeError):
            msg = _("Could not parse imageRef from request.")
            raise exc.HTTPBadRequest(explanation=msg)

        image_href = self._image_uuid_from_href(image_href)

        password = self._get_server_admin_password(body)

        context = req.environ['nova.context']
        instance = self._get_server(context, req, id)

        attr_map = {
            'personality': 'files_to_inject',
            'name': 'display_name',
            'accessIPv4': 'access_ip_v4',
            'accessIPv6': 'access_ip_v6',
            'metadata': 'metadata',
            'auto_disk_config': 'auto_disk_config',
        }

        kwargs = {}

        # take the preserve_ephemeral value into account only when the
        # corresponding extension is active
        if (self.ext_mgr.is_loaded('os-preserve-ephemeral-rebuild')
                and 'preserve_ephemeral' in body):
            kwargs['preserve_ephemeral'] = strutils.bool_from_string(
                body['preserve_ephemeral'], strict=True)

        if 'accessIPv4' in body:
            self._validate_access_ipv4(body['accessIPv4'])

        if 'accessIPv6' in body:
            self._validate_access_ipv6(body['accessIPv6'])

        if 'name' in body:
            self._validate_server_name(body['name'])

        for request_attribute, instance_attribute in attr_map.items():
            try:
                kwargs[instance_attribute] = body[request_attribute]
            except (KeyError, TypeError):
                pass

        self._validate_metadata(kwargs.get('metadata', {}))

        if 'files_to_inject' in kwargs:
            personality = kwargs.pop('files_to_inject')
            files_to_inject = self._get_injected_files(personality)
        else:
            files_to_inject = None

        try:
            self.compute_api.rebuild(context,
                                     instance,
                                     image_href,
                                     password,
                                     files_to_inject=files_to_inject,
                                     **kwargs)
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'rebuild', id)
        except exception.InstanceNotFound:
            msg = _("Instance could not be found")
            raise exc.HTTPNotFound(explanation=msg)
        except exception.InvalidMetadataSize as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.format_message())
        except exception.ImageNotFound:
            msg = _("Cannot find image for rebuild")
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.QuotaError as error:
            raise exc.HTTPForbidden(explanation=error.format_message())
        except (exception.ImageNotActive, exception.FlavorDiskTooSmall,
                exception.FlavorMemoryTooSmall, exception.InvalidMetadata,
                exception.AutoDiskConfigDisabledByImage) as error:
            raise exc.HTTPBadRequest(explanation=error.format_message())

        instance = self._get_server(context, req, id)

        view = self._view_builder.show(req, instance)

        # Add on the adminPass attribute since the view doesn't do it
        # unless instance passwords are disabled
        if CONF.enable_instance_password:
            view['server']['adminPass'] = password

        robj = wsgi.ResponseObject(view)
        return self._add_location(robj)
示例#28
0
文件: servers.py 项目: mattstep/nova
    def create(self, req, body):
        """Creates a new server for a given user."""
        if not body:
            raise exc.HTTPUnprocessableEntity()

        if not 'server' in body:
            raise exc.HTTPUnprocessableEntity()

        body['server']['key_name'] = self._get_key_name(req, body)

        context = req.environ['nova.context']
        server_dict = body['server']
        password = self._get_server_admin_password(server_dict)

        if not 'name' in server_dict:
            msg = _("Server name is not defined")
            raise exc.HTTPBadRequest(explanation=msg)

        name = server_dict['name']
        self._validate_server_name(name)
        name = name.strip()

        image_href = self._image_ref_from_req_data(body)
        image_href = self._image_uuid_from_href(image_href)

        personality = server_dict.get('personality')
        config_drive = server_dict.get('config_drive')

        injected_files = []
        if personality:
            injected_files = self._get_injected_files(personality)

        sg_names = []
        security_groups = server_dict.get('security_groups')
        if security_groups is not None:
            sg_names = [sg['name'] for sg in security_groups if sg.get('name')]
        if not sg_names:
            sg_names.append('default')

        sg_names = list(set(sg_names))

        requested_networks = server_dict.get('networks')
        if requested_networks is not None:
            requested_networks = self._get_requested_networks(
                                                    requested_networks)

        (access_ip_v4, ) = server_dict.get('accessIPv4'),
        if access_ip_v4 is not None:
            self._validate_access_ipv4(access_ip_v4)

        (access_ip_v6, ) = server_dict.get('accessIPv6'),
        if access_ip_v6 is not None:
            self._validate_access_ipv6(access_ip_v6)

        try:
            flavor_id = self._flavor_id_from_req_data(body)
        except ValueError as error:
            msg = _("Invalid flavorRef provided.")
            raise exc.HTTPBadRequest(explanation=msg)

        # optional openstack extensions:
        key_name = server_dict.get('key_name')
        user_data = server_dict.get('user_data')
        self._validate_user_data(user_data)

        availability_zone = server_dict.get('availability_zone')

        block_device_mapping = self._get_block_device_mapping(server_dict)

        ret_resv_id = server_dict.get('return_reservation_id', False)

        min_count = server_dict.get('min_count')
        max_count = server_dict.get('max_count')
        # min_count and max_count are optional.  If they exist, they come
        # in as strings.  We want to default 'min_count' to 1, and default
        # 'max_count' to be 'min_count'.
        min_count = int(min_count) if min_count else 1
        max_count = int(max_count) if max_count else min_count
        if min_count > max_count:
            min_count = max_count

        auto_disk_config = server_dict.get('auto_disk_config')
        scheduler_hints = server_dict.get('scheduler_hints', {})

        try:
            _get_inst_type = instance_types.get_instance_type_by_flavor_id
            inst_type = _get_inst_type(flavor_id, read_deleted="no")

            (instances, resv_id) = self.compute_api.create(context,
                            inst_type,
                            image_href,
                            display_name=name,
                            display_description=name,
                            key_name=key_name,
                            metadata=server_dict.get('metadata', {}),
                            access_ip_v4=access_ip_v4,
                            access_ip_v6=access_ip_v6,
                            injected_files=injected_files,
                            admin_password=password,
                            min_count=min_count,
                            max_count=max_count,
                            requested_networks=requested_networks,
                            security_group=sg_names,
                            user_data=user_data,
                            availability_zone=availability_zone,
                            config_drive=config_drive,
                            block_device_mapping=block_device_mapping,
                            auto_disk_config=auto_disk_config,
                            scheduler_hints=scheduler_hints)
        except exception.QuotaError as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=unicode(error),
                                                headers={'Retry-After': 0})
        except exception.InstanceTypeMemoryTooSmall as error:
            raise exc.HTTPBadRequest(explanation=unicode(error))
        except exception.InstanceTypeNotFound as error:
            raise exc.HTTPBadRequest(explanation=unicode(error))
        except exception.InstanceTypeDiskTooSmall as error:
            raise exc.HTTPBadRequest(explanation=unicode(error))
        except exception.InvalidMetadata as error:
            raise exc.HTTPBadRequest(explanation=unicode(error))
        except exception.ImageNotFound as error:
            msg = _("Can not find requested image")
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.FlavorNotFound as error:
            msg = _("Invalid flavorRef provided.")
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.KeypairNotFound as error:
            msg = _("Invalid key_name provided.")
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.SecurityGroupNotFound as error:
            raise exc.HTTPBadRequest(explanation=unicode(error))
        except rpc_common.RemoteError as err:
            msg = "%(err_type)s: %(err_msg)s" % {'err_type': err.exc_type,
                                                 'err_msg': err.value}
            raise exc.HTTPBadRequest(explanation=msg)
        # Let the caller deal with unhandled exceptions.

        # If the caller wanted a reservation_id, return it
        if ret_resv_id:
            return {'reservation_id': resv_id}

        req.cache_db_instances(instances)
        server = self._view_builder.create(req, instances[0])

        if '_is_precooked' in server['server'].keys():
            del server['server']['_is_precooked']
        else:
            if FLAGS.enable_instance_password:
                server['server']['adminPass'] = password

        robj = wsgi.ResponseObject(server)

        return self._add_location(robj)
示例#29
0
    def restore(self, req, id, body):
        """Restore an existing backup to a volume."""
        LOG.debug('Restoring backup %(backup_id)s (%(body)s)', {
            'backup_id': id,
            'body': body
        })
        if not self.is_valid_body(body, 'restore'):
            msg = _("Incorrect request body format")
            raise exc.HTTPBadRequest(explanation=msg)

        context = req.environ['cinder.context']
        restore = body['restore']
        volume_id = restore.get('volume_id', None)

        periodic = restore.get('periodic', False)
        if periodic:
            backup = self.backup_api.get(context, backup_id=id)
            if backup['volume_id'] != volume_id:
                LOG.debug(
                    "Can't restore backup %(backup_id)s to "
                    "volume %(volume_id)s", {
                        'backup_id': id,
                        'volume_id': volume_id
                    },
                    context=context)
                msg = _("Periodic backup must be restored to "
                        "the original volume")
                raise exc.HTTPBadRequest(explanation=msg)
            context.set_periodic(True)
            LOG.info(_LI("Restoring periodic backup %(backup_id)s to "
                         "volume %(volume_id)s"), {
                             'backup_id': id,
                             'volume_id': volume_id
                         },
                     context=context)
        else:
            LOG.info(_LI("Restoring backup %(backup_id)s to "
                         "volume %(volume_id)s"), {
                             'backup_id': id,
                             'volume_id': volume_id
                         },
                     context=context)

        try:
            new_restore = self.backup_api.restore(context,
                                                  backup_id=id,
                                                  volume_id=volume_id)
        except exception.InvalidInput as error:
            raise exc.HTTPBadRequest(explanation=error.msg)
        except exception.InvalidVolume as error:
            raise exc.HTTPBadRequest(explanation=error.msg)
        except exception.InvalidBackup as error:
            raise exc.HTTPBadRequest(explanation=error.msg)
        except exception.BackupNotFound as error:
            raise exc.HTTPNotFound(explanation=error.msg)
        except exception.VolumeNotFound as error:
            raise exc.HTTPNotFound(explanation=error.msg)
        except exception.VolumeSizeExceedsAvailableQuota as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=error.msg,
                                                headers={'Retry-After': 0})
        except exception.VolumeLimitExceeded as error:
            raise exc.HTTPRequestEntityTooLarge(explanation=error.msg,
                                                headers={'Retry-After': 0})

        retval = self._view_builder.restore_summary(
            req, dict(new_restore.iteritems()))
        return retval
示例#30
0
    def _action_rebuild(self, req, id, body):
        """Rebuild an instance with the given attributes."""
        try:
            rebuild_dict = body['rebuild']
        except (KeyError, TypeError):
            msg = _('Invalid request body')
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            image_href = rebuild_dict["image_ref"]
        except (KeyError, TypeError):
            msg = _("Could not parse image_ref from request.")
            raise exc.HTTPBadRequest(explanation=msg)

        image_href = self._image_uuid_from_href(image_href)

        password = self._get_server_admin_password(rebuild_dict)

        context = req.environ['nova.context']
        instance = self._get_server(context, req, id)

        attr_map = {
            'name': 'display_name',
            'metadata': 'metadata',
        }

        rebuild_kwargs = {}

        if 'name' in rebuild_dict:
            self._validate_server_name(rebuild_dict['name'])

        if 'preserve_ephemeral' in rebuild_dict:
            rebuild_kwargs['preserve_ephemeral'] = strutils.bool_from_string(
                rebuild_dict['preserve_ephemeral'], strict=True)

        if list(self.rebuild_extension_manager):
            self.rebuild_extension_manager.map(self._rebuild_extension_point,
                                               rebuild_dict, rebuild_kwargs)

        for request_attribute, instance_attribute in attr_map.items():
            try:
                rebuild_kwargs[instance_attribute] = rebuild_dict[
                    request_attribute]
            except (KeyError, TypeError):
                pass

        try:
            self.compute_api.rebuild(context, instance, image_href, password,
                                     **rebuild_kwargs)
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'rebuild')
        except exception.InstanceNotFound:
            msg = _("Instance could not be found")
            raise exc.HTTPNotFound(explanation=msg)
        except exception.InvalidMetadataSize as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.format_message())
        except exception.ImageNotFound:
            msg = _("Cannot find image for rebuild")
            raise exc.HTTPBadRequest(explanation=msg)
        except (exception.ImageNotActive, exception.FlavorDiskTooSmall,
                exception.FlavorMemoryTooSmall,
                exception.InvalidMetadata) as error:
            raise exc.HTTPBadRequest(explanation=error.format_message())

        instance = self._get_server(context, req, id)

        view = self._view_builder.show(req, instance)

        # Add on the admin_password attribute since the view doesn't do it
        # unless instance passwords are disabled
        if CONF.enable_instance_password:
            view['server']['admin_password'] = password

        robj = wsgi.ResponseObject(view)
        return self._add_location(robj)