Example #1
0
    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)
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
    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
Example #5
0
    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
Example #6
0
    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)
Example #7
0
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
Example #8
0
    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)
Example #9
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')
        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)
Example #10
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))