Esempio n. 1
0
    def index(self, req):
        """Returns a list of snapshots, transformed through view builder."""
        LOG.info(_LI("Show snapshot list"))
        context = req.environ['sgservice.context']
        params = req.params.copy()
        marker, limit, offset = common.get_pagination_params(params)
        sort_keys, sort_dirs = common.get_sort_params(params)
        filters = params

        utils.remove_invaild_filter_options(
            context, filters, self._get_snapshot_filter_options())
        utils.check_filters(filters)

        if 'name' in sort_keys:
            sort_keys[sort_keys.index('name')] = 'display_name'

        if 'name' in filters:
            filters['display_name'] = filters.pop('name')

        snapshots = self.service_api.get_all_snapshots(context,
                                                       marker=marker,
                                                       limit=limit,
                                                       sort_keys=sort_keys,
                                                       sort_dirs=sort_dirs,
                                                       filters=filters,
                                                       offset=offset)

        retval_snapshots = self._view_builder.detail_list(req, snapshots)
        LOG.info(_LI("Show snapshot list request issued successfully."))
        return retval_snapshots
Esempio n. 2
0
    def __exit__(self, ex_type, ex_value, ex_traceback):
        if not ex_value:
            return True

        if isinstance(ex_value, exception.NotAuthorized):
            raise Fault(webob.exc.HTTPForbidden(explanation=ex_value.msg))
        elif isinstance(ex_value, exception.Invalid):
            raise Fault(
                exception.ConvertedException(code=ex_value.code,
                                             explanation=ex_value.msg))
        elif isinstance(ex_value, TypeError):
            exc_info = (ex_type, ex_value, ex_traceback)
            LOG.error(_LE('Exception handling resource: %s'),
                      ex_value,
                      exc_info=exc_info)
            raise Fault(webob.exc.HTTPBadRequest())
        elif isinstance(ex_value, Fault):
            LOG.info(_LI("Fault thrown: %s"), ex_value)
            raise ex_value
        elif isinstance(ex_value, webob.exc.HTTPException):
            LOG.info(_LI("HTTP exception thrown: %s"), ex_value)
            raise Fault(ex_value)

        # We didn't handle the exception
        return False
Esempio n. 3
0
    def reset_status(self, req, id, body):
        """reset checkpoint status"""
        LOG.info(_LI("Reset checkpoint status, id: %s"), id)
        status = body['reset_status'].get('status',
                                          fields.CheckpointStatus.AVAILABLE)
        if status not in fields.CheckpointStatus.ALL:
            msg = _("Invalid status provided.")
            LOG.error(msg)
            raise exception.InvalidStatus(status=status)

        context = req.environ['sgservice.context']
        checkpoint = self.service_api.get_checkpoint(context, id)
        checkpoint.status = status
        checkpoint.save()
        # reset master snapshot status
        try:
            master_snapshot = self.service_api.get_snapshot(
                context, checkpoint.master_snapshot)
            master_snapshot.status = status
            master_snapshot.save()
        except Exception:
            pass
        # reset slave snapshot status
        try:
            slave_snapshot = self.service_api.get_snapshot(
                context, checkpoint.slave_snapshot)
            slave_snapshot.status = status
            slave_snapshot.save()
        except Exception:
            pass

        return webob.Response(status_int=202)
Esempio n. 4
0
 def rollback(self, req, id, body):
     """Rollback a checkpoint"""
     LOG.info(_LI("Rollback checkpoint with id: %s"), id)
     context = req.environ['sgservice.context']
     checkpoint = self.service_api.get_checkpoint(context, id)
     rollback = self.service_api.rollback_checkpoint(context, checkpoint)
     return self._view_builder.rollback_summary(req, rollback)
Esempio n. 5
0
 def delete(self, req, id):
     """Delete a checkpoint."""
     LOG.info(_LI("Delete checkpoint with id: %s"), id)
     context = req.environ['sgservice.context']
     checkpoint = self.service_api.get_checkpoint(context, id)
     self.service_api.delete_checkpoint(context, checkpoint)
     return webob.Response(status_int=202)
Esempio n. 6
0
    def update(self, req, id, body):
        """Update a snapshot."""
        LOG.info(_LI("Update snapshot with id: %s"), id)
        context = req.environ['sgservice.context']
        if not body:
            msg = _("Missing request body")
            raise webob.exc.HTTPBadRequest(explanation=msg)
        if 'snapshot' not in body:
            msg = (_("Missing required element '%s' in request body"),
                   'snapshot')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        snapshot = body['snapshot']
        update_dict = {}

        valid_update_keys = (
            'name',
            'description',
            'display_name',
            'display_description',
        )
        for key in valid_update_keys:
            if key in snapshot:
                update_dict[key] = snapshot[key]
        self.validate_name_and_description(update_dict)
        if 'name' in update_dict:
            update_dict['display_name'] = update_dict.pop('name')
        if 'description' in update_dict:
            update_dict['display_description'] = update_dict.pop('description')

        snapshot = self.service_api.get_snapshot(context, id)
        snapshot.update(update_dict)
        snapshot.save()
        return self._view_builder.detail(req, snapshot)
Esempio n. 7
0
 def rollback(self, req, id, body):
     """Rollback a snapshot to volume"""
     LOG.info(_LI("Rollback snapshot with id: %s"), id)
     context = req.environ['sgservice.context']
     snapshot = self.service_api.get_snapshot(context, id)
     rollback = self.service_api.rollback_snapshot(context, snapshot)
     return self._view_builder.rollback_summary(req, rollback)
Esempio n. 8
0
 def enable(self, req, id, body):
     """Enable a disabled-replication"""
     LOG.info(_LI("Enable replication with id: %s"), id)
     context = req.environ['sgservice.context']
     replication = self.service_api.get_replication(context, id)
     replication = self.service_api.enable_replication(context, replication)
     return self._view_builder.detail(req, replication)
Esempio n. 9
0
 def delete(self, req, id):
     """Delete a replication."""
     LOG.info(_LI("Delete replication with id: %s"), id)
     context = req.environ['sgservice.context']
     replication = self.service_api.get_replication(context, id)
     self.service_api.delete_replication(context, replication)
     return webob.Response(status_int=202)
Esempio n. 10
0
    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
        # NOTE(johannes): We leave the explanation empty here on
        # purpose. It could possibly have sensitive information
        # that should not be returned back to the user. See
        # bugs 868360 and 874472
        # NOTE(eglynn): However, it would be over-conservative and
        # inconsistent with the EC2 API to hide every exception,
        # including those that are safe to expose, see bug 1021373
        if safe:
            msg = (inner.msg if isinstance(inner, exception.SGServiceException)
                   else six.text_type(inner))
            params = {
                'exception': inner.__class__.__name__,
                'explanation': msg
            }
            outer.explanation = _('%(exception)s: %(explanation)s') % params
        return wsgi.Fault(outer)
Esempio n. 11
0
    def update(self, req, id, body):
        """Update a backup."""
        LOG.info(_LI("Update backup, backup_id: %s"), id)
        context = req.environ['sgservice.context']
        if not body:
            msg = _("Missing request body")
            raise webob.exc.HTTPBadRequest(explanation=msg)
        if 'backup' not in body:
            msg = (_("Missing required element '%s' in request body"),
                   'backup')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        backup = body['backup']
        update_dict = {}

        valid_update_keys = (
            'name',
            'description',
            'display_name',
            'display_description',
        )
        for key in valid_update_keys:
            if key in backup:
                update_dict[key] = backup[key]
        self.validate_name_and_description(update_dict)
        if 'name' in update_dict:
            update_dict['display_name'] = update_dict.pop('name')
        if 'description' in update_dict:
            update_dict['display_description'] = update_dict.pop('description')

        backup = self.service_api.get_backup(context, id)
        backup.update(update_dict)
        backup.save()
        return self._view_builder.detail(req, backup)
Esempio n. 12
0
 def delete(self, req, id):
     """Delete a backup."""
     LOG.info(_LI("Delete backup, backup_id: %s"), id)
     context = req.environ['sgservice.context']
     backup = self.service_api.get_backup(context, id)
     self.service_api.delete_backup(context, backup)
     return webob.Response(status_int=202)
Esempio n. 13
0
 def delete(self, req, id):
     """Delete a snapshot."""
     LOG.info(_LI("Delete snapshot with id: %s"), id)
     context = req.environ['sgservice.context']
     snapshot = self.service_api.get_snapshot(context, id)
     self.service_api.delete_snapshot(context, snapshot)
     return webob.Response(status_int=202)
Esempio n. 14
0
 def disable(self, req, id, body):
     """Disable a enabled-volume."""
     LOG.info(_LI("Disable volume SG, volume_id: %s"), id)
     context = req.environ['sgservice.context']
     volume = self.service_api.get(context, id)
     volume = self.service_api.disable_sg(context, volume)
     return self._view_builder.detail(req, volume)
Esempio n. 15
0
 def delete(self, req, id):
     """Delete a sg volume."""
     LOG.info(_LI("Delete sg volume, volume_id: %s"), id)
     context = req.environ['sgservice.context']
     volume = self.service_api.get(context, id)
     self.service_api.delete(context, volume)
     return webob.Response(status_int=202)
Esempio n. 16
0
    def reset_status(self, req, id, body):
        """reset replication status"""
        LOG.info(_LI("Reset replication status, id: %s"), id)
        status = body['reset_status'].get('status',
                                          fields.ReplicationStatus.ENABLED)
        if status not in fields.ReplicationStatus.ALL:
            msg = _("Invalid status provided.")
            LOG.error(msg)
            raise exception.InvalidStatus(status=status)

        context = req.environ['sgservice.context']
        replication = self.service_api.get_replication(context, id)
        replication.status = status
        replication.save()
        # reset master volume replicate status
        master_volume = self.service_api.get(context,
                                             replication.master_volume)
        if master_volume.replicate_status not in [
                None, fields.ReplicateStatus.DELETED
        ]:
            master_volume.replicate_status = status
        master_volume.save()

        # reset slave volume replicate status
        slave_volume = self.service_api.get(context, replication.slave_volume)
        if slave_volume.replicate_status not in [
                None, fields.ReplicateStatus.DELETED
        ]:
            slave_volume.replicate_status = status
        slave_volume.save()
        return webob.Response(status_int=202)
Esempio n. 17
0
    def export_record(self, req, id, body):
        """Export backup record"""
        LOG.info(_LI("Export backup record, backup_id: %s"), id)
        context = req.environ['sgservice.context']
        backup = self.service_api.get_backup(context, id)

        record = self.service_api.export_record(context, backup)
        return self._view_builder.export_summary(req, record)
Esempio n. 18
0
 def detach(self, req, id, body):
     """Clear attachment metadata."""
     LOG.info(_LI("Clear SG-volume attachment with volume_id: %s"), id)
     context = req.environ['sgservice.context']
     volume = self.service_api.get(context, id)
     params = body['detach']
     params = {} if params is None else params
     instance_uuid = params.get('instance_uuid', None)
     self.service_api.detach(context, volume, instance_uuid)
     return webob.Response(status_int=202)
Esempio n. 19
0
    def failover(self, req, id, body):
        """Failover a enabled replication"""
        LOG.info(_LI("Failover replication with id: %s"), id)
        context = req.environ['sgservice.context']

        params = body['failover']
        force = params.get('force', False)
        replication = self.service_api.get_replication(context, id)
        replication = self.service_api.failover_replication(
            context, replication, force)
        return self._view_builder.detail(req, replication)
Esempio n. 20
0
    def restore(self, req, id, body):
        """Restore backup to an SG-enabled volume"""
        LOG.info(_LI("Restore backup to sg-enabled volume, backup_id: %s"), id)
        context = req.environ['sgservice.context']
        backup = self.service_api.get_backup(context, id)
        restore = body['restore']
        volume_id = restore.get('volume_id', None)
        if volume_id is None:
            msg = _('restored volume should be specified.')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        restore = self.service_api.restore_backup(context, backup, volume_id)
        return self._view_builder.restore_summary(req, restore)
Esempio n. 21
0
    def wait(self):
        """Block, until the server has stopped.

        Waits on the server's eventlet to finish, then returns.

        :returns: None

        """
        try:
            if self._server is not None:
                self._pool.waitall()
                self._server.wait()
        except greenlet.GreenletExit:
            LOG.info(_LI("WSGI server has stopped."))
Esempio n. 22
0
    def stop(self):
        """Stop this server.

        This is not a very nice action, as currently the method by which a
        server is stopped is by killing its eventlet.

        :returns: None

        """
        LOG.info(_LI("Stopping WSGI server."))
        if self._server is not None:
            # Resize pool to stop new requests from being processed
            self._pool.resize(0)
            self._server.kill()
Esempio n. 23
0
    def reset_status(self, req, id, body):
        """reset snapshot status"""
        LOG.info(_LI("Reset snapshot status, id: %s"), id)
        status = body['reset_status'].get('status',
                                          fields.SnapshotStatus.AVAILABLE)
        if status not in fields.SnapshotStatus.ALL:
            msg = _("Invalid status provided.")
            LOG.error(msg)
            raise exception.InvalidStatus(status=status)

        context = req.environ['sgservice.context']
        snapshot = self.service_api.get_snapshot(context, id)
        snapshot.status = status
        snapshot.save()
        return webob.Response(status_int=202)
Esempio n. 24
0
    def reset_status(self, req, id, body):
        """reset volume status"""
        LOG.info(_LI("Reset volume status, id: %s"), id)
        status = body['reset_status'].get('status',
                                          fields.VolumeStatus.ENABLED)
        if status not in fields.VolumeStatus.ALL:
            msg = _("Invalid status provided.")
            LOG.error(msg)
            raise exception.InvalidStatus(status=status)

        context = req.environ['sgservice.context']
        volume = self.service_api.get(context, id)
        volume.status = status
        volume.save()
        return webob.Response(status_int=202)
Esempio n. 25
0
    def start(self):
        version_string = version.version_string()
        LOG.info(_LI('Starting %(topic)s node (version %(version_string)s)'),
                 {'topic': self.topic, 'version_string': version_string})
        self.model_disconnected = False
        ctxt = context.get_admin_context()
        try:
            service_ref = db.service_get_by_args(ctxt,
                                                 self.host,
                                                 self.binary)
            self.service_id = service_ref['id']
        except exception.NotFound:
            self._create_service_ref(ctxt)

        self.manager.init_host(service_id=self.service_id)

        LOG.debug("Creating RPC server for service %s", self.topic)

        target = messaging.Target(topic=self.topic, server=self.host)
        endpoints = [self.manager]
        endpoints.extend(self.manager.additional_endpoints)
        serializer = objects_base.SGServiceObjectSerializer()
        self.rpcserver = rpc.get_server(target, endpoints, serializer)
        self.rpcserver.start()

        self.manager.init_host_with_rpc()

        if self.report_interval:
            pulse = loopingcall.FixedIntervalLoopingCall(
                self.report_state)
            pulse.start(interval=self.report_interval,
                        initial_delay=self.report_interval)
            self.timers.append(pulse)

        if self.periodic_interval:
            if self.periodic_fuzzy_delay:
                initial_delay = random.randint(0, self.periodic_fuzzy_delay)
            else:
                initial_delay = None

            periodic = loopingcall.FixedIntervalLoopingCall(
                self.periodic_tasks)
            periodic.start(interval=self.periodic_interval,
                           initial_delay=initial_delay)
            self.timers.append(periodic)
Esempio n. 26
0
    def __call__(self, request):
        """WSGI method that controls (de)serialization and method dispatch."""

        LOG.info(_LI("%(method)s %(url)s"), {
            "method": request.method,
            "url": request.url
        })

        # Identify the action, its arguments, and the requested
        # content type
        action_args = self.get_action_args(request.environ)
        action = action_args.pop('action', None)
        content_type, body = self.get_body(request)
        accept = request.best_match_content_type()

        # NOTE(Vek): Splitting the function up this way allows for
        #            auditing by external tools that wrap the existing
        #            function.  If we try to audit __call__(), we can
        #            run into troubles due to the @webob.dec.wsgify()
        #            decorator.
        return self._process_stack(request, action, action_args, content_type,
                                   body, accept)
Esempio n. 27
0
    def import_record(self, req, body):
        """Import a backup"""
        LOG.info(_LI("Importing record from body: %s"), body)
        self.assert_valid_body(body, 'backup_record')
        context = req.environ['sgservice.context']
        backup_record = body['backup_record']
        # Verify that body elements are provided
        try:
            driver_data = backup_record['driver_data']
        except KeyError:
            msg = _("Incorrect request body format.")
            raise webob.exc.HTTPBadRequest(explanation=msg)
        LOG.debug('Importing backup using driver_data %s.', driver_data)

        try:
            new_backup = self.service_api.import_record(context, backup_record)
        except exception.InvalidBackup as error:
            raise webob.exc.HTTPBadRequest(explanation=error.msg)
        # Other Not found exceptions will be handled at the wsgi level
        except exception.ServiceNotFound as error:
            raise webob.exc.HTTPInternalServerError(explanation=error.msg)

        retval = self._view_builder.detail(req, new_backup)
        return retval
Esempio n. 28
0
    def attach(self, req, id, body):
        """Add sg-volume attachment metadata."""
        LOG.info(_LI("Add SG-volume attachment, volume_id: %s"), id)
        context = req.environ['sgservice.context']
        volume = self.service_api.get(context, id)

        params = body['attach']
        params = {} if params is None else params
        instance_uuid = params.get('instance_uuid', None)

        mode = params.get('mode', None)
        if mode is None:
            mode = 'rw'
        if instance_uuid is None:
            msg = _("Invalid request to attach volume to an invalid target")
            raise webob.exc.HTTPBadRequest(explanation=msg)
        if mode not in ('rw', 'ro'):
            msg = _("Invalid request to attach volume to an invalid mode. "
                    "Attaching mode should be 'rw' or 'ro'.")
            raise webob.exc.HTTPBadRequest(explanation=msg)

        attach_result = self.service_api.attach(context, volume, instance_uuid,
                                                mode)
        return self._view_builder.attach_summary(req, attach_result)
Esempio n. 29
0
 def index(self, req):
     """Returns a list of snapshots, transformed through view builder."""
     LOG.info(_LI("Show snapshot list"))
     return {"snapshots": {}}
Esempio n. 30
0
 def delete(self, req, id):
     """Delete a snapshot."""
     LOG.info(_LI("Delete snapshot with id: %s"), id)
     pass
     return webob.Response(status_int=202)