Пример #1
0
    def get(self, request, project_id):
        """获取项目下所有的secrets"""
        params = dict(request.GET.items())
        is_decode = str2bool(request.GET.get('decode'))

        cluster_id = params['cluster_id']

        code, cluster_secrets = self.get_secrets_by_cluster_id(request, params, project_id, cluster_id)
        if code != ErrorCode.NoError:
            return Response({'code': code, 'message': cluster_secrets})

        self.handle_data(
            cluster_secrets,
            self.cate,
            cluster_id,
            is_decode,
            namespace_dict=app_utils.get_ns_id_map(request.user.token.access_token, project_id),
        )

        # 按时间倒序排列
        cluster_secrets.sort(key=lambda x: x.get('createTime', ''), reverse=True)

        return PermsResponse(
            cluster_secrets,
            NamespaceRequest(project_id=project_id, cluster_id=cluster_id),
        )
Пример #2
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

        return PermsResponse(
            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,
            },
            resource_data=template_list,
            resource_request=TemplatesetRequest(project_id=project_id),
        )
Пример #3
0
    def list(self, request, project_id, cluster_id):
        """获取 ServiceMonitor 列表"""
        cluster_map = self._get_cluster_map(project_id)
        namespace_map = self._get_namespace_map(project_id)

        if cluster_id not in cluster_map:
            raise error_codes.APIError(_('集群 ID {} 不合法').format(cluster_id))

        client = K8SClient(request.user.token.access_token,
                           project_id,
                           cluster_id,
                           env=None)
        manifest = client.list_service_monitor()
        service_monitors = self._handle_items(cluster_id, cluster_map,
                                              namespace_map, manifest)

        # 共享集群需要再过滤下属于当前项目的命名空间
        if get_cluster_type(cluster_id) == ClusterType.SHARED:
            project_namespaces = get_shared_cluster_proj_namespaces(
                request.ctx_cluster, request.project.english_name)
            service_monitors = [
                sm for sm in service_monitors
                if sm['namespace'] in project_namespaces
            ]

        for m in service_monitors:
            m['is_system'] = m['namespace'] in constants.SM_NO_PERM_NAMESPACE
            m['iam_ns_id'] = calc_iam_ns_id(m['cluster_id'], m['namespace'])

        return PermsResponse(
            service_monitors,
            resource_request=NamespaceRequest(project_id=project_id,
                                              cluster_id=cluster_id),
        )
Пример #4
0
    def list(self, request, project_id):
        slz = FilterNamespacesSLZ(data=request.query_params)
        slz.is_valid(raise_exception=True)
        params = slz.validated_data

        cluster_id = params["cluster_id"]
        ns_list = self.filter_namespaces(cluster_id)

        if not ns_list:
            return Response([])

        # check which namespace has the chart_id initialized
        namespace_ids = []
        chart_id = params.get("chart_id")
        if chart_id:
            namespace_ids = set(
                App.objects.filter(project_id=self.project_id,
                                   chart__id=chart_id).values_list(
                                       "namespace_id", flat=True))

        serializer = self.serializer_class(ns_list, many=True)
        data = serializer.data

        for item in data:
            item["has_initialized"] = item["id"] in namespace_ids
            item['iam_ns_id'] = calc_iam_ns_id(cluster_id, item['name'])

        return PermsResponse(
            data, NamespaceRequest(project_id=project_id,
                                   cluster_id=cluster_id))
Пример #5
0
    def get(self, request, project_id):
        """获取项目下的所有Ingress"""
        cluster_id = request.query_params.get("cluster_id")

        code, cluster_ingress = self.get_ingress_by_cluser_id(
            request, {}, project_id, cluster_id)
        # 单个集群错误时,不抛出异常信息
        if code != ErrorCode.NoError:
            return Response({'code': code, 'message': cluster_ingress})

        self.handle_data(
            cluster_ingress,
            self.cate,
            cluster_id,
            False,
            namespace_dict=app_utils.get_ns_id_map(
                request.user.token.access_token, project_id),
        )

        # 按时间倒序排列
        cluster_ingress.sort(key=lambda x: x.get('createTime', ''),
                             reverse=True)

        return PermsResponse(
            cluster_ingress,
            NamespaceRequest(project_id=project_id, cluster_id=cluster_id))
Пример #6
0
    def list(self, request, project_id):
        """获取所有HPA数据"""
        cluster_id = request.query_params.get("cluster_id")
        hpa_list = utils.get_cluster_hpa_list(request, project_id, cluster_id)

        for h in hpa_list:
            h['iam_ns_id'] = calc_iam_ns_id(cluster_id, h['namespace'])

        return PermsResponse(
            hpa_list,
            NamespaceRequest(project_id=project_id, cluster_id=cluster_id))
Пример #7
0
    def get_template(self, request, project_id, template_id):
        serializer = GetLatestShowVersionSLZ(data=self.kwargs)
        serializer.is_valid(raise_exception=True)
        validated_data = serializer.validated_data

        template = validated_data["template"]
        self.can_view_template(request, template)

        serializer = serializers.GetTemplateFilesSLZ(
            validated_data, context={"with_file_content": True})
        return PermsResponse(serializer.data,
                             TemplatesetRequest(project_id=project_id))
Пример #8
0
    def get(self, request, project_id, ns_id):
        cluster_type, app_status, app_id, filter_ns_id, request_cluster_id = self.get_filter_params(
            request, project_id)
        if filter_ns_id and str(ns_id) != str(filter_ns_id):
            return APIResponse({"data": {}})
        # 获取项目下集群类型
        cluster_env_map = self.get_cluster_id_env(request, project_id)
        # 检查命名空间属于项目
        cluster_id, ns_name = self.check_ns_with_project(
            request, project_id, ns_id, cluster_type, cluster_env_map)
        # 共享集群不允许通过该接口查询应用
        if get_cluster_type(cluster_id) == ClusterType.SHARED:
            return APIResponse({"data": {}})

        inst_name = None
        if app_id:
            inst_name = self.get_inst_name(app_id)
        ns_name_id = self.get_namespace_name_id(request, project_id)
        # 根据类型进行过滤数据
        category = request.GET.get("category")
        if not category or category not in CATEGORY_MAP.keys():
            raise error_codes.CheckFailed(_("类型不正确"))
        client = k8s_views.GetInstances()
        ret_data = client.get(
            request,
            project_id,
            ns_id,
            category,
            inst_name,
            app_status,
            cluster_env_map,
            cluster_id,
            ns_name,
            ns_name_id,
        )

        iam_ns_id = calc_iam_ns_id(cluster_id, ns_name)
        for inst in ret_data["instance_list"]:
            inst['iam_ns_id'] = iam_ns_id

        return PermsResponse(
            ret_data,
            NamespaceRequest(project_id=project_id, cluster_id=cluster_id),
            resource_data={'iam_ns_id': iam_ns_id},
        )
Пример #9
0
    def list_projects(self, request):
        """
        提供查询项目列表的功能, 同时能够根据 project_code 或 project_name 过滤项目
        """
        project_code = request.query_params.get("project_code")
        project_name = request.query_params.get("project_name")
        access_token = request.user.token.access_token

        if project_code:
            projects = Project.list_projects(access_token, {"english_names": project_code})
        elif project_name:
            projects = Project.list_projects(access_token, {"project_names": project_name})
        else:
            projects = Project.list_projects(access_token)

        if not projects:
            return Response(projects)

        projects.sort(key=operator.itemgetter('created_at'), reverse=True)
        return PermsResponse(projects, ProjectRequest())
Пример #10
0
    def get(self, request, project_id, pk):
        self.request = request
        self.project_id = project_id
        self.pk = pk

        validate_template_id(project_id, pk, is_return_tempalte=True)

        perm_ctx = TemplatesetPermCtx(username=request.user.username,
                                      project_id=project_id,
                                      template_id=pk)
        self.iam_perm.can_view(perm_ctx)

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

        tems = self.get_queryset()
        if tems:
            tem = tems.first()
            data = get_template_info(tem, kind)
        else:
            data = {}

        return PermsResponse(data, TemplatesetRequest(project_id=project_id))
Пример #11
0
    def get(self, request, project_id):
        """获取项目下的所有命名空间"""
        # 获取过滤参数
        cluster_type, app_status, app_id, ns_id, request_cluster_id = self.get_filter_params(
            request, project_id)
        exist_app = request.GET.get("exist_app")
        # 获取项目类型
        project_kind = self.project_kind(request)
        # 获取项目下集群类型
        cluster_list, cluster_env_map = self.get_cluster_id_env(
            request, project_id)
        if not cluster_list:
            return APIResponse({"data": []})
        # 获取项目下面的namespace
        ns_list = self.get_namespace(request, project_id)
        if not ns_list:
            return APIResponse({"data": []})
        # 组装命名空间数据、命名空间ID、项目下集群信息
        ns_map, ns_id_list, cluster_id_list, ns_name_list = self.get_cluster_ns(
            ns_list, cluster_type, ns_id, cluster_env_map, request_cluster_id)
        # 匹配集群的环境
        cluster_env = {
            info["cluster_id"]: {
                'env_type': CLUSTER_ENV_MAP.get(info["environment"], "stag"),
                'name': info['name']
            }
            for info in cluster_list
        }
        inst_name = None
        if app_id:
            inst_name = self.get_inst_name(app_id)
        category = request.GET.get("category")
        if not category or category not in CATEGORY_MAP.keys():
            raise error_codes.CheckFailed(_("类型不正确"))
        client = k8s_views.GetNamespace()
        ns_app, ns_inst_error_count, create_error, all_ns_inst_count = client.get(
            request,
            ns_id_list,
            category,
            ns_map,
            project_id,
            project_kind,
            self.get_app_deploy_with_post,
            inst_name,
            ns_name_list,
            cluster_id_list,
        )
        # 匹配数据
        self.compose_data(ns_map, cluster_env, ns_app, exist_app,
                          ns_inst_error_count, create_error, app_status,
                          all_ns_inst_count)
        ret_data = list(ns_map.values())

        iam_ns_ids = set()
        for ns in ret_data:
            iam_ns_id = calc_iam_ns_id(ns['cluster_id'], ns['name'])
            ns['iam_ns_id'] = iam_ns_id
            iam_ns_ids.add(iam_ns_id)

        return PermsResponse(
            ret_data,
            NamespaceRequest(project_id=project_id,
                             cluster_id=request_cluster_id))
Пример #12
0
    def list(self, request, project_id):
        """命名空间列表
        权限控制: 必须有对应集群的使用权限
        """
        access_token = request.user.token.access_token
        valid_group_by = ['env_type', 'cluster_id', 'cluster_name']

        group_by = request.GET.get('group_by')
        cluster_id = request.GET.get('cluster_id')

        # 获取全部namespace,前台分页
        result = paas_cc.get_namespace_list(access_token,
                                            project_id,
                                            limit=LIMIT_FOR_ALL_DATA)
        if result.get('code') != 0:
            raise error_codes.APIError.f(result.get('message', ''))

        results = result["data"]["results"] or []
        # 针对k8s集群过滤掉平台命名空间
        results = self._ignore_ns_for_k8s(results)

        # 补充cluster_name字段
        cluster_list = get_clusters(access_token, project_id)
        # 添加共享集群
        cluster_list = append_shared_clusters(cluster_list)
        # TODO: 后续发现cluster_id不存在时,再处理
        cluster_dict = {i["cluster_id"]: i for i in (cluster_list or [])}

        # no_vars=1 不显示变量
        no_vars = request.GET.get('no_vars')
        if no_vars == '1':
            project_var = []
        else:
            project_var = NameSpaceVariable.get_project_ns_vars(project_id)

        for i in results:
            # ns_vars = NameSpaceVariable.get_ns_vars(i['id'], project_id)
            ns_id = i['id']
            ns_vars = []
            for _var in project_var:
                _ns_values = _var['ns_values']
                _ns_value_ids = _ns_values.keys()
                ns_vars.append({
                    'id':
                    _var['id'],
                    'key':
                    _var['key'],
                    'name':
                    _var['name'],
                    'value':
                    _ns_values.get(ns_id)
                    if ns_id in _ns_value_ids else _var['default_value'],
                })
            i['ns_vars'] = ns_vars

            if i['cluster_id'] in cluster_dict:
                i['cluster_name'] = cluster_dict[i['cluster_id']]['name']
                i['environment'] = cluster_dict[i['cluster_id']]['environment']
            else:
                i['cluster_name'] = i['cluster_id']
                i['environment'] = None

        if cluster_id:
            results = filter(lambda x: x['cluster_id'] == cluster_id, results)

        if group_by and group_by in valid_group_by:
            # 分组, 排序
            results = [{
                'name':
                k,
                'results':
                sorted(list(v), key=lambda x: x['id'], reverse=True)
            } for k, v in groupby(sorted(results, key=lambda x: x[group_by]),
                                  key=lambda x: x[group_by])]
            if group_by == 'env_type':
                ordering = [i.value for i in EnvType]
                results = sorted(results,
                                 key=lambda x: ordering.index(x['name']))
            else:
                results = sorted(results,
                                 key=lambda x: x['name'],
                                 reverse=True)
                # 过滤带有ns的集群id
                cluster_ids_with_ns = []
                # 按集群分组时,添加集群环境信息
                for r in results:
                    r_ns_list = r.get('results') or []
                    r_ns = r_ns_list[0] if r_ns_list else {}
                    r['environment'] = r_ns.get('environment', '')
                    r['environment_name'] = get_cluster_env_name(
                        r['environment'])
                    r["cluster_id"] = r_ns.get("cluster_id")
                    if get_cluster_type(r["cluster_id"]) == ClusterType.SHARED:
                        r["is_shared"] = True
                    cluster_ids_with_ns.append(r_ns.get("cluster_id"))

                # 添加无命名空间集群ID
                results.extend(
                    self.get_clusters_without_ns(cluster_dict,
                                                 cluster_ids_with_ns))
        else:
            results = sorted(results, key=lambda x: x['id'], reverse=True)

        with_perms = str2bool(request.query_params.get('with_perms', True))
        if not with_perms:
            return response.Response(results)

        namespace_list = []
        for namespace in results:
            namespace['iam_ns_id'] = calc_iam_ns_id(namespace['cluster_id'],
                                                    namespace['name'])
            namespace_list.append(namespace)

        return PermsResponse(
            namespace_list,
            NamespaceRequest(project_id=project_id, cluster_id=cluster_id))
Пример #13
0
 def get_clusters(self, request):
     return PermsResponse(
         cluster_data,
         ClusterRequest(project_id=generate_random_string(32)))
Пример #14
0
 def get_project(self, request, project_id):
     project = Project.get_project(request.user.token.access_token, project_id)
     return PermsResponse(project, ProjectRequest())
Пример #15
0
    def list(self, request, project_id, *args, **kwargs):
        """"""
        project_cluster = self.get_project_cluster(request, project_id)
        qs = self.get_queryset()
        # 获取过滤参数
        params = request.query_params
        # 集群和命名空间必须传递
        cluster_id = params.get('cluster_id')
        namespace = params.get("namespace")
        # TODO: 先写入db中,防止前端通过ID,获取数据失败;后续通过helm服务提供API
        if cluster_id:
            try:
                ctx_cluster = CtxCluster.create(
                    id=cluster_id,
                    token=request.user.token.access_token,
                    project_id=project_id)
                RecordReleases(ctx_cluster, namespace).record()
            except Exception as e:
                logger.error("获取集群内release数据失败,%s", e)

        if cluster_id:
            qs = qs.filter(cluster_id=cluster_id)
        if namespace:
            if not cluster_id:
                raise ValidationError(_("命名空间作为过滤参数时,需要提供集群ID"))
            qs = qs.filter(namespace=namespace)
        # 获取返回的数据
        slz = ReleaseListSLZ(qs, many=True)
        data = slz.data

        # do fix on the data which version is emtpy
        iam_ns_ids = []
        app_list = []
        for item in data:
            # 过滤掉k8s系统和bcs平台命名空间下的release
            if item["namespace"] in K8S_PLAT_NAMESPACE:
                continue
            cluster_info = project_cluster.get(item['cluster_id']) or {
                'name': item['cluster_id']
            }
            item['cluster_name'] = cluster_info['name']

            item['iam_ns_id'] = calc_iam_ns_id(item['cluster_id'],
                                               item['namespace'])
            iam_ns_ids.append({'iam_ns_id': item['iam_ns_id']})

            item['cluster_env'] = settings.CLUSTER_ENV_FOR_FRONT.get(
                cluster_info.get('environment'))
            item["current_version"] = item.pop("version")
            if not item["current_version"]:
                version = App.objects.filter(id=item["id"]).values_list(
                    "release__chartVersionSnapshot__version", flat=True)[0]
                App.objects.filter(id=item["id"]).update(version=version)
                item["current_version"] = version

            # 判断任务超时,并更新字段
            if self._is_transition_timeout(item["updated"],
                                           item["transitioning_on"]):
                err_msg = _("Helm操作超时,请重试!")
                App.objects.filter(id=item["id"]).update(
                    transitioning_on=False,
                    transitioning_result=False,
                    transitioning_message=err_msg,
                )
                item["transitioning_result"] = False
                item["transitioning_on"] = False
                item["transitioning_message"] = err_msg

            app_list.append(item)

        result = {
            "count": len(app_list),
            "next": None,
            "previous": None,
            "results": app_list
        }
        try:
            ns_request = NamespaceRequest(project_id=project_id,
                                          cluster_id=cluster_id)
        except TypeError:
            return Response(result)
        else:
            return PermsResponse(
                data=result,
                resource_request=ns_request,
                resource_data=iam_ns_ids,
            )
Пример #16
0
 def get_clusters(self, request):
     return PermsResponse(
         cluster_data,
         iam_path_attrs={'project_id': generate_random_string(32)})
Пример #17
0
    def get(self, request, project_id):
        """获取项目下所有的服务"""
        params = dict(request.GET.items())
        params['env'] = 'k8s'

        # 获取命名空间的id
        namespace_dict = app_utils.get_ns_id_map(
            request.user.token.access_token, project_id)

        # 项目下的所有模板集id
        all_template_id_list = Template.objects.filter(
            project_id=project_id,
            edit_mode=TemplateEditMode.PageForm.value).values_list('id',
                                                                   flat=True)
        all_template_id_list = [
            str(template_id) for template_id in all_template_id_list
        ]
        skip_namespace_list = list(K8S_SYS_NAMESPACE)
        skip_namespace_list.extend(K8S_PLAT_NAMESPACE)

        cluster_id = params['cluster_id']
        code, cluster_services = self.get_services_by_cluster_id(
            request, params, project_id, cluster_id)
        if code != ErrorCode.NoError:
            return Response({'code': code, 'message': cluster_services})

        for _s in cluster_services:
            # NOTE: 兼容处理,因为key: clusterId已被前端使用;通过非bcs创建的service,不一定包含cluster_id
            _s["clusterId"] = cluster_id
            _s["cluster_id"] = cluster_id
            _config = _s.get('data', {})
            annotations = _config.get('metadata', {}).get('annotations', {})
            _s['update_time'] = annotations.get(ANNOTATIONS_UPDATE_TIME, '')
            _s['updator'] = annotations.get(ANNOTATIONS_UPDATOR, '')
            _s['status'] = 'Running'

            _s['can_update'] = True
            _s['can_update_msg'] = ''
            _s['can_delete'] = True
            _s['can_delete_msg'] = ''

            namespace_id = namespace_dict.get(
                (cluster_id, _s['namespace'])) if namespace_dict else None
            _s['namespace_id'] = namespace_id
            _s['iam_ns_id'] = calc_iam_ns_id(cluster_id, _s['namespace'])

            labels = _config.get('metadata', {}).get('labels', {})
            template_id = labels.get(LABLE_TEMPLATE_ID)
            # 资源来源
            source_type = labels.get(SOURCE_TYPE_LABEL_KEY)
            if not source_type:
                source_type = "template" if template_id else "other"
            _s['source_type'] = SOURCE_TYPE_MAP.get(source_type)
            extended_routes = get_svc_extended_routes(project_id,
                                                      _s['clusterId'])
            _s['access_info'] = get_svc_access_info(_config, _s['clusterId'],
                                                    extended_routes)
            # 处理 k8s 的系统命名空间的数据
            if _s['namespace'] in skip_namespace_list:
                _s['can_update'] = _s['can_delete'] = False
                _s['can_update_msg'] = _s['can_delete_msg'] = _("不允许操作系统命名空间")
                continue

            # 非模板集创建,可以删除但是不可以更新
            _s['can_update'] = False
            _s['can_update_msg'] = _("所属模板集不存在,无法操作")
            if template_id and template_id in all_template_id_list:
                _s['can_update'] = True
                _s['can_update_msg'] = ''

        # 按时间倒序排列
        cluster_services.sort(key=lambda x: x.get('createTime', ''),
                              reverse=True)

        return PermsResponse(
            cluster_services,
            NamespaceRequest(project_id=project_id,
                             cluster_id=params['cluster_id']))