예제 #1
0
파일: k8s.py 프로젝트: aikjjl/bk-bcs-saas
def create_imagepullsecret(access_token, project_id, project_code, cluster_id,
                           namespace):
    """先和先前逻辑保持一致
    """
    dept_auth = {
        'auths':
        create_dept_account(access_token, project_id, project_code, cluster_id)
    }
    auth_bytes = bytes(json.dumps(dept_auth), 'utf-8')
    secret_config = {
        "apiVersion": "v1",
        "kind": "Secret",
        "metadata": {
            "name": f"{K8S_IMAGE_SECRET_PRFIX}{namespace}",
            "namespace": namespace
        },
        "data": {
            ".dockerconfigjson": base64.b64encode(auth_bytes).decode()
        },
        "type": "kubernetes.io/dockerconfigjson"
    }
    #
    client = K8SClient(access_token, project_id, cluster_id, env=None)
    resp = client.create_secret(namespace, secret_config)
    if (resp.get('code') != ErrorCode.NoError) and ('already exists'
                                                    not in resp.get(
                                                        'message', '')):
        raise error_codes.APIError(
            f'create secret error, {resp.get("message")}')
예제 #2
0
 def rollback_k8sservice(self, ns, cluster_id, spec):
     client = K8SClient(self.access_token,
                        self.project_id, cluster_id, env=None)
     name = spec['metadata']['name']
     result = client.delete_service(ns, name)
     if result.get('code') != 0:
         raise ComponentError(result.get('message', ''))
예제 #3
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
예제 #4
0
def exec_command(access_token: str, project_id: str, cluster_id: str,
                 container_id: str, command: str) -> str:
    """在k8s容器中执行命令
    """
    context = {}
    client = K8SClient(access_token, project_id, cluster_id, None)
    _context = utils.get_k8s_context(client, container_id)
    if not _context:
        raise ValueError(_("container_id不正确或者容器不是运行状态"))

    context.update(_context)

    try:
        bcs_context = utils.get_k8s_cluster_context(client, project_id,
                                                    cluster_id)
    except Exception as error:
        raise ValueError(f'{_("获取集群信息失败, ")}{error}')

    bcs_context = utils.get_k8s_admin_context(client, bcs_context,
                                              WebConsoleMode.INTERNEL.value)
    bcs_context['user_pod_name'] = context['pod_name']
    context.update(bcs_context)
    client = _k8s_client(context)
    result = client.exec_command(command)
    return result
예제 #5
0
    def batch_delete(self, request, project_id, cluster_id):
        """ 批量删除 ServiceMonitor """
        params = self.params_validate(ServiceMonitorBatchDeleteSLZ)
        svc_monitors = params['service_monitors']

        self._validate_namespace_use_perm(
            project_id, cluster_id, [sm['namespace'] for sm in svc_monitors])
        client = K8SClient(request.user.token.access_token,
                           project_id,
                           cluster_id,
                           env=None)
        for m in svc_monitors:
            self._single_service_monitor_operate_handler(
                client.delete_service_monitor, _('删除'), project_id,
                ActivityType.Delete, m['namespace'], m['name'])

        metrics_names = ','.join(
            [f"{sm['namespace']}/{sm['name']}" for sm in svc_monitors])
        message = _('删除 Metrics: {} 成功').format(metrics_names)
        self._activity_log(
            project_id,
            request.user.username,
            metrics_names,
            message,
            ActivityType.Delete,
            ActivityStatus.Succeed,
        )
        return Response({'successes': svc_monitors})
예제 #6
0
    def get_k8s_pod_info(self,
                         request,
                         project_id,
                         cluster_id,
                         ns_name,
                         category_name=None,
                         field=None,
                         pod_name=None):
        client = K8SClient(request.user.token.access_token, project_id,
                           cluster_id, None)
        extra_encode = None
        if category_name:
            extra = {"data.metadata.ownerReferences.name": category_name}
            extra_encode = base64_encode_params(extra)
        field_list = field or [
            "resourceName,createTime", "data.status.podIP",
            "data.status.hostIP", "data.status.phase",
            "data.status.containerStatuses"
        ]
        params = {"namespace": ns_name}
        if pod_name:
            params["name"] = pod_name
        resp = client.get_pod(extra=extra_encode,
                              field=",".join(field_list),
                              params=params)
        if resp.get("code") != 0:
            raise error_codes.APIError.f(resp.get("message") or _("查询出现异常"),
                                         replace=True)

        return resp
예제 #7
0
    def list(self, request, project_id, cluster_id):
        """获取 ServiceMonitor 列表"""
        cluster_map = self._get_cluster_map(project_id)
        namespace_map = self._get_namespace_map(project_id)

        if cluster_id not in cluster_map:
            raise error_codes.APIError(_('集群 ID {} 不合法').format(cluster_id))

        client = K8SClient(request.user.token.access_token,
                           project_id,
                           cluster_id,
                           env=None)
        manifest = client.list_service_monitor()
        service_monitors = self._handle_items(cluster_id, cluster_map,
                                              namespace_map, manifest)

        # 共享集群需要再过滤下属于当前项目的命名空间
        if get_cluster_type(cluster_id) == ClusterType.SHARED:
            project_namespaces = get_shared_cluster_proj_namespaces(
                request.ctx_cluster, request.project.english_name)
            service_monitors = [
                sm for sm in service_monitors
                if sm['namespace'] in project_namespaces
            ]

        for m in service_monitors:
            m['is_system'] = m['namespace'] in constants.SM_NO_PERM_NAMESPACE
            m['iam_ns_id'] = calc_iam_ns_id(m['cluster_id'], m['namespace'])

        return PermsResponse(
            service_monitors,
            resource_request=NamespaceRequest(project_id=project_id,
                                              cluster_id=cluster_id),
        )
예제 #8
0
 def get_k8s_category_info(self, request, project_id, cluster_ns_inst, category):
     """获取分类的上报信息
     {'BCS-K8S-15007': {'K8sDeployment': {'inst_list': ['bellke-test-deploy-1'], 'ns_list': ['abc1']}}}
     """
     ret_data = {}
     for cluster_id, app_info in cluster_ns_inst.items():
         client = K8SClient(request.user.token.access_token, project_id, cluster_id, None)
         curr_func = FUNC_MAP[category] % 'get'
         resp = getattr(client, curr_func)({'field': ','.join(app_constants.RESOURCE_STATUS_FIELD_LIST)})
         if resp.get('code') != ErrorCode.NoError:
             raise error_codes.APIError.f(resp.get('message'))
         data = resp.get('data') or []
         # TODO: 关于状态匹配可以再根据实际情况进行调整
         for info in data:
             curr_app_id = f'{info["namespace"]}:{info["resourceName"]}'
             if curr_app_id not in app_info:
                 continue
             spec = (info.get('data') or {}).get('spec') or {}
             # 针对不同的模板获取不同的值
             replicas, available = utils.get_k8s_desired_ready_instance_count(info, category)
             curr_key = (cluster_id, info['namespace'], info['resourceName'])
             ret_data[curr_key] = {
                 'pod_count': f'{available}/{replicas}',
                 'build_instance': available,
                 'instance': replicas,
                 'status': utils.get_k8s_resource_status(category, info, replicas, available),
             }
             if spec.get('paused'):
                 ret_data[curr_key]['status'] = 'Paused'
     return ret_data
예제 #9
0
    def update_deployment(self,
                          request,
                          project_id,
                          cluster_id,
                          ns,
                          data,
                          kind=2,
                          category=None,
                          app_name=None):
        """滚动升级
        """
        if kind == 2:
            client = MesosClient(request.user.token.access_token, project_id,
                                 cluster_id, None)
            resp = client.update_deployment(ns, data)
        else:
            client = K8SClient(request.user.token.access_token, project_id,
                               cluster_id, None)
            curr_func = getattr(client, FUNC_MAP[category] % "update")
            resp = curr_func(ns, app_name, data)

        if resp.get("code") != ErrorCode.NoError:
            return APIResponse({
                "code": resp.get("code", DEFAULT_ERROR_CODE),
                "message": resp.get("message", _("请求出现异常!"))
            })
        return APIResponse({"message": _("更新成功!")})
예제 #10
0
    def rescheduler_taskgroup(self,
                              request,
                              project_id,
                              cluster_id,
                              ns,
                              instance_name,
                              taskgroup_name,
                              kind=2):
        """重启更新
        """
        if kind == 2:
            client = MesosClient(request.user.token.access_token, project_id,
                                 cluster_id, None)
            resp = client.rescheduler_mesos_taskgroup(ns, instance_name,
                                                      taskgroup_name)
        else:
            client = K8SClient(request.user.token.access_token, project_id,
                               cluster_id, None)
            resp = client.delete_pod(ns, taskgroup_name)

        if resp.get("code") != ErrorCode.NoError:
            return APIResponse({
                "code": resp.get("code", DEFAULT_ERROR_CODE),
                "message": resp.get("message", _("请求出现异常!"))
            })
        return APIResponse({"message": _("重新调度成功!")})
예제 #11
0
 def get_k8s_rs_info(self, request, project_id, cluster_id, ns_name, resource_name):
     """获取k8s deployment副本信息
     """
     ret_data = {}
     client = K8SClient(
         request.user.token.access_token,
         project_id, cluster_id, None
     )
     extra = {"data.metadata.ownerReferences.name": resource_name}
     extra_encode = base64_encode_params(extra)
     resp = client.get_rs({
         "extra": extra_encode,
         "namespace": ns_name,
         "field": "resourceName"
     })
     if resp.get("code") != 0:
         raise error_codes.APIError.f(
             resp.get("message") or _("查询出现异常"),
             replace=True
         )
     data = resp.get("data") or []
     if not data:
         return ret_data
     all_name = [info["resourceName"] for info in data if info.get("resourceName")]
     return all_name
예제 #12
0
    def update_instance(self,
                        request,
                        project_id,
                        cluster_id,
                        ns,
                        instance_num,
                        conf,
                        kind=2,
                        category=None,
                        name=None):  # noqa
        if kind == 2:
            client = MesosClient(request.user.token.access_token, project_id,
                                 cluster_id, None)
            resp = client.update_mesos_app_instance(ns, instance_num, conf)
        else:
            client = K8SClient(request.user.token.access_token, project_id,
                               cluster_id, None)
            curr_func = getattr(client, FUNC_MAP[category] % "update")
            resp = curr_func(ns, name, conf)

        if resp.get("code") != ErrorCode.NoError:
            return False, APIResponse({
                "code":
                resp.get("code", DEFAULT_ERROR_CODE),
                "message":
                resp.get("message", _("请求出现异常!"))
            })
        return True, APIResponse({"message": _("更新成功!")})
예제 #13
0
파일: k8s.py 프로젝트: douit/bk-bcs-saas
 def rollback_k8sdeployment(self, ns, cluster_id, spec):
     client = K8SClient(self.access_token,
                        self.project_id,
                        cluster_id,
                        env=None)
     deployment_name = spec['metadata']['name']
     client.deep_delete_deployment(ns, deployment_name)
예제 #14
0
 def create_node_label_via_bcs(self, request, project_id, cluster_id, node_id_labels={}):
     """调用BCS服务创建节点标签
     """
     client = K8SClient(
         request.user.token.access_token, project_id, cluster_id, None)
     node_list = paas_cc.get_node_list(
         request.user.token.access_token, project_id, cluster_id)
     if node_list.get("code") != 0:
         raise error_codes.APIError(_("查询节点失败,请联系管理员处理!"))
     results = node_list.get("data", {}).get("results", [])
     if not results:
         raise error_codes.APIError(_("当前集群下没有节点信息!"))
     # compose id: ip
     node_id_ip = {
         info["id"]: info["inner_ip"]
         for info in results
         if str(info["id"]) in node_id_labels.keys()
     }
     for node_id, ip in node_id_ip.items():
         k8s_resp = client.get_node_detail(ip)
         if k8s_resp.get("code") != 0:
             raise error_codes.APIError.f(k8s_resp.get("message"), replace=True)
         exist_metadata = (k8s_resp.get("data") or {}).get("metadata") or {}
         exist_labels = exist_metadata.get("labels") or {}
         if node_id_labels[str(node_id)] == "del":
             exist_labels.pop("nodetype", None)
         else:
             exist_labels.update(K8S_LB_LABEL)
         exist_labels["$patch"] = "replace"
         resp = client.create_node_labels(ip, exist_labels)
         if resp.get("code") != 0:
             raise error_codes.APIError(_("节点打标签异常,请联系管理员处理!"))
예제 #15
0
파일: k8s.py 프로젝트: douit/bk-bcs-saas
 def rollback_k8sstatefulset(self, ns, cluster_id, spec):
     client = K8SClient(self.access_token,
                        self.project_id,
                        cluster_id,
                        env=None)
     name = spec['metadata']['name']
     client.deep_delete_statefulset(ns, name)
예제 #16
0
 def handler_k8sconfigmap(self, ns, cluster_id, spec):
     client = K8SClient(self.access_token, self.project_id, cluster_id, env=None)
     result = client.create_configmap(ns, spec)
     if result.get('code') != 0:
         if result.get('code') == 4001:
             raise ConfigError(_("配置文件格式错误:{}").format(result.get('message')))
         raise ComponentError(_("创建K8sConfigMap失败,{}").format(result.get('message')))
예제 #17
0
    def update(self, request, project_id, cluster_id, namespace, name):
        """ 更新 ServiceMonitor (先删后增) """
        params = self.params_validate(ServiceMonitorUpdateSLZ)
        client = K8SClient(request.user.token.access_token,
                           project_id,
                           cluster_id,
                           env=None)
        result = self._single_service_monitor_operate_handler(
            client.get_service_monitor, _('更新'), project_id,
            ActivityType.Retrieve, namespace, name)
        manifest = self._update_manifest(result, params)

        # 更新会合并 selector,因此先删除, 再创建
        self._single_service_monitor_operate_handler(
            client.delete_service_monitor, _('更新'), project_id,
            ActivityType.Delete, namespace, name)
        result = self._single_service_monitor_operate_handler(
            client.create_service_monitor,
            _('更新'),
            project_id,
            ActivityType.Add,
            namespace,
            name,
            manifest,
            log_success=True,
        )
        return Response(result)
예제 #18
0
 def create_instance(self,
                     request,
                     project_id,
                     cluster_id,
                     ns,
                     data,
                     category="application",
                     kind=2):
     """创建实例
     """
     if kind == 2:
         client = MesosClient(request.user.token.access_token, project_id,
                              cluster_id, None)
         if category == "application":
             resp = client.create_application(ns, data)
         else:
             resp = client.create_deployment(ns, data)
     else:
         client = K8SClient(request.user.token.access_token, project_id,
                            cluster_id, None)
         curr_func = getattr(client, FUNC_MAP[category] % "create")
         resp = curr_func(ns, data)
     if resp.get("code") != ErrorCode.NoError:
         return APIResponse({
             "code": resp.get("code") or DEFAULT_ERROR_CODE,
             "message": resp.get("message")
         })
     return APIResponse({
         "code": resp.get("code", DEFAULT_ERROR_CODE),
         "message": resp.get("message")
     })
예제 #19
0
 def online_app_conf(self, request, project_id, project_kind, cluster_id,
                     name, namespace, category):
     """针对非模板创建的应用,获取线上的配置"""
     conf = {}
     client = K8SClient(request.user.token.access_token, project_id,
                        cluster_id, None)
     curr_func = FUNC_MAP[category] % "get"
     resp = getattr(client, curr_func)({
         "name": name,
         "namespace": namespace
     })
     if resp.get("code") != 0:
         raise error_codes.APIError.f(
             resp.get("message", _("获取应用线上配置异常,请联系管理员处理!")))
     data = resp.get("data") or []
     if not data:
         return {}
     data = data[0]
     # 组装数据
     conf["kind"] = data["resourceType"]
     conf["metadata"] = {}
     conf["spec"] = data["data"]["spec"]
     conf["metadata"]["name"] = data["data"]["metadata"]["name"]
     conf["metadata"]["namespace"] = data["data"]["metadata"]["namespace"]
     conf["metadata"]["labels"] = data["data"]["metadata"]["labels"]
     conf["metadata"]["annotations"] = data["data"]["metadata"][
         "annotations"]
     return conf
예제 #20
0
    def get_k8s_app_deploy_with_post(self,
                                     request,
                                     project_id,
                                     cluster_id,
                                     instance_name=None,
                                     category="application",
                                     namespace=None,
                                     field=None):
        """获取k8s下application和deployment状态
        """
        client = K8SClient(request.user.token.access_token, project_id,
                           cluster_id, None)
        curr_func = getattr(client,
                            "%s_with_post" % (FUNC_MAP[category] % "get"))
        params = {
            "name": instance_name,
            "namespace": namespace,
            "field": ",".join(field)
        }
        resp = curr_func(params)
        if resp.get("code") != ErrorCode.NoError:
            return False, APIResponse({
                "code": resp.get("code") or DEFAULT_ERROR_CODE,
                "message": resp.get("message")
            })

        return True, resp
예제 #21
0
def register_default_ns(access_token, username, project_id, project_code,
                        cluster_id):
    """注册默认的命名空间(针对k8s集群)
    1. 创建存储镜像账号的secret
    2. 将 default 命名空间注册到paas_cc 上
    project_code = request.project.english_name
    """
    # 组装创建ns的数据
    data = {'env_type': 'dev', 'name': 'default', 'cluster_id': cluster_id}
    ns_base = NamespaceBase()
    # 1. 创建存储镜像账号的secret
    client = K8SClient(access_token, project_id, data['cluster_id'], env=None)
    ns_base.create_jfrog_secret(client, access_token, project_id, project_code,
                                data)

    # 2. 将 default 命名空间注册到paas_cc 上
    result = paas_cc.create_namespace(access_token, project_id,
                                      data['cluster_id'], data['name'], None,
                                      username, data['env_type'])
    if result.get('code') != 0:
        if 'Duplicate entry' in result.get('message', ''):
            message = _("创建失败,namespace名称已经在其他项目存在")
        else:
            message = result.get('message', '')
        return False, message

    # 注册资源到权限中心
    request = RequestClass(username=username,
                           access_token=access_token,
                           project_code=project_code)
    perm = bcs_perm.Namespace(request, project_id, bcs_perm.NO_RES,
                              data['cluster_id'])
    perm.register(str(result['data']['id']), result['data']['name'])
    return True, _("命名空间[default]注册成功")
예제 #22
0
    def scale_instance(self,
                       request,
                       project_id,
                       cluster_id,
                       ns,
                       app_name,
                       instance_num,
                       kind=2,
                       category=None,
                       data=None):  # noqa
        """扩缩容
        """
        if kind == 2:
            client = MesosClient(request.user.token.access_token, project_id,
                                 cluster_id, None)
            resp = client.scale_mesos_app_instance(ns, app_name, instance_num)
        else:
            client = K8SClient(request.user.token.access_token, project_id,
                               cluster_id, None)
            data["spec"]["replicas"] = int(instance_num)
            curr_func = getattr(client, FUNC_MAP[category] % "update")
            resp = curr_func(ns, app_name, data)

        if resp.get("code") != ErrorCode.NoError:
            return APIResponse({
                "code": resp.get("code", DEFAULT_ERROR_CODE),
                "message": resp.get("message", _("请求出现异常!"))
            })
        return APIResponse({"message": _("更新成功!")})
예제 #23
0
    def get_k8s_context(self, request, project_id, cluster_id):
        """获取k8s的上下文信息"""
        client = K8SClient(request.user.token.access_token, project_id,
                           cluster_id, None)
        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 信息失败").format(
                self.cluster_name, cluster_id)
            # 记录操作日志
            utils.activity_log(project_id, cluster_id, self.cluster_name,
                               request.user.username, False, message)
            # 返回前端消息
            raise error_codes.APIError(
                _("{},请检查 Deployment【kube-system/bcs-agent】是否正常{}").format(
                    message, settings.COMMON_EXCEPTION_MSG))

        if request.GET.get("container_id"):
            bcs_context = self.get_k8s_container_context(
                request, project_id, cluster_id, client, bcs_context)
        else:
            bcs_context = self.get_k8s_cluster_context(request, project_id,
                                                       cluster_id, client,
                                                       bcs_context)

        return bcs_context
예제 #24
0
 def resume_update_deployment(self,
                              request,
                              project_id,
                              cluster_id,
                              ns,
                              deployment_name,
                              kind=2,
                              category=None):
     """重启更新
     """
     if kind == 2:
         client = MesosClient(request.user.token.access_token, project_id,
                              cluster_id, None)
         resp = client.resume_update_deployment(ns, deployment_name)
     else:
         client = K8SClient(request.user.token.access_token, project_id,
                            cluster_id, None)
         curr_func = getattr(client, FUNC_MAP[category] % "patch")
         params = {"spec": {"paused": False}}
         resp = curr_func(ns, deployment_name, params)
     if resp.get("code") != ErrorCode.NoError:
         return APIResponse({
             "code": resp.get("code", DEFAULT_ERROR_CODE),
             "message": resp.get("message", _("请求出现异常!"))
         })
     return APIResponse({"message": _("重启更新成功!")})
예제 #25
0
    def get_k8s_rs_info(self, request, project_id, cluster_id, ns_name,
                        resource_name):
        """获取k8s deployment副本信息"""
        ret_data = {}
        client = K8SClient(request.user.token.access_token, project_id,
                           cluster_id, None)
        extra = {"data.metadata.ownerReferences.name": resource_name}
        extra_encode = base64_encode_params(extra)
        resp = client.get_rs({
            "extra": extra_encode,
            "namespace": ns_name,
            "field": "resourceName,data.status"
        })
        if resp.get("code") != 0:
            raise error_codes.APIError.f(resp.get("message") or _("查询出现异常"),
                                         replace=True)
        data = resp.get("data") or []
        if not data:
            return ret_data
        # NOTE: 因为线上存在revision history,需要忽略掉replica为0的rs
        rs_name_list = [
            info["resourceName"] for info in data if info.get("resourceName")
            and getitems(info, ["data", "status", "replicas"], 0) > 0
        ]

        return rs_name_list
예제 #26
0
    def delete_instance(
        self,
        request,
        project_id,
        cluster_id,
        ns,
        instance_name,
        category="application",
        kind=2,
        inst_id_list=None,
        enforce=0,
    ):
        """删除instance"""
        if kind == 2:
            client = MesosClient(request.user.token.access_token, project_id, cluster_id, None)
            if category == "application":
                resp = client.delete_mesos_app_instance(ns, instance_name, enforce=enforce)
            elif category == "deployment":
                resp = client.delete_deployment(ns, instance_name, enforce=enforce)
            elif category == "secret":
                resp = client.delete_secret(ns, instance_name)
            elif category == "configmap":
                resp = client.delete_configmap(ns, instance_name)
            else:
                resp = client.delete_service(ns, instance_name)
            if inst_id_list:
                delete_instance_task.delay(request.user.token.access_token, inst_id_list, kind)
        else:
            client = K8SClient(request.user.token.access_token, project_id, cluster_id, None)
            # deployment 需要级联删除 res\pod; daemonset/job/statefulset 需要级联删除 pod
            if FUNC_MAP[category] in ['%s_deployment', '%s_daemonset', '%s_job', '%s_statefulset']:
                fun_prefix = 'deep_delete'
            else:
                fun_prefix = 'delete'
            curr_func = getattr(client, FUNC_MAP[category] % fun_prefix)

            resp = curr_func(ns, instance_name)
        # 级联删除,会返回空
        if resp is None:
            # 启动后台任务,轮训任务状态
            if inst_id_list:
                delete_instance_task.delay(request.user.token.access_token, inst_id_list, kind)
            return APIResponse({"code": ErrorCode.NoError, "message": _("删除成功")})

        # response
        msg = resp.get("message")
        # message中有not found或者node does not exist时,认为已经删除成功
        # 状态码为正常或者满足不存在条件时,认为已经删除成功
        if (
            (
                resp.get("code")
                in [ErrorCode.NoError, ErrorCode.MesosDeploymentNotFound, ErrorCode.MesosApplicationNotFound]
            )
            or ("not found" in msg)
            or ("node does not exist" in msg)
        ):
            return APIResponse({"code": ErrorCode.NoError, "message": _("删除成功")})

        return APIResponse({"code": resp.get("code"), "message": msg})
예제 #27
0
 def handler_update_k8sconfigmap(self, ns, cluster_id, spec):
     client = K8SClient(self.access_token, self.project_id, cluster_id, env=None)
     name = spec['metadata']['name']
     result = client.update_configmap(ns, name, spec)
     if result.get('code') != 0:
         if result.get('code') == 4001:
             raise ConfigError(_("配置文件格式错误:{}").format(result.get('message')))
         raise ComponentError(_("更新K8sConfigMap失败,{}").format(result.get('message')))
예제 #28
0
 def handler_update_k8sstatefulset(self, ns, cluster_id, spec):
     client = K8SClient(self.access_token, self.project_id, cluster_id, env=None)
     deployment_name = spec['metadata']['name']
     result = client.update_statefulset(ns, deployment_name, spec)
     if result.get('code') != 0:
         if result.get('code') == 4001:
             raise ConfigError(_("配置文件格式错误:{}").format(result.get('message')))
         raise ComponentError(_("更新K8sStatefulSet失败,{}").format(result.get('message')))
예제 #29
0
    def get_k8s_context(self, request, project_id, cluster_id):
        """获取docker监控信息
        """
        client = K8SClient(request.user.token.access_token, project_id, cluster_id, None)
        slz = K8SWebConsoleSLZ(data=request.query_params, 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 = f"获取集群{self.cluster_name}【{cluster_id}】WebConsole 信息失败"
            # 记录操作日志
            utils.activity_log(project_id, self.cluster_name, request.user.username, False, message)
            # 返回前端消息
            raise error_codes.APIError(
                f"{message},请检查 Deployment【kube-system/bcs-agent】是否正常{settings.COMMON_EXCEPTION_MSG}")

        # kubectl版本区别
        _, version = get_cluster_proper_kubectl(request.user.token.access_token, project_id, cluster_id)
        kubectld_version = get_kubectld_version(version)

        container_id = slz.validated_data.get('container_id')
        if container_id:
            bcs_context['mode'] = k8s.ContainerDirectClient.MODE
            bcs_context['user_pod_name'] = slz.validated_data['pod_name']
            bcs_context.update(slz.validated_data)

        else:
            bcs_context = utils.get_k8s_admin_context(client, bcs_context, settings.WEB_CONSOLE_MODE)

            ctx = {'username': self.request.user.username,
                   'settings': settings,
                   'kubectld_version': kubectld_version,
                   'namespace': constants.NAMESPACE,
                   'pod_spec': utils.get_k8s_pod_spec(client),
                   'username_slug': utils.get_username_slug(self.request.user.username),
                   # 缓存ctx, 清理使用
                   'should_cache_ctx': True}
            ctx.update(bcs_context)
            try:
                pod_life_cycle.ensure_namespace(ctx)
                configmap = pod_life_cycle.ensure_configmap(ctx)
                logger.debug('get configmap %s', configmap)
                pod = pod_life_cycle.ensure_pod(ctx)
                logger.debug('get pod %s', pod)
            except pod_life_cycle.PodLifeError as error:
                logger.error("kubetctl apply error: %s", error)
                utils.activity_log(project_id, self.cluster_name, request.user.username, False, '%s' % error)
                raise error_codes.APIError('%s' % error)
            except Exception as error:
                logger.exception("kubetctl apply error: %s", error)
                utils.activity_log(project_id, self.cluster_name, request.user.username, False, "申请pod资源失败")
                raise error_codes.APIError(f"申请pod资源失败,请稍后再试{settings.COMMON_EXCEPTION_MSG}")

            bcs_context['user_pod_name'] = pod.metadata.name

        return bcs_context
예제 #30
0
 def list(self, request, project_id, cluster_id):
     """ 获取可选 Service 列表"""
     client = K8SClient(request.user.token.access_token,
                        project_id,
                        cluster_id,
                        env=None)
     resp = client.get_service({'env': 'k8s'})
     response_data = self._slim_down_service(resp.get('data') or [])
     return Response(response_data)