예제 #1
0
    def process(self, request, *args, **kwargs):
        if request.is_trust:
            return

        params = json.loads(request.body)
        template_source = params.get("template_source", PROJECT)
        template_id = kwargs["template_id"]
        subject = Subject("user", request.user.username)

        if template_source in NON_COMMON_TEMPLATE_TYPES:
            action = Action(IAMMeta.FLOW_CREATE_TASK_ACTION)
            resources = res_factory.resources_for_flow(template_id)
            allow_or_raise_auth_failed(iam,
                                       IAMMeta.SYSTEM_ID,
                                       subject,
                                       action,
                                       resources,
                                       cache=True)
        else:
            action = Action(IAMMeta.COMMON_FLOW_CREATE_TASK_ACTION)
            resources = [
                res_factory.resources_for_common_flow(template_id)[0],
                res_factory.resources_for_project_obj(request.project)[0],
            ]
            allow_or_raise_auth_failed(iam,
                                       IAMMeta.SYSTEM_ID,
                                       subject,
                                       action,
                                       resources,
                                       cache=True)
예제 #2
0
    def get_create_detail_resources(self, bundle):

        from gcloud.core.resources import ProjectResource

        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"))

        return res_factory.resources_for_project_obj(project)
예제 #3
0
    def process(self, request, *args, **kwargs):
        if request.is_trust:
            return

        project = request.project

        subject = Subject("user", request.user.username)
        action = Action(IAMMeta.PROJECT_VIEW_ACTION)
        resources = res_factory.resources_for_project_obj(project)
        allow_or_raise_auth_failed(iam,
                                   IAMMeta.SYSTEM_ID,
                                   subject,
                                   action,
                                   resources,
                                   cache=True)
예제 #4
0
    def process(self, request, *args, **kwargs):
        if request.is_trust:
            return

        project = request.project

        subject = Subject("user", request.user.username)
        action = Action(IAMMeta.PROJECT_FAST_CREATE_TASK_ACTION)
        resources = res_factory.resources_for_project_obj(project)
        allow_or_raise_auth_failed(iam,
                                   IAMMeta.SYSTEM_ID,
                                   subject,
                                   action,
                                   resources,
                                   cache=True)

        params = request.params_json
        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:
            action = Action(IAMMeta.FLOW_VIEW_ACTION)
            resources_list = res_factory.resources_list_for_flows(
                list(templates_in_task))
        else:
            action = Action(IAMMeta.COMMON_FLOW_VIEW_ACTION)
            resources_list = res_factory.resources_list_for_common_flows(
                list(templates_in_task))
        allow_or_raise_immediate_response_for_resources_list(
            iam=iam,
            system=IAMMeta.SYSTEM_ID,
            subject=subject,
            action=action,
            resources_list=resources_list,
        )
예제 #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
예제 #6
0
    def alter_list_data_to_serialize(self, request, data):
        data = super().alter_list_data_to_serialize(request, data)

        # 项目流程任务
        templates_id = {
            bundle.obj.template_id
            for bundle in data["objects"]
            if bundle.obj.template_id and bundle.obj.template_source == "project"
        }
        templates_allowed_actions = get_flow_allowed_actions_for_user(
            request.user.username, [IAMMeta.FLOW_VIEW_ACTION, IAMMeta.FLOW_CREATE_TASK_ACTION], templates_id
        )
        template_info = TaskTemplate.objects.filter(id__in=templates_id).values(
            "id", "pipeline_template__name", "is_deleted"
        )
        template_info_map = {
            str(t["id"]): {"name": t["pipeline_template__name"], "is_deleted": t["is_deleted"]} for t in template_info
        }

        # 公共流程任务
        common_templates_id = {
            bundle.obj.template_id
            for bundle in data["objects"]
            if bundle.obj.template_id and bundle.obj.template_source == "common"
        }
        common_templates_allowed_actions = get_common_flow_allowed_actions_for_user(
            request.user.username, [IAMMeta.COMMON_FLOW_VIEW_ACTION], common_templates_id,
        )
        common_template_info = CommonTemplate.objects.filter(id__in=common_templates_id).values(
            "id", "pipeline_template__name", "is_deleted"
        )
        common_template_info_map = {
            str(t["id"]): {"name": t["pipeline_template__name"], "is_deleted": t["is_deleted"]}
            for t in common_template_info
        }

        for bundle in data["objects"]:
            if bundle.obj.template_source == "project":
                bundle.data["template_name"] = template_info_map.get(bundle.obj.template_id, {}).get("name")
                bundle.data["template_deleted"] = template_info_map.get(bundle.obj.template_id, {}).get(
                    "is_deleted", True
                )
                for act, allowed in templates_allowed_actions.get(str(bundle.obj.template_id), {}).items():
                    if allowed:
                        bundle.data["auth_actions"].append(act)
            elif bundle.obj.template_source == "common":
                bundle.data["template_name"] = common_template_info_map.get(bundle.obj.template_id, {}).get("name")
                bundle.data["template_deleted"] = common_template_info_map.get(bundle.obj.template_id, {}).get(
                    "is_deleted", True
                )
                for act, allowed in common_templates_allowed_actions.get(str(bundle.obj.template_id), {}).items():
                    if allowed:
                        bundle.data["auth_actions"].append(act)
                action = IAMMeta.COMMON_FLOW_CREATE_TASK_ACTION
                action_request = Request(
                    system=IAMMeta.SYSTEM_ID,
                    subject=Subject("user", request.user.username),
                    action=Action(action),
                    resources=[
                        res_factory.resources_for_project_obj(bundle.obj.project)[0],
                        res_factory.resources_for_common_flow(bundle.obj.template_id)[0],
                    ],
                    environment=None,
                )
                allowed = iam.is_allowed(action_request)
                if allowed:
                    bundle.data["auth_actions"].append(action)

        return data
예제 #7
0
파일: project.py 프로젝트: Tencent/bk-sops
 def get_update_detail_resources(self, bundle):
     return res_factory.resources_for_project_obj(bundle.obj)
예제 #8
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