예제 #1
0
    def get(self, request, project_id, cluster_id, namespace, name):
        """ 获取项目下所有的endpoints """
        # 获取kind
        flag, project_kind = self.get_project_kind(request, project_id)
        if not flag:
            return project_kind

        access_token = request.user.token.access_token
        params = {"name": name, "namespace": namespace}
        if project_kind == MESOS_VALUE:
            client = mesos.MesosClient(access_token,
                                       project_id,
                                       cluster_id,
                                       env=None)
            resp = client.get_endpoints(params)
        else:
            client = k8s.K8SClient(access_token,
                                   project_id,
                                   cluster_id,
                                   env=None)
            resp = client.get_endpoints(params)

        if resp.get("code") != ErrorCode.NoError:
            return APIResponse({
                "code": resp.get("code", DEFAULT_ERROR_CODE),
                "message": resp.get("message", _("请求出现异常!"))
            })

        return APIResponse({
            "code": ErrorCode.NoError,
            "data": resp.get("data"),
            "message": "ok"
        })
예제 #2
0
    def get(self, request, project_id):
        """ 获取项目下所有的secrets """
        # 获取kind
        flag, project_kind = self.get_project_kind(request, project_id)
        if not flag:
            return project_kind

        cluster_dicts = self.get_project_cluster_info(request, project_id)
        cluster_data = cluster_dicts.get('results', {}) or {}

        data = []
        params = dict(request.GET.items())
        s_cate = 'secret' if project_kind == MESOS_VALUE else 'K8sSecret'
        access_token = request.user.token.access_token
        is_decode = request.GET.get('decode')
        is_decode = True if is_decode == '1' else False
        # get project namespace info
        namespace_dict = app_utils.get_ns_id_map(
            request.user.token.access_token, project_id)

        for cluster_info in cluster_data:
            cluster_id = cluster_info.get('cluster_id')
            # 当参数中集群ID存在时,判断集群ID匹配成功后,继续后续逻辑
            if params.get('cluster_id') and params['cluster_id'] != cluster_id:
                continue
            cluster_env = cluster_info.get('environment')
            code, cluster_secrets = self.get_secrets_by_cluster_id(
                request,
                params,
                project_id,
                cluster_id,
                project_kind=project_kind)
            # 单个集群错误时,不抛出异常信息
            if code != ErrorCode.NoError:
                continue
            self.handle_data(
                request,
                cluster_secrets,
                project_kind,
                s_cate,
                access_token,
                project_id,
                cluster_id,
                is_decode,
                cluster_env,
                cluster_info.get('name', ''),
                namespace_dict=namespace_dict,
            )
            data += cluster_secrets

        # 按时间倒序排列
        data.sort(key=lambda x: x.get('createTime', ''), reverse=True)
        return APIResponse({
            "code": ErrorCode.NoError,
            "data": {
                "data": data,
                "length": len(data)
            },
            "message": "ok"
        })
예제 #3
0
    def get(self, request, project_id, cluster_id, namespace, name):
        """ 获取项目下所有的endpoints """
        params = {"name": name, "namespace": namespace}
        client = k8s.K8SClient(request.user.token.access_token,
                               project_id,
                               cluster_id,
                               env=None)
        resp = client.get_endpoints(params)

        if resp.get("code") != ErrorCode.NoError:
            return APIResponse({
                "code": resp.get("code", ErrorCode.UnknownError),
                "message": resp.get("message", _("请求出现异常!"))
            })

        return APIResponse({
            "code": ErrorCode.NoError,
            "data": resp.get("data"),
            "message": "ok"
        })
예제 #4
0
    def get(self, request, project_id):
        """获取项目下的所有Ingress"""
        project_kind = request.project.kind
        project_kind_name = ClusterType.get(project_kind)

        if project_kind_name != 'Kubernetes':
            raise error_codes.CheckFailed(_("K8S项目才有Ingress"))

        cluster_dicts = self.get_project_cluster_info(request, project_id)
        cluster_data = cluster_dicts.get('results', {}) or {}

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

        s_cate = 'K8sIngress'
        is_decode = False
        params = {}
        access_token = request.user.token.access_token
        data = []
        # 如果请求参数中cluster_id存在,根据cluster_id过滤集群信息
        query_cluster_id = request.query_params.get("cluster_id")
        if query_cluster_id:
            cluster_data = [info for info in cluster_data if query_cluster_id == info.get('cluster_id')]

        for cluster_info in cluster_data:
            cluster_id = cluster_info.get('cluster_id')
            cluster_env = cluster_info.get('environment')
            code, cluster_data = self.get_ingress_by_cluser_id(request, params, project_id, cluster_id)
            # 单个集群错误时,不抛出异常信息
            if code != ErrorCode.NoError:
                continue
            self.handle_data(
                request,
                cluster_data,
                project_kind,
                s_cate,
                access_token,
                project_id,
                cluster_id,
                is_decode,
                cluster_env,
                cluster_info.get('name', ''),
                namespace_dict=namespace_dict,
            )
            data += cluster_data

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

        return APIResponse({"code": ErrorCode.NoError, "data": {"data": data, "length": len(data)}, "message": "ok"})
예제 #5
0
파일: k8s.py 프로젝트: penglongli/bk-bcs
 def list(self, request, project_id, cluster_id):
     used_ns_id_list = K8SLoadBlance.objects.filter(
         project_id=project_id, cluster_id=cluster_id,
         is_deleted=False).values("namespace_id")
     return APIResponse(
         {"data": [info["namespace_id"] for info in used_ns_id_list]})
예제 #6
0
    def get(self, request, project_id):
        """ 获取项目下所有的ConfigMap """
        # 获取kind
        project_kind = request.project.kind
        if project_kind not in [
                info[0] for info in constants.ProjectKind.get_choices()
        ]:
            raise error_codes.CheckFailed(_("项目编排类型不正确"))

        cluster_dicts = self.get_project_cluster_info(request, project_id)
        cluster_data = cluster_dicts.get('results', {}) or {}

        data = []
        params = dict(request.GET.items())
        s_cate = 'configmap' if project_kind == MESOS_VALUE else 'K8sConfigMap'
        access_token = request.user.token.access_token
        is_decode = request.GET.get('decode')
        is_decode = True if is_decode == '1' else False

        # get project namespace info
        namespace_dict = app_utils.get_ns_id_map(access_token, project_id)

        for cluster_info in cluster_data:
            cluster_id = cluster_info.get('cluster_id')
            # 当参数中集群ID存在时,判断集群ID匹配成功后,继续后续逻辑
            if params.get('cluster_id') and params['cluster_id'] != cluster_id:
                continue
            cluster_env = cluster_info.get('environment')
            code, cluster_configmaps = self.get_configmaps_by_cluster_id(
                request,
                params,
                project_id,
                cluster_id,
                project_kind=project_kind)
            # 单个集群错误时,不抛出异常信息
            if code != ErrorCode.NoError:
                continue
            self.handle_data(
                request,
                cluster_configmaps,
                project_kind,
                s_cate,
                access_token,
                project_id,
                cluster_id,
                is_decode,
                cluster_env,
                cluster_info.get('name', ''),
                namespace_dict=namespace_dict,
            )
            data += cluster_configmaps

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

        return APIResponse({
            "code": ErrorCode.NoError,
            "data": {
                "data": data,
                "length": len(data)
            },
            "message": "ok"
        })
예제 #7
0
    def get(self, request, project_id):
        """ 获取项目下所有的服务 """
        cluster_dicts = self.get_project_cluster_info(request, project_id)
        cluster_data = cluster_dicts.get('results', {}) or {}

        project_kind = request.project.kind
        params = dict(request.GET.items())
        params['env'] = 'mesos' if project_kind == MESOS_VALUE else '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)

        data = []
        for cluster_info in cluster_data:
            cluster_id = cluster_info.get('cluster_id')
            if params.get('cluster_id') and params['cluster_id'] != cluster_id:
                continue
            cluster_name = cluster_info.get('name')
            code, cluster_services = self.get_services_by_cluster_id(
                request, params, project_id, cluster_id, project_kind=project_kind
            )
            if code != ErrorCode.NoError:
                continue
            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['cluster_name'] = cluster_name
                _s['status'] = 'Running'
                _s['environment'] = cluster_info.get('environment')

                _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

                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)

                if project_kind == ProjectKind.K8S.value:
                    extended_routes = get_svc_extended_routes(project_id, _s['clusterId'])
                    _s['access_info'] = get_svc_access_info(_config, _s['clusterId'], extended_routes)
                # 处理 k8s 的系统命名空间的数据
                if project_kind == ProjectKind.K8S.value and _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'] = ''

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

        if data:
            # 检查是否用命名空间的使用权限
            perm = bcs_perm.Namespace(request, project_id, bcs_perm.NO_RES)
            data = perm.hook_perms(
                data, ns_id_flag='namespace_id', cluster_id_flag='clusterId', ns_name_flag='namespace'
            )
        return APIResponse({"code": ErrorCode.NoError, "data": {"data": data, "length": len(data)}, "message": "ok"})
예제 #8
0
    def get_service_info(self, request, project_id, cluster_id, namespace, name):  # noqa
        """获取单个 service 的信息"""
        project_kind = request.project.kind
        access_token = request.user.token.access_token
        params = {
            "env": "mesos" if project_kind == MESOS_VALUE else "k8s",
            "namespace": namespace,
            "name": name,
        }
        if project_kind == MESOS_VALUE:
            client = mesos.MesosClient(access_token, project_id, cluster_id, env=None)
            resp = client.get_services(params)
            # 跳转到模板集页面需要的参数
            template_cate = 'mesos'
            relate_app_cate = 'application'
        else:
            client = k8s.K8SClient(access_token, project_id, cluster_id, env=None)
            resp = client.get_service(params)
            template_cate = 'k8s'
            relate_app_cate = 'deployment'

        if resp.get("code") != ErrorCode.NoError:
            raise ComponentError(resp.get("message"))

        resp_data = resp.get("data", [])
        if not resp_data:
            return APIResponse({"code": 400, "message": _("查询不到 Service[{}] 的信息").format(name)})
        s_data = resp_data[0].get('data', {})
        labels = s_data.get('metadata', {}).get('labels') or {}

        # 获取命名空间的id
        namespace_id = app_utils.get_namespace_id(
            access_token, project_id, (cluster_id, namespace), cluster_id=cluster_id
        )

        instance_id = labels.get(LABLE_INSTANCE_ID)

        # 是否关联LB
        lb_balance = labels.get('BCSBALANCE')
        if lb_balance:
            s_data['isLinkLoadBalance'] = True
            s_data['metadata']['lb_labels'] = {'BCSBALANCE': lb_balance}
        else:
            s_data['isLinkLoadBalance'] = False
        lb_name = labels.get('BCSGROUP')

        # 获取模板集信息
        template_id = labels.get(LABLE_TEMPLATE_ID)
        try:
            lasetest_ver = ShowVersion.objects.filter(template_id=template_id).order_by('-updated').first()
            show_version_name = lasetest_ver.name
            version_id = lasetest_ver.real_version_id
            version_entity = VersionedEntity.objects.get(id=version_id)
        except Exception:
            return APIResponse({"code": 400, "message": _("模板集[id:{}]没有可用的版本,无法更新service").format(template_id)})

        entity = version_entity.get_entity()

        # 获取更新人和创建人
        annotations = s_data.get('metadata', {}).get('annotations', {})
        creator = annotations.get(ANNOTATIONS_CREATOR, '')
        updator = annotations.get(ANNOTATIONS_UPDATOR, '')
        create_time = annotations.get(ANNOTATIONS_CREATE_TIME, '')
        update_time = annotations.get(ANNOTATIONS_UPDATE_TIME, '')

        # k8s 更新需要获取版本号
        resource_version = s_data.get('metadata', {}).get('resourceVersion') or ''

        web_cache = annotations.get(ANNOTATIONS_WEB_CACHE)
        if not web_cache:
            # 备注中无,则从模板中获取,兼容mesos之前实例化过的模板数据
            _services = entity.get('service') if entity else None
            _services_id_list = _services.split(',') if _services else []
            _s = Service.objects.filter(id__in=_services_id_list, name=name).first()
            try:
                web_cache = _s.get_config.get('webCache')
            except Exception:
                pass
        else:
            try:
                web_cache = json.loads(web_cache)
            except Exception:
                pass
        s_data['webCache'] = web_cache
        deploy_tag_list = web_cache.get('deploy_tag_list') or []

        app_weight = {}
        if project_kind == MESOS_VALUE:
            # 处理 mesos 中Service的关联数据
            apps = entity.get('application') if entity else None
            application_id_list = apps.split(',') if apps else []

            apps = Application.objects.filter(id__in=application_id_list)
            if apps:
                # 关联应用的权重
                for key in labels:
                    if key.startswith('BCS-WEIGHT-'):
                        app_name = key[11:]
                        _app = apps.filter(name=app_name).first()
                        if _app:
                            weight = int(labels[key])
                            app_weight[_app.app_id] = weight
        else:
            # 处理 k8s 中Service的关联数据
            if not deploy_tag_list:
                _servs = entity.get('K8sService') if entity else None
                _serv_id_list = _servs.split(',') if _servs else []
                _k8s_s = K8sService.objects.filter(id__in=_serv_id_list, name=name).first()
                if _k8s_s:
                    deploy_tag_list = _k8s_s.get_deploy_tag_list()

        # 标签 和 备注 去除后台自动添加的
        or_annotations = s_data.get('metadata', {}).get('annotations', {})
        or_labels = s_data.get('metadata', {}).get('labels', {})
        if or_labels:
            pub_keys = PUBLIC_LABELS.keys()
            show_labels = {key: or_labels[key] for key in or_labels if key not in pub_keys}
            s_data['metadata']['labels'] = show_labels
        if or_annotations:
            pub_an_keys = PUBLIC_ANNOTATIONS.keys()
            show_annotations = {key: or_annotations[key] for key in or_annotations if key not in pub_an_keys}
            remove_key(show_annotations, ANNOTATIONS_WEB_CACHE)
            s_data['metadata']['annotations'] = show_annotations

        return APIResponse(
            {
                "data": {
                    'service': [
                        {
                            'name': name,
                            'app_id': app_weight.keys(),
                            'app_weight': app_weight,
                            'deploy_tag_list': deploy_tag_list,
                            'config': s_data,
                            'version': version_id,
                            'lb_name': lb_name,
                            'instance_id': instance_id,
                            'namespace_id': namespace_id,
                            'cluster_id': cluster_id,
                            'namespace': namespace,
                            'creator': creator,
                            'updator': updator,
                            'create_time': create_time,
                            'update_time': update_time,
                            'show_version_name': show_version_name,
                            'resource_version': resource_version,
                            'template_id': template_id,
                            'template_cate': template_cate,
                            'relate_app_cate': relate_app_cate,
                        }
                    ]
                }
            }
        )