Exemplo n.º 1
0
 def obj_create(self, bundle, **kwargs):
     model = bundle.obj.__class__
     try:
         pipeline_template_kwargs = {
             'name': bundle.data.pop('name'),
             'creator': bundle.request.user.username,
             'pipeline_tree': json.loads(bundle.data.pop('pipeline_tree')),
             'description': bundle.data.pop('description', ''),
         }
     except (KeyError, ValueError) as e:
         raise BadRequest(e.message)
     # XSS handle
     self.handle_template_name_attr(pipeline_template_kwargs)
     # validate pipeline tree
     try:
         validate_web_pipeline_tree(pipeline_template_kwargs['pipeline_tree'])
     except PipelineException as e:
         raise BadRequest(e.message)
     # Note: tastypie won't use model's create method
     try:
         pipeline_template = model.objects.create_pipeline_template(
             **pipeline_template_kwargs)
     except PipelineException as e:
         raise BadRequest(e.message)
     except CommonTemplate.DoesNotExist:
         raise BadRequest('flow template referred as SubProcess does not exist')
     kwargs['pipeline_template_id'] = pipeline_template.template_id
     return super(CommonTemplateResource, self).obj_create(bundle, **kwargs)
Exemplo n.º 2
0
    def obj_create(self, bundle, **kwargs):
        try:
            template_id = bundle.data.pop('template_id')
            name = bundle.data.pop('name')
            cron = json.loads(bundle.data.pop('cron'))
            pipeline_tree = json.loads(bundle.data.pop('pipeline_tree'))
            business_path = bundle.data['business']
        except (KeyError, ValueError) as e:
            raise BadRequest(e.message)

        # XSS handle
        name = name_handler(name, PERIOD_TASK_NAME_MAX_LENGTH)
        creator = bundle.request.user.username

        # validate pipeline tree
        try:
            validate_web_pipeline_tree(pipeline_tree)
        except PipelineException as e:
            raise BadRequest(e.message)

        try:
            template = TaskTemplate.objects.get(id=template_id)
            kwargs['template_id'] = template.id
        except TaskTemplate.DoesNotExist:
            raise BadRequest('template[id=%s] does not exist' % template_id)

        try:
            replace_template_id(TaskTemplate, pipeline_tree)
        except TaskTemplate.DoesNotExist:
            raise BadRequest(
                'invalid subprocess, check subprocess node please')

        if not isinstance(cron, dict):
            raise BadRequest('cron must be a object json string')

        try:
            business = Business.objects.get(
                cc_id=int(business_path.split('/')[-2]))
        except Exception as e:
            raise BadRequest(e.message)

        try:
            kwargs['task'] = PeriodicTask.objects.create_pipeline_task(
                business=business,
                template=template,
                name=name,
                cron=cron,
                pipeline_tree=pipeline_tree,
                creator=creator)
        except Exception as e:
            logger.warning(traceback.format_exc())
            raise BadRequest(e.message)

        response = super(PeriodicTaskResource,
                         self).obj_create(bundle, **kwargs)
        response.obj.set_enabled(True)

        return response
Exemplo n.º 3
0
    def obj_create(self, bundle, **kwargs):
        model = bundle.obj.__class__
        try:
            template_id = bundle.data['template_id']
            template_source = bundle.data.get('template_source', 'business')
            creator = bundle.request.user.username
            pipeline_instance_kwargs = {
                'name': bundle.data.pop('name'),
                'creator': creator,
                'pipeline_tree': json.loads(bundle.data.pop('pipeline_tree')),
            }
            if 'description' in bundle.data:
                pipeline_instance_kwargs['description'] = bundle.data.pop(
                    'description')
        except (KeyError, ValueError) as e:
            raise BadRequest(e.message)
        # XSS handle
        self.handle_task_name_attr(pipeline_instance_kwargs)
        # validate pipeline tree
        try:
            validate_web_pipeline_tree(
                pipeline_instance_kwargs['pipeline_tree'])
        except PipelineException as e:
            raise BadRequest(e.message)
        except ParserException as e:
            raise BadRequest(e.message)

        if template_source == 'business':
            try:
                template = TaskTemplate.objects.get(pk=template_id)
            except TaskTemplate.DoesNotExist:
                raise BadRequest('template[pk=%s] does not exist' %
                                 template_id)
        else:
            try:
                template = CommonTemplate.objects.get(pk=str(template_id),
                                                      is_deleted=False)
            except CommonTemplate.DoesNotExist:
                raise BadRequest('common template[pk=%s] does not exist' %
                                 template_id)

        try:
            pipeline_instance = model.objects.__class__.create_pipeline_instance(
                template, **pipeline_instance_kwargs)
        except PipelineException as e:
            raise BadRequest(e.message)
        kwargs['category'] = template.category
        if bundle.data['flow_type'] == 'common_func':
            kwargs['current_flow'] = 'func_claim'
        else:
            kwargs['current_flow'] = 'execute_task'
        kwargs['pipeline_instance_id'] = pipeline_instance.id
        super(TaskFlowInstanceResource, self).obj_create(bundle, **kwargs)
        return bundle
Exemplo n.º 4
0
    def validate(self, request, *args, **kwargs):
        valid, err = super().validate(request, *args, **kwargs)
        if not valid:
            return valid, err

        try:
            params = json.loads(request.body)
        except Exception:
            return False, "invalid json format"

        try:
            pipeline_tree = params["pipeline_tree"]
            standardize_pipeline_node_name(pipeline_tree)
            pipeline_tree.setdefault("gateways", {})
            pipeline_tree.setdefault("constants", {})
            pipeline_tree.setdefault("outputs", [])
            draw_pipeline(pipeline_tree)
            validate_web_pipeline_tree(pipeline_tree)
        except Exception as e:
            message = "[API] fast_create_task get invalid pipeline_tree: %s" % str(
                e)
            logger.warning(message)
            return False, message

        # 校验流程树中子流程是否在当前项目下
        has_common_subprocess = params.get("has_common_subprocess", False)
        templates_in_task = set()
        pipeline_tree = params["pipeline_tree"]
        for activity in pipeline_tree["activities"].values():
            if "template_id" in activity:
                templates_in_task.add(activity["template_id"])
        if not has_common_subprocess:
            project_templates = set(
                TaskTemplate.objects.filter(
                    project_id=request.project.id).values_list("id",
                                                               flat=True))
            if not templates_in_task.issubset(project_templates):
                invalid_template_ids = [
                    str(template)
                    for template in list(templates_in_task - project_templates)
                ]
                message = (
                    "[API] fast_create_task get invalid template_id: {}, template_id "
                    "should belong to current project.".format(
                        ",".join(invalid_template_ids)))
                logger.warning(message)
                return False, message

        setattr(request, "params_json", params)
        return True, ""
Exemplo n.º 5
0
    def obj_create(self, bundle, **kwargs):
        model = bundle.obj.__class__
        try:
            template_id = bundle.data["template_id"]
            template_source = bundle.data.get("template_source", PROJECT)
            creator = bundle.request.user.username
            pipeline_instance_kwargs = {
                "name": bundle.data.pop("name"),
                "creator": creator,
                "pipeline_tree": json.loads(bundle.data.pop("pipeline_tree")),
            }
            if "description" in bundle.data:
                pipeline_instance_kwargs["description"] = bundle.data.pop("description")
        except (KeyError, ValueError) as e:
            raise BadRequest(str(e))

        try:
            project = ProjectResource().get_via_uri(bundle.data.get("project"), request=bundle.request)
        except NotFound:
            raise BadRequest("project with uri(%s) does not exist" % bundle.data.get("project"))

        # perms validate
        if template_source == PROJECT:
            try:
                template = TaskTemplate.objects.get(pk=template_id, project=project, is_deleted=False)
            except TaskTemplate.DoesNotExist:
                raise BadRequest("template[pk=%s] does not exist" % template_id)

            create_method = bundle.data["create_method"]

            # mini app create task perm
            if create_method == "app_maker":
                app_maker_id = bundle.data["create_info"]
                try:
                    app_maker = AppMaker.objects.get(id=app_maker_id)
                except AppMaker.DoesNotExist:
                    raise BadRequest("app_maker[pk=%s] does not exist" % app_maker_id)

                allow_or_raise_immediate_response(
                    iam=iam,
                    system=IAMMeta.SYSTEM_ID,
                    subject=Subject("user", bundle.request.user.username),
                    action=Action(IAMMeta.MINI_APP_CREATE_TASK_ACTION),
                    resources=res_factory.resources_for_mini_app_obj(app_maker),
                )

            # flow create task perm
            else:
                allow_or_raise_immediate_response(
                    iam=iam,
                    system=IAMMeta.SYSTEM_ID,
                    subject=Subject("user", bundle.request.user.username),
                    action=Action(IAMMeta.FLOW_CREATE_TASK_ACTION),
                    resources=res_factory.resources_for_flow_obj(template),
                )

        else:
            try:
                template = CommonTemplate.objects.get(pk=template_id, is_deleted=False)
            except CommonTemplate.DoesNotExist:
                raise BadRequest("common template[pk=%s] does not exist" % template_id)

            allow_or_raise_immediate_response(
                iam=iam,
                system=IAMMeta.SYSTEM_ID,
                subject=Subject("user", bundle.request.user.username),
                action=Action(IAMMeta.COMMON_FLOW_CREATE_TASK_ACTION),
                resources=[
                    res_factory.resources_for_project_obj(project)[0],
                    res_factory.resources_for_common_flow_obj(template)[0],
                ],
            )

        # XSS handle
        self.handle_task_name_attr(pipeline_instance_kwargs)

        # validate pipeline tree
        try:
            validate_web_pipeline_tree(pipeline_instance_kwargs["pipeline_tree"])
        except PipelineException as e:
            raise BadRequest(str(e))

        try:
            pipeline_instance = model.objects.create_pipeline_instance(template, **pipeline_instance_kwargs)
        except PipelineException as e:
            raise BadRequest(str(e))
        kwargs["category"] = template.category
        if bundle.data["flow_type"] == "common_func":
            kwargs["current_flow"] = "func_claim"
        else:
            kwargs["current_flow"] = "execute_task"
        kwargs["pipeline_instance_id"] = pipeline_instance.id

        # set engine type
        kwargs["engine_ver"] = EngineConfig.objects.get_engine_ver(
            project_id=project.id, template_id=template.id, template_source=template_source
        )

        super(TaskFlowInstanceResource, self).obj_create(bundle, **kwargs)

        # crete auto retry strategy
        arn_creator = AutoRetryNodeStrategyCreator(
            taskflow_id=bundle.obj.id, root_pipeline_id=pipeline_instance.instance_id
        )
        arn_creator.batch_create_strategy(pipeline_instance.execution_data)

        # create timeout config
        TimeoutNodeConfig.objects.batch_create_node_timeout_config(
            taskflow_id=bundle.obj.id,
            root_pipeline_id=pipeline_instance.instance_id,
            pipeline_tree=pipeline_instance.execution_data,
        )

        return bundle
Exemplo n.º 6
0
    def obj_create(self, bundle, **kwargs):
        model = bundle.obj.__class__
        try:
            template_id = bundle.data['template_id']
            template_source = bundle.data.get('template_source', PROJECT)
            creator = bundle.request.user.username
            pipeline_instance_kwargs = {
                'name': bundle.data.pop('name'),
                'creator': creator,
                'pipeline_tree': json.loads(bundle.data.pop('pipeline_tree')),
            }
            if 'description' in bundle.data:
                pipeline_instance_kwargs['description'] = bundle.data.pop(
                    'description')
        except (KeyError, ValueError) as e:
            raise BadRequest(e.message)
        # XSS handle
        self.handle_task_name_attr(pipeline_instance_kwargs)
        # validate pipeline tree
        try:
            validate_web_pipeline_tree(
                pipeline_instance_kwargs['pipeline_tree'])
        except PipelineException as e:
            raise BadRequest(e.message)

        if template_source == PROJECT:
            try:
                template = TaskTemplate.objects.get(pk=template_id)
            except TaskTemplate.DoesNotExist:
                raise BadRequest('template[pk=%s] does not exist' %
                                 template_id)

            create_method = bundle.data['create_method']

            if create_method == 'app_maker':
                app_maker_id = bundle.data['create_info']
                try:
                    app_maker = AppMaker.objects.get(id=app_maker_id)
                except AppMaker.DoesNotExist:
                    raise BadRequest('app_maker[pk=%s] does not exist' %
                                     app_maker_id)

                verify_or_raise_immediate_response(
                    principal_type='user',
                    principal_id=creator,
                    resource=mini_app_resource,
                    action_ids=[mini_app_resource.actions.create_task.id],
                    instance=app_maker)

            else:
                verify_or_raise_immediate_response(
                    principal_type='user',
                    principal_id=creator,
                    resource=task_template_resource,
                    action_ids=[task_template_resource.actions.create_task.id],
                    instance=template)

        else:
            try:
                template = CommonTemplate.objects.get(pk=str(template_id),
                                                      is_deleted=False)
            except CommonTemplate.DoesNotExist:
                raise BadRequest('common template[pk=%s] does not exist' %
                                 template_id)

            try:
                project = ProjectResource().get_via_uri(
                    bundle.data.get('project'), request=bundle.request)
            except NotFound:
                raise BadRequest('project with uri(%s) does not exist' %
                                 bundle.data.get('project'))

            perms_tuples = [
                (project_resource,
                 [project_resource.actions.use_common_template.id], project),
                (common_template_resource,
                 [common_template_resource.actions.create_task.id], template)
            ]
            batch_verify_or_raise_immediate_response(principal_type='user',
                                                     principal_id=creator,
                                                     perms_tuples=perms_tuples)

        try:
            pipeline_instance = model.objects.create_pipeline_instance(
                template, **pipeline_instance_kwargs)
        except PipelineException as e:
            raise BadRequest(e.message)
        kwargs['category'] = template.category
        if bundle.data['flow_type'] == 'common_func':
            kwargs['current_flow'] = 'func_claim'
        else:
            kwargs['current_flow'] = 'execute_task'
        kwargs['pipeline_instance_id'] = pipeline_instance.id
        super(TaskFlowInstanceResource, self).obj_create(bundle, **kwargs)
        return bundle
Exemplo n.º 7
0
 def __init__(self, web_pipeline_tree):
     validate_web_pipeline_tree(web_pipeline_tree)
     pipeline_tree = format_web_data_to_pipeline(web_pipeline_tree)
     super(WebPipelineAdapter, self).__init__(pipeline_tree)
Exemplo n.º 8
0
def fast_create_task(request, project_id):
    try:
        params = json.loads(request.body)
    except Exception:
        return JsonResponse({
            'result': False,
            'message': 'invalid json format'
        })

    project = request.project
    logger.info('apigw fast_create_task info, project_id: {project_id}, params: {params}'.format(
        project_id=project.id,
        params=params))

    if not request.is_trust:
        perms_tuples = [(project_resource, [project_resource.actions.fast_create_task.id], project)]
        batch_verify_or_raise_auth_failed(principal_type='user',
                                          principal_id=request.user.username,
                                          perms_tuples=perms_tuples,
                                          status=200)

    try:
        pipeline_tree = params['pipeline_tree']
        pipeline_node_name_handle(pipeline_tree)
        pipeline_tree.setdefault('gateways', {})
        pipeline_tree.setdefault('constants', {})
        pipeline_tree.setdefault('outputs', [])
        draw_pipeline(pipeline_tree)
        validate_web_pipeline_tree(pipeline_tree)
    except Exception as e:
        message = u'invalid param pipeline_tree: %s' % e.message
        logger.exception(message)
        return JsonResponse({
            'result': False,
            'message': message
        })

    try:
        pipeline_instance_kwargs = {
            'name': name_handler(params['name'], TASK_NAME_MAX_LENGTH),
            'creator': request.user.username,
            'pipeline_tree': pipeline_tree,
            'description': params.get('description', '')
        }
    except (KeyError, ValueError) as e:
        return JsonResponse({
            'result': False,
            'message': u'invalid params: %s' % e.message
        })

    try:
        pipeline_instance = TaskFlowInstance.objects.create_pipeline_instance(
            template=None,
            **pipeline_instance_kwargs
        )
    except PipelineException as e:
        message = u'create pipeline instance error: %s' % e.message
        logger.exception(message)
        return JsonResponse({
            'result': False,
            'message': message
        })

    taskflow_kwargs = {
        'project': project,
        'pipeline_instance': pipeline_instance,
        'template_source': ONETIME,
        'create_method': 'api',
    }
    if params.get('category') in [cate[0] for cate in TASK_CATEGORY]:
        taskflow_kwargs['category'] = params['category']
    # 职能化任务,新建后进入职能化认领阶段
    if params.get('flow_type', 'common') == 'common_func':
        taskflow_kwargs['flow_type'] = 'common_func'
        taskflow_kwargs['current_flow'] = 'func_claim'
    # 常规流程,新建后即可执行
    else:
        taskflow_kwargs['flow_type'] = 'common'
        taskflow_kwargs['current_flow'] = 'execute_task'
    task = TaskFlowInstance.objects.create(**taskflow_kwargs)
    return JsonResponse({
        'result': True,
        'data': {
            'task_id': task.id,
            'task_url': task.url,
            'pipeline_tree': task.pipeline_tree
        }})
Exemplo n.º 9
0
def create_task(request, template_id, project_id):
    params = json.loads(request.body)
    project = request.project
    template_source = params.get("template_source", PROJECT)

    logger.info(
        "[API] create_task info, template_id: {template_id}, project_id: {project_id}, params: {params}"
        .format(template_id=template_id, project_id=project.id, params=params))

    # 兼容老版本的接口调用
    if template_source in NON_COMMON_TEMPLATE_TYPES:
        template_source = PROJECT
        try:
            tmpl = TaskTemplate.objects.select_related(
                "pipeline_template").get(id=template_id,
                                         project_id=project.id,
                                         is_deleted=False)
        except TaskTemplate.DoesNotExist:
            result = {
                "result":
                False,
                "message":
                "template[id={template_id}] of project[project_id={project_id},biz_id={biz_id}] "
                "does not exist".format(template_id=template_id,
                                        project_id=project.id,
                                        biz_id=project.bk_biz_id),
                "code":
                err_code.CONTENT_NOT_EXIST.code,
            }
            return result

    else:
        try:
            tmpl = CommonTemplate.objects.select_related(
                "pipeline_template").get(id=template_id, is_deleted=False)
        except CommonTemplate.DoesNotExist:
            result = {
                "result":
                False,
                "message":
                "common template[id={template_id}] does not exist".format(
                    template_id=template_id),
                "code":
                err_code.CONTENT_NOT_EXIST.code,
            }
            return result

    app_code = getattr(request.jwt.app, settings.APIGW_APP_CODE_KEY)
    if not app_code:
        message = "app_code cannot be empty, make sure api gateway has sent correct params"
        return {
            "result": False,
            "message": message,
            "code": err_code.CONTENT_NOT_EXIST.code
        }

    try:
        params.setdefault("flow_type", "common")
        params.setdefault("constants", {})
        params.setdefault("exclude_task_nodes_id", [])
        params.setdefault("simplify_vars", [])
        params.setdefault("execute_task_nodes_id", [])
        jsonschema.validate(params, APIGW_CREATE_TASK_PARAMS)
    except jsonschema.ValidationError as e:
        logger.exception("[API] create_task raise prams error: %s" % e)
        message = "task params is invalid: %s" % e
        return {
            "result": False,
            "message": message,
            "code": err_code.REQUEST_PARAM_INVALID.code
        }

    create_with_tree = "pipeline_tree" in params

    pipeline_instance_kwargs = {
        "name": params["name"],
        "creator": request.user.username,
        "description": params.get("description", ""),
    }

    if create_with_tree:
        try:
            pipeline_tree = params["pipeline_tree"]
            for key, value in params["constants"].items():
                if key in pipeline_tree["constants"]:
                    if pipeline_tree["constants"][key].get("is_meta", False):
                        meta = copy.deepcopy(pipeline_tree["constants"][key])
                        pipeline_tree["constants"][key]["meta"] = meta
                    pipeline_tree["constants"][key]["value"] = value
            standardize_pipeline_node_name(pipeline_tree)
            validate_web_pipeline_tree(pipeline_tree)
        except Exception as e:
            message = "[API] create_task get invalid pipeline_tree: %s" % str(
                e)
            logger.exception(message)
            return {
                "result": False,
                "message": message,
                "code": err_code.UNKNOWN_ERROR.code
            }

        pipeline_instance_kwargs["pipeline_tree"] = pipeline_tree

        try:
            data = TaskFlowInstance.objects.create_pipeline_instance(
                template=tmpl, **pipeline_instance_kwargs)
        except PipelineException as e:
            message = "[API] create_task create pipeline error: %s" % str(e)
            logger.exception(message)
            return {
                "result": False,
                "message": message,
                "code": err_code.UNKNOWN_ERROR.code
            }
    else:
        # 如果请求参数中含有非空的execute_task_nodes_id(要执行的节点),就将其转换为exclude_task_nodes_id(要排除的节点)
        if not params["execute_task_nodes_id"]:
            exclude_task_nodes_id = params["exclude_task_nodes_id"]
        else:
            exclude_task_nodes_id = get_exclude_nodes_by_execute_nodes(
                params["execute_task_nodes_id"], tmpl)
        try:
            data = TaskFlowInstance.objects.create_pipeline_instance_exclude_task_nodes(
                tmpl,
                pipeline_instance_kwargs,
                params["constants"],
                exclude_task_nodes_id,
                params["simplify_vars"],
            )
        except Exception as e:
            message = f"[API] create_task create pipeline without tree error: {e}"
            logger.exception(message)
            return {
                "result": False,
                "message": message,
                "code": err_code.UNKNOWN_ERROR.code
            }

    task = TaskFlowInstance.objects.create(
        project=project,
        pipeline_instance=data,
        category=tmpl.category,
        template_id=template_id,
        template_source=template_source,
        create_method="api",
        create_info=app_code,
        flow_type=params.get("flow_type", "common"),
        current_flow="execute_task"
        if params.get("flow_type", "common") == "common" else "func_claim",
        engine_ver=EngineConfig.objects.get_engine_ver(
            project_id=project.id,
            template_id=template_id,
            template_source=template_source),
    )

    # crete auto retry strategy
    arn_creator = AutoRetryNodeStrategyCreator(
        taskflow_id=task.id,
        root_pipeline_id=task.pipeline_instance.instance_id)
    arn_creator.batch_create_strategy(task.pipeline_instance.execution_data)

    # create timeout config
    TimeoutNodeConfig.objects.batch_create_node_timeout_config(
        taskflow_id=task.id,
        root_pipeline_id=task.pipeline_instance.instance_id,
        pipeline_tree=task.pipeline_instance.execution_data,
    )

    return {
        "result": True,
        "data": {
            "task_id": task.id,
            "task_url": task.url,
            "pipeline_tree": task.pipeline_tree
        },
        "code": err_code.SUCCESS.code,
    }
Exemplo n.º 10
0
 def test_valid_pipeline_tree(self):
     validator.validate_web_pipeline_tree(self.valid_tree)
Exemplo n.º 11
0
    def obj_create(self, bundle, **kwargs):
        try:
            template_id = bundle.data.pop("template_id")
            template_source = bundle.data.get("template_source", PROJECT)
            name = bundle.data.pop("name")
            cron = bundle.data.pop("cron")
            pipeline_tree = json.loads(bundle.data.pop("pipeline_tree"))
        except (KeyError, ValueError) as e:
            message = "create periodic_task params error: %s" % e.message
            logger.error(message)
            raise BadRequest(message)

        if not isinstance(cron, dict):
            raise BadRequest("cron must be a object json string")

        try:
            project = ProjectResource().get_via_uri(bundle.data.get("project"),
                                                    request=bundle.request)
        except NotFound:
            raise BadRequest("project [uri=%s] does not exist" %
                             bundle.data.get("project"))

        # check if the periodic task of the project reach the limit
        periodic_task_limit = env.PERIODIC_TASK_PROJECT_MAX_NUMBER
        project_config = ProjectConfig.objects.filter(
            project_id=project.id).only("max_periodic_task_num").first()
        if project_config and project_config.max_periodic_task_num > 0:
            periodic_task_limit = project_config.max_periodic_task_num
        if PeriodicTask.objects.filter(
                project__id=project.id).count() >= periodic_task_limit:
            raise BadRequest("Periodic task number reaches limit: {}".format(
                periodic_task_limit))

        if template_source == PROJECT:
            try:
                template = TaskTemplate.objects.get(id=template_id,
                                                    project=project,
                                                    is_deleted=False)
            except TaskTemplate.DoesNotExist:
                raise BadRequest(
                    "template[id={template_id}] of project[{project_id}] does not exist"
                    .format(template_id=template_id, project_id=project.id))

            allow_or_raise_immediate_response(
                iam=iam,
                system=IAMMeta.SYSTEM_ID,
                subject=Subject("user", bundle.request.user.username),
                action=Action(IAMMeta.FLOW_CREATE_PERIODIC_TASK_ACTION),
                resources=res_factory.resources_for_flow_obj(template),
            )

            try:
                replace_template_id(TaskTemplate, pipeline_tree)
            except TaskTemplate.DoesNotExist:
                raise BadRequest(
                    "invalid subprocess, check subprocess node please")

        elif template_source == COMMON:
            try:
                template = CommonTemplate.objects.get(id=template_id,
                                                      is_deleted=False)
            except CommonTemplate.DoesNotExist:
                raise BadRequest("common template[id=%s] does not exist" %
                                 template_id)

            allow_or_raise_immediate_response(
                iam=iam,
                system=IAMMeta.SYSTEM_ID,
                subject=Subject("user", bundle.request.user.username),
                action=Action(IAMMeta.COMMON_FLOW_CREATE_PERIODIC_TASK_ACTION),
                resources=[
                    res_factory.resources_for_project_obj(project)[0],
                    res_factory.resources_for_common_flow_obj(template)[0],
                ],
            )

            try:
                replace_template_id(CommonTemplate, pipeline_tree)
            except TaskTemplate.DoesNotExist:
                raise BadRequest(
                    "invalid subprocess, check subprocess node please")

        else:
            raise BadRequest("invalid template_source[%s]" % template_source)

        # XSS handle
        name = standardize_name(name, PERIOD_TASK_NAME_MAX_LENGTH)
        creator = bundle.request.user.username

        # validate pipeline tree
        try:
            validate_web_pipeline_tree(pipeline_tree)
        except PipelineException as e:
            raise BadRequest(str(e))

        kwargs["template_id"] = template_id
        kwargs["template_source"] = template_source
        try:
            kwargs["task"] = PeriodicTask.objects.create_pipeline_task(
                project=project,
                template=template,
                name=name,
                cron=cron,
                pipeline_tree=pipeline_tree,
                creator=creator,
                template_source=template_source,
            )
        except Exception as e:
            logger.warning(traceback.format_exc())
            raise BadRequest(str(e))

        response = super(PeriodicTaskResource,
                         self).obj_create(bundle, **kwargs)
        response.obj.set_enabled(True)

        return response
Exemplo n.º 12
0
    def create_pipeline(
        self,
        name: str,
        creator: str,
        pipeline_tree: dict,
        description: str = "",
    ) -> dict:
        """
        创建 pipeline 层模板

        :param name: 模板名
        :type name: str
        :param creator: 创建者
        :type creator: str
        :param pipeline_tree: 模板数据
        :type pipeline_tree: dict
        :param description: 模板描述, defaults to ""
        :type description: str, optional
        :return: [description]
        :rtype: dict
        """
        name = standardize_name(name, TEMPLATE_NODE_NAME_MAX_LENGTH)
        standardize_pipeline_node_name(pipeline_tree)

        try:
            validate_web_pipeline_tree(pipeline_tree)
        except PipelineException as e:
            return {
                "result":
                False,
                "data":
                None,
                "message":
                "[TemplateManager]validate_web_pipeline_tree failed: {}".
                format(str(e)),
                "verbose_message":
                "[TemplateManager]validate_web_pipeline_tree failed: {}".
                format(traceback.format_exc()),
            }

        create_template_kwargs = {
            "name": name,
            "creator": creator,
            "pipeline_tree": pipeline_tree,
            "description": description,
        }
        try:
            pipeline_template = self.template_model_cls.objects.create_pipeline_template(
                **create_template_kwargs)
        except Exception as e:
            return {
                "result":
                False,
                "data":
                None,
                "message":
                "[TemplateManager]create_pipeline_template({kwargs}) failed: {e}"
                .format(kwargs=create_template_kwargs, e=str(e)),
                "verbose_message":
                "[TemplateManager]create_pipeline_template({kwargs}) failed: {trace}"
                .format(kwargs=create_template_kwargs,
                        trace=traceback.format_exc()),
            }

        return {
            "result": True,
            "data": pipeline_template,
            "message": "success",
            "verbose_message": "success"
        }
Exemplo n.º 13
0
    def update_pipeline(
        self,
        pipeline_template: PipelineTemplate,
        editor: str,
        name: str = "",
        pipeline_tree: str = None,
        description: str = "",
    ) -> dict:
        """
        更新 pipeline 层模板

        :param pipeline_template: pipeline 模板对象
        :type pipeline_template: PipelineTemplate
        :param editor: 编辑者
        :type editor: str
        :param name: 模板名, defaults to ""
        :type name: str, optional
        :param pipeline_tree: 模板结构, defaults to None
        :type pipeline_tree: str, optional
        :param description: 模板描述, defaults to ""
        :type description: str, optional
        :return: [description]
        :rtype: dict
        """
        update_kwargs = {"editor": editor}
        if name:
            update_kwargs["name"] = standardize_name(
                name, TEMPLATE_NODE_NAME_MAX_LENGTH)

        if description:
            update_kwargs["description"] = description

        if pipeline_tree:
            standardize_pipeline_node_name(pipeline_tree)
            try:
                validate_web_pipeline_tree(pipeline_tree)
            except PipelineException as e:
                return {
                    "result":
                    False,
                    "data":
                    None,
                    "message":
                    "[TemplateManager]validate_web_pipeline_tree failed: {}".
                    format(str(e)),
                    "verbose_message":
                    "[TemplateManager]validate_web_pipeline_tree failed: {}".
                    format(traceback.format_exc()),
                }

            replace_template_id(self.template_model_cls, pipeline_tree)

            pipeline_web_tree = PipelineWebTreeCleaner(pipeline_tree)
            pipeline_web_tree.clean()
            update_kwargs["structure_data"] = pipeline_tree

            try:
                pipeline_template.update_template(**update_kwargs)
            except Exception as e:
                return {
                    "result":
                    False,
                    "data":
                    None,
                    "message":
                    "[TemplateManager]update_template({update_kwargs}) failed: {e}"
                    .format(update_kwargs=update_kwargs, e=str(e)),
                    "verbose_message":
                    "[TemplateManager]update_template({update_kwargs}) failed: {trace}"
                    .format(update_kwargs=update_kwargs,
                            trace=traceback.format_exc()),
                }

            # create node in template
            NodeInTemplate.objects.update_nodes_in_template(
                pipeline_template, pipeline_web_tree.origin_data)
        else:
            for k, v in update_kwargs.items():
                setattr(pipeline_template, k, v)
            pipeline_template.save()

        return {
            "result": True,
            "data": pipeline_template,
            "message": "success",
            "verbose_message": "success"
        }