Example #1
0
    def checkpoints_update(self, req, provider_id, checkpoint_id, body):
        """Reset a checkpoint's state"""
        context = req.environ['karbor.context']
        context.notification = notification.KarborCheckpointUpdate(
            context, request=req)

        LOG.info("Reset checkpoint state with id: %s", checkpoint_id)
        LOG.info("provider_id: %s.", provider_id)

        if not uuidutils.is_uuid_like(provider_id):
            msg = _("Invalid provider id provided.")
            raise exc.HTTPBadRequest(explanation=msg)

        if not uuidutils.is_uuid_like(checkpoint_id):
            msg = _("Invalid checkpoint id provided.")
            raise exc.HTTPBadRequest(explanation=msg)

        context.can(provider_policy.CHECKPOINT_UPDATE_POLICY)

        if body.get("os-resetState"):
            with StartNotification(context, checkpoint_id=checkpoint_id):
                state = body["os-resetState"]["state"]
                return self._checkpoint_reset_state(
                    context, provider_id, checkpoint_id, state)
        else:
            msg = _("Invalid input.")
            raise exc.HTTPBadRequest(explanation=msg)
Example #2
0
    def delete(self, req, id):
        """Delete a trigger."""

        LOG.debug('Delete trigger(%s) start', id)

        context = req.environ['karbor.context']
        trigger = self._get_trigger_by_id(context, id)
        context.notification = notification.KarborTriggerDelete(
            context, request=req)

        context.can(trigger_policy.DELETE_POLICY, trigger)

        try:
            operations = objects.ScheduledOperationList.get_by_filters(
                context, {"trigger_id": id}, limit=1)
        except Exception as ex:
            self._raise_unknown_exception(ex)

        if operations:
            msg = _("Trigger is being used by one or more operations")
            raise exc.HTTPFailedDependency(explanation=msg)

        try:
            with StartNotification(context, id=id):
                self.operationengine_api.delete_trigger(context, id)
        except exception.TriggerNotFound:
            pass
        except (exception.DeleteTriggerNotAllowed,
                Exception) as ex:
            self._raise_unknown_exception(ex)

        trigger.destroy()
Example #3
0
    def delete(self, req, id):
        """Delete a plan."""
        context = req.environ['karbor.context']

        LOG.info("Delete plan with id: %s", id, context=context)
        context.notification = notification.KarborPlanDelete(context,
                                                             request=req)
        try:
            plan = self._plan_get(context, id)
        except exception.PlanNotFound as error:
            raise exc.HTTPNotFound(explanation=error.msg)

        context.can(plan_policy.DELETE_POLICY, target_obj=plan)
        project_id = plan.project_id

        try:
            with StartNotification(context, id=id):
                plan.destroy()
        except Exception:
            msg = _("Failed to destroy a plan.")
            raise exc.HTTPServerError(reason=msg)

        try:
            reserve_opts = {'plans': -1}
            reservations = QUOTAS.reserve(context,
                                          project_id=project_id,
                                          **reserve_opts)
        except Exception:
            LOG.exception("Failed to update usages deleting plan.")
        else:
            QUOTAS.commit(context, reservations, project_id=project_id)
        LOG.info("Delete plan request issued successfully.",
                 resource={'id': plan.id})
Example #4
0
    def checkpoints_delete(self, req, provider_id, checkpoint_id):
        """Delete a checkpoint."""
        context = req.environ['karbor.context']
        context.can(provider_policy.CHECKPOINT_DELETE_POLICY)
        context.notification = notification.KarborCheckpointDelete(
            context, request=req)

        LOG.info("Delete checkpoint with id: %s.", checkpoint_id)
        LOG.info("provider_id: %s.", provider_id)
        try:
            checkpoint = self._checkpoint_get(context, provider_id,
                                              checkpoint_id)
        except exception.CheckpointNotFound as error:
            raise exc.HTTPNotFound(explanation=error.msg)
        except exception.AccessCheckpointNotAllowed as error:
            raise exc.HTTPForbidden(explanation=error.msg)
        project_id = checkpoint.get('project_id')

        try:
            with StartNotification(context, checkpoint_id=checkpoint_id):
                self.protection_api.delete(context, provider_id, checkpoint_id)
        except exception.DeleteCheckpointNotAllowed as error:
            raise exc.HTTPForbidden(explantion=error.msg)

        try:
            reserve_opts = {'checkpoints': -1}
            reservations = QUOTAS.reserve(
                context, project_id=project_id, **reserve_opts)
        except Exception:
            LOG.exception("Failed to update usages after deleting checkpoint.")
        else:
            QUOTAS.commit(context, reservations, project_id=project_id)

        LOG.info("Delete checkpoint request issued successfully.")
        return {}
Example #5
0
    def create(self, req, body):
        """Creates a new plan."""

        LOG.debug('Create plan request body: %s', body)
        context = req.environ['karbor.context']
        context.can(plan_policy.CREATE_POLICY)
        plan = body['plan']
        LOG.debug('Create plan request plan: %s', plan)
        context.notification = notification.KarborPlanCreate(context,
                                                             request=req)

        parameters = plan.get("parameters", None)

        self.validate_plan_resources(plan)
        self.validate_plan_parameters(context, plan)

        resources = plan.get('resources', None)
        if resources:
            for resource in resources:
                extra_info = resource.get('extra_info', None)
                if extra_info is not None:
                    resource['extra_info'] = jsonutils.dumps(extra_info)

        plan_properties = {
            'name': plan.get('name', None),
            'description': plan.get('description', None),
            'provider_id': plan.get('provider_id', None),
            'project_id': context.project_id,
            'status': constants.PLAN_STATUS_SUSPENDED,
            'resources': resources,
            'parameters': parameters,
        }

        try:
            reserve_opts = {'plans': 1}
            reservations = QUOTAS.reserve(context, **reserve_opts)
        except exception.OverQuota as e:
            quota.process_reserve_over_quota(context, e, resource='plans')
        try:
            plan = objects.Plan(context=context, **plan_properties)
            with StartNotification(context, name=plan.get('name', None)):
                plan.create()
            QUOTAS.commit(context, reservations)
        except Exception:
            with excutils.save_and_reraise_exception():
                try:
                    if plan and 'id' in plan:
                        plan.destroy()
                finally:
                    QUOTAS.rollback(context, reservations)

        retval = self._view_builder.detail(req, plan)

        return retval
    def create(self, req, body):
        """Creates a new scheduled operation."""

        LOG.debug('Create scheduled operation start')

        LOG.debug('Create a scheduled operation, request body: %s', body)

        context = req.environ['karbor.context']
        context.can(scheduled_operation_policy.CREATE_POLICY)
        context.notification = notification.KarborScheduledOpsCreate(
            context, request=req)
        operation_info = body['scheduled_operation']

        name = operation_info.get("name", None)
        operation_type = operation_info.get("operation_type", None)
        operation_definition = operation_info.get("operation_definition", None)
        if not all([name, operation_type, operation_definition]):
            msg = _("Operation name or type or definition is not provided.")
            raise exc.HTTPBadRequest(explanation=msg)

        trigger_id = operation_info.get("trigger_id", None)
        trigger = self._get_trigger_by_id(context, trigger_id)
        if context.project_id != trigger.project_id:
            msg = _("Invalid trigger id provided.")
            raise exc.HTTPBadRequest(explanation=msg)

        operation_obj = {
            'name': operation_info.get('name', None),
            'description': operation_info.get('description', None),
            'operation_type': operation_type,
            'user_id': context.user_id,
            'project_id': context.project_id,
            'trigger_id': trigger_id,
            'operation_definition': operation_definition,
        }
        try:
            operation = objects.ScheduledOperation(context=context,
                                                   **operation_obj)
            operation.create()
        except Exception as ex:
            self._raise_unknown_exception(ex)

        try:
            with StartNotification(context, operation_obj=operation_obj):
                self._create_scheduled_operation(context, operation)
        except Exception:
            try:
                operation.destroy()
            except Exception:
                pass

            raise

        return self._view_builder.detail(req, operation)
Example #7
0
    def update(self, req, id, body):
        """Update a plan."""
        context = req.environ['karbor.context']
        context.notification = notification.KarborPlanUpdate(context,
                                                             request=req)

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

        valid_update_keys = {
            'name',
            'resources',
            'status',
            'description',
        }
        for key in valid_update_keys.intersection(plan):
            update_dict[key] = plan[key]

        if not update_dict:
            msg = _("Missing updated parameters in request body.")
            raise exc.HTTPBadRequest(explanation=msg)

        if update_dict.get("resources"):
            self.validate_plan_resources(update_dict)

        resources = update_dict.get('resources', None)
        if resources:
            for resource in resources:
                extra_info = resource.get('extra_info', None)
                if extra_info is not None:
                    resource['extra_info'] = jsonutils.dumps(extra_info)

        try:
            plan = self._plan_get(context, id)
        except exception.PlanNotFound as error:
            raise exc.HTTPNotFound(explanation=error.msg)

        with StartNotification(context, id=id):
            self._plan_update(context, plan, update_dict)
            plan.update(update_dict)

        retval = self._view_builder.detail(req, plan)
        return retval
Example #8
0
    def create(self, req, body):
        """Creates a new restore."""

        LOG.debug('Create restore request body: %s', body)
        context = req.environ['karbor.context']
        context.can(restore_policy.CREATE_POLICY)
        context.notification = notification.KarborRestoreCreate(context,
                                                                request=req)
        restore = body['restore']
        LOG.debug('Create restore request : %s', restore)

        parameters = restore.get("parameters")
        restore_auth = restore.get("restore_auth", None)
        restore_properties = {
            'project_id': context.project_id,
            'provider_id': restore.get('provider_id'),
            'checkpoint_id': restore.get('checkpoint_id'),
            'restore_target': restore.get('restore_target'),
            'parameters': parameters,
            'status': constants.RESTORE_STATUS_IN_PROGRESS,
        }

        restoreobj = objects.Restore(context=context, **restore_properties)
        restoreobj.create()
        LOG.debug('call restore RPC  : restoreobj:%s', restoreobj)

        # call restore rpc API of protection service
        try:
            with StartNotification(context, parameters=parameters):
                self.protection_api.restore(context, restoreobj, restore_auth)
        except exception.AccessCheckpointNotAllowed as error:
            raise exc.HTTPForbidden(explanation=error.msg)
        except Exception:
            # update the status of restore
            update_dict = {"status": constants.RESTORE_STATUS_FAILURE}
            context.can(restore_policy.UPDATE_POLICY, restoreobj)
            restoreobj = self._restore_update(context, restoreobj.get("id"),
                                              update_dict)

        retval = self._view_builder.detail(req, restoreobj)

        return retval
Example #9
0
    def create(self, req, body):
        """Creates a new trigger."""

        LOG.debug('Create trigger start')

        LOG.debug('Create a trigger, request body: %s', body)

        context = req.environ['karbor.context']
        context.can(trigger_policy.CREATE_POLICY)
        trigger_info = body['trigger_info']
        context.notification = notification.KarborTriggerCreate(
            context, request=req)

        trigger_name = trigger_info.get("name", None)
        trigger_type = trigger_info.get("type", None)
        trigger_property = trigger_info.get("properties", None)

        trigger_property.setdefault(
            'start_time', datetime.utcnow().replace(microsecond=0))
        trigger_definition = {
            'id': uuidutils.generate_uuid(),
            'name': trigger_name,
            'project_id': context.project_id,
            'type': trigger_type,
            'properties': trigger_property,
        }
        try:
            with StartNotification(
                    context, name=trigger_name):
                trigger = objects.Trigger(
                    context=context, **trigger_definition)
                self.operationengine_api.verify_trigger(context, trigger)
                self.operationengine_api.create_trigger(context, trigger)
                trigger.create()
        except exception.Invalid as ex:
            raise exc.HTTPBadRequest(explanation=ex.msg)
        except Exception as ex:
            self._raise_unknown_exception(ex)

        return self._view_builder.detail(req, trigger)
Example #10
0
    def update(self, req, id, body):
        """Update a trigger"""

        LOG.debug('Update trigger(%s) start', id)

        context = req.environ['karbor.context']
        trigger = self._get_trigger_by_id(context, id)
        context.notification = notification.KarborTriggerUpdate(
            context, request=req)

        context.can(trigger_policy.UPDATE_POLICY, trigger)

        trigger_info = body['trigger_info']
        trigger_name = trigger_info.get("name", None)
        trigger_property = trigger_info.get("properties", None)

        if trigger_name:
            self.validate_name_and_description(trigger_info)
            trigger.name = trigger_name

        if trigger_property:
            start_time = trigger_property.get('start_time', None)
            if not start_time:
                msg = (_("start_time should be supplied"))
                raise exc.HTTPBadRequest(explanation=msg)
            try:
                trigger.properties = trigger_property
                self.operationengine_api.verify_trigger(context, trigger)
                self.operationengine_api.update_trigger(context, trigger)
            except exception.InvalidInput as ex:
                raise exc.HTTPBadRequest(explanation=ex.msg)
            except (exception.TriggerNotFound, Exception) as ex:
                self._raise_unknown_exception(ex)
        try:
            with StartNotification(context, id=id):
                trigger.save()
        except Exception as ex:
            self._raise_unknown_exception(ex)

        return self._view_builder.detail(req, trigger)
    def delete(self, req, id):
        """Delete a scheduled operation."""

        LOG.debug('Delete scheduled operation(%s) start', id)

        context = req.environ['karbor.context']
        context.notification = notification.KarborScheduledOpsDelete(
            context, request=req)
        operation = self._get_operation_by_id(context, id, ['trigger'])
        trigger = operation.trigger

        context.can(scheduled_operation_policy.DELETE_POLICY, operation)

        try:
            with StartNotification(context, id=id):
                self.operationengine_api.delete_scheduled_operation(
                    context, id, trigger.id)

        except (exception.ScheduledOperationStateNotFound,
                exception.TriggerNotFound, Exception) as ex:
            self._raise_unknown_exception(ex)

        operation.destroy()
Example #12
0
    def checkpoints_create(self, req, provider_id, body):
        """Creates a new checkpoint."""

        context = req.environ['karbor.context']
        context.notification = notification.KarborCheckpointCreate(context,
                                                                   request=req)

        LOG.debug('Create checkpoint request '
                  'body: %s provider_id:%s', body, provider_id)

        context.can(provider_policy.CHECKPOINT_CREATE_POLICY)
        checkpoint = body['checkpoint']
        LOG.debug('Create checkpoint request checkpoint: %s', checkpoint)

        if not provider_id:
            msg = _("provider_id must be provided when creating "
                    "a checkpoint.")
            raise exception.InvalidInput(reason=msg)

        plan_id = checkpoint.get("plan_id")

        plan = objects.Plan.get_by_id(context, plan_id)
        if not plan:
            raise exception.PlanNotFound(plan_id=plan_id)

        # check the provider_id
        if provider_id != plan.get("provider_id"):
            msg = _("The parameter provider_id is not the same as "
                    "the value in the plan.")
            raise exception.InvalidPlan(reason=msg)

        extra_info = checkpoint.get("extra_info", None)
        if extra_info is not None:
            if not isinstance(extra_info, dict):
                msg = _("The extra_info in checkpoint must be a dict when "
                        "creating a checkpoint.")
                raise exception.InvalidInput(reason=msg)
            elif not all(
                    map(lambda s: isinstance(s, six.string_types),
                        extra_info.keys())):
                msg = _("Key of extra_info in checkpoint must be string when"
                        "creating a checkpoint.")
                raise exception.InvalidInput(reason=msg)
        else:
            extra_info = {'created_by': constants.MANUAL}

        checkpoint_extra_info = None
        if extra_info is not None:
            checkpoint_extra_info = jsonutils.dumps(extra_info)
        checkpoint_properties = {
            'project_id': context.project_id,
            'status': constants.CHECKPOINT_STATUS_PROTECTING,
            'provider_id': provider_id,
            "protection_plan": {
                "id": plan.get("id"),
                "name": plan.get("name"),
                "resources": plan.get("resources"),
            },
            "extra_info": checkpoint_extra_info
        }

        try:
            reserve_opts = {'checkpoints': 1}
            reservations = QUOTAS.reserve(context, **reserve_opts)
        except exception.OverQuota as e:
            quota.process_reserve_over_quota(context,
                                             e,
                                             resource='checkpoints')
        else:
            checkpoint_id = None
            try:
                with StartNotification(
                        context, checkpoint_properties=checkpoint_properties):
                    checkpoint_id = self.protection_api.protect(
                        context, plan, checkpoint_properties)
                    QUOTAS.commit(context, reservations)
            except Exception as error:
                if not checkpoint_id:
                    QUOTAS.rollback(context, reservations)
                msg = _("Create checkpoint failed: %s") % error
                raise exc.HTTPBadRequest(explanation=msg)

            checkpoint_properties['id'] = checkpoint_id

            LOG.info("Create the checkpoint successfully. checkpoint_id:%s",
                     checkpoint_id)
            returnval = self._checkpoint_view_builder.detail(
                req, checkpoint_properties)
            return returnval
Example #13
0
 def test_call(self):
     with patch.object(self.context, "notification") as notification:
         with StartNotification(self.context):
             pass
         self.assertTrue(notification.notify_start.called)