def check_perm(self, request, project_id, all_node_id_ip_map, node_id_list): # 校验权限 cluster_id_list = [ info["cluster_id"] for node_id, info in all_node_id_ip_map.items() if node_id in node_id_list ] for cluster_id in set(cluster_id_list): perm_client = bcs_perm.Cluster(request, project_id, cluster_id) perm_client.can_view(raise_exception=True)
def validate_cluster_perm(request, project_id: str, cluster_id: str, raise_exception: bool = True) -> bool: """ 检查用户是否有操作集群权限 """ if request.user.is_superuser: return True perm = bcs_perm.Cluster(request, project_id, cluster_id) return perm.can_use(raise_exception=raise_exception)
def check_cluster_perm(user, project_id, cluster_id, raise_exception=True, request=None): if request is None: Request = namedtuple('Request', 'user') request = Request(user=user) perm = bcs_perm.Cluster(request, project_id, cluster_id) perm.can_use(raise_exception=True)
def get_cluser_list_by_user_perm(self, request, project_id): """获取用户所有有使用权限的命名空间""" access_token = request.user.token.access_token cluster_data = paas_cc.get_all_clusters(access_token, project_id).get('data') or {} cluster_list = cluster_data.get('results') or [] perm = bcs_perm.Cluster(request, project_id, bcs_perm.NO_RES) cluster_list = perm.hook_perms(request, project_id, cluster_list, filter_use=True) return cluster_list
def get(self, request, project_id, cluster_id): """获取session信息 """ cluster_data = cluster.get_cluster(request.user.token.access_token, project_id, cluster_id) self.cluster_name = cluster_data.get("name", "")[:32] # 检查白名单, 不在名单中再通过权限中心校验 if not utils.allowed_login_web_console(request.user.username): perm = bcs_perm.Cluster(request, project_id, cluster_id) try: perm.can_use(raise_exception=True) except Exception as error: utils.activity_log(project_id, cluster_id, self.cluster_name, request.user.username, False, _("集群不正确或没有集群使用权限")) raise error # 获取web-console context信息 if request.project.kind == ProjectKind.MESOS.value: # 添加白名单控制 from .views_bk import ensure_mesos_wlist ensure_mesos_wlist(project_id, cluster_id, request.user.username) context = self.get_mesos_context(request, project_id, cluster_id) else: context = self.get_k8s_context(request, project_id, cluster_id) context["username"] = request.user.username context.setdefault("namespace", constants.NAMESPACE) logger.info(context) session = session_mgr.create(project_id, cluster_id) session_id = session.set(context) # 替换http为ws地址 bcs_api_url = urlparse(settings.DEVOPS_BCS_API_URL) if bcs_api_url.scheme == "https": scheme = "wss" else: scheme = "ws" bcs_api_url = bcs_api_url._replace(scheme=scheme) # 连接ws的来源方式, 有容器直连(direct)和多tab管理(mgr) source = request.query_params.get("source", "direct") ws_url = f"{bcs_api_url.geturl()}/web_console/projects/{project_id}/clusters/{cluster_id}/ws/?session_id={session_id}&source={source}" # noqa data = {"session_id": session_id, "ws_url": ws_url} utils.activity_log(project_id, cluster_id, self.cluster_name, request.user.username, True) return BKAPIResponse(data, message=_("获取session成功"))
def get(self, request, project_id, cluster_id): """获取session信息 """ perm = bcs_perm.Cluster(request, project_id, cluster_id) try: perm.can_use(raise_exception=True) except Exception as error: utils.activity_log(project_id, cluster_id, request.user.username, False, "集群不正确或没有集群使用权限") raise error # resource_name字段长度限制32位 self.cluster_name = perm.res['name'][:32] # 获取web-console context信息 if request.project.kind == ProjectKind.MESOS.value: # 添加白名单控制 from .views_bk import ensure_mesos_wlist ensure_mesos_wlist(project_id, cluster_id, request.user.username) context = self.get_mesos_context(request, project_id, cluster_id) else: context = self.get_k8s_context(request, project_id, cluster_id) context['username'] = request.user.username context.setdefault('namespace', constants.NAMESPACE) logger.info(context) session = session_mgr.create(project_id, cluster_id) session_id = session.set(context) # 替换http为ws地址 bcs_api_url = urlparse(settings.DEVOPS_BCS_API_URL) if bcs_api_url.scheme == 'https': scheme = 'wss' else: scheme = 'ws' bcs_api_url = bcs_api_url._replace(scheme=scheme) ws_url = '{bcs_api_url}/web_console/ws/{project_id}/cluster/{cluster_id}/?session_id={session_id}'.format( # noqa bcs_api_url=bcs_api_url.geturl(), project_id=project_id, cluster_id=cluster_id, session_id=session_id, ) data = {'session_id': session_id, 'ws_url': ws_url} utils.activity_log(project_id, self.cluster_name, request.user.username, True) return BKAPIResponse(data, message="获取session成功")
def get_node_labels(self, request, project_id): """获取节点标签""" # 获取节点ID node_ids = request.GET.get("node_ids") cluster_id = request.GET.get("cluster_id") if not node_ids: raise error_codes.CheckFailed(_("节点信息不存在,请确认后重试!")) # 以半角逗号分隔 node_id_list = [int(node_id) for node_id in node_ids.split(",") if str(node_id).isdigit()] # 判断节点属于项目 all_nodes = self.get_node_list(request, project_id, cluster_id).get('results') or [] if not all_nodes: raise error_codes.APIError(_("当前项目下没有节点!")) all_node_id_list = [info["id"] for info in all_nodes] diff_node_id_list = set(node_id_list) - set(all_node_id_list) if diff_node_id_list: return Response( { "code": ErrorCode.UserError, "message": _("节点ID [{}] 不属于当前项目,请确认").format(",".join(diff_node_id_list)), } ) node_label_list = self.get_labels_by_node(request, project_id, node_id_list) # 校验权限 cluster_id_list = [info["cluster_id"] for info in all_nodes if info["id"] in node_id_list] for cluster_id in set(cluster_id_list): perm_client = bcs_perm.Cluster(request, project_id, cluster_id) perm_client.can_view(raise_exception=True) if not node_label_list: return Response({"code": ErrorCode.NoError, "data": {}}) # 如果有多个节点,并且有的节点不存在标签,则全部value为mix value exist_node_without_label = False if len(node_label_list) != len(node_id_list): exist_node_without_label = True for info in node_label_list: if not info.get("labels"): exist_node_without_label = True ret_data = self.label_syntax(node_label_list, exist_node_without_label=exist_node_without_label) return Response({"code": ErrorCode.NoError, "data": ret_data})
def can_edit_cluster(self, request, project_id, cluster_id): cluster_perm = bcs_perm.Cluster(request, project_id, cluster_id) return cluster_perm.can_edit(raise_exception=True)
def can_view_cluster(self, request, project_id, cluster_id): """has view cluster perm""" cluster_perm = bcs_perm.Cluster(request, project_id, cluster_id) cluster_perm.can_view(raise_exception=True)
def can_view_cluster(self, request, project_id, cluster_id): perm = bcs_perm.Cluster(request, project_id, cluster_id) perm.can_view(raise_exception=True)
def handle_lb_dtail_data(self, request, access_token, project_id, merge_data, cluster, namespace, cluster_envs): # 按前端需要二次处理数据 for i in merge_data: i['constraints'] = json.loads(i['data']) i['ip_list'] = json.loads(i['ip_list']) i['cluster_name'] = cluster.get(i['cluster_id'], i['cluster_id']) i['environment'] = cluster_envs.get(i['cluster_id'], '') i.pop('data', None) # 处理新添加的字段 data_dict = i['data_dict'] if data_dict: data_dict = json.loads(data_dict) else: data_dict = {} ns = data_dict.get('namespace_id') or data_dict.get('namespace') if ns and str(ns).isdigit(): ns = int(ns) ns_name = namespace.get(ns) or MESOS_LB_NAMESPACE_NAME i['namespace'] = ns i['namespace_name'] = ns_name i['network_mode'] = data_dict.get('networkMode') i['network_type'] = data_dict.get('networkType') i['custom_value'] = data_dict.get('custom_value') i['image_url'] = data_dict.get('image_url') i['image_version'] = data_dict.get('image_version') i['forward_mode'] = data_dict.get('forward_mode') i['resources'] = data_dict.get('resources') i['instance'] = data_dict.get('instance') i['host_port'] = data_dict.get('host_port') i['eth_value'] = data_dict.get('eth_value', 'eth1') i.pop('data_dict', None) status = i.get('status') or LB_DEFAULT_STATUS if status == LB_DEFAULT_STATUS: i['status'] = status i['status_name'] = [LB_STATUS_DICT.get(status)] i['status_tips'] = [LB_STATUS_DICT.get(status)] else: # 已经创建的应用需要查询 bcs 的状态 lb_res, status_dict = get_lb_status(access_token, project_id, i['name'], i['cluster_id'], ns_name, lb_id=i['id']) deployment_status = status_dict.get('deployment_status') # 用户执行过删除操作 if status == 'deleted' and not deployment_status: i['status'] = status i['status_name'] = [LB_STATUS_DICT.get(status)] i['status_tips'] = [LB_STATUS_DICT.get(status)] else: i['status'] = deployment_status status_name = [] status_tips = [] status_name.append('deployment:%s' % ( status_dict.get('deployment_status') or '--')) status_name.append('application:%s' % ( status_dict.get('application_status') or '--')) status_tips.append('deployment:%s' % ( status_dict.get('deployment_status_message') or '--')) status_tips.append('application:%s' % ( status_dict.get('application_status_message') or '--')) i['status_name'] = status_name i['status_tips'] = status_tips # 停用后,如果不是 deleting 状态,方便前端轮询则需要添加一个中间状态 if status == 'deleted' and deployment_status != 'Deleting': i['status'] = 'before_deleting' # 可以调用 bcs 删除lb 的情况 is_delete_lb = True if i['status'] in [ 'Deploying', 'Running', 'Update', 'UpdatePaused', 'UpdateSuspend'] else False i['is_delete_lb'] = is_delete_lb # 检查是否有集群的相关权限 if merge_data: perm = bcs_perm.Cluster(request, project_id, bcs_perm.NO_RES) merge_data = perm.hook_perms(request, project_id, merge_data) return merge_data
def can_use_perm(self, request, project_id, cluster_id): """检查使用是否有集群的使用权限 """ perm = bcs_perm.Cluster(request, project_id, cluster_id) perm.can_use(raise_exception=True)
def get_create_node_perm(self, request, project_id, cluster_id): perm_client = bcs_perm.Cluster(request, project_id, cluster_id) return perm_client.can_edit(raise_exception=False)
def can_use_cluster(request, project_id, cluster_id): perm_client = bcs_perm.Cluster(request, project_id, cluster_id) return perm_client.can_use(raise_exception=False)