def retrieve(self, request, project_id, *args, **kwargs): cluster_id = request.query_params.get("cluster_id") check_cluster_perm(user=request.user, project_id=project_id, cluster_id=cluster_id, request=request) # 获取镜像地址 jfrog_domain = paas_cc.get_jfrog_domain(access_token=self.access_token, project_id=self.project_id, cluster_id=cluster_id) cluster_info = paas_cc.get_cluster(request.user.token.access_token, project_id, cluster_id)["data"] context = dict( cluster_id=cluster_id, cluster_name=cluster_info["name"], jfrog_domain=jfrog_domain, expr="{{ .Values.__BCS__.SYS_JFROG_DOMAIN }}", link=settings.HELM_DOC_TRICKS, ) note = _('''集群: {cluster}({cluster_id})的容器仓库域名为:{dept_domain}, 可在Chart直接引用 {expr} 更加方便, [详细说明]({link})''').format( cluster=context['cluster_name'], cluster_id=context['cluster_id'], dept_domain=context['jfrog_domain'], expr=context['expr'], link=context['link'], ) context["note"] = note return Response(data=context)
def create(self, request, project_id, *args, **kwargs): serializer = ClusterImportSLZ(data=request.data) serializer.is_valid(raise_exception=True) cluster_id = serializer.data["cluster_id"] check_cluster_perm(user=request.user, project_id=project_id, cluster_id=cluster_id, request=request) bcs_client = bcs_utils_client.get_bcs_client( project_id=project_id, cluster_id=cluster_id, access_token=self.access_token) bcs_cluster_info = bcs_client.get_or_register_bcs_cluster() if not bcs_cluster_info["result"]: return Response(data=bcs_cluster_info) bcs_cluster_info = bcs_cluster_info["data"] content = render_bcs_agent_template( token=bcs_cluster_info["token"], bcs_cluster_id=bcs_cluster_info["bcs_cluster_id"], namespace=self.bcs_agent_namespace, access_token=self.access_token, project_id=project_id, cluster_id=cluster_id, ) response = HttpResponse(content=content, content_type='text/plain; charset=UTF-8') response[ 'Content-Disposition'] = 'attachment; filename="bcs-agent-%s.yaml"' % cluster_id return response
def create(self, validated_data): namespace_info = self.get_ns_info_by_id(validated_data["namespace_info"]) check_cluster_perm( user=self.context["request"].user, project_id=namespace_info["project_id"], cluster_id=namespace_info["cluster_id"], request=self.context["request"], ) sys_variables = collect_system_variable( access_token=self.context["request"].user.token.access_token, project_id=namespace_info["project_id"], namespace_id=namespace_info["id"], ) return App.objects.initialize_app( access_token=self.access_token, name=validated_data.get("name"), project_id=self.project_id, cluster_id=namespace_info["cluster_id"], namespace_id=namespace_info["id"], namespace=namespace_info["name"], chart_version=validated_data["chart_version"], answers=validated_data["get_answers"], customs=validated_data["get_customs"], valuefile=validated_data.get("get_valuefile"), creator=self.request_username, updator=self.request_username, sys_variables=sys_variables, valuefile_name=validated_data.get('get_valuefile_name'), cmd_flags=validated_data["cmd_flags"], )
def create(self, validated_data): data = super(AppCreatePreviewDiffWithClusterSLZ, self).create(validated_data) namespace_info = self.get_ns_info_by_id( validated_data["namespace_info"]) check_cluster_perm( user=self.context["request"].user, project_id=namespace_info["project_id"], cluster_id=namespace_info["cluster_id"], request=self.context["request"], ) with save_to_temporary_dir(data["content"]) as tempdir: with make_kubectl_client( project_id=self.project_id, cluster_id=namespace_info["cluster_id"], access_token=self.access_token) as (client, err): if err: raise serializers.ValidationError( "make kubectl client failed, %s", err) args = [ "kubediff", "--kubeconfig", client.kubeconfig, "--json", "--no-error-on-diff", tempdir ] difference = subprocess.check_output(args) difference = json.loads(difference) data.update(difference=difference) return data
def provide(user, config): from backend.helm.app.models import App from backend.utils.client import get_kubectl_config_context if not App.objects.filter(project_id=config.get("project_id"), cluster_id=config.get("cluster_id"), id=config.get("app_id")).exists(): raise PermissionDenied() check_cluster_perm(user, config.get("project_id"), config.get("cluster_id")) # bke_client = get_bke_client( # project_id=config.get("project_id"), # cluster_id=config.get("cluster_id"), # access_token=user.token.access_token # ) # bke_client.active_admin() kubeconfig = get_kubectl_config_context( access_token=user.token.access_token, project_id=config.get("project_id"), cluster_id=config.get("cluster_id"), ) kubeconfig_obj = yaml_load(kubeconfig) kubeconfig_obj["users"][0]["user"]["token"] = settings.BKE_ADMIN_TOKEN config["kubeconfig"] = yaml_dump(kubeconfig_obj) return config
def update(self, request, project_id, app_id, *args, **kwargs): app = self.queryset.get(project_id=project_id, id=app_id) check_cluster_perm(user=request.user, project_id=app.project_id, cluster_id=app.cluster_id, request=request) app.inject_configs = None app.save(update_fields=["inject_configs"]) return Response(data={"code": 0, "message": "ok"})
def update(self, instance, validated_data): check_cluster_perm( user=self.context["request"].user, project_id=instance.project_id, cluster_id=instance.cluster_id, request=self.context["request"], ) # operation record return instance.rollback_app( username=self.request_username, access_token=self.access_token, release_id=validated_data["release"], )
def create(self, validated_data): """ 生成应用的预览数据 """ instance = App.objects.get(id=self.app_id) check_cluster_perm( user=self.context["request"].user, project_id=instance.project_id, cluster_id=instance.cluster_id, request=self.context["request"], ) difference = instance.diff_release(release_id=validated_data["release"]) content, notes = instance.render_app( username=self.context["request"].user.username, access_token=self.access_token ) return { "difference": difference, "content": preview_parse(content, instance.namespace), "notes": notes, }
def create(self, request, project_id, *args, **kwargs): serializer = ClusterKubeConfigSLZ(data=request.data) serializer.is_valid(raise_exception=True) cluster_id = serializer.data["cluster_id"] check_cluster_perm(user=request.user, project_id=project_id, cluster_id=cluster_id, request=request) kubeconfig = bcs_utils_client.get_kubectl_config_context( access_token=self.access_token, project_id=project_id, cluster_id=cluster_id) response = HttpResponse(content=kubeconfig, content_type='text/plain; charset=UTF-8') response[ 'Content-Disposition'] = 'attachment; filename="bcs-%s-kubeconfig.yaml"' % cluster_id return response
def retrieve(self, request, app_id, *args, **kwargs): app = App.objects.get(id=self.app_id) check_cluster_perm(user=request.user, project_id=app.project_id, cluster_id=app.cluster_id, request=request) content = app.release.content # resources = parser.parse(content, app.namespace) with bcs_utils_client.make_kubectl_client( access_token=self.access_token, project_id=app.project_id, cluster_id=app.cluster_id) as (client, err): if err: raise APIException(str(err)) state = collect_resource_state(kube_client=client, namespace=app.namespace, content=content) return Response(state)
def create(self, request, project_id, *args, **kwargs): serializer = ClusterKubeConfigSLZ(data=request.data) serializer.is_valid(raise_exception=True) cluster_id = serializer.data["cluster_id"] check_cluster_perm(user=request.user, project_id=project_id, cluster_id=cluster_id, request=request) # 检查是否有 node, 没有node时,bcs-agent无法启动 nodes_info = paas_cc.get_node_list(self.access_token, project_id, cluster_id) if not nodes_info["data"]["results"]: return Response(data={ "code": 40032, "message": _("集群下没有Node节点,无法启用,请先添加") }) data = helm_init(self.access_token, project_id, cluster_id, self.bcs_agent_namespace) return Response(data=data)
def destroy(self, request, *args, **kwargs): """重载默认的 destroy 方法,用于实现判断是否删除成功""" instance = self.get_object() check_cluster_perm(user=request.user, project_id=instance.project_id, cluster_id=instance.cluster_id, request=request) self.perform_destroy(instance) if App.objects.filter(id=instance.id).exists(): instance = App.objects.get(id=instance.id) data = { "transitioning_result": instance.transitioning_result, "transitioning_message": instance.transitioning_message, } else: data = { "transitioning_result": True, "transitioning_message": "success deleted" } return Response(data)
def retrieve(self, request, project_id, *args, **kwargs): parameter = dict(request.GET.items()) serializer = ClusterKubeConfigSLZ(data=parameter) serializer.is_valid(raise_exception=True) cluster_id = serializer.data["cluster_id"] check_cluster_perm(user=request.user, project_id=project_id, cluster_id=cluster_id, request=request) if settings.HELM_HAS_ABILITY_SUPPLY_CHART_REPO_SERVICE: bcs_client = bcs_utils_client.get_bcs_client( project_id=project_id, cluster_id=cluster_id, access_token=self.access_token) bcs_cluster_info = bcs_client.get_cluster() if bcs_cluster_info is None or not bcs_cluster_info.get( "bcs_cluster_id"): result = { "code": 17602, "message": "cluster does not regist to bcs yet.", "initialized": False } return Response(result) serializer = self.serializer_class({ "public_repos": self.get_or_add_public_repos(project_id), "private_repos": self.get_or_add_private_repos(project_id, request.user), "initialized": True, }) return Response(data=serializer.data)
def retrieve(self, request, app_id, *args, **kwargs): app = App.objects.get(id=self.app_id) project_code_cache_key = "helm_project_cache_key:%s" % self.project_id if project_code_cache_key in cache: resp = cache.get(project_code_cache_key) else: # get_project_name resp = paas_cc.get_project(self.access_token, self.project_id) if resp.get('code') != 0: logger.error( "查询project的信息出错(project_id:{project_id}):{message}".format( project_id=self.project_id, message=resp.get('message'))) return Response({ "code": 500, "message": _("后台接口异常,根据项目ID获取项目英文名失败!") }) cache.set(project_code_cache_key, resp, 60 * 15) project_code = resp["data"]["english_name"] check_cluster_perm(user=request.user, project_id=app.project_id, cluster_id=app.cluster_id, request=request) kubeconfig = bcs_utils_client.get_kubectl_config_context( access_token=self.access_token, project_id=app.project_id, cluster_id=app.cluster_id) # 获取dashboard对应的path bin_path = get_helm_dashboard_path(access_token=self.access_token, project_id=app.project_id, cluster_id=app.cluster_id) base_url = get_base_url(request) try: with tempfile.NamedTemporaryFile("w") as f: f.write(kubeconfig) f.flush() data = collect_resource_status(base_url=base_url, kubeconfig=f.name, app=app, project_code=project_code, bin_path=bin_path) except DashboardExecutionError as e: message = "get helm app status failed, error_no: {error_no}\n{output}".format( error_no=e.error_no, output=e.output) return Response({ "code": 400, "message": message, }) except DashboardError as e: message = "get helm app status failed, dashboard ctl error: {err}".format( err=e) logger.exception(message) return Response({ "code": 400, "message": message, }) except Exception as e: message = "get helm app status failed, {err}".format(err=e) logger.exception(message) return Response({ "codee": 500, "message": message, }) response = { "status": data, "app": { "transitioning_action": app.transitioning_action, "transitioning_on": app.transitioning_on, "transitioning_result": app.transitioning_result, "transitioning_message": app.transitioning_message, }, } return Response(response)
def create(self, validated_data): """ 生成应用的预览数据,这个时候应用没有创建,release也没有创建 """ namespace_info = self.get_ns_info_by_id(validated_data["namespace_info"]) cluster_id = namespace_info["cluster_id"] check_cluster_perm( user=self.context["request"].user, project_id=namespace_info["project_id"], cluster_id=cluster_id, request=self.context["request"], ) # prepare parameters parameters = merge_rancher_answers(validated_data["get_answers"], validated_data["get_customs"]) valuefile = get_valuefile_with_bcs_variable_injected( access_token=self.context["request"].user.token.access_token, project_id=namespace_info["project_id"], namespace_id=namespace_info["id"], valuefile=validated_data["valuefile"], cluster_id=cluster_id, ) # inject bcs info now = datetime.datetime.now() username = self.context["request"].user.username # 组装注入的参数 bcs_inject_data = bcs_helm_utils.BCSInjectData( source_type="helm", creator=username, updator=username, version=validated_data["chart_version"].version, project_id=self.project_id, app_id=self.context["request"].project.cc_app_id, cluster_id=cluster_id, namespace=namespace_info["name"], stdlog_data_id=bcs_helm_utils.get_stdlog_data_id(self.project_id), image_pull_secret=bcs_helm_utils.provide_image_pull_secrets(namespace_info["name"]), ) client = KubeHelmClient(helm_bin=settings.HELM3_BIN) try: extra_params = {"cmd_flags": validated_data["cmd_flags"]} content, notes = client.template_with_ytt_renderer( files=validated_data["chart_version"].files, namespace=namespace_info["name"], name=validated_data.get("name"), parameters=parameters, valuefile=valuefile, cluster_id=cluster_id, bcs_inject_data=bcs_inject_data, **extra_params ) except helm_exceptions.HelmBaseException: # raise ParseError(str(e)) # NOTE: 现阶段为防止出现未测试到的情况,允许出错时,按照先前流程渲染;后续删除 content, notes = _template_with_bcs_renderer( client, validated_data["chart_version"].files, validated_data.get("name"), namespace_info["name"], namespace_info["id"], parameters, valuefile, cluster_id, username, now, validated_data["chart_version"].version, self.access_token, self.project_id, ) return {"content": preview_parse(content, namespace_info["name"]), "notes": notes}
def create(self, validated_data): """ 应用更新时的预览数据,这个时候目标release还没有创建 """ instance = App.objects.get(id=self.app_id) check_cluster_perm( user=self.context["request"].user, project_id=instance.project_id, cluster_id=instance.cluster_id, request=self.context["request"], ) # 标记Chart中的values.yaml是否发生变化,用于提醒用户 chart_version_changed = False # prepare parameters parameters = merge_rancher_answers(validated_data["get_answers"], validated_data["get_customs"]) chart_version_id = validated_data["upgrade_verion"] chart_version_id = int(chart_version_id) if chart_version_id == KEEP_TEMPLATE_UNCHANGED: files = instance.release.chartVersionSnapshot.files else: chart_version_changed = True chart_version = ChartVersion.objects.get(id=chart_version_id) files = chart_version.files valuefile = get_valuefile_with_bcs_variable_injected( access_token=self.context["request"].user.token.access_token, project_id=instance.project_id, namespace_id=instance.namespace_id, valuefile=validated_data["valuefile"], cluster_id=instance.cluster_id, ) now = datetime.datetime.now() username = self.context["request"].user.username # 组装注入的参数 bcs_inject_data = bcs_helm_utils.BCSInjectData( source_type="helm", creator=username, updator=username, version=instance.release.chartVersionSnapshot.version, project_id=self.project_id, app_id=self.context["request"].project.cc_app_id, cluster_id=instance.cluster_id, namespace=instance.namespace, stdlog_data_id=bcs_helm_utils.get_stdlog_data_id(self.project_id), image_pull_secret=bcs_helm_utils.provide_image_pull_secrets(instance.namespace), ) # 默认为使用helm3 client client = KubeHelmClient(helm_bin=settings.HELM3_BIN) try: content, notes = client.template_with_ytt_renderer( files=files, namespace=instance.namespace, name=instance.name, parameters=parameters, valuefile=valuefile, cluster_id=instance.cluster_id, bcs_inject_data=bcs_inject_data, ) except helm_exceptions.HelmBaseException: # raise ParseError(str(e)) # NOTE: 现阶段为防止出现未测试到的情况,允许出错时,按照先前流程渲染;后续删除 content, notes = _template_with_bcs_renderer( client, files, instance.name, instance.namespace, instance.namespace_id, parameters, valuefile, instance.cluster_id, username, now, instance.release.chartVersionSnapshot.version, self.access_token, instance.project_id, ) # compute diff old_content = instance.release.content if not old_content: old_content, _ = instance.render_app( username=self.context["request"].user.username, access_token=self.access_token ) difference = simple_diff(old_content, content, instance.namespace) return { "content": preview_parse(content, instance.namespace), "notes": notes, "difference": difference, "chart_version_changed": chart_version_changed, "old_content": old_content, "new_content": content, }