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)
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
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
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, ""
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
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
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)
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 }})
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, }
def test_valid_pipeline_tree(self): validator.validate_web_pipeline_tree(self.valid_tree)
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
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" }
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" }