コード例 #1
0
ファイル: k8s.py プロジェクト: penglongli/bk-bcs
    def retrieve(self, request, project_id, pk):
        details = self.queryset.filter(id=pk,
                                       project_id=project_id,
                                       is_deleted=False).values()
        if not details:
            raise error_codes.ResNotFoundError(_("没有查询到实例信息!"))
        data = details[0]

        access_token = request.user.token.access_token
        cluster_id_name_map = self.get_cluster_id_name_map(
            access_token, project_id)
        data["cluster_name"] = cluster_id_name_map[data["cluster_id"]]["name"]
        ip_info = json.loads(data["ip_info"])
        ip_used_data = convert_ip_used_data(access_token, project_id,
                                            data["cluster_id"], ip_info)
        render_ip_info = [{
            "id": ip,
            "inner_ip": ip,
            "unshared": used
        } for ip, used in ip_used_data.items()]
        data["ip_info"] = json.dumps(render_ip_info)

        # 添加release对应的版本及values内容
        data.update(
            self.get_release_info(project_id,
                                  data["cluster_id"],
                                  namespace_id=data["namespace_id"],
                                  namespace=data["namespace"]))
        return Response(data)
コード例 #2
0
ファイル: views.py プロジェクト: pythonton/bk-bcs-saas
    def sync_namespace(self, request, project_id):
        """同步命名空间
        用来同步线上和本地存储的数据,并进行secret等的处理,保证数据一致
        """
        resp = paas_cc.get_all_clusters(request.user.token.access_token,
                                        project_id,
                                        desire_all_data=1)
        if resp.get('code') != ErrorCode.NoError:
            raise error_codes.APIError(
                f'get cluster error {resp.get("message")}')
        data = resp.get('data') or {}
        results = data.get('results')
        if not results:
            raise error_codes.ResNotFoundError(
                f'not found cluster in project: {project_id}')

        cluster_id_list = [info['cluster_id'] for info in results]
        # 触发后台任务进行同步数据
        sync_ns_task.delay(
            request.user.token.access_token,
            project_id,
            request.project.project_code,
            request.project.kind,
            cluster_id_list,
            request.user.username,
        )
        return response.Response({'code': 0, 'message': 'task is running'})
コード例 #3
0
    def retrieve(self, request, project_id, pk):
        details = self.queryset.filter(id=pk,
                                       project_id=project_id,
                                       is_deleted=False).values()
        if not details:
            raise error_codes.ResNotFoundError(_("没有查询到实例信息!"))
        data = details[0]

        access_token = request.user.token.access_token
        cluster_id_name_map = self.get_cluster_id_name_map(
            access_token, project_id)
        data["cluster_name"] = cluster_id_name_map[data["cluster_id"]]["name"]
        ip_info = json.loads(data["ip_info"])
        nodes_id_ip = self.get_nodes_id_ip(access_token, project_id,
                                           data["cluster_id"])
        render_ip_info = []
        for node_id in ip_info:
            item = {
                "id": node_id,
                "inner_ip": nodes_id_ip[int(node_id)]["inner_ip"],
                "unshared": ip_info[node_id]
            }
            render_ip_info.append(item)
        data["ip_info"] = json.dumps(render_ip_info)

        # 添加release对应的版本及values内容
        data.update(
            self.get_release_info(project_id,
                                  data["cluster_id"],
                                  namespace_id=data["namespace_id"],
                                  namespace=data["namespace"]))
        return Response(data)
コード例 #4
0
ファイル: collector.py プロジェクト: pythonton/bk-bcs-saas
    def get_metric_info(self, project_id, metric_id):
        """获取metric信息"""
        resource = MetricModel.objects.filter(project_id=project_id, pk=metric_id).first()
        if not resource:
            raise error_codes.ResNotFoundError(_('metric 不存在'))

        return resource
コード例 #5
0
    def put(self, request, project_id, metric_id):
        """更新put"""
        serializer = serializers.UpdateMetricSLZ(data=request.data,
                                                 context={
                                                     'request': request,
                                                     'project_id': project_id
                                                 })
        serializer.is_valid(raise_exception=True)

        queryset = MetricModel.objects.filter(project_id=project_id,
                                              pk=metric_id)
        ref = queryset.first()
        if not ref:
            raise error_codes.ResNotFoundError(_('metric不存在'))

        # metric_type 不可变,创建是已经申请了dataid,编辑时不能编辑dataid的属性
        if ref.metric_type != serializer.data.get('metric_type', ''):
            raise error_codes.APIError(_('Metric 类型不可更改'))

        # 校验权限
        perm = bcs_perm.Metric(request, project_id, metric_id, ref.name)
        perm.can_edit(raise_exception=True)

        # 更新version
        queryset.update(updator=request.user.username,
                        version=ref.update_version(),
                        **serializer.data)

        # 异步下发metric
        tasks.set_metric.delay(request.user.token.access_token, project_id,
                               request.project['kind'], metric_id)

        return BKAPIResponse({}, message=_('修改metric成功'))
コード例 #6
0
    def sync_namespace(self, request, project_id):
        """同步命名空间
        用来同步线上和本地存储的数据,并进行secret等的处理,保证数据一致
        """
        resp = paas_cc.get_all_clusters(request.user.token.access_token,
                                        project_id,
                                        desire_all_data=1)
        if resp.get('code') != ErrorCode.NoError:
            raise error_codes.APIError(
                f'get cluster error {resp.get("message")}')
        data = resp.get('data') or {}
        results = data.get('results')
        if not results:
            raise error_codes.ResNotFoundError(
                f'not found cluster in project: {project_id}')

        # 共享集群的命名空间只能通过产品创建,不允许同步
        cluster_id_list = [
            info['cluster_id'] for info in results
            if get_cluster_type(info['cluster_id']) != ClusterType.SHARED
        ]
        # 触发后台任务进行同步数据
        sync_ns_task.delay(
            request.user.token.access_token,
            project_id,
            request.project.project_code,
            request.project.kind,
            cluster_id_list,
            request.user.username,
        )
        request.audit_ctx.update_fields(description=_("同步项目下所有集群的命名空间"))
        return response.Response({'code': 0, 'message': 'task is running'})
コード例 #7
0
ファイル: models.py プロジェクト: mayouzi/bk-bcs-saas
    def update(self, id, data):
        queryset = self.filter(id=id)
        if not queryset:
            raise error_codes.ResNotFoundError()
        # 不允许变动的信息
        for key in ['cluster_id', 'region', 'clb_name', 'vpc_id']:
            data.pop(key, '')

        data['config'] = json.dumps({
            'network_type':
            data.pop('network_type'),
            'clb_type':
            data.pop('clb_type'),
            'svc_discovery_type':
            data.pop('svc_discovery_type'),
            'clb_project_id':
            data.pop('clb_project_id'),
            'metric_port':
            data.pop('metric_port'),
            'implement_type':
            data.pop('implement_type'),
            'backend_type':
            data.pop('backend_type'),
        })
        return queryset.update(**data)
コード例 #8
0
    def update(self, request, project_id, pk):
        """
        更新LB配置,包含下面几种场景
        1. 增加/减少LB协议类型
        2. 增加/减少节点数量(标签+replica)
        """
        serializer = UpdateK8SLoadBalancerSLZ(data=request.data)
        serializer.is_valid(raise_exception=True)
        data = serializer.data

        username = request.user.username
        data.update({"id": pk, "updator": username})
        lb_conf, delete_node_id_list, add_node_id_list = self.get_update_node_info(
            request, data)

        # 判断调整的节点是否已经存在,并且是独享的
        # self.update_check_node_id(lb_conf, data)

        # 删除节点配置
        if delete_node_id_list:
            self.delete_node_label(request, delete_node_id_list, project_id,
                                   lb_conf)
        # 添加节点配置
        if add_node_id_list:
            self.add_node_label(request, add_node_id_list, project_id, lb_conf)

        # 更新lb
        self.update_lb_conf(lb_conf, data["ip_info"], data["protocol_type"],
                            username)
        release = self.get_helm_release(lb_conf.cluster_id,
                                        lb_conf.name,
                                        namespace_id=lb_conf.namespace_id)
        if not release:
            raise error_codes.ResNotFoundError(_("没有查询到对应的release信息"))

        data["namespace_id"] = lb_conf.namespace_id
        user_log = log_client.ContextActivityLogClient(
            project_id=project_id,
            user=request.user.username,
            resource_type='lb',
            resource="%s:%s" % (lb_conf.cluster_id, lb_conf.namespace_id),
            resource_id=pk,
            extra=json.dumps(data))
        # release 对应的版本为"(current-unchanged) v1.1.2"
        version = data["version"].split(
            constants.RELEASE_VERSION_PREFIX)[-1].strip()
        chart_version = self.get_chart_version(project_id, version)
        updated_instance = release.upgrade_app(
            access_token=request.user.token.access_token,
            chart_version_id=chart_version.id,
            answers=[],
            customs=[],
            valuefile=data["values_content"],
            updator=username)
        if updated_instance.transitioning_result:
            user_log.log_modify(activity_status="succeed")
            return Response()
        user_log.log_modify(activity_status="failed")
        raise error_codes.APIError(updated_instance.transitioning_message)
コード例 #9
0
ファイル: views.py プロジェクト: penglongli/bk-bcs
 def sync_repo(self, request, project_id_or_code):
     project_id = request.project.project_id
     repos = Repository.objects.filter(project_id=project_id)
     # 同步项目仓库
     for info in repos:
         if info.name != 'public-repo':
             return self.create(request, project_id, info.id)
     # 查询不到项目仓库时,返回异常提示
     return error_codes.ResNotFoundError(_("没有查询到项目仓库"))
コード例 #10
0
ファイル: cluster.py プロジェクト: pythonton/bk-bcs-saas
 def get_params_for_reupgrade(self, project_id, cluster_id):
     """获取重新升级的参数
     通过升级时记录的参数中直接拿取请求参数
     """
     log = ClusterInstallLog.objects.filter(
         oper_type=ClusterOperType.ClusterUpgrade, project_id=project_id, cluster_id=cluster_id
     ).last()
     if not log:
         raise error_codes.ResNotFoundError(_("没有查询到集群的升级记录"))
     return log.log_params
コード例 #11
0
    def list_custom_objects(self, request, project_id, cluster_id, crd_name):
        cluster_auth = ClusterAuth(request.user.token.access_token, project_id, cluster_id)
        crd_client = CustomResourceDefinition(cluster_auth)
        crd = crd_client.get(name=crd_name, is_format=False)
        if not crd:
            raise error_codes.ResNotFoundError(_("集群({})中未注册自定义资源({})").format(cluster_id, crd_name))

        cobj_client = get_cobj_client_by_crd(cluster_auth, crd_name)
        cobj_list = cobj_client.list(namespace=request.query_params.get("namespace"))
        return Response(to_table_format(crd.to_dict(), cobj_list, cluster_id=cluster_id))
コード例 #12
0
def get_cobj_client_by_crd(ctx_cluster: CtxCluster,
                           crd_name: str) -> CustomObject:
    crd_client = CustomResourceDefinition(ctx_cluster)
    crd = crd_client.get(name=crd_name, is_format=False)
    if crd:
        return CustomObject(ctx_cluster,
                            kind=crd.spec.names.kind,
                            api_version=_get_cobj_api_version(crd))
    raise error_codes.ResNotFoundError(
        _("集群({})中未注册自定义资源({})").format(ctx_cluster.id, crd_name))
コード例 #13
0
ファイル: k8s.py プロジェクト: piglei/bk-bcs-saas
 def get_chart_version(self, project_id, version):
     try:
         chart_version = ChartVersion.objects.get(
             name=K8S_LB_CHART_NAME,
             chart__repository__project_id=project_id,
             version=version,
             chart__repository__name="public-repo",
         )
     except ChartVersion.DoesNotExist:
         raise error_codes.ResNotFoundError(_("没有查询到chart版本: {}").format(version))
     return chart_version
コード例 #14
0
ファイル: collector.py プロジェクト: yasuolumia/bk-bcs-saas
    def get_instance(self, request, project_id, metric_id):
        """查询Metric实例化的详细信息
        """
        ref = MetricModel.objects.filter(project_id=project_id,
                                         pk=metric_id).first()
        if not ref:
            raise error_codes.ResNotFoundError(_('metric不存在'))

        metric_name = ref.name

        # 查询项目下的所有集群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 []

        cluster_dict = {}
        for _n in cluster_list:
            _env = _n['environment']
            if _env in cluster_dict:
                cluster_dict[_env].append(_n['cluster_id'])
            else:
                cluster_dict[_env] = [_n['cluster_id']]

        # 查询项目下的命名空间列表
        access_token = request.user.token.access_token
        result = paas_cc.get_namespace_list(access_token,
                                            project_id,
                                            with_lb=0,
                                            limit=ALL_LIMIT)
        ns_list = result.get('data', {}).get('results') or []
        ns_dict = {}
        for _n in ns_list:
            ns_dict[_n['name']] = _n['id']

        if request.project.kind == ProjectKind.MESOS.value:
            # mesos
            category_list = ['application', 'deployment']
        else:
            category_list = POD_RES_LIST

        instance_info = InstanceConfig.objects.filter(
            is_deleted=False, category__in=category_list).exclude(
                ins_state=InsState.NO_INS.value)

        data = []
        # 根据集群的环境不同调用不同环境的storageAPI
        for env, cluster_id_list in cluster_dict.items():
            metric_instance_list = get_metric_instances(
                access_token, project_id, metric_name, env, cluster_id_list,
                ns_dict, instance_info)
            data.extend(metric_instance_list)

        return Response(data)
コード例 #15
0
 def __init__(self, request, project_id, resource_id, resource_type=None):
     super(Cluster, self).__init__(request, project_id, resource_id)
     if resource_id != NO_RES:
         cluster = paas_cc.get_cluster(self.access_token, self.project_id, resource_id)
         if cluster.get('code') != 0:
             raise error_codes.ResNotFoundError(cluster.get('message', ''))
         # 通过接口判断资源类型
         self.res = cluster['data']
         self.resource_name = cluster['data']['name']
     else:
         self.res = None
コード例 #16
0
ファイル: collector.py プロジェクト: pythonton/bk-bcs-saas
    def get(self, request, project_id, metric_id):
        """获取metric"""
        ref = MetricModel.objects.filter(project_id=project_id, pk=metric_id).first()
        if not ref:
            raise error_codes.ResNotFoundError(_('metric不存在'))

        # 校验权限
        perm = bcs_perm.Metric(request, project_id, metric_id, ref.name)
        perm.can_use(raise_exception=True)

        return BKAPIResponse(ref.to_json(), message=_('获取metric成功'))
コード例 #17
0
ファイル: utils.py プロジェクト: zzdx713/bk-bcs-saas
def get_namespace_id(access_token, project_id, cluster_ns_name, cluster_id=None):
    if cluster_id:
        namespace_list = get_cluster_namespaces(access_token, project_id, cluster_id)
    else:
        namespace_list = get_project_namespaces(access_token, project_id)
    for ns_info in namespace_list:
        cluster_ns_name_item = (ns_info['cluster_id'], ns_info['name'])
        if cluster_ns_name == cluster_ns_name_item:
            return ns_info['id']

    raise error_codes.ResNotFoundError(f'not found namespace: {cluster_ns_name}')
コード例 #18
0
ファイル: views.py プロジェクト: penglongli/bk-bcs
 def retrieve(self, request):
     """获取共享chart仓库的信息"""
     # 因为每个项目下都关联公共仓库,而公共仓库最先存在,因此,取第一个记录
     repo = Repository.objects.filter(
         name=PUBLIC_REPO_NAME).order_by("id").first()
     if not repo:
         raise error_codes.ResNotFoundError(
             _("公共仓库: {}不存在").format(PUBLIC_REPO_NAME))
     # 获取仓库的用户名和密码
     username, password = repo.username_password
     return Response({
         "url": repo.url,
         "username": username,
         "password": password
     })
コード例 #19
0
ファイル: namespace.py プロジェクト: penglongli/bk-bcs
    def update(self, request, project_id_or_code, cluster_id, ns_name):
        if ns_name in BCS_RESERVED_NAMESPACES:
            raise error_codes.ValidateError('不允许更新 BCS 保留的命名空间')
        # 更新操作审计信息
        request.audit_ctx.update_fields(resource_type=ResourceType.Namespace, resource=ns_name)

        params = self.params_validate(UpdateNamespaceSLZ)
        ns_client = Namespace(request.ctx_cluster)
        namespace = ns_client.get(ns_name, is_format=False)
        if not namespace:
            raise error_codes.ResNotFoundError('集群 {} 中不存在命名空间 {}'.format(cluster_id, ns_name))

        manifest = namespace.data.to_dict()
        for key in ['labels', 'annotations']:
            manifest['metadata'][key] = params[key]
        ns_client.replace(name=ns_name, body=manifest)
        return Response(manifest)
コード例 #20
0
ファイル: views.py プロジェクト: penglongli/bk-bcs
 def retrieve(self, request, project_id_or_code):
     """获取项目下chart仓库的信息"""
     # project code 为仓库的名称
     repo_name = request.project.project_code
     # NOTE: 现在一个项目仅有一个私有仓库
     try:
         repo = Repository.objects.get(
             name=repo_name, project_id=request.project.project_id)
     except Repository.DoesNotExist:
         raise error_codes.ResNotFoundError(
             _("仓库: {}不存在").format(repo_name))
     # 获取仓库的用户名和密码
     username, password = repo.username_password
     return Response({
         "url": repo.url,
         "username": username,
         "password": password
     })
コード例 #21
0
def scale_instance_resource(username: str, inst_data: InstanceData,
                            ctx_cluster: CtxCluster,
                            show_version: Optional[ShowVersion]):
    # 针对没有版本控制或者通过非模板集创建的资源进行操作
    if not show_version:
        inst_controller = InstanceController(ctx_cluster, inst_data)
        inst_controller.scale_resource()
        return
    # 通过版本获取资源配置
    ns_id = get_namespace_id(ctx_cluster, inst_data.namespace)
    if not ns_id:
        raise error_codes.ResNotFoundError(
            _("集群:{}下命名空间:{}不存在").format(ctx_cluster.id, inst_data.namespace))
    instance = get_instance(ns_id, inst_data.name, inst_data.kind)
    if not instance:
        raise error_codes.RecordNotFound(
            _("资源{kind}:{ns_id}:{name}不存在").format(kind=inst_data.kind,
                                                   ns_id=ns_id,
                                                   name=inst_data.name))
    render_data = VersionInstanceData(
        instance_id=instance.id,
        name=inst_data.name,
        username=username,
        templateset_id=show_version.template_id,
        namespace_id=ns_id,
        version_id=show_version.real_version_id,
        show_version_id=show_version.id,
        kind=inst_data.kind,
        variables=inst_data.variables,
    )
    inst_data.manifest = generate_manifest(ctx_cluster, render_data)
    inst_controller = InstanceController(ctx_cluster, inst_data)
    inst_controller.scale_resource()
    # 更新db中记录
    VersionInstance.objects.update_versions(
        instance_id=instance.instance_id,
        show_version_name=show_version.name,
        version_id=show_version.real_version_id,
        show_version_id=show_version.id,
    )
    InstanceConfig.objects.update_vars_and_configs(instance.id,
                                                   inst_data.variables,
                                                   inst_data.manifest)
コード例 #22
0
ファイル: models.py プロジェクト: mayouzi/bk-bcs-saas
 def retrieve(self, id):
     queryset = self.filter(id=id)
     if not queryset:
         raise error_codes.ResNotFoundError()
     return queryset[0]
コード例 #23
0
ファイル: models.py プロジェクト: mayouzi/bk-bcs-saas
 def retrieve_record(self, id):
     queryset = self.filter(id=id)
     if not queryset:
         raise error_codes.ResNotFoundError()
     return self.parse_record(queryset[0])
コード例 #24
0
ファイル: crd.py プロジェクト: nancyjhsueh/bk-bcs-saas
 def get_custom_resource_definition(self, name):
     crds = self.list_custom_resource_definition()
     for crd in crds.items:
         if crd.metadata.name == name:
             return crd
     raise error_codes.ResNotFoundError(f"no crd {name}")
コード例 #25
0
ファイル: namespace.py プロジェクト: penglongli/bk-bcs
 def retrieve(self, request, project_id_or_code, cluster_id, ns_name):
     namespace = Namespace(request.ctx_cluster).get(ns_name, is_format=False)
     if not namespace:
         raise error_codes.ResNotFoundError('集群 {} 中不存在命名空间 {}'.format(cluster_id, ns_name))
     return Response(namespace.data.to_dict())