Пример #1
0
    def post(self, request, project_id, pk):
        self.request = request
        self.project_id = project_id
        self.pk = pk
        template = validate_template_id(project_id,
                                        pk,
                                        is_return_tempalte=True)

        # 验证用户是否有编辑权限
        perm = bcs_perm.Templates(request, project_id, pk, template.name)
        perm.can_edit(raise_exception=True)
        self.perm = perm

        # 检查模板集是否可操作(即未被加锁)
        check_tempalte_available(template, request.user.username)

        # 验证模板名是否已经存在
        new_template_name = request.data.get('name')
        is_exist = Template.default_objects.exclude(id=pk).filter(
            name=new_template_name, project_id=project_id).exists()
        if is_exist:
            detail = {'field': [_('模板集名称[{}]已经存在').format(new_template_name)]}
            raise ValidationError(detail=detail)

        self.slz = serializers_new.UpdateTemplateSLZ(data=request.data)
        self.slz.is_valid(raise_exception=True)
        return super(SingleTempalteView, self).update(self.slz)
Пример #2
0
    def get(self, request, project_id):
        serializer = SearchTemplateSLZ(data=request.query_params)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data

        templates = self.filter_queryset_with_params(project_id, data['search'])
        num_of_templates = templates.count()

        # 获取项目类型 backend.utils.permissions做了处理
        kind = request.project.kind
        # 添加分页信息
        limit, offset = data['limit'], data['offset']
        templates = templates[offset:limit + offset]

        serializer = ListTemplateSLZ(templates, many=True, context={'kind': kind})
        template_list = serializer.data

        # 初始化模板权限模板
        perm = bcs_perm.Templates(request, project_id, bcs_perm.NO_RES)
        # 过滤有使用权限的模板集
        template_list = perm.hook_perms(template_list, data['perm_can_use'])
        return Response({
            'code': 0,
            'message': 'OK',
            'data': {
                'count': num_of_templates,
                'has_previous': True if offset != 0 else False,
                'has_next': True if (offset + limit) < num_of_templates else False,
                'results': template_list
            },
            'permissions': {'create': perm.can_create(raise_exception=False)}
        })
Пример #3
0
    def put(self, request, project_id, pk):
        """复制模板
        """
        self.request = request
        # 验证用户是否使用权限
        template = validate_template_id(project_id, pk, is_return_tempalte=True)
        perm = bcs_perm.Templates(request, project_id, pk, template.name)
        perm.can_edit(raise_exception=True)

        self.project_id = project_id
        self.pk = pk
        data = request.data
        data['project_id'] = project_id
        self.slz = TemplateCreateSLZ(data=data)
        self.slz.is_valid(raise_exception=True)
        new_template_name = self.slz.data['name']
        # 验证模板名是否已经存在
        is_exist = Template.default_objects.filter(
            name=new_template_name, project_id=project_id).exists()
        if is_exist:
            detail = {
                'field': ['{prefix_msg}[{tmpl_name}]{suffix_msg}'.format(
                    prefix_msg=_("模板集名称"),
                    tmpl_name=new_template_name,
                    suffix_msg=_("已经存在")
                )]
            }
            raise ValidationError(detail=detail)
        # 验证 old模板集id 是否正确
        old_tems = self.get_queryset()
        if not old_tems.exists():
            detail = {
                'field': [_("要复制的模板集不存在")]
            }
            raise ValidationError(detail=detail)
        old_tem = old_tems.first()

        username = request.user.username
        template_id, version_id, show_version_id = old_tem.copy_tempalte(
            project_id, new_template_name, username)
        # 注册资源到权限中心
        perm.register(template_id, new_template_name)
        # 记录操作日志
        client.ContextActivityLogClient(
            project_id=project_id,
            user=request.user.username,
            resource_type="template",
            resource=new_template_name,
            resource_id=template_id,
            description=_("复制模板集")
        ).log_add()
        return Response({
            "code": 0,
            "message": "OK",
            "data": {
                "template_id": template_id,
                "version_id": version_id,
                "show_version_id": show_version_id,
            }
        })
Пример #4
0
 def can_edit_template(self, request, template):
     # 验证模板是否被其他用户加锁
     validate_template_locked(template, request.user.username)
     # 验证用户是否有编辑权限
     perm = bcs_perm.Templates(request, template.project_id, template.id,
                               template.name)
     perm.can_edit(raise_exception=True)
Пример #5
0
 def get_permissions(self, obj):
     request = self.context.get('request')
     perm = bcs_perm.Templates(request, obj.project_id, obj.id, obj.name)
     data = {'id': obj.id, 'name': obj.name}
     data_list = perm.hook_perms([data])
     permissions = data_list[0].get('permissions')
     return permissions
Пример #6
0
def update_template_with_perm_check(request, template, tpl_args):
    validate_template_locked(template, request.user.username)
    # 验证用户是否有编辑权限
    perm = bcs_perm.Templates(request, template.project_id, template.id, template.name)
    perm.can_edit(raise_exception=True)
    template = update_template(request.user.username, template, tpl_args)
    if template.name != tpl_args.get('name'):
        perm.update_name(template.name)
    return template
Пример #7
0
def create_template_with_perm_check(request, project_id, tpl_args):
    # 验证用户是否有创建的权限
    perm = bcs_perm.Templates(request, project_id, bcs_perm.NO_RES)
    # 如果没有权限,会抛出异常
    perm.can_create(raise_exception=True)
    template = create_template(request.user.username, project_id, tpl_args)
    # 注册资源到权限中心
    perm.register(template.id, tpl_args['name'])
    return template
Пример #8
0
    def get_quote_info(self, request, project_id, pk):
        qs = Variable.objects.filter(
            (Q(project_id=project_id) | Q(project_id=0)), id=pk)
        if not qs:
            raise ValidationError(u"not found")
        qs = qs.first()
        quote_list = []
        all_template_info = get_all_template_info_by_project(project_id)
        for tem in all_template_info:
            config = tem.get('config') or ''

            key_pattern = re.compile(r'"([^"]+)":\s*"([^"]*{{%s}}[^"]*)"' %
                                     qs.key)
            search_list = key_pattern.findall(config)

            for _q in search_list:
                quote_key = _q[0]
                context = _q[1]
                quote_list.append({
                    "context":
                    context,
                    "quote_location":
                    "%s/%s/%s/%s/%s" % (
                        tem['template_name'],
                        tem['show_version_name'],
                        tem['category_name'],
                        tem['resource_name'],
                        quote_key,
                    ),
                    "key":
                    qs.key,
                    'template_id':
                    tem['template_id'],
                    'template_name':
                    tem['template_name'],
                    'show_version_id':
                    tem['show_version_id'],
                    'category':
                    tem['category'],
                    'resource_id':
                    tem['resource_id'],
                })
        # 添加模板集的权限信息
        if quote_list:
            perm = bcs_perm.Templates(request, project_id, bcs_perm.NO_RES)
            quote_list = perm.hook_perms(quote_list, id_flag='template_id')
        return Response({
            "code": 0,
            "message": "OK",
            "data": {
                'quote_list': quote_list,
                'project_kind': request.project.kind,
                'project_id': request.project.project_id,
                'project_code': request.project.english_name,
            },
        })
Пример #9
0
    def preview_config(self, request, project_id):
        project_kind = request.project.kind
        serializer = PreviewInstanceSLZ(data=request.data, context={'project_kind': project_kind})
        serializer.is_valid(raise_exception=True)
        slz_data = serializer.data

        # 验证 version_id 是否属于该项目
        version_id = slz_data['version_id']
        show_version_id = slz_data['show_version_id']

        template, version_entity = validate_version_id(
            project_id, version_id, is_return_all=True, show_version_id=show_version_id
        )
        # 验证用户是否有使用权限
        perm = bcs_perm.Templates(request, project_id, template.id, template.name)
        perm.can_use(raise_exception=True)

        template_id = version_entity.template_id
        version = version_entity.version
        tem_instance_entity = version_entity.get_version_instance_resource_ids

        # 验证前端传过了的预览资源是否在该版本的资源
        req_instance_entity = slz_data.get('instance_entity') or {}
        instance_entity = validate_instance_entity(req_instance_entity, tem_instance_entity)

        access_token = self.request.user.token.access_token
        username = self.request.user.username

        namespace = slz_data['namespace']
        lb_info = slz_data.get('lb_info', {})
        # 验证关联lb情况下,lb 是否都已经选中
        service_id_list = instance_entity.get('service') or []
        v_res, err_list, err_msg = validate_lb_info_by_version_id(
            access_token, project_id, version_entity, [namespace], lb_info, service_id_list
        )
        if not v_res:
            return Response({"code": 400, "message": err_msg, "data": err_list})

        # 查询当前命名空间的变量信息
        variable_dict = slz_data.get('variable_info', {}).get(namespace) or {}
        params = {
            "instance_id": "instanceID",
            "version_id": version_id,
            "show_version_id": show_version_id,
            "template_id": template_id,
            "version": version,
            "project_id": project_id,
            "access_token": access_token,
            "username": username,
            "lb_info": lb_info,
            "variable_dict": variable_dict,
            "is_preview": True,
        }
        data = preview_config_json(namespace, instance_entity, **params)
        return Response({"code": 0, "message": "OK", "data": data})
Пример #10
0
    def bcs_perm_handler(
        self,
        request,
        project_id,
        data,
        filter_use=False,
        ns_id_flag="namespace_id",
        ns_name_flag='namespace',
        tmpl_view=True,
    ):  # noqa
        """列表权限处理"""
        ns_perm_client = bcs_perm.Namespace(request, project_id, bcs_perm.NO_RES)
        ns_ret_instance_list = ns_perm_client.hook_perms(
            data, ns_id_flag=ns_id_flag, filter_use=filter_use, ns_name_flag=ns_name_flag
        )
        ns_ret_data_map = {info["id"]: info["permissions"] for info in ns_ret_instance_list}
        if not tmpl_view:
            for info in data:
                if info['id'] in ns_ret_data_map:
                    info['permissions'] = info['permissions']
                else:
                    info["permissions"] = {
                        "create": False,
                        "delete": False,
                        "view": False,
                        "edit": False,
                        "use": False,
                    }  # noqa
            return data
        # ns_ret_data_map = {(info["namespace"], info["name"]): info["permissions"] for info in ns_ret_instance_list}
        tmpl_perm_client = bcs_perm.Templates(request, project_id, bcs_perm.NO_RES)
        tmpl_ret_instance_list = tmpl_perm_client.hook_perms(data, id_flag="muster_id", filter_use=filter_use)
        # map handle
        ret_data = []
        for info in tmpl_ret_instance_list:
            # item_key = (info["namespace"], info["name"])
            if info["id"] in ns_ret_data_map:
                curr_permissions = ns_ret_data_map[info["id"]]
                insert_set = set(curr_permissions.keys()) & set(info["permissions"].keys())
                diff_set = (set(info["permissions"].keys()) | set(curr_permissions.keys())) - insert_set
                for key in insert_set:
                    info["permissions"][key] = info["permissions"][key] and curr_permissions[key]
                for key in diff_set:
                    info["permissions"][key] = False
            else:
                info["permissions"] = {"create": False, "delete": False, "view": False, "edit": False, "use": False}
            if filter_use:
                if info["permissions"].get("use"):
                    ret_data.append(info)
                continue
            ret_data.append(info)

        return ret_data
Пример #11
0
 def bcs_single_app_perm_handler(self, request, project_id, muster_id, ns_id, source_type="模板集"):
     """针对具体资源的权限处理"""
     # 继承命名空间的权限
     ns_perm = bcs_perm.Namespace(request, project_id, ns_id)
     ns_perm.can_use(raise_exception=True)
     if source_type == "模板集":
         muster_info = Template.objects.filter(id=muster_id, is_deleted=False).first()
         if not muster_info:
             raise error_codes.CheckFailed(_("没有查询到模板集信息"))
         # 继承模板集的权限
         tmpl_perm = bcs_perm.Templates(request, project_id, muster_id, resource_name=muster_info.name)
         tmpl_perm.can_use(raise_exception=True)
Пример #12
0
def _delete_old_init_templates(template_qsets, project_id, project_code, access_token, username):
    request = RequestClass(username=username, access_token=access_token, project_code=project_code)
    for template in template_qsets:
        template_id = template.id
        perm = bcs_perm.Templates(request, project_id, template_id, template.name)
        perm.can_delete(raise_exception=True)
        perm.delete()

        VersionedEntity.objects.filter(template_id=template_id).delete()
        ShowVersion.objects.filter(template_id=template_id, name='init_version').delete()

        template.name = f'[deleted_{int(time.time())}]{template.name}'
        template.is_deleted = True
        template.deleted_time = timezone.now()
        template.save(update_fields=['name', 'is_deleted', 'deleted_time'])
Пример #13
0
    def put(self, request, project_id, pk):
        """复制模板"""
        self.request = request
        # 验证用户是否使用权限
        template = validate_template_id(project_id,
                                        pk,
                                        is_return_tempalte=True)
        perm = bcs_perm.Templates(request, project_id, pk, template.name)
        perm.can_edit(raise_exception=True)

        self.project_id = project_id
        self.pk = pk
        data = request.data
        data["project_id"] = project_id
        self.slz = TemplateCreateSLZ(data=data)
        self.slz.is_valid(raise_exception=True)
        new_template_name = self.slz.data["name"]
        # 验证模板名是否已经存在
        is_exist = Template.default_objects.filter(
            name=new_template_name, project_id=project_id).exists()
        if is_exist:
            detail = {"field": [_("模板集名称[{}]已经存在").format(new_template_name)]}
            raise ValidationError(detail=detail)
        # 验证 old模板集id 是否正确
        old_tems = self.get_queryset()
        if not old_tems.exists():
            detail = {"field": [_("要复制的模板集不存在")]}
            raise ValidationError(detail=detail)
        old_tem = old_tems.first()

        username = request.user.username
        template_id, version_id, show_version_id = old_tem.copy_tempalte(
            project_id, new_template_name, username)
        # 注册资源到权限中心
        perm.register(template_id, new_template_name)
        # 记录操作日志
        request.audit_ctx.update_fields(resource=new_template_name,
                                        resource_id=template_id,
                                        description=_("复制模板集"))
        return Response({
            "code": 0,
            "message": "OK",
            "data": {
                "template_id": template_id,
                "version_id": version_id,
                "show_version_id": show_version_id
            },
        })
Пример #14
0
    def delete(self, request, project_id, pk):
        self.request = request
        self.project_id = project_id
        self.pk = pk
        # 验证用户是否删除权限
        template = validate_template_id(project_id, pk, is_return_tempalte=True)
        perm = bcs_perm.Templates(request, project_id, pk, template.name)
        perm.can_delete(raise_exception=True)

        # 检查模板集是否可操作(即未被加锁)
        check_tempalte_available(template, request.user.username)

        # 已经实例化过的版本,不能被删除
        exist_version = is_tempalte_instance(pk)
        if exist_version:
            return Response({
                "code": 400,
                "message": "模板集已经被实例化过,不能被删除",
                "data": {}
            })
        instance = self.get_queryset().first()
        with client.ContextActivityLogClient(
                project_id=project_id,
                user=request.user.username,
                resource_type="template",
                resource=instance.name,
                resource_id=instance.id,
                description=u"删除模板集"
        ).log_delete():
            # 删除后名称添加 [deleted]前缀
            _del_prefix = '[deleted_%s]' % int(time.time())
            del_tem_name = "%s%s" % (_del_prefix, instance.name)
            self.get_queryset().update(name=del_tem_name, is_deleted=True,
                                       deleted_time=timezone.now())
            # 直接调用delete删除权限中心的资源
            perm.delete()

        return Response({
            "code": 0,
            "message": "OK",
            "data": {
                "id": pk
            }
        })
Пример #15
0
    def get(self, request, project_id, pk):
        self.request = request
        self.project_id = project_id
        self.pk = pk
        template = validate_template_id(project_id,
                                        pk,
                                        is_return_tempalte=True)

        # 获取项目类型
        kind = request.project.kind

        tems = self.get_queryset()
        if tems:
            tem = tems.first()
            data = get_tempate_info(tem, kind)
        else:
            data = {}
        perm = bcs_perm.Templates(request, project_id, pk, template.name)
        data_list = perm.hook_perms([data])
        return Response({"code": 0, "message": "OK", "data": data_list[0]})
Пример #16
0
 def can_use_instance(cls,
                      request,
                      project_id,
                      ns_id,
                      tmpl_set_id=None,
                      source_type=SourceType.TEMPLATE):
     # 继承命名空间的权限
     ns_perm = bcs_perm.Namespace(request, project_id, ns_id)
     ns_perm.can_use(raise_exception=True)
     if source_type == SourceType.TEMPLATE:
         tmpl_set_info = Template.objects.filter(id=tmpl_set_id).first()
         if not tmpl_set_info:
             raise error_codes.CheckFailed(
                 f"template:{tmpl_set_id} not found")
         # 继承模板集的权限
         tmpl_perm = bcs_perm.Templates(request,
                                        project_id,
                                        tmpl_set_id,
                                        resource_name=tmpl_set_info.name)
         tmpl_perm.can_use(raise_exception=True)
Пример #17
0
    def get(self, request, project_id):
        serializer = serializers_new.SearchTemplateSLZ(
            data=request.query_params)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data

        templates = self.filter_queryset_with_params(project_id,
                                                     data["search"])
        num_of_templates = templates.count()

        # 获取项目类型 backend.utils.permissions做了处理
        kind = request.project.kind
        # 添加分页信息
        limit, offset = data["limit"], data["offset"]
        templates = templates[offset:limit + offset]

        serializer = serializers_new.ListTemplateSLZ(templates,
                                                     many=True,
                                                     context={"kind": kind})
        template_list = serializer.data

        # 初始化模板权限模板
        perm = bcs_perm.Templates(request, project_id, bcs_perm.NO_RES)
        # 过滤有使用权限的模板集
        template_list = perm.hook_perms(template_list, data["perm_can_use"])
        return Response({
            "code": 0,
            "message": "OK",
            "data": {
                "count": num_of_templates,
                "has_previous": True if offset != 0 else False,
                "has_next": True if
                (offset + limit) < num_of_templates else False,
                "results": template_list,
            },
            "permissions": {
                "create": perm.can_create(raise_exception=False)
            },
        })
Пример #18
0
    def delete(self, request, project_id, pk):
        self.request = request
        self.project_id = project_id
        self.pk = pk
        # 验证用户是否删除权限
        template = validate_template_id(project_id,
                                        pk,
                                        is_return_tempalte=True)
        perm = bcs_perm.Templates(request, project_id, pk, template.name)
        perm.can_delete(raise_exception=True)

        # 检查模板集是否可操作(即未被加锁)
        check_tempalte_available(template, request.user.username)

        # 已经实例化过的版本,不能被删除
        exist_version = is_tempalte_instance(pk)
        if exist_version:
            return Response({
                "code": 400,
                "message": _("模板集已经被实例化过,不能被删除"),
                "data": {}
            })
        instance = self.get_queryset().first()

        request.audit_ctx.update_fields(resource=instance.name,
                                        resource_id=instance.id,
                                        description=_("删除模板集"))

        # 删除后名称添加 [deleted]前缀
        _del_prefix = f"[deleted_{int(time.time())}]"
        del_tem_name = f"{_del_prefix}{instance.name}"
        self.get_queryset().update(name=del_tem_name,
                                   is_deleted=True,
                                   deleted_time=timezone.now())
        # 直接调用delete删除权限中心的资源
        perm.delete()

        return Response({"code": 0, "message": "OK", "data": {"id": pk}})
Пример #19
0
    def post(self, request, project_id):
        """实例化模板
        """
        # 参数验证
        self.project_id = project_id
        version_id = request.data.get('version_id')
        show_version_id = request.data.get('show_version_id')

        template, version_entity = validate_version_id(
            project_id,
            version_id,
            is_return_all=True,
            show_version_id=show_version_id)
        # 验证用户是否有使用权限
        perm = bcs_perm.Templates(request, project_id, template.id,
                                  template.name)
        perm.can_use(raise_exception=True)

        self.template_id = version_entity.template_id
        tem_instance_entity = version_entity.get_version_instance_resource_ids

        project_kind = request.project.kind
        self.slz = VersionInstanceCreateOrUpdateSLZ(
            data=request.data, context={'project_kind': project_kind})
        self.slz.is_valid(raise_exception=True)
        slz_data = self.slz.data

        # 验证前端传过了的预览资源是否在该版本的资源
        req_instance_entity = slz_data.get('instance_entity') or {}
        self.instance_entity = validate_instance_entity(
            req_instance_entity, tem_instance_entity)

        namespaces = slz_data['namespaces']
        ns_list = namespaces.split(',') if namespaces else []

        access_token = self.request.user.token.access_token
        username = self.request.user.username

        # 验证关联lb情况下,lb 是否都已经选中
        service_id_list = self.instance_entity.get('service') or []
        v_res, err_list, err_msg = validate_lb_info_by_version_id(
            access_token, project_id, version_entity, ns_list,
            slz_data.get('lb_info', {}), service_id_list)
        if not v_res:
            return Response({
                "code": 400,
                "message": err_msg,
                "data": err_list
            })

        # 判断 template 下 前台传过来的 namespace 是否已经实例化过
        res, ns_name_list, namespace_dict = validate_ns_by_tempalte_id(
            self.template_id, ns_list, access_token, project_id,
            req_instance_entity)
        if not res:
            return Response({
                "code":
                400,
                "message":
                "以下命名空间已经实例化过,不能再实例化\n%s" % "\n".join(ns_name_list),
                "data":
                ns_name_list
            })

        # 在数据平台创建项目信息
        cc_app_id = request.project.cc_app_id
        english_name = request.project.english_name
        create_data_project(request.user.username, project_id, cc_app_id,
                            english_name)
        # 创建/启动标准日志采集任务
        create_and_start_standard_data_flow(username, project_id, cc_app_id)

        slz_data['ns_list'] = ns_list
        slz_data['instance_entity'] = self.instance_entity
        slz_data['template_id'] = self.template_id
        slz_data['project_id'] = project_id
        slz_data['version_id'] = version_id
        slz_data['show_version_id'] = show_version_id

        result = handle_all_config(slz_data, access_token, username)
        instance_entity = slz_data.get("instance_entity")
        all_tmpl_name_dict = self.get_tmpl_name(instance_entity)

        # 添加操作记录
        temp_name = version_entity.get_template_name()
        for i in result['success']:
            client.ContextActivityLogClient(
                project_id=project_id,
                user=username,
                resource_type="template",
                resource=temp_name,
                resource_id=self.template_id,
                extra=json.dumps(self.instance_entity),
                description=u"实例化模板集[%s]命名空间[%s]" %
                (temp_name, i['ns_name'])).log_add(activity_status="succeed")

        failed_ns_name_list = []
        failed_msg = []
        is_show_failed_msg = False
        # 针对createError的触发后台任务轮训
        if result.get('failed'):
            check_instance_status.delay(request.user.token.access_token,
                                        project_id,
                                        request.project.get("kind"),
                                        all_tmpl_name_dict, result['failed'])
        for i in result['failed']:
            if i['res_type']:
                description = "实例化模板集[%s]命名空间[%s],在实例化%s时失败,错误消息:%s" % (
                    temp_name, i['ns_name'], i['res_type'], i['err_msg'])
                failed_ns_name_list.append("%s(实例化%s时)" %
                                           (i['ns_name'], i['res_type']))
            else:
                description = "实例化模板集[%s]命名空间[%s]失败,错误消息:%s" % (
                    temp_name, i['ns_name'], i['err_msg'])
                failed_ns_name_list.append(i['ns_name'])
                if i.get('show_err_msg'):
                    failed_msg.append(i['err_msg'])
                    is_show_failed_msg = True

            client.ContextActivityLogClient(
                project_id=project_id,
                user=username,
                resource_type="template",
                resource=temp_name,
                resource_id=self.template_id,
                extra=json.dumps(self.instance_entity),
                description=description).log_add(activity_status="failed")

            if is_show_failed_msg:
                msg = '\n'.join(failed_msg)
            else:
                msg = "以下命名空间实例化失败,\n%s,请联系集群管理员解决" % "\n".join(
                    failed_ns_name_list)
            if failed_ns_name_list:
                return Response({
                    "code": 400,
                    "message": msg,
                    "data": failed_ns_name_list
                })

        return Response({
            "code": 0,
            "message": "OK",
            "data": {
                "version_id": version_id,
                "template_id": self.template_id,
            }
        })
Пример #20
0
    def post(self, request, project_id):
        """实例化模板"""
        # 参数验证
        self.project_id = project_id
        version_id = request.data.get('version_id')
        show_version_id = request.data.get('show_version_id')

        template, version_entity = validate_version_id(
            project_id, version_id, is_return_all=True, show_version_id=show_version_id
        )
        # 验证用户是否有使用权限
        perm = bcs_perm.Templates(request, project_id, template.id, template.name)
        perm.can_use(raise_exception=True)

        self.template_id = version_entity.template_id
        tem_instance_entity = version_entity.get_version_instance_resource_ids

        project_kind = request.project.kind
        self.slz = VersionInstanceCreateOrUpdateSLZ(data=request.data, context={'project_kind': project_kind})
        self.slz.is_valid(raise_exception=True)
        slz_data = self.slz.data

        # 验证前端传过了的预览资源是否在该版本的资源
        req_instance_entity = slz_data.get('instance_entity') or {}
        self.instance_entity = validate_instance_entity(req_instance_entity, tem_instance_entity)

        namespaces = slz_data['namespaces']
        ns_list = namespaces.split(',') if namespaces else []

        access_token = self.request.user.token.access_token
        username = self.request.user.username

        # 验证关联lb情况下,lb 是否都已经选中
        service_id_list = self.instance_entity.get('service') or []

        # 判断 template 下 前台传过来的 namespace 是否已经实例化过
        res, ns_name_list, namespace_dict = validate_ns_by_tempalte_id(
            self.template_id, ns_list, access_token, project_id, req_instance_entity
        )
        if not res:
            return Response(
                {
                    "code": 400,
                    "message": _("以下命名空间已经实例化过,不能再实例化\n{}").format("\n".join(ns_name_list)),
                    "data": ns_name_list,
                }
            )

        slz_data['ns_list'] = ns_list
        slz_data['instance_entity'] = self.instance_entity
        slz_data['template_id'] = self.template_id
        slz_data['project_id'] = project_id
        slz_data['version_id'] = version_id
        slz_data['show_version_id'] = show_version_id

        result = handle_all_config(slz_data, access_token, username, project_kind=request.project.kind)
        instance_entity = slz_data.get("instance_entity")
        all_tmpl_name_dict = self.get_tmpl_name(instance_entity)

        # 添加操作记录
        temp_name = version_entity.get_template_name()
        for i in result['success']:
            TemplatesetAuditor(
                audit_ctx=AuditContext(
                    project_id=project_id,
                    user=username,
                    resource=temp_name,
                    resource_id=self.template_id,
                    extra=self.instance_entity,
                    description=_("实例化模板集[{}]命名空间[{}]").format(temp_name, i['ns_name']),
                    activity_type=ActivityType.Add,
                    activity_status=ActivityStatus.Succeed,
                )
            ).log_raw()

        failed_ns_name_list = []
        failed_msg = []
        is_show_failed_msg = False
        # 针对createError的触发后台任务轮训
        if result.get('failed'):
            check_instance_status.delay(
                request.user.token.access_token,
                project_id,
                request.project.get("kind"),
                all_tmpl_name_dict,
                result['failed'],
            )
        for i in result['failed']:
            if i['res_type']:
                description = _("实例化模板集[{}]命名空间[{}],在实例化{}时失败,错误消息:{}").format(
                    temp_name, i['ns_name'], i['res_type'], i['err_msg']
                )
                failed_ns_name_list.append(_("{}(实例化{}时)").format(i['ns_name'], i['res_type']))
            else:
                description = _("实例化模板集[{}]命名空间[{}]失败,错误消息:{}").format(temp_name, i['ns_name'], i['err_msg'])
                failed_ns_name_list.append(i['ns_name'])
                if i.get('show_err_msg'):
                    failed_msg.append(i['err_msg'])
                    is_show_failed_msg = True

            TemplatesetAuditor(
                audit_ctx=AuditContext(
                    project_id=project_id,
                    user=username,
                    resource=temp_name,
                    resource_id=self.template_id,
                    extra=self.instance_entity,
                    description=description,
                    activity_type=ActivityType.Add,
                    activity_status=ActivityStatus.Failed,
                )
            ).log_raw()

            if is_show_failed_msg:
                msg = '\n'.join(failed_msg)
            else:
                msg = _("以下命名空间实例化失败,\n{},请联系集群管理员解决").format("\n".join(failed_ns_name_list))
            if failed_ns_name_list:
                return Response({"code": 400, "message": msg, "data": failed_ns_name_list})

        return Response(
            {
                "code": 0,
                "message": "OK",
                "data": {
                    "version_id": version_id,
                    "template_id": self.template_id,
                },
            }
        )
Пример #21
0
def init_template(project_id, project_code, project_kind, access_token, username):
    """创建项目时,初始化示例模板集
    request.project.english_name
    """
    # 判断模板集是否已经创建, 如果已经创建, 删除旧模板
    exit_templates = Template.objects.filter(project_id=project_id, name=TEMPLATE_NAME)
    if exit_templates.exists():
        _delete_old_init_templates(exit_templates, project_id, project_code, access_token, username)

    template_data = {}
    if project_kind == K8S_KIND:
        template_data = K8S_TEMPLATE.get('data', {})
    elif project_kind == MESOS_KIND:
        template_data = MESOS_TEMPLATE.get('data', {})

    logger.info(f'init_template [begin] project_id: {project_id}, project_kind: {ClusterType.get(project_kind)}')
    # 新建模板集
    init_template = Template.objects.create(
        project_id=project_id,
        name=TEMPLATE_NAME,
        desc=TEMPLATE_DESC,
        creator=username,
        updator=username,
    )

    new_entity = {}
    for cate in template_data:
        new_item_id_list = []
        data_list = template_data[cate]
        for _data in data_list:
            _save_data = {}
            for _d_key in _data:
                # 新建,忽略 id 字段
                if _d_key == 'id':
                    continue
                # 目前只有 dict、list这两类非字符格式
                _d_value = _data[_d_key]
                if isinstance(_d_value, list) or isinstance(_d_value, dict):
                    _save_data[_d_key] = json.dumps(_d_value)
                else:
                    _save_data[_d_key] = _d_value
            _ins = MODULE_DICT.get(cate).objects.create(**_save_data)
            new_item_id_list.append(str(_ins.id))
        new_entity[cate] = ','.join(new_item_id_list)

    # 新建version
    new_ver = VersionedEntity.objects.create(
        template_id=init_template.id,
        entity=json.dumps(new_entity),
        version=get_default_version(),
        creator=username,
        updator=username,
    )
    # 新建可见版本
    ShowVersion.objects.create(
        template_id=init_template.id,
        real_version_id=new_ver.id,
        name='init_version',
    )

    # 将模板集注册到权限中心
    request = RequestClass(username=username, access_token=access_token, project_code=project_code)
    perm = bcs_perm.Templates(request, project_id, bcs_perm.NO_RES)
    perm.register(str(init_template.id), str(init_template.name))

    logger.info(f'init_template [end] project_id: {project_id}, project_kind: {ClusterType.get(project_kind)}')
    return
Пример #22
0
 def can_use_template(self, request, template):
     # 验证用户是否有使用权限
     perm = bcs_perm.Templates(request, template.project_id, template.id,
                               template.name)
     perm.can_use(raise_exception=True)