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)
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()
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})
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 {}
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)
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
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
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)
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()
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
def test_call(self): with patch.object(self.context, "notification") as notification: with StartNotification(self.context): pass self.assertTrue(notification.notify_start.called)