Пример #1
0
    def has_bcs_service(self, access_token, project_id, request_namespace):
        """判断是否开启容器服务
        开启后就不能关闭,所以缓存很久,默认30天
        """
        cache_key = f"BK_DEVOPS_BCS:HAS_BCS_SERVICE:{project_id}"
        project = region.get(cache_key, expiration_time=3600 * 24 * 30)

        if not project or not isinstance(project, FancyDict):
            result = paas_cc.get_project(access_token, project_id)
            project = result.get("data") or {}

            # coes: container orchestration engines
            project['coes'] = project['kind']
            try:
                from backend.container_service.projects.utils import get_project_kind

                # k8s类型包含kind为1(bcs k8s)或其它属于k8s的编排引擎
                project['kind'] = get_project_kind(project['kind'])
            except ImportError:
                pass

            project = FancyDict(project)

            if request_namespace in SKIP_REQUEST_NAMESPACE:
                # 如果是SKIP_REQUEST_NAMESPACE,有更新接口,不判断kind
                if project.get("cc_app_id") != 0:
                    region.set(cache_key, project)

            elif project.get("cc_app_id") != 0:
                region.set(cache_key, project)
            else:
                # 其他抛出没有开启容器服务
                raise error_codes.NoBCSService()

        return project
Пример #2
0
    def has_bcs_service(self, access_token, project_id, request_namespace):
        """判断是否开启容器服务
        开启后就不能关闭,所以缓存很久,默认30天
        """
        cache_key = f'BK_DEVOPS_BCS:HAS_BCS_SERVICE:{project_id}'
        project = region.get(cache_key, expiration_time=3600 * 24 * 30)

        if not project or not isinstance(project, FancyDict):
            result = paas_cc.get_project(access_token, project_id)
            project = result.get('data') or {}
            project = FancyDict(project)

            if request_namespace in SKIP_REQUEST_NAMESPACE:
                # 如果是SKIP_REQUEST_NAMESPACE,有更新接口,不判断kind
                if project.get('cc_app_id') != 0 and project.get(
                        'kind') in ClusterType:
                    region.set(cache_key, project)

            elif project.get('kind') in ClusterType:
                # 如果已经开启容器服务,判断是否cc_app_id再缓存
                if project.get('cc_app_id') != 0:
                    region.set(cache_key, project)
            else:
                # 其他抛出没有开启容器服务
                raise error_codes.NoBCSService()

        return project
Пример #3
0
def get_cc_app_id(access_token, project_id):
    resp = paas_cc.get_project(access_token, project_id)
    if not resp.get("code"):
        return ""

    data = resp.get('data')
    return data.get("cc_app_id", "")
Пример #4
0
 def get_or_add_private_repos(self, project_id, user):
     project = paas_cc.get_project(access_token=self.access_token,
                                   project_id=project_id)
     if settings.HELM_HAS_ABILITY_SUPPLY_CHART_REPO_SERVICE:
         # 2. add/get private repo for project
         private_repo = add_repo(
             target_project_id=project_id,
             name=project["data"]["english_name"],
             provider_name="chartmuseum",
             url="http://localhost/",  # merely provide schema
             user=user,
         )
     else:
         repo_auth = {
             "type": "basic",
             "role": "admin",
             "credentials": {
                 "username": settings.HELM_MERELY_REPO_USERNAME,
                 "password": settings.HELM_MERELY_REPO_PASSWORD,
             }
         }
         english_name = project['data']['english_name']
         url = '%s/chartrepo/%s/' % (settings.HELM_MERELY_REPO_URL,
                                     english_name)
         private_repo = add_plain_repo(target_project_id=project_id,
                                       name=english_name,
                                       url=url,
                                       repo_auth=repo_auth)
     return [private_repo]
Пример #5
0
    def get_k8s_context(self, request, project_id_or_code, cluster_id):
        """获取docker监控信息"""
        access_token = paas_auth.get_access_token().get("access_token")

        result = paas_cc.get_project(access_token, project_id_or_code)

        if result.get("code") != ErrorCode.NoError:
            raise error_codes.APIError(
                _("项目Code或者ID不正确: {}").format(result.get("message", "")))

        project_id = result["data"]["project_id"]

        client = K8SClient(access_token, project_id, cluster_id, None)
        slz = K8SWebConsoleOpenSLZ(data=request.data,
                                   context={"client": client})
        slz.is_valid(raise_exception=True)

        try:
            bcs_context = utils.get_k8s_cluster_context(
                client, project_id, cluster_id)
        except Exception as error:
            logger.exception("get access cluster context failed: %s", error)
            message = _("获取集群{}【{}】WebConsole session 信息失败").format(
                cluster_id, cluster_id)
            # 返回前端消息
            raise error_codes.APIError(message)

        bcs_context["mode"] = k8s.ContainerDirectClient.MODE
        bcs_context["user_pod_name"] = slz.validated_data["pod_name"]
        bcs_context["project_id"] = project_id
        bcs_context.update(slz.validated_data)

        return bcs_context
Пример #6
0
 def get_project_info(self, request, project_id):
     """获取项目信息
     """
     resp = paas_cc.get_project(request.user.token.access_token, project_id)
     if resp.get('code') != ErrorCode.NoError:
         raise error_codes.APIError.f(resp.get('message'))
     request.project = FancyDict(resp.get('data', {}))
Пример #7
0
        def cached_project_info(project_code):
            """缓存项目类型"""
            result = paas_cc.get_project(request.user.token.access_token,
                                         project_code)
            if result['code'] != 0:
                return {}

            return result['data']
Пример #8
0
 def get_project_kind(self, request, project_id):
     """获取项目类型,现阶段包含mesos和k8s"""
     project_info = paas_cc.get_project(request.user.token.access_token, project_id)
     if project_info.get("code") != ErrorCode.NoError:
         return False, APIResponse({"code": project_info.get("code", DEFAULT_ERROR_CODE), "message": _("请求出现异常!")})
     if project_info.get("data", {}).get("kind") not in constants.PROJECT_KIND_LIST:
         return False, APIResponse({"code": ErrorCode.UserError, "message": _("该项目编排类型不正确!"), "data": None})
     return True, project_info["data"]["kind"]
Пример #9
0
    def retrieve(self, request, project_id, *args, **kwargs):
        project = paas_cc.get_project(
            access_token=request.user.token.access_token,
            project_id=project_id)
        project_code = project["data"]["english_name"]
        repo_info = self.get_private_repo_info(user=request.user,
                                               project_id=project_id,
                                               project_code=project_code)

        base_url = request.build_absolute_uri()
        base_url = base_url.split("bcs/k8s")[0]
        if not settings.HELM_HAS_ABILITY_SUPPLY_CHART_REPO_SERVICE:
            repo_url = repo_info["url"]
        else:
            repo_url = f"http://{settings.PLATFORM_REPO_DOMAIN}/{settings.HELM_REPO_ENV}/{project_code}"

        context = {
            "project_id": project_id,
            "chart_domain": settings.PLATFORM_REPO_DOMAIN,
            "helm_env": settings.HELM_REPO_ENV,
            "project_code": str(project_code),
            "username": repo_info["username"],
            "password": repo_info["password"],
            "base_url": base_url,
            "repo_url": repo_url,
            "helm_push_parameters": "",
            "rumpetroll_demo_url": settings.RUMPETROLL_DEMO_DOWNLOAD_URL
        }

        if settings.HELM_HAS_ABILITY_SUPPLY_CHART_REPO_SERVICE:
            context[
                "helm_push_parameters"] = "--context-path=/{helm_env}/{project_code}".format(
                    helm_env=settings.HELM_REPO_ENV,
                    project_code=str(project_code))

        file_prefix = 'backend/bcs_k8s/app/documentation'

        if request.LANGUAGE_CODE == 'en':
            filename = f'{file_prefix}/how-to-push-chart-en.md'
        else:
            filename = f'{file_prefix}/how-to-push-chart.md'

        with open(
                os.path.join(
                    settings.STATIC_ROOT.split("staticfiles")[0], filename),
                "r") as f:
            template = Template(f.read())

        content = template.render(**context)
        response = HttpResponse(content=content,
                                content_type='text/plain; charset=UTF-8')
        response[
            'Content-Disposition'] = 'attachment; filename="how-to-push-helm-chart.md"'
        return response
Пример #10
0
    def handle(self, *args, **options):
        access_token = bcs_perm.get_access_token().get('access_token')
        if not access_token:
            print('get access_token by paas_auth fail')
            return

        for project in ProjectDataInfo.objects.all():
            result = paas_cc.get_project(access_token, project.project_id)
            if result['result']:
                project.cc_biz_id = result['data']['cc_app_id']
                project.save(update_fields=['cc_biz_id'])
            else:
                print(project.project_id, result)
Пример #11
0
 def info(self, request, project_id):
     """单个项目信息"""
     project_resp = paas_cc.get_project(request.user.token.access_token, project_id)
     if project_resp.get("code") != ErrorCode.NoError:
         raise error_codes.APIError(f'not found project info, {project_resp.get("message")}')
     data = project_resp["data"]
     data["created_at"], data["updated_at"] = self.normalize_create_update_time(
         data["created_at"], data["updated_at"]
     )
     # 添加业务名称
     data["cc_app_name"] = get_application_name(request)
     data["can_edit"] = self.can_edit(request, project_id)
     return Response(data)
Пример #12
0
 def get_project_code(self, access_token, project_id):
     """获取project_code
     缓存较长时间
     """
     cache_key = f'BK_DEVOPS_BCS:PROJECT_CODE:{project_id}'
     project_code = region.get(cache_key, expiration_time=3600 * 24 * 30)
     if not project_code:
         result = paas_cc.get_project(access_token, project_id)
         if result.get('code') != 0:
             return None
         project_code = result['data']['english_name']
         region.set(cache_key, project_code)
     return project_code
Пример #13
0
    def get_request_user(self, request, access_token, project_id):
        if settings.DEBUG:
            app_code, username = DEFAULT_APP_CODE, DEFAULT_USER
        else:
            app_code, username = parse_jwt_info(self.jwt_info(request))
        request.user = APIUser
        request.user.token.access_token = access_token
        request.user.username = DEFAULT_USER if settings.DEBUG else username
        request.user.app_code = app_code

        result = get_project(access_token, project_id)
        project = result.get("data") or {}
        project = FancyDict(project)
        request.project = project
Пример #14
0
 def get_project_code(self, access_token, project_id):
     """获取project_code
     缓存较长时间
     """
     cache_key = f"BK_DEVOPS_BCS:PROJECT_CODE:{project_id}"
     project_code = region.get(cache_key, expiration_time=3600 * 24 * 30)
     if not project_code:
         # 这里的project_id对应实际的project_id或project_code, paas_cc接口兼容了两种类型的查询
         result = paas_cc.get_project(access_token, project_id)
         if result.get("code") != 0:
             return None
         project_code = result["data"]["english_name"]
         region.set(cache_key, project_code)
     return project_code
Пример #15
0
def check_user_project(access_token,
                       project_id,
                       cc_app_id,
                       jwt_info,
                       project_code_flag=False,
                       is_orgin_project=False):
    """检测用户有项目权限
    """
    # 针对非用户态进行特殊处理
    if not jwt_info and settings.DEBUG:
        app_code = DEFAULT_APP_CODE
    else:
        app_code, _ = parse_jwt_info(jwt_info)
    if skip_authentication(app_code):
        resp = paas_cc.get_project(access_token, project_id)
        if resp.get("code") != ErrorCode.NoError:
            raise error_codes.APIError.f(resp.get("message", ""))
        data = resp.get("data") or {}
        if str(data.get("cc_app_id")) != str(cc_app_id):
            raise error_codes.CheckFailed.f("用户没有访问项目的权限,请确认", replace=True)
        project_kind = PROJECT_KIND_MAP.get(str(data.get("kind", "")))
        if project_code_flag:
            project_code = data.get("english_name")
        project_info = data
    else:
        project_info = paas_cc.get_auth_project(access_token)
        # 通过cc app id过滤
        if project_info.get("code") != ErrorCode.NoError:
            raise error_codes.APIError.f(project_info.get("message"))
        ret_data = [
            info for info in project_info.get("data") or []
            if str(info.get("cc_app_id")) == str(cc_app_id)
            and info["project_id"] == project_id
        ]
        if not ret_data:
            raise error_codes.CheckFailed.f("用户没有访问项目的权限,请确认", replace=True)
        project_kind = PROJECT_KIND_MAP.get(str(ret_data[0].get("kind", "")))
        project_info = ret_data[0]
        project_code = project_info.get("english_name")
    # 统一处理项目类型
    if not project_kind:
        raise error_codes.CheckFailed.f("项目类型只能为k8s/mesos,请确认", replace=True)

    # 直接返回原生的project信息
    if is_orgin_project:
        return project_kind, app_code, project_info
    if project_code_flag:
        return project_kind, app_code, project_code
    return project_kind, app_code
Пример #16
0
def register_ns(log):
    # 添加default命名空间
    # 如果存在则跳过
    resp = paas_cc.get_cluster_namespace_list(
        log.token, log.project_id, log.cluster_id, desire_all_data=True
    )
    ns_name_list = [
        info["name"] for info in resp.get("data", {}).get("results") or [] if info.get("name")
    ]
    if "default" not in ns_name_list:
        # 获取项目编排类型,只有为k8s时,才会执行注册操作
        resp = paas_cc.get_project(log.token, log.project_id)
        data = resp.get("data", {})
        if data.get("kind") == 1:
            register_default_ns(log.token, log.operator, log.project_id, data.get("english_name"), log.cluster_id)
Пример #17
0
 def get_project_id(self, access_token, project_id):
     """获取project_id
     缓存较长时间
     # TODO 临时使用
     """
     cache_key = f"BK_DEVOPS_BCS:REAL_PROJECT_ID:{project_id}"
     real_project_id = region.get(cache_key, expiration_time=3600 * 24 * 30)
     if not real_project_id:
         # 这里的project_id对应实际的project_id或project_code, paas_cc接口兼容了两种类型的查询
         result = paas_cc.get_project(access_token, project_id)
         if result.get("code") != 0:
             return None
         real_project_id = result["data"]["project_id"]
         region.set(cache_key, real_project_id)
     return real_project_id
Пример #18
0
        def cached_project_kind(project_code):
            """缓存项目类型"""
            result = paas_cc.get_project(request.user.token.access_token,
                                         project_code)
            if result['code'] != 0:
                return ""

            # 未开启容器服务
            if result['data']['kind'] == 0:
                return ""
            # mesos
            if result['data']['kind'] != ProjectKindID:
                return "mesos"
            # 包含 k8s, tke
            return "k8s"
Пример #19
0
def get_bcs_context(access_token, project_id):
    # 获取项目相关的信息
    context = {}
    project = paas_cc.get_project(access_token, project_id)
    if project.get("code") != 0:
        raise ValidationError("{}(project_id:{}):{}".format(_("查询项目信息出错"), project_id, project.get("message")))
    project = project.get("data") or {}
    context["SYS_CC_APP_ID"] = project.get("cc_app_id")
    # TODO  以下变量未初始化到变量表中
    context["SYS_PROJECT_KIND"] = ProjectKindName
    context["SYS_PROJECT_CODE"] = project.get("english_name")

    # 获取标准日志采集的dataid
    data_info = get_data_id_by_project_id(project_id)
    context["SYS_STANDARD_DATA_ID"] = data_info.get("standard_data_id")
    context["SYS_NON_STANDARD_DATA_ID"] = data_info.get("non_standard_data_id")
    return context
Пример #20
0
def get_scheduler_driver(access_token, project_id, configuration):
    project = paas_cc.get_project(access_token, project_id)
    if project.get('code') != 0 or not project.get('data'):
        raise error_codes.APIError.f(project.get('message'))

    cluster_type = ClusterType.get(project['data']['kind'])
    # for test
    # cluster_type = 'Mesos'

    if cluster_type == 'Kubernetes':
        schduler = k8s.Scheduler(
            access_token, project_id, configuration, kind="Kubernetes", is_rollback=True)
    elif cluster_type == 'Mesos':
        schduler = mesos.Scheduler(
            access_token, project_id, configuration, kind="Mesos", is_rollback=True)
    else:
        raise NotImplementedError("only support k8s and mesos")
    return schduler
Пример #21
0
    def project_info(self):
        """
        {
            "cc_app_id": 764,
            "cc_app_name": "blueking",
        }
        """
        if not self.access_token and self.ignore_empty_access_token:
            return self.context.get("project_info", dict())

        resp = paas_cc.get_project(self.access_token, self.project_id)
        if resp.get('code') != 0:
            logger.error(
                "查询project的信息出错(project_id:{project_id}):{message}".format(
                    project_id=self.project_id, message=resp.get('message')))
            return None

        return resp.get('data')
Пример #22
0
    def refine_project_field(self, access_token, field_name, kwargs):
        if field_name not in kwargs:
            return

        result = paas_cc.get_project(access_token, kwargs[field_name])
        if result.get("code") != ErrorCode.NoError:
            raise error_codes.APIError(
                _("项目Code或者ID不正确: {}").format(result.get("message", "")))

        if self.project_field_name == "project_code":
            field_value = result["data"]["english_name"]
        elif self.project_field_name == "project_id":
            field_value = result["data"]["project_id"]
        else:
            field_value = kwargs[field_name]

        kwargs[self.project_field_name] = field_value
        self.kwargs[self.project_field_name] = field_value

        kwargs.pop(field_name, "")
        self.kwargs.pop(field_name, "")
Пример #23
0
def collect_system_variable(access_token, project_id, namespace_id):
    sys_variables = {}

    # 获取标准日志采集的dataid
    data_info = get_data_id_by_project_id(project_id)
    sys_variables['SYS_STANDARD_DATA_ID'] = data_info.get('standard_data_id')
    sys_variables['SYS_NON_STANDARD_DATA_ID'] = data_info.get('non_standard_data_id')

    resp = paas_cc.get_project(access_token, project_id)
    if resp.get('code') != 0:
        logger.error(
            "查询project的信息出错(project_id:{project_id}):{message}".format(
                project_id=project_id, message=resp.get('message')
            )
        )
    project_info = resp["data"]
    sys_variables["SYS_CC_APP_ID"] = project_info["cc_app_id"]
    sys_variables['SYS_PROJECT_KIND'] = project_info["kind"]
    sys_variables['SYS_PROJECT_CODE'] = project_info["english_name"]

    resp = paas_cc.get_namespace(access_token, project_id, namespace_id)
    if resp.get('code') != 0:
        logger.error(
            "查询命名空间的信息出错(namespace_id:{project_id}-{namespace_id}):{message}".format(
                namespace_id=namespace_id, project_id=project_id, message=resp.get('message')
            )
        )
    namespace_info = resp["data"]

    sys_variables["SYS_NAMESPACE"] = namespace_info["name"]
    sys_variables["SYS_CLUSTER_ID"] = namespace_info["cluster_id"]
    sys_variables["SYS_PROJECT_ID"] = namespace_info["project_id"]
    # SYS_JFROG_DOMAIN
    # SYS_NON_STANDARD_DATA_ID

    # 获取镜像地址
    jfrog_domain = paas_cc.get_jfrog_domain(access_token, project_id, sys_variables['SYS_CLUSTER_ID'])
    sys_variables['SYS_JFROG_DOMAIN'] = jfrog_domain

    return sys_variables
Пример #24
0
def get_cc_app_id(access_token, project_id):
    resp = paas_cc.get_project(access_token, project_id)
    project_info = resp.get("data") or {}
    return str(project_info.get("cc_app_id") or "")
Пример #25
0
def get_project_code_by_id(access_token, project_id):
    result = paas_cc.get_project(access_token, project_id)
    project = result.get('data') or {}
    project_code = project.get('english_name', '')
    return project_code
Пример #26
0
    def retrieve(self, request, app_id, *args, **kwargs):
        app = App.objects.get(id=self.app_id)

        project_code_cache_key = "helm_project_cache_key:%s" % self.project_id
        if project_code_cache_key in cache:
            resp = cache.get(project_code_cache_key)

        else:
            # get_project_name
            resp = paas_cc.get_project(self.access_token, self.project_id)
            if resp.get('code') != 0:
                logger.error(
                    "查询project的信息出错(project_id:{project_id}):{message}".format(
                        project_id=self.project_id,
                        message=resp.get('message')))
                return Response({
                    "code": 500,
                    "message": _("后台接口异常,根据项目ID获取项目英文名失败!")
                })

            cache.set(project_code_cache_key, resp, 60 * 15)

        project_code = resp["data"]["english_name"]

        check_cluster_perm(user=request.user,
                           project_id=app.project_id,
                           cluster_id=app.cluster_id,
                           request=request)

        kubeconfig = bcs_utils_client.get_kubectl_config_context(
            access_token=self.access_token,
            project_id=app.project_id,
            cluster_id=app.cluster_id)

        base_url = get_base_url(request)
        try:
            with tempfile.NamedTemporaryFile("w") as f:
                f.write(kubeconfig)
                f.flush()

                data = collect_resource_status(base_url=base_url,
                                               kubeconfig=f.name,
                                               app=app,
                                               project_code=project_code)
        except DashboardExecutionError as e:
            message = "get helm app status failed, error_no: {error_no}\n{output}".format(
                error_no=e.error_no, output=e.output)
            return Response({
                "code": 400,
                "message": message,
            })
        except DashboardError as e:
            message = "get helm app status failed, dashboard ctl error: {err}".format(
                err=e)
            logger.exception(message)
            return Response({
                "code": 400,
                "message": message,
            })
        except Exception as e:
            message = "get helm app status failed, {err}".format(err=e)
            logger.exception(message)
            return Response({
                "codee": 500,
                "message": message,
            })

        response = {
            "status": data,
            "app": {
                "transitioning_action": app.transitioning_action,
                "transitioning_on": app.transitioning_on,
                "transitioning_result": app.transitioning_result,
                "transitioning_message": app.transitioning_message,
            },
        }
        return Response(response)
Пример #27
0
 def validate_project_id(self, user, project_id):
     result = paas_cc.get_project(user.token.access_token, project_id)
     if result.get('code') != 0:
         raise PermissionDenied("project not found")
Пример #28
0
def get_project(access_token, project_id):
    return paas_cc.get_project(access_token, project_id)