def update(self, request, project_id, namespace_id, is_validate_perm=True): """修改命名空间 不允许修改命名空间信息,只能修改变量信息 TODO: 在wesley提供集群下使用的命名空间后,允许命名空间修改名称 """ serializer = slz.UpdateNSVariableSLZ(data=request.data, context={ 'request': request, 'project_id': project_id, 'ns_id': namespace_id }) serializer.is_valid(raise_exception=True) data = serializer.validated_data result = {'code': 0, 'data': data, 'message': _("更新成功")} # 更新成功后需要保存变量信息 if data.get('ns_vars'): res, not_exist_vars = NameSpaceVariable.batch_save( namespace_id, data['ns_vars']) if not_exist_vars: not_exist_show_msg = [ '%s[id:%s]' % (i['key'], i['id']) for i in not_exist_vars ] result['message'] = _("以下变量不存在:{}").format( ";".join(not_exist_show_msg)) result['data']['ns_vars'] = NameSpaceVariable.get_ns_vars( namespace_id, project_id) return response.Response(result)
def create_namespace(self, request, project_id_or_code, cluster_id): project_id = request.project.project_id slz = CreateNamespaceParamsSLZ(data=request.data, context={"project_id": project_id}) slz.is_valid(raise_exception=True) data = slz.data access_token = request.user.token.access_token username = request.user.username namespace = self._create_kubernetes_namespace(access_token, username, project_id, cluster_id, data["name"]) # 创建命名空间下的变量值 ns_id = namespace.get("namespace_id") or namespace.get("id") namespace["id"] = ns_id NameSpaceVariable.batch_save(ns_id, data["variables"]) namespace["variables"] = data["variables"] # 命名空间权限Client ns_perm_client = bcs_perm.Namespace(request, project_id, bcs_perm.NO_RES, cluster_id) ns_perm_client.register(namespace["id"], f"{namespace['name']}({cluster_id})") return Response(namespace)
def update(self, request, project_id, namespace_id, is_validate_perm=True): """修改命名空间下变量""" # TODO 增加权限控制 serializer = slz.UpdateNSVariableSLZ(data=request.data, context={ 'request': request, 'project_id': project_id, 'ns_id': namespace_id }) serializer.is_valid(raise_exception=True) data = serializer.validated_data result = {'code': 0, 'data': data, 'message': _("更新成功")} # 更新成功后需要保存变量信息 if data.get('ns_vars'): res, not_exist_vars = NameSpaceVariable.batch_save( namespace_id, data['ns_vars']) if not_exist_vars: not_exist_show_msg = [ '%s[id:%s]' % (i['key'], i['id']) for i in not_exist_vars ] result['message'] = _("以下变量不存在:{}").format( ";".join(not_exist_show_msg)) result['data']['ns_vars'] = NameSpaceVariable.get_ns_vars( namespace_id, project_id) request.audit_ctx.update_fields(resource=namespace_id, description=_("调整命名空间({})下的变量").format( namespace_id, extra=data)) return response.Response(result)
def create_flow(self, request, project_id, data, perm): access_token = request.user.token.access_token project_kind = request.project.kind project_code = request.project.english_name ns_name = data['name'] cluster_id = data['cluster_id'] if ClusterType.get(project_kind) == 'Kubernetes': # k8s 集群需要调用 bcs api 初始化数据 self.init_namespace_by_bcs(access_token, project_id, project_code, data) has_image_secret = None else: self.init_mesos_ns_by_bcs(access_token, project_id, project_code, cluster_id, ns_name) has_image_secret = True result = paas_cc.create_namespace( access_token, project_id, cluster_id, ns_name, None, # description 现在没有用到 request.user.username, data['env_type'], has_image_secret, ) if result.get('code') != 0: if ClusterType.get(project_kind) != 'Kubernetes': self.delete_secret_for_mesos(access_token, project_id, cluster_id, ns_name) if 'Duplicate entry' in result.get('message', ''): message = _("创建失败,namespace名称已经在其他项目存在") else: message = result.get('message', '') return response.Response({ 'code': result['code'], 'data': None, 'message': message }) else: # 注册资源到权限中心 perm.register(result['data']['id'], f'{ns_name}({cluster_id})') # 创建成功后需要保存变量信息 result_data = result.get('data') if data.get('ns_vars') and result_data: ns_id = result_data.get('id') res, not_exist_vars = NameSpaceVariable.batch_save( ns_id, data['ns_vars']) if not_exist_vars: not_exist_show_msg = [ f'{i["key"]}[id:{i["id"]}]' for i in not_exist_vars ] result['message'] = _("以下变量不存在:{}").format( ';'.join(not_exist_show_msg)) result['data']['ns_vars'] = NameSpaceVariable.get_ns_vars( ns_id, project_id) return result
def create_flow(self, request, project_id, data): access_token = request.user.token.access_token project_code = request.project.english_name ns_name = data['name'] cluster_id = data['cluster_id'] # k8s 集群需要调用 bcs api 初始化数据 self.init_namespace_by_bcs(access_token, project_id, project_code, data) has_image_secret = None result = paas_cc.create_namespace( access_token, project_id, cluster_id, ns_name, None, # description 现在没有用到 request.user.username, data['env_type'], has_image_secret, ) if result.get('code') != 0: if 'Duplicate entry' in result.get('message', ''): message = _("创建失败,namespace名称已经在其他项目存在") else: message = result.get('message', '') return response.Response({ 'code': result['code'], 'data': None, 'message': message }) else: self.iam_perm.grant_resource_creator_actions( NamespaceCreatorAction(project_id=project_id, cluster_id=cluster_id, creator=request.user.username, name=ns_name), ) # 创建成功后需要保存变量信息 result_data = result.get('data') if data.get('ns_vars') and result_data: ns_id = result_data.get('id') res, not_exist_vars = NameSpaceVariable.batch_save( ns_id, data['ns_vars']) if not_exist_vars: not_exist_show_msg = [ f'{i["key"]}[id:{i["id"]}]' for i in not_exist_vars ] result['message'] = _("以下变量不存在:{}").format( ';'.join(not_exist_show_msg)) result['data']['ns_vars'] = NameSpaceVariable.get_ns_vars( ns_id, project_id) return result
def create(self, request, project_id_or_code, cluster_id): project_id = request.project.project_id params = self.params_validate(CreateNamespaceSLZ, context={'project_id': project_id}) ns_name, variables = params['name'], params['variables'] if ns_name in BCS_RESERVED_NAMESPACES: raise error_codes.ValidateError('不允许创建 BCS 保留的命名空间') # 更新操作审计信息 request.audit_ctx.update_fields(resource_type=ResourceType.Namespace, resource=ns_name) namespace = Namespace(request.ctx_cluster).get_or_create_cc_namespace( ns_name, request.user.username, params['labels'], params['annotations'] ) # 创建命名空间下的变量值 ns_id = namespace['namespace_id'] namespace['id'] = ns_id NameSpaceVariable.batch_save(ns_id, variables) namespace['variables'] = variables return Response(namespace)
def get_namespace_variables(project_id, namespace_id): # 仅能拿到用户自定义的变量 """ project_var = [{ 'id': _v.id, 'key': _v.key, 'name': _v.name, 'default_value': _v.get_default_value, 'ns_values': ns_values }] ns_vars = NameSpaceVariable.get_ns_vars(namespace_id, project_id) ns_vars = [{ 'id': _v.id, 'key': _v.key, 'name': _v.name, 'value': _ns_value if _ns_value else '' }] """ project_var = NameSpaceVariable.get_project_ns_vars(project_id) namespace_vars = [] for _var in project_var: _ns_values = _var['ns_values'] _ns_value_ids = _ns_values.keys() namespace_vars.append({ 'id': _var['id'], 'key': _var['key'], 'name': _var['name'], 'value': _ns_values.get(namespace_id) if namespace_id in _ns_value_ids else _var['default_value'], }) ns_vars = NameSpaceVariable.get_ns_vars(namespace_id, project_id) namespace_vars += ns_vars variable = {item["key"]: item["value"] for item in namespace_vars} logger.info("get_namespace_variables %s:%s \n %s", project_id, namespace_id, json.dumps(variable)) return variable
def create_namespace(self, request, project_id_or_code, cluster_id): project_id = request.project.project_id slz = CreateNamespaceParamsSLZ(data=request.data, context={"project_id": project_id}) slz.is_valid(raise_exception=True) data = slz.data access_token = request.user.token.access_token username = request.user.username project_id = request.project.project_id project_kind_name = ProjectKind.get_choice_label(request.project.kind) namespace = getattr(self, f"create_{project_kind_name.lower()}_namespace")( access_token, username, project_id, cluster_id, data["name"]) # 创建命名空间下的变量值 ns_id = namespace["id"] NameSpaceVariable.batch_save(ns_id, data["variables"]) namespace["variables"] = data["variables"] return Response(namespace)
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') with_lb = request.GET.get('with_lb', 0) # 过滤有使用权限的命名空间 perm_can_use = request.GET.get('perm_can_use') if perm_can_use == '1': perm_can_use = True else: perm_can_use = False # 获取全部namespace,前台分页 result = paas_cc.get_namespace_list(access_token, project_id, with_lb=with_lb, limit=constants.ALL_LIMIT) if result.get('code') != 0: raise error_codes.APIError.f(result.get('message', '')) results = result["data"]["results"] or [] # 针对k8s集群过滤掉系统和平台命名空间 if request.project.kind == ProjectKind.K8S.value: results = self._ignore_ns_for_k8s(results) # 是否有创建权限 perm = bcs_perm.Namespace(request, project_id, bcs_perm.NO_RES) can_create = perm.can_create(raise_exception=False) # 补充cluster_name字段 cluster_list = get_clusters(access_token, project_id) # 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 # 添加permissions到数据中 results = perm.hook_perms(results, perm_can_use) 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 constants.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") 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) permissions = { 'create': can_create, 'sync_namespace': enabled_sync_namespace(project_id) } return APIResult(results, 'success', permissions=permissions)
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))