From 9cfeac0774b523c09e1bd7b06bde27ad376c2de6 Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Mon, 25 May 2026 16:49:52 +0800 Subject: [PATCH 01/18] feat: add cluster name into service config Signed-off-by: YuTang Song <2313186065@qq.com> --- .../aslan/core/common/service/kube/parse.go | 5 +- .../aslan/core/common/service/kube/render.go | 44 ++++++-- .../aslan/core/service/service/environment.go | 101 +++++++++--------- 3 files changed, 93 insertions(+), 57 deletions(-) diff --git a/pkg/microservice/aslan/core/common/service/kube/parse.go b/pkg/microservice/aslan/core/common/service/kube/parse.go index 9c71df0edb..f60b34fb1f 100644 --- a/pkg/microservice/aslan/core/common/service/kube/parse.go +++ b/pkg/microservice/aslan/core/common/service/kube/parse.go @@ -30,6 +30,7 @@ const ( envRegexString = `\$EnvName\$` productRegexString = `\$Product\$` serviceRegexString = `\$Service\$` + clusterRegexString = `\$ClusterName\$` ) var ( @@ -41,13 +42,15 @@ var ( productRegex = regexp.MustCompile(productRegexString) envNameRegex = regexp.MustCompile(envRegexString) serviceRegex = regexp.MustCompile(serviceRegexString) + clusterRegex = regexp.MustCompile(clusterRegexString) ) // ParseSysKeys 渲染系统变量键值 -func ParseSysKeys(namespace, envName, productName, serviceName, ori string) string { +func ParseSysKeys(namespace, envName, productName, serviceName, clusterName, ori string) string { ori = envNameRegex.ReplaceAllLiteralString(ori, strings.ToLower(envName)) ori = namespaceRegex.ReplaceAllLiteralString(ori, strings.ToLower(namespace)) ori = productRegex.ReplaceAllLiteralString(ori, strings.ToLower(productName)) ori = serviceRegex.ReplaceAllLiteralString(ori, strings.ToLower(serviceName)) + ori = clusterRegex.ReplaceAllLiteralString(ori, strings.ToLower(clusterName)) return ori } diff --git a/pkg/microservice/aslan/core/common/service/kube/render.go b/pkg/microservice/aslan/core/common/service/kube/render.go index 939c8dadd0..d65f00bca3 100644 --- a/pkg/microservice/aslan/core/common/service/kube/render.go +++ b/pkg/microservice/aslan/core/common/service/kube/render.go @@ -412,7 +412,11 @@ func FetchCurrentAppliedYaml(option *GeneSvcYamlOption) (string, int, error) { if err != nil { return "", 0, err } - fullRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, fullRenderedYaml) + clusterName, err := getClusterNameByID(productInfo.ClusterID) + if err != nil { + return "", 0, err + } + fullRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, clusterName, fullRenderedYaml) mergedContainers := mergeContainers(prodSvcTemplate.Containers, curProductSvc.Containers) fullRenderedYaml, _, err = ReplaceWorkloadImages(fullRenderedYaml, mergedContainers) if err != nil { @@ -430,7 +434,11 @@ func FetchImportedAllManifests(envInfo *models.Product, serviceTmp *models.Servi if err != nil { return "", nil, err } - fullRenderedYaml = ParseSysKeys(envInfo.Namespace, envInfo.EnvName, envInfo.ProductName, serviceTmp.ServiceName, fullRenderedYaml) + clusterName, err := getClusterNameByID(envInfo.ClusterID) + if err != nil { + return "", nil, err + } + fullRenderedYaml = ParseSysKeys(envInfo.Namespace, envInfo.EnvName, envInfo.ProductName, serviceTmp.ServiceName, clusterName, fullRenderedYaml) manifests := util.SplitManifestsOrdered(fullRenderedYaml) @@ -686,7 +694,11 @@ func FetchImportedManifests(option *GeneSvcYamlOption, productInfo *models.Produ if err != nil { return "", nil, err } - fullRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, fullRenderedYaml) + clusterName, err := getClusterNameByID(productInfo.ClusterID) + if err != nil { + return "", nil, err + } + fullRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, clusterName, fullRenderedYaml) manifests := releaseutil.SplitManifests(fullRenderedYaml) @@ -831,7 +843,11 @@ func GenerateRenderedYaml(option *GeneSvcYamlOption) (string, int, []*WorkloadRe if renderErr != nil { return "", 0, nil, fmt.Errorf("failed to render current service yaml: %v", renderErr) } - currentRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, currentRenderedYaml) + clusterName, err := getClusterNameByID(productInfo.ClusterID) + if err != nil { + return "", 0, nil, err + } + currentRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, clusterName, currentRenderedYaml) currentBaseReplicaMap, err = ExtractWorkloadReplicas(currentRenderedYaml) if err != nil { return "", 0, nil, fmt.Errorf("failed to extract workload replicas: %v", err) @@ -860,7 +876,11 @@ func GenerateRenderedYaml(option *GeneSvcYamlOption) (string, int, []*WorkloadRe if err != nil { return "", 0, nil, fmt.Errorf("failed to render service yaml: %v", err) } - fullRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, fullRenderedYaml) + clusterName, err := getClusterNameByID(productInfo.ClusterID) + if err != nil { + return "", 0, nil, err + } + fullRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, clusterName, fullRenderedYaml) // service may not be deployed in environment, we need to extract containers again, since image related variables may be changed latestSvcTemplate.KubeYamls = util.SplitYaml(fullRenderedYaml) @@ -981,10 +1001,22 @@ func RenderEnvServiceWithTempl(prod *commonmodels.Product, serviceRender *templa log.Errorf("failed to render service yaml, err: %s", err) return "", err } - parsedYaml = ParseSysKeys(prod.Namespace, prod.EnvName, prod.ProductName, service.ServiceName, parsedYaml) + clusterName, err := getClusterNameByID(prod.ClusterID) + if err != nil { + return "", err + } + parsedYaml = ParseSysKeys(prod.Namespace, prod.EnvName, prod.ProductName, service.ServiceName, clusterName, parsedYaml) parsedYaml, _, err = ReplaceWorkloadImages(parsedYaml, service.Containers) if err != nil { return "", err } return ApplyReplicaOverrides(parsedYaml, service.WorkLoads) } + +func getClusterNameByID(clusterID string) (string, error) { + cluster, err := commonrepo.NewK8SClusterColl().FindByID(clusterID) + if err != nil { + return "", errors.Wrapf(err, "failed to find cluster by id %s", clusterID) + } + return cluster.Name, nil +} diff --git a/pkg/microservice/aslan/core/service/service/environment.go b/pkg/microservice/aslan/core/service/service/environment.go index 576bb3005a..c818f8020c 100644 --- a/pkg/microservice/aslan/core/service/service/environment.go +++ b/pkg/microservice/aslan/core/service/service/environment.go @@ -44,6 +44,7 @@ type DeployableEnv struct { Alias string `json:"alias"` Namespace string `json:"namespace"` ClusterID string `json:"cluster_id"` + ClusterName string `json:"cluster_name"` Services []*types.ServiceWithVariable `json:"services"` GlobalVariableKVs []*commontypes.GlobalVariableKV `json:"global_variable_kvs"` } @@ -84,6 +85,32 @@ func GetDeployableEnvs(svcName, projectName string, production bool) (*Deployabl return resp, nil } +func getClusterNameMap() (map[string]string, error) { + clusters, err := commonrepo.NewK8SClusterColl().List(&commonrepo.ClusterListOpts{}) + if err != nil { + return nil, err + } + + clusterNameMap := make(map[string]string, len(clusters)) + for _, cluster := range clusters { + clusterNameMap[cluster.ID.Hex()] = cluster.Name + } + + return clusterNameMap, nil +} + +func newDeployableEnv(templateProduct *template.Product, env *commonmodels.Product, clusterNameMap map[string]string) *DeployableEnv { + return &DeployableEnv{ + EnvName: env.EnvName, + Alias: env.Alias, + Namespace: env.Namespace, + ClusterID: env.ClusterID, + ClusterName: clusterNameMap[env.ClusterID], + GlobalVariableKVs: env.GlobalVariables, + Services: getServiceVariables(templateProduct, env), + } +} + type GetKubeWorkloadsResp struct { WorkloadsMap map[string][]string `json:"workloads_map"` } @@ -356,20 +383,14 @@ func getAllGeneralEnvs(templateProduct *template.Product, production bool) ([]*D return nil, err } - ret := make([]*DeployableEnv, len(envs)) + clusterNameMap, err := getClusterNameMap() + if err != nil { + return nil, err + } - envNames := make([]string, len(envs)) + ret := make([]*DeployableEnv, len(envs)) for i, env := range envs { - - envNames[i] = env.EnvName - ret[i] = &DeployableEnv{ - EnvName: env.EnvName, - Alias: env.Alias, - Namespace: env.Namespace, - ClusterID: env.ClusterID, - GlobalVariableKVs: env.GlobalVariables, - Services: getServiceVariables(templateProduct, env), - } + ret[i] = newDeployableEnv(templateProduct, env, clusterNameMap) } return ret, nil @@ -388,23 +409,20 @@ func getDeployableShareEnvs(svcName string, templateProduct *template.Product, p return nil, err } + clusterNameMap, err := getClusterNameMap() + if err != nil { + return nil, err + } + ret := make([]*DeployableEnv, 0) for _, baseEnv := range baseEnvs { - - ret = append(ret, &DeployableEnv{ - EnvName: baseEnv.EnvName, - Alias: baseEnv.Alias, - Namespace: baseEnv.Namespace, - ClusterID: baseEnv.ClusterID, - GlobalVariableKVs: baseEnv.GlobalVariables, - Services: getServiceVariables(templateProduct, baseEnv), - }) + ret = append(ret, newDeployableEnv(templateProduct, baseEnv, clusterNameMap)) if !hasSvcInEnv(svcName, baseEnv) { continue } - subEnvs, err := getSubEnvs(baseEnv.EnvName, templateProduct) + subEnvs, err := getSubEnvs(baseEnv.EnvName, templateProduct, clusterNameMap) if err != nil { return nil, err } @@ -424,23 +442,20 @@ func getDeployableShareEnvs(svcName string, templateProduct *template.Product, p return nil, err } + clusterNameMap, err := getClusterNameMap() + if err != nil { + return nil, err + } + ret := make([]*DeployableEnv, 0) for _, baseEnv := range baseEnvs { - - ret = append(ret, &DeployableEnv{ - EnvName: baseEnv.EnvName, - Alias: baseEnv.Alias, - Namespace: baseEnv.Namespace, - ClusterID: baseEnv.ClusterID, - GlobalVariableKVs: baseEnv.GlobalVariables, - Services: getServiceVariables(templateProduct, baseEnv), - }) + ret = append(ret, newDeployableEnv(templateProduct, baseEnv, clusterNameMap)) if !hasSvcInEnv(svcName, baseEnv) { continue } - grayEnvs, err := getGrayEnvs(baseEnv.EnvName, baseEnv.ClusterID, templateProduct) + grayEnvs, err := getGrayEnvs(baseEnv.EnvName, baseEnv.ClusterID, templateProduct, clusterNameMap) if err != nil { return nil, err } @@ -452,7 +467,7 @@ func getDeployableShareEnvs(svcName string, templateProduct *template.Product, p } } -func getSubEnvs(baseEnvName string, templateProduct *template.Product) ([]*DeployableEnv, error) { +func getSubEnvs(baseEnvName string, templateProduct *template.Product, clusterNameMap map[string]string) ([]*DeployableEnv, error) { projectName := templateProduct.ProjectName envs, err := commonrepo.NewProductColl().List(&commonrepo.ProductListOptions{ Name: projectName, @@ -467,20 +482,13 @@ func getSubEnvs(baseEnvName string, templateProduct *template.Product) ([]*Deplo ret := make([]*DeployableEnv, len(envs)) for i, env := range envs { - ret[i] = &DeployableEnv{ - EnvName: env.EnvName, - Alias: env.Alias, - Namespace: env.Namespace, - ClusterID: env.ClusterID, - GlobalVariableKVs: env.GlobalVariables, - Services: getServiceVariables(templateProduct, env), - } + ret[i] = newDeployableEnv(templateProduct, env, clusterNameMap) } return ret, nil } -func getGrayEnvs(baseEnvName, clusterID string, templateProduct *template.Product) ([]*DeployableEnv, error) { +func getGrayEnvs(baseEnvName, clusterID string, templateProduct *template.Product, clusterNameMap map[string]string) ([]*DeployableEnv, error) { projectName := templateProduct.ProjectName envs, err := commonutil.FetchGrayEnvs(context.TODO(), projectName, clusterID, baseEnvName) if err != nil { @@ -489,14 +497,7 @@ func getGrayEnvs(baseEnvName, clusterID string, templateProduct *template.Produc ret := make([]*DeployableEnv, len(envs)) for i, env := range envs { - ret[i] = &DeployableEnv{ - EnvName: env.EnvName, - Alias: env.Alias, - Namespace: env.Namespace, - ClusterID: env.ClusterID, - GlobalVariableKVs: env.GlobalVariables, - Services: getServiceVariables(templateProduct, env), - } + ret[i] = newDeployableEnv(templateProduct, env, clusterNameMap) } return ret, nil From 339e0e94da818099bb8250bee034b11905275f3e Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Mon, 25 May 2026 16:51:58 +0800 Subject: [PATCH 02/18] feat: add render for get cluster name Signed-off-by: YuTang Song <2313186065@qq.com> --- pkg/microservice/aslan/core/common/service/kube/render.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/microservice/aslan/core/common/service/kube/render.go b/pkg/microservice/aslan/core/common/service/kube/render.go index d65f00bca3..5bed86b13f 100644 --- a/pkg/microservice/aslan/core/common/service/kube/render.go +++ b/pkg/microservice/aslan/core/common/service/kube/render.go @@ -412,7 +412,8 @@ func FetchCurrentAppliedYaml(option *GeneSvcYamlOption) (string, int, error) { if err != nil { return "", 0, err } - clusterName, err := getClusterNameByID(productInfo.ClusterID) + // render cluster name + clusterName, err := getClusterNameByID(productInfo.ClusterID) if err != nil { return "", 0, err } From 1ee1f3f6544f2fcf19354928cc95402574b226df Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Tue, 26 May 2026 10:43:05 +0800 Subject: [PATCH 03/18] refactor(environment): unify cluster name handling Signed-off-by: YuTang Song <2313186065@qq.com> --- .../aslan/core/common/service/kube/render.go | 46 ++++++++++--------- .../aslan/core/common/service/service.go | 11 ++++- .../core/environment/service/configmap.go | 8 +++- .../core/environment/service/environment.go | 9 +++- .../aslan/core/environment/service/kube.go | 6 ++- .../core/environment/service/replica_sync.go | 9 +++- .../aslan/core/environment/service/service.go | 3 +- 7 files changed, 63 insertions(+), 29 deletions(-) diff --git a/pkg/microservice/aslan/core/common/service/kube/render.go b/pkg/microservice/aslan/core/common/service/kube/render.go index 5bed86b13f..323898b9e9 100644 --- a/pkg/microservice/aslan/core/common/service/kube/render.go +++ b/pkg/microservice/aslan/core/common/service/kube/render.go @@ -385,6 +385,12 @@ func FetchCurrentAppliedYaml(option *GeneSvcYamlOption) (string, int, error) { return "", 0, errors.Wrapf(err, "failed to find product %s", option.ProductName) } + // get cluster name by cluster id + clusterName, err := GetClusterNameByID(productInfo.ClusterID) + if err != nil { + return "", 0, err + } + curProductSvc := productInfo.GetServiceMap()[option.ServiceName] // service not installed, nothing to return @@ -412,11 +418,6 @@ func FetchCurrentAppliedYaml(option *GeneSvcYamlOption) (string, int, error) { if err != nil { return "", 0, err } - // render cluster name - clusterName, err := getClusterNameByID(productInfo.ClusterID) - if err != nil { - return "", 0, err - } fullRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, clusterName, fullRenderedYaml) mergedContainers := mergeContainers(prodSvcTemplate.Containers, curProductSvc.Containers) fullRenderedYaml, _, err = ReplaceWorkloadImages(fullRenderedYaml, mergedContainers) @@ -435,7 +436,8 @@ func FetchImportedAllManifests(envInfo *models.Product, serviceTmp *models.Servi if err != nil { return "", nil, err } - clusterName, err := getClusterNameByID(envInfo.ClusterID) + // get cluster name by cluster id + clusterName, err := GetClusterNameByID(envInfo.ClusterID) if err != nil { return "", nil, err } @@ -695,7 +697,8 @@ func FetchImportedManifests(option *GeneSvcYamlOption, productInfo *models.Produ if err != nil { return "", nil, err } - clusterName, err := getClusterNameByID(productInfo.ClusterID) + // get cluster name by id + clusterName, err := GetClusterNameByID(productInfo.ClusterID) if err != nil { return "", nil, err } @@ -783,6 +786,12 @@ func GenerateRenderedYaml(option *GeneSvcYamlOption) (string, int, []*WorkloadRe return "", 0, nil, errors.Wrapf(err, "failed to find product %s", option.ProductName) } + // get cluster name by id + clusterName, err := GetClusterNameByID(productInfo.ClusterID) + if err != nil { + return "", 0, nil, err + } + curProductSvc := productInfo.GetServiceMap()[option.ServiceName] // nothing to render when trying to uninstall a service which is not deployed @@ -844,10 +853,6 @@ func GenerateRenderedYaml(option *GeneSvcYamlOption) (string, int, []*WorkloadRe if renderErr != nil { return "", 0, nil, fmt.Errorf("failed to render current service yaml: %v", renderErr) } - clusterName, err := getClusterNameByID(productInfo.ClusterID) - if err != nil { - return "", 0, nil, err - } currentRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, clusterName, currentRenderedYaml) currentBaseReplicaMap, err = ExtractWorkloadReplicas(currentRenderedYaml) if err != nil { @@ -877,10 +882,6 @@ func GenerateRenderedYaml(option *GeneSvcYamlOption) (string, int, []*WorkloadRe if err != nil { return "", 0, nil, fmt.Errorf("failed to render service yaml: %v", err) } - clusterName, err := getClusterNameByID(productInfo.ClusterID) - if err != nil { - return "", 0, nil, err - } fullRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, clusterName, fullRenderedYaml) // service may not be deployed in environment, we need to extract containers again, since image related variables may be changed @@ -992,20 +993,21 @@ func RenderEnvService(prod *commonmodels.Product, serviceRender *template.Servic return "", err } - return RenderEnvServiceWithTempl(prod, serviceRender, service, svcTmpl) + // get cluster name by cluster id + clusterName, err := GetClusterNameByID(prod.ClusterID) + if err != nil { + return "", err + } + return RenderEnvServiceWithTempl(prod, serviceRender, service, svcTmpl, clusterName) } -func RenderEnvServiceWithTempl(prod *commonmodels.Product, serviceRender *template.ServiceRender, service *commonmodels.ProductService, svcTmpl *commonmodels.Service) (yaml string, err error) { +func RenderEnvServiceWithTempl(prod *commonmodels.Product, serviceRender *template.ServiceRender, service *commonmodels.ProductService, svcTmpl *commonmodels.Service, clusterName string) (yaml string, err error) { // Note only the keys in TemplateService.ServiceVar can work parsedYaml, err := RenderServiceYaml(svcTmpl.Yaml, prod.ProductName, svcTmpl.ServiceName, serviceRender) if err != nil { log.Errorf("failed to render service yaml, err: %s", err) return "", err } - clusterName, err := getClusterNameByID(prod.ClusterID) - if err != nil { - return "", err - } parsedYaml = ParseSysKeys(prod.Namespace, prod.EnvName, prod.ProductName, service.ServiceName, clusterName, parsedYaml) parsedYaml, _, err = ReplaceWorkloadImages(parsedYaml, service.Containers) if err != nil { @@ -1014,7 +1016,7 @@ func RenderEnvServiceWithTempl(prod *commonmodels.Product, serviceRender *templa return ApplyReplicaOverrides(parsedYaml, service.WorkLoads) } -func getClusterNameByID(clusterID string) (string, error) { +func GetClusterNameByID(clusterID string) (string, error) { cluster, err := commonrepo.NewK8SClusterColl().FindByID(clusterID) if err != nil { return "", errors.Wrapf(err, "failed to find cluster by id %s", clusterID) diff --git a/pkg/microservice/aslan/core/common/service/service.go b/pkg/microservice/aslan/core/common/service/service.go index 207da6640e..acc439bad5 100644 --- a/pkg/microservice/aslan/core/common/service/service.go +++ b/pkg/microservice/aslan/core/common/service/service.go @@ -1361,6 +1361,12 @@ func GetServiceImpl(serviceName string, serviceTmpl *commonmodels.Service, workL err = nil namespace := env.Namespace + // get cluster name by id + clusterName, err := kube.GetClusterNameByID(env.ClusterID) + if err != nil { + log.Errorf("", err) + return nil, err + } switch env.Source { case setting.SourceFromHelm: k8sServices, _ := getter.ListServicesWithCache(nil, inf) @@ -1421,8 +1427,9 @@ func GetServiceImpl(serviceName string, serviceTmpl *commonmodels.Service, workL log.Errorf("failed to render service yaml, err: %s", err) return nil, err } - // 渲染系统变量键值 - parsedYaml = kube.ParseSysKeys(namespace, envName, productName, service.ServiceName, parsedYaml) + + // render system kv value + parsedYaml = kube.ParseSysKeys(namespace, envName, productName, service.ServiceName, clusterName, parsedYaml) manifests := releaseutil.SplitManifests(parsedYaml) for _, item := range manifests { diff --git a/pkg/microservice/aslan/core/environment/service/configmap.go b/pkg/microservice/aslan/core/environment/service/configmap.go index 2db490da57..9a6d60d96a 100644 --- a/pkg/microservice/aslan/core/environment/service/configmap.go +++ b/pkg/microservice/aslan/core/environment/service/configmap.go @@ -204,6 +204,12 @@ func UpdateConfigMap(args *models.CreateUpdateCommonEnvCfgArgs, userName string, return e.ErrUpdateConfigMap.AddErr(err) } + // get clusterName by id + clusterName, err := kube.GetClusterNameByID(product.ClusterID) + if err != nil { + return e.ErrUpdateConfigMap.AddErr(err) + } + namespace := product.Namespace for key, value := range cm.Data { @@ -211,7 +217,7 @@ func UpdateConfigMap(args *models.CreateUpdateCommonEnvCfgArgs, userName string, //for _, kv := range renderSet.KVs { // value = strings.Replace(value, kv.Alias, kv.Value, -1) //} - value = kube.ParseSysKeys(product.Namespace, product.EnvName, product.ProductName, args.ServiceName, value) + value = kube.ParseSysKeys(product.Namespace, product.EnvName, product.ProductName, args.ServiceName, clusterName, value) cm.Data[key] = value } diff --git a/pkg/microservice/aslan/core/environment/service/environment.go b/pkg/microservice/aslan/core/environment/service/environment.go index 850d55640f..a94081b36d 100644 --- a/pkg/microservice/aslan/core/environment/service/environment.go +++ b/pkg/microservice/aslan/core/environment/service/environment.go @@ -4310,6 +4310,13 @@ func EnvSleep(productName, envName string, isEnable, isProduction bool, log *zap log.Error(err) return e.ErrEnvSleep.AddErr(err) } + clusterName, err := kube.GetClusterNameByID(prod.ClusterID) + if err != nil { + wrapErr := fmt.Errorf("failed to get cluster name for cluster %s, err: %v", prod.ClusterID, err) + log.Error(wrapErr) + return e.ErrEnvSleep.AddErr(wrapErr) + } + if prod.Production != isProduction { err = fmt.Errorf("Insufficient permissions: %s/%s, is production %v", productName, envName, prod.Production) log.Error(err) @@ -4404,7 +4411,7 @@ func EnvSleep(productName, envName string, isEnable, isProduction bool, log *zap return e.ErrEnvSleep.AddErr(wrapErr) } - parsedYaml, err := kube.RenderEnvServiceWithTempl(prod, prodSvc.GetServiceRender(), prodSvc, svc) + parsedYaml, err := kube.RenderEnvServiceWithTempl(prod, prodSvc.GetServiceRender(), prodSvc, svc, clusterName) if err != nil { return e.ErrEnvSleep.AddErr(fmt.Errorf("failed to render service %s, err: %s", svc.ServiceName, err)) } diff --git a/pkg/microservice/aslan/core/environment/service/kube.go b/pkg/microservice/aslan/core/environment/service/kube.go index 78d7ffcbaa..1abcf6b424 100644 --- a/pkg/microservice/aslan/core/environment/service/kube.go +++ b/pkg/microservice/aslan/core/environment/service/kube.go @@ -934,6 +934,10 @@ func getWorkloadDetail(ns, resType, name string, kc client.Client, cs *kubernete func GetResourceDeployStatus(productName string, request *K8sDeployStatusCheckRequest, production bool, log *zap.SugaredLogger) ([]*ServiceDeployStatus, error) { clusterID, namespace := request.ClusterID, request.Namespace + clusterName, err := kube.GetClusterNameByID(clusterID) + if err != nil { + return nil, e.ErrGetResourceDeployInfo.AddErr(fmt.Errorf("failed to get cluster name by id: %s, err: %s", clusterID, err)) + } svcSet := sets.NewString() for _, svc := range request.Services { @@ -983,7 +987,7 @@ func GetResourceDeployStatus(productName string, request *K8sDeployStatusCheckRe if err != nil { return nil, e.ErrGetResourceDeployInfo.AddErr(fmt.Errorf("failed to render service yaml, serviceName:%s, err: %w", svc.ServiceName, err)) } - rederedYaml = kube.ParseSysKeys(request.Namespace, request.EnvName, productName, svc.ServiceName, rederedYaml) + rederedYaml = kube.ParseSysKeys(request.Namespace, request.EnvName, productName, svc.ServiceName, clusterName, rederedYaml) manifests := releaseutil.SplitManifests(rederedYaml) resources := make([]*ResourceDeployStatus, 0) diff --git a/pkg/microservice/aslan/core/environment/service/replica_sync.go b/pkg/microservice/aslan/core/environment/service/replica_sync.go index 19c41c3784..a2c87c05d5 100644 --- a/pkg/microservice/aslan/core/environment/service/replica_sync.go +++ b/pkg/microservice/aslan/core/environment/service/replica_sync.go @@ -96,7 +96,14 @@ func renderServiceWithOverrides(prod *commonmodels.Product, service *commonmodel return "", fmt.Errorf("service is nil") } serviceCopy.WorkLoads = cloneWorkLoads(overrides) - return kube.RenderEnvServiceWithTempl(prod, serviceCopy.GetServiceRender(), serviceCopy, tmpl) + + // get clusterName + clusterName, err := kube.GetClusterNameByID(prod.ClusterID) + if err != nil { + return "", fmt.Errorf("failed to get cluster name for cluster %s: %w", prod.ClusterID, err) + } + + return kube.RenderEnvServiceWithTempl(prod, serviceCopy.GetServiceRender(), serviceCopy, tmpl, clusterName) } func serviceReplicaStateChanged(currentSvc, candidateSvc *commonmodels.ProductService) bool { diff --git a/pkg/microservice/aslan/core/environment/service/service.go b/pkg/microservice/aslan/core/environment/service/service.go index 8e40402b14..1e6c4cd849 100644 --- a/pkg/microservice/aslan/core/environment/service/service.go +++ b/pkg/microservice/aslan/core/environment/service/service.go @@ -179,6 +179,7 @@ func GetService(envName, productName, serviceName string, production bool, workL func GetServiceWorkloads(svcTmpl *commonmodels.Service, env *commonmodels.Product, inf informers.SharedInformerFactory, log *zap.SugaredLogger) ([]*commonservice.Workload, error) { ret := make([]*commonservice.Workload, 0) envName, productName, namespace := env.EnvName, env.ProductName, env.Namespace + clusterName, err := kube.GetClusterNameByID(env.ClusterID) svcRender := env.GetSvcRender(svcTmpl.ServiceName) parsedYaml, err := kube.RenderServiceYaml(svcTmpl.Yaml, productName, svcTmpl.ServiceName, svcRender) @@ -186,7 +187,7 @@ func GetServiceWorkloads(svcTmpl *commonmodels.Service, env *commonmodels.Produc log.Errorf("failed to render service yaml, err: %s", err) return nil, err } - parsedYaml = kube.ParseSysKeys(namespace, envName, productName, svcTmpl.ServiceName, parsedYaml) + parsedYaml = kube.ParseSysKeys(namespace, envName, productName, svcTmpl.ServiceName, clusterName, parsedYaml) manifests := releaseutil.SplitManifests(parsedYaml) for _, item := range manifests { From 514e606e162bbfae952c7119c8c9d599f533ec79 Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Mon, 1 Jun 2026 11:45:15 +0800 Subject: [PATCH 04/18] pref: return structure cluster value from db Signed-off-by: YuTang Song <2313186065@qq.com> --- .../aslan/core/common/service/kube/render.go | 31 ++++++++++--------- .../aslan/core/common/service/service.go | 4 +-- .../core/environment/service/configmap.go | 4 +-- .../core/environment/service/environment.go | 6 ++-- .../aslan/core/environment/service/kube.go | 6 ++-- .../core/environment/service/replica_sync.go | 8 ++--- .../aslan/core/environment/service/service.go | 7 +++-- 7 files changed, 35 insertions(+), 31 deletions(-) diff --git a/pkg/microservice/aslan/core/common/service/kube/render.go b/pkg/microservice/aslan/core/common/service/kube/render.go index 323898b9e9..d88287a546 100644 --- a/pkg/microservice/aslan/core/common/service/kube/render.go +++ b/pkg/microservice/aslan/core/common/service/kube/render.go @@ -386,9 +386,10 @@ func FetchCurrentAppliedYaml(option *GeneSvcYamlOption) (string, int, error) { } // get cluster name by cluster id - clusterName, err := GetClusterNameByID(productInfo.ClusterID) + // return structured cluster name + cluster, err := GetCluster(productInfo.ClusterID) if err != nil { - return "", 0, err + return "", 0, errors.Wrapf(err, "failed to get cluster name by cluster id %s", productInfo.ClusterID) } curProductSvc := productInfo.GetServiceMap()[option.ServiceName] @@ -418,7 +419,7 @@ func FetchCurrentAppliedYaml(option *GeneSvcYamlOption) (string, int, error) { if err != nil { return "", 0, err } - fullRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, clusterName, fullRenderedYaml) + fullRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, cluster.Name, fullRenderedYaml) mergedContainers := mergeContainers(prodSvcTemplate.Containers, curProductSvc.Containers) fullRenderedYaml, _, err = ReplaceWorkloadImages(fullRenderedYaml, mergedContainers) if err != nil { @@ -437,11 +438,11 @@ func FetchImportedAllManifests(envInfo *models.Product, serviceTmp *models.Servi return "", nil, err } // get cluster name by cluster id - clusterName, err := GetClusterNameByID(envInfo.ClusterID) + cluster, err := GetCluster(envInfo.ClusterID) if err != nil { return "", nil, err } - fullRenderedYaml = ParseSysKeys(envInfo.Namespace, envInfo.EnvName, envInfo.ProductName, serviceTmp.ServiceName, clusterName, fullRenderedYaml) + fullRenderedYaml = ParseSysKeys(envInfo.Namespace, envInfo.EnvName, envInfo.ProductName, serviceTmp.ServiceName, cluster.Name, fullRenderedYaml) manifests := util.SplitManifestsOrdered(fullRenderedYaml) @@ -698,11 +699,11 @@ func FetchImportedManifests(option *GeneSvcYamlOption, productInfo *models.Produ return "", nil, err } // get cluster name by id - clusterName, err := GetClusterNameByID(productInfo.ClusterID) + cluster, err := GetCluster(productInfo.ClusterID) if err != nil { return "", nil, err } - fullRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, clusterName, fullRenderedYaml) + fullRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, cluster.Name, fullRenderedYaml) manifests := releaseutil.SplitManifests(fullRenderedYaml) @@ -787,7 +788,7 @@ func GenerateRenderedYaml(option *GeneSvcYamlOption) (string, int, []*WorkloadRe } // get cluster name by id - clusterName, err := GetClusterNameByID(productInfo.ClusterID) + cluster, err := GetCluster(productInfo.ClusterID) if err != nil { return "", 0, nil, err } @@ -853,7 +854,7 @@ func GenerateRenderedYaml(option *GeneSvcYamlOption) (string, int, []*WorkloadRe if renderErr != nil { return "", 0, nil, fmt.Errorf("failed to render current service yaml: %v", renderErr) } - currentRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, clusterName, currentRenderedYaml) + currentRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, cluster.Name, currentRenderedYaml) currentBaseReplicaMap, err = ExtractWorkloadReplicas(currentRenderedYaml) if err != nil { return "", 0, nil, fmt.Errorf("failed to extract workload replicas: %v", err) @@ -882,7 +883,7 @@ func GenerateRenderedYaml(option *GeneSvcYamlOption) (string, int, []*WorkloadRe if err != nil { return "", 0, nil, fmt.Errorf("failed to render service yaml: %v", err) } - fullRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, clusterName, fullRenderedYaml) + fullRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, cluster.Name, fullRenderedYaml) // service may not be deployed in environment, we need to extract containers again, since image related variables may be changed latestSvcTemplate.KubeYamls = util.SplitYaml(fullRenderedYaml) @@ -994,11 +995,11 @@ func RenderEnvService(prod *commonmodels.Product, serviceRender *template.Servic } // get cluster name by cluster id - clusterName, err := GetClusterNameByID(prod.ClusterID) + cluster, err := GetCluster(prod.ClusterID) if err != nil { return "", err } - return RenderEnvServiceWithTempl(prod, serviceRender, service, svcTmpl, clusterName) + return RenderEnvServiceWithTempl(prod, serviceRender, service, svcTmpl, cluster.Name) } func RenderEnvServiceWithTempl(prod *commonmodels.Product, serviceRender *template.ServiceRender, service *commonmodels.ProductService, svcTmpl *commonmodels.Service, clusterName string) (yaml string, err error) { @@ -1016,10 +1017,10 @@ func RenderEnvServiceWithTempl(prod *commonmodels.Product, serviceRender *templa return ApplyReplicaOverrides(parsedYaml, service.WorkLoads) } -func GetClusterNameByID(clusterID string) (string, error) { +func GetCluster(clusterID string) (*commonmodels.K8SCluster, error) { cluster, err := commonrepo.NewK8SClusterColl().FindByID(clusterID) if err != nil { - return "", errors.Wrapf(err, "failed to find cluster by id %s", clusterID) + return nil, errors.Wrapf(err, "failed to find cluster by id %s", clusterID) } - return cluster.Name, nil + return cluster, nil } diff --git a/pkg/microservice/aslan/core/common/service/service.go b/pkg/microservice/aslan/core/common/service/service.go index acc439bad5..73e0da3faa 100644 --- a/pkg/microservice/aslan/core/common/service/service.go +++ b/pkg/microservice/aslan/core/common/service/service.go @@ -1362,7 +1362,7 @@ func GetServiceImpl(serviceName string, serviceTmpl *commonmodels.Service, workL namespace := env.Namespace // get cluster name by id - clusterName, err := kube.GetClusterNameByID(env.ClusterID) + cluster, err := kube.GetCluster(env.ClusterID) if err != nil { log.Errorf("", err) return nil, err @@ -1429,7 +1429,7 @@ func GetServiceImpl(serviceName string, serviceTmpl *commonmodels.Service, workL } // render system kv value - parsedYaml = kube.ParseSysKeys(namespace, envName, productName, service.ServiceName, clusterName, parsedYaml) + parsedYaml = kube.ParseSysKeys(namespace, envName, productName, service.ServiceName, cluster.Name, parsedYaml) manifests := releaseutil.SplitManifests(parsedYaml) for _, item := range manifests { diff --git a/pkg/microservice/aslan/core/environment/service/configmap.go b/pkg/microservice/aslan/core/environment/service/configmap.go index 9a6d60d96a..1fd3bc66ba 100644 --- a/pkg/microservice/aslan/core/environment/service/configmap.go +++ b/pkg/microservice/aslan/core/environment/service/configmap.go @@ -205,7 +205,7 @@ func UpdateConfigMap(args *models.CreateUpdateCommonEnvCfgArgs, userName string, } // get clusterName by id - clusterName, err := kube.GetClusterNameByID(product.ClusterID) + cluster, err := kube.GetCluster(product.ClusterID) if err != nil { return e.ErrUpdateConfigMap.AddErr(err) } @@ -217,7 +217,7 @@ func UpdateConfigMap(args *models.CreateUpdateCommonEnvCfgArgs, userName string, //for _, kv := range renderSet.KVs { // value = strings.Replace(value, kv.Alias, kv.Value, -1) //} - value = kube.ParseSysKeys(product.Namespace, product.EnvName, product.ProductName, args.ServiceName, clusterName, value) + value = kube.ParseSysKeys(product.Namespace, product.EnvName, product.ProductName, args.ServiceName, cluster.Name, value) cm.Data[key] = value } diff --git a/pkg/microservice/aslan/core/environment/service/environment.go b/pkg/microservice/aslan/core/environment/service/environment.go index a94081b36d..71749423ae 100644 --- a/pkg/microservice/aslan/core/environment/service/environment.go +++ b/pkg/microservice/aslan/core/environment/service/environment.go @@ -4310,9 +4310,9 @@ func EnvSleep(productName, envName string, isEnable, isProduction bool, log *zap log.Error(err) return e.ErrEnvSleep.AddErr(err) } - clusterName, err := kube.GetClusterNameByID(prod.ClusterID) + cluster, err := kube.GetCluster(prod.ClusterID) if err != nil { - wrapErr := fmt.Errorf("failed to get cluster name for cluster %s, err: %v", prod.ClusterID, err) + wrapErr := fmt.Errorf("failed to get cluster for cluster %s, err: %v", prod.ClusterID, err) log.Error(wrapErr) return e.ErrEnvSleep.AddErr(wrapErr) } @@ -4411,7 +4411,7 @@ func EnvSleep(productName, envName string, isEnable, isProduction bool, log *zap return e.ErrEnvSleep.AddErr(wrapErr) } - parsedYaml, err := kube.RenderEnvServiceWithTempl(prod, prodSvc.GetServiceRender(), prodSvc, svc, clusterName) + parsedYaml, err := kube.RenderEnvServiceWithTempl(prod, prodSvc.GetServiceRender(), prodSvc, svc, cluster.Name) if err != nil { return e.ErrEnvSleep.AddErr(fmt.Errorf("failed to render service %s, err: %s", svc.ServiceName, err)) } diff --git a/pkg/microservice/aslan/core/environment/service/kube.go b/pkg/microservice/aslan/core/environment/service/kube.go index 1abcf6b424..40e208605a 100644 --- a/pkg/microservice/aslan/core/environment/service/kube.go +++ b/pkg/microservice/aslan/core/environment/service/kube.go @@ -934,9 +934,9 @@ func getWorkloadDetail(ns, resType, name string, kc client.Client, cs *kubernete func GetResourceDeployStatus(productName string, request *K8sDeployStatusCheckRequest, production bool, log *zap.SugaredLogger) ([]*ServiceDeployStatus, error) { clusterID, namespace := request.ClusterID, request.Namespace - clusterName, err := kube.GetClusterNameByID(clusterID) + cluster, err := kube.GetCluster(clusterID) if err != nil { - return nil, e.ErrGetResourceDeployInfo.AddErr(fmt.Errorf("failed to get cluster name by id: %s, err: %s", clusterID, err)) + return nil, e.ErrGetResourceDeployInfo.AddErr(fmt.Errorf("failed to get cluster by id: %s, err: %s", clusterID, err)) } svcSet := sets.NewString() @@ -987,7 +987,7 @@ func GetResourceDeployStatus(productName string, request *K8sDeployStatusCheckRe if err != nil { return nil, e.ErrGetResourceDeployInfo.AddErr(fmt.Errorf("failed to render service yaml, serviceName:%s, err: %w", svc.ServiceName, err)) } - rederedYaml = kube.ParseSysKeys(request.Namespace, request.EnvName, productName, svc.ServiceName, clusterName, rederedYaml) + rederedYaml = kube.ParseSysKeys(request.Namespace, request.EnvName, productName, svc.ServiceName, cluster.Name, rederedYaml) manifests := releaseutil.SplitManifests(rederedYaml) resources := make([]*ResourceDeployStatus, 0) diff --git a/pkg/microservice/aslan/core/environment/service/replica_sync.go b/pkg/microservice/aslan/core/environment/service/replica_sync.go index a2c87c05d5..f154de52eb 100644 --- a/pkg/microservice/aslan/core/environment/service/replica_sync.go +++ b/pkg/microservice/aslan/core/environment/service/replica_sync.go @@ -97,13 +97,13 @@ func renderServiceWithOverrides(prod *commonmodels.Product, service *commonmodel } serviceCopy.WorkLoads = cloneWorkLoads(overrides) - // get clusterName - clusterName, err := kube.GetClusterNameByID(prod.ClusterID) + // get cluster + cluster, err := kube.GetCluster(prod.ClusterID) if err != nil { - return "", fmt.Errorf("failed to get cluster name for cluster %s: %w", prod.ClusterID, err) + return "", fmt.Errorf("failed to get cluster for cluster %s: %w", prod.ClusterID, err) } - return kube.RenderEnvServiceWithTempl(prod, serviceCopy.GetServiceRender(), serviceCopy, tmpl, clusterName) + return kube.RenderEnvServiceWithTempl(prod, serviceCopy.GetServiceRender(), serviceCopy, tmpl, cluster.Name) } func serviceReplicaStateChanged(currentSvc, candidateSvc *commonmodels.ProductService) bool { diff --git a/pkg/microservice/aslan/core/environment/service/service.go b/pkg/microservice/aslan/core/environment/service/service.go index 1e6c4cd849..ddba143f78 100644 --- a/pkg/microservice/aslan/core/environment/service/service.go +++ b/pkg/microservice/aslan/core/environment/service/service.go @@ -179,7 +179,10 @@ func GetService(envName, productName, serviceName string, production bool, workL func GetServiceWorkloads(svcTmpl *commonmodels.Service, env *commonmodels.Product, inf informers.SharedInformerFactory, log *zap.SugaredLogger) ([]*commonservice.Workload, error) { ret := make([]*commonservice.Workload, 0) envName, productName, namespace := env.EnvName, env.ProductName, env.Namespace - clusterName, err := kube.GetClusterNameByID(env.ClusterID) + cluster, err := kube.GetCluster(env.ClusterID) + if err != nil { + return nil, e.ErrGetService.AddErr(fmt.Errorf("failed to get cluster for cluster %s: %w", env.ClusterID, err)) + } svcRender := env.GetSvcRender(svcTmpl.ServiceName) parsedYaml, err := kube.RenderServiceYaml(svcTmpl.Yaml, productName, svcTmpl.ServiceName, svcRender) @@ -187,7 +190,7 @@ func GetServiceWorkloads(svcTmpl *commonmodels.Service, env *commonmodels.Produc log.Errorf("failed to render service yaml, err: %s", err) return nil, err } - parsedYaml = kube.ParseSysKeys(namespace, envName, productName, svcTmpl.ServiceName, clusterName, parsedYaml) + parsedYaml = kube.ParseSysKeys(namespace, envName, productName, svcTmpl.ServiceName, cluster.Name, parsedYaml) manifests := releaseutil.SplitManifests(parsedYaml) for _, item := range manifests { From cd185c4de4ed7802db6358f90d5ad2acffcef0f1 Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Mon, 1 Jun 2026 13:30:49 +0800 Subject: [PATCH 05/18] fix: add cluster name service option Signed-off-by: YuTang Song <2313186065@qq.com> --- pkg/microservice/aslan/core/common/service/kube/render.go | 1 - pkg/microservice/aslan/core/service/service/service.go | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/microservice/aslan/core/common/service/kube/render.go b/pkg/microservice/aslan/core/common/service/kube/render.go index d88287a546..b083cd2bbd 100644 --- a/pkg/microservice/aslan/core/common/service/kube/render.go +++ b/pkg/microservice/aslan/core/common/service/kube/render.go @@ -385,7 +385,6 @@ func FetchCurrentAppliedYaml(option *GeneSvcYamlOption) (string, int, error) { return "", 0, errors.Wrapf(err, "failed to find product %s", option.ProductName) } - // get cluster name by cluster id // return structured cluster name cluster, err := GetCluster(productInfo.ClusterID) if err != nil { diff --git a/pkg/microservice/aslan/core/service/service/service.go b/pkg/microservice/aslan/core/service/service/service.go index a0dd57faf3..99894dafe2 100644 --- a/pkg/microservice/aslan/core/service/service/service.go +++ b/pkg/microservice/aslan/core/service/service/service.go @@ -181,6 +181,9 @@ func GetServiceOption(args *commonmodels.Service, log *zap.SugaredLogger) (*Serv { Key: "$EnvName$", Value: ""}, + { + Key: "$ClusterName$", + Value: ""}, } serviceOption.VariableYaml = args.VariableYaml From 0b098235ee3481576955cc38b4b2c0596c68c02c Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Mon, 1 Jun 2026 16:01:51 +0800 Subject: [PATCH 06/18] fix: cant find target cluster from mongodb Signed-off-by: YuTang Song <2313186065@qq.com> --- pkg/microservice/aslan/core/common/service/kube/render.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pkg/microservice/aslan/core/common/service/kube/render.go b/pkg/microservice/aslan/core/common/service/kube/render.go index b083cd2bbd..c05f0175df 100644 --- a/pkg/microservice/aslan/core/common/service/kube/render.go +++ b/pkg/microservice/aslan/core/common/service/kube/render.go @@ -25,6 +25,7 @@ import ( "github.com/koderover/zadig/v2/pkg/types" "github.com/pkg/errors" + "go.mongodb.org/mongo-driver/bson/primitive" appsv1 "k8s.io/api/apps/v1" batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" @@ -1017,7 +1018,12 @@ func RenderEnvServiceWithTempl(prod *commonmodels.Product, serviceRender *templa } func GetCluster(clusterID string) (*commonmodels.K8SCluster, error) { - cluster, err := commonrepo.NewK8SClusterColl().FindByID(clusterID) + clusterObjectID, err := primitive.ObjectIDFromHex(clusterID) + if err != nil { + return nil, errors.Wrapf(err, "cluster id %s is not hex string", clusterID) + } + + cluster, err := commonrepo.NewK8SClusterColl().FindByID(clusterObjectID.Hex()) if err != nil { return nil, errors.Wrapf(err, "failed to find cluster by id %s", clusterID) } From 287ea76af76fe6b6437e431f8f532ad851e59d35 Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Mon, 1 Jun 2026 16:26:08 +0800 Subject: [PATCH 07/18] pref: get target cluster from db Signed-off-by: YuTang Song <2313186065@qq.com> --- .../aslan/core/common/service/kube/render.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/pkg/microservice/aslan/core/common/service/kube/render.go b/pkg/microservice/aslan/core/common/service/kube/render.go index c05f0175df..3c480bc9b0 100644 --- a/pkg/microservice/aslan/core/common/service/kube/render.go +++ b/pkg/microservice/aslan/core/common/service/kube/render.go @@ -1018,12 +1018,19 @@ func RenderEnvServiceWithTempl(prod *commonmodels.Product, serviceRender *templa } func GetCluster(clusterID string) (*commonmodels.K8SCluster, error) { - clusterObjectID, err := primitive.ObjectIDFromHex(clusterID) - if err != nil { - return nil, errors.Wrapf(err, "cluster id %s is not hex string", clusterID) + clusterColl := commonrepo.NewK8SClusterColl() + if clusterID == "" { + clusterID = setting.LocalClusterID + } + if _, err := primitive.ObjectIDFromHex(clusterID); err != nil { + cluster, err := clusterColl.FindByName(clusterID) + if err != nil { + return nil, errors.Wrapf(err, "failed to find cluster by name %s", clusterID) + } + return cluster, nil } - cluster, err := commonrepo.NewK8SClusterColl().FindByID(clusterObjectID.Hex()) + cluster, err := clusterColl.FindByID(clusterID) if err != nil { return nil, errors.Wrapf(err, "failed to find cluster by id %s", clusterID) } From a8e86f518cc3341c19dea655687a1db1b361276a Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Tue, 2 Jun 2026 09:26:37 +0800 Subject: [PATCH 08/18] pref: add log for check the clusterID Signed-off-by: YuTang Song <2313186065@qq.com> --- pkg/microservice/aslan/core/common/service/kube/render.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkg/microservice/aslan/core/common/service/kube/render.go b/pkg/microservice/aslan/core/common/service/kube/render.go index 3c480bc9b0..808e94186c 100644 --- a/pkg/microservice/aslan/core/common/service/kube/render.go +++ b/pkg/microservice/aslan/core/common/service/kube/render.go @@ -1019,20 +1019,28 @@ func RenderEnvServiceWithTempl(prod *commonmodels.Product, serviceRender *templa func GetCluster(clusterID string) (*commonmodels.K8SCluster, error) { clusterColl := commonrepo.NewK8SClusterColl() + log.Infof("GetCluster called with clusterID=%q", clusterID) if clusterID == "" { clusterID = setting.LocalClusterID + log.Infof("GetCluster fallback to local clusterID=%q", clusterID) } if _, err := primitive.ObjectIDFromHex(clusterID); err != nil { + log.Infof("GetCluster clusterID=%q is not a valid object id, fallback to FindByName, err=%v", clusterID, err) cluster, err := clusterColl.FindByName(clusterID) if err != nil { + log.Errorf("GetCluster failed to find cluster by name, clusterID=%q, err=%v", clusterID, err) return nil, errors.Wrapf(err, "failed to find cluster by name %s", clusterID) } + log.Infof("GetCluster found cluster by name, clusterID=%q, clusterName=%q", clusterID, cluster.Name) return cluster, nil } + log.Infof("GetCluster clusterID=%q is a valid object id, querying by id", clusterID) cluster, err := clusterColl.FindByID(clusterID) if err != nil { + log.Errorf("GetCluster failed to find cluster by id, clusterID=%q, err=%v", clusterID, err) return nil, errors.Wrapf(err, "failed to find cluster by id %s", clusterID) } + log.Infof("GetCluster found cluster by id, clusterID=%q, clusterName=%q", clusterID, cluster.Name) return cluster, nil } From 5cab8149dfeeabc53e8ed6310d9ea892ac5cf675 Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Tue, 2 Jun 2026 09:52:19 +0800 Subject: [PATCH 09/18] debug: clusterID is nil Signed-off-by: YuTang Song <2313186065@qq.com> --- .../aslan/core/common/service/kube/render.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/pkg/microservice/aslan/core/common/service/kube/render.go b/pkg/microservice/aslan/core/common/service/kube/render.go index 808e94186c..db96963e87 100644 --- a/pkg/microservice/aslan/core/common/service/kube/render.go +++ b/pkg/microservice/aslan/core/common/service/kube/render.go @@ -25,7 +25,6 @@ import ( "github.com/koderover/zadig/v2/pkg/types" "github.com/pkg/errors" - "go.mongodb.org/mongo-driver/bson/primitive" appsv1 "k8s.io/api/apps/v1" batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" @@ -1024,16 +1023,6 @@ func GetCluster(clusterID string) (*commonmodels.K8SCluster, error) { clusterID = setting.LocalClusterID log.Infof("GetCluster fallback to local clusterID=%q", clusterID) } - if _, err := primitive.ObjectIDFromHex(clusterID); err != nil { - log.Infof("GetCluster clusterID=%q is not a valid object id, fallback to FindByName, err=%v", clusterID, err) - cluster, err := clusterColl.FindByName(clusterID) - if err != nil { - log.Errorf("GetCluster failed to find cluster by name, clusterID=%q, err=%v", clusterID, err) - return nil, errors.Wrapf(err, "failed to find cluster by name %s", clusterID) - } - log.Infof("GetCluster found cluster by name, clusterID=%q, clusterName=%q", clusterID, cluster.Name) - return cluster, nil - } log.Infof("GetCluster clusterID=%q is a valid object id, querying by id", clusterID) cluster, err := clusterColl.FindByID(clusterID) From 9ec5973b669b0ecf0de027a749ac2938e6416386 Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Tue, 2 Jun 2026 10:11:45 +0800 Subject: [PATCH 10/18] debug: add debug log for finding out clusterID Signed-off-by: YuTang Song <2313186065@qq.com> --- pkg/microservice/aslan/core/environment/handler/environment.go | 2 ++ .../aslan/core/environment/service/environment_creation.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/pkg/microservice/aslan/core/environment/handler/environment.go b/pkg/microservice/aslan/core/environment/handler/environment.go index e9db96bd8c..2d3b7e9f48 100644 --- a/pkg/microservice/aslan/core/environment/handler/environment.go +++ b/pkg/microservice/aslan/core/environment/handler/environment.go @@ -302,6 +302,8 @@ func CreateProduct(c *gin.Context) { ctx.RespErr = e.ErrInvalidParam.AddErr(err) return } + // debug + log.Infof("CreateProduct, createArgs: %v", createArgs) if production { err = service.EnsureProductionNamespace(createArgs) diff --git a/pkg/microservice/aslan/core/environment/service/environment_creation.go b/pkg/microservice/aslan/core/environment/service/environment_creation.go index 5f3286a05e..16876e89a1 100644 --- a/pkg/microservice/aslan/core/environment/service/environment_creation.go +++ b/pkg/microservice/aslan/core/environment/service/environment_creation.go @@ -302,6 +302,8 @@ func prepareK8sProductCreation(templateProduct *templatemodels.Product, productO } func createSingleYamlProduct(templateProduct *templatemodels.Product, requestID, userName string, arg *CreateSingleProductArg, log *zap.SugaredLogger) error { + // debug + log.Infof("createSingleYamlProduct, arg: %v", arg) productObj := &commonmodels.Product{ ProductName: templateProduct.ProductName, Revision: templateProduct.Revision, From 5ea6d6c7aa9f88d133196bba9d1dc542722f3191 Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Tue, 2 Jun 2026 10:51:19 +0800 Subject: [PATCH 11/18] fix: cant get correct clusterID Signed-off-by: YuTang Song <2313186065@qq.com> --- .../aslan/core/common/service/kube/render.go | 1 + .../aslan/core/common/service/version.go | 12 ++++++++++++ .../aslan/core/environment/handler/environment.go | 2 -- .../core/environment/service/environment_creation.go | 3 +-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/pkg/microservice/aslan/core/common/service/kube/render.go b/pkg/microservice/aslan/core/common/service/kube/render.go index db96963e87..7b07214d4e 100644 --- a/pkg/microservice/aslan/core/common/service/kube/render.go +++ b/pkg/microservice/aslan/core/common/service/kube/render.go @@ -1016,6 +1016,7 @@ func RenderEnvServiceWithTempl(prod *commonmodels.Product, serviceRender *templa return ApplyReplicaOverrides(parsedYaml, service.WorkLoads) } +// find the nil pointer error func GetCluster(clusterID string) (*commonmodels.K8SCluster, error) { clusterColl := commonrepo.NewK8SClusterColl() log.Infof("GetCluster called with clusterID=%q", clusterID) diff --git a/pkg/microservice/aslan/core/common/service/version.go b/pkg/microservice/aslan/core/common/service/version.go index 2829d42600..e1d42a7523 100644 --- a/pkg/microservice/aslan/core/common/service/version.go +++ b/pkg/microservice/aslan/core/common/service/version.go @@ -135,6 +135,16 @@ func GetEnvServiceVersionYaml(ctx *internalhandler.Context, projectName, envName resp.DeployStrategy = envSvcRevision.DeployStrategy resp.Containers = envSvcRevision.Service.Containers + // for get clusterID + env, err := mongodb.NewProductColl().Find(&mongodb.ProductFindOptions{ + Name: projectName, + EnvName: envName, + Production: &isProduction, + }) + if err != nil { + return resp, fmt.Errorf("failed to find %s/%s env, isProduction %v, error: %v", projectName, envName, isProduction, err) + } + if envSvcRevision.ProductFeature.IsHostProduct() { return resp, nil } @@ -143,6 +153,7 @@ func GetEnvServiceVersionYaml(ctx *internalhandler.Context, projectName, envName fakeEnv := &commonmodels.Product{ ProductName: envSvcRevision.ProductName, EnvName: envSvcRevision.EnvName, + ClusterID: env.ClusterID, Namespace: envSvcRevision.Namespace, Production: envSvcRevision.Production, } @@ -419,6 +430,7 @@ func RollbackEnvServiceVersion(ctx *internalhandler.Context, projectName, envNam fakeEnv := &commonmodels.Product{ ProductName: envSvcVersion.ProductName, EnvName: envSvcVersion.EnvName, + ClusterID: env.ClusterID, Namespace: envSvcVersion.Namespace, Production: envSvcVersion.Production, } diff --git a/pkg/microservice/aslan/core/environment/handler/environment.go b/pkg/microservice/aslan/core/environment/handler/environment.go index 2d3b7e9f48..e9db96bd8c 100644 --- a/pkg/microservice/aslan/core/environment/handler/environment.go +++ b/pkg/microservice/aslan/core/environment/handler/environment.go @@ -302,8 +302,6 @@ func CreateProduct(c *gin.Context) { ctx.RespErr = e.ErrInvalidParam.AddErr(err) return } - // debug - log.Infof("CreateProduct, createArgs: %v", createArgs) if production { err = service.EnsureProductionNamespace(createArgs) diff --git a/pkg/microservice/aslan/core/environment/service/environment_creation.go b/pkg/microservice/aslan/core/environment/service/environment_creation.go index 16876e89a1..92df6ed1b6 100644 --- a/pkg/microservice/aslan/core/environment/service/environment_creation.go +++ b/pkg/microservice/aslan/core/environment/service/environment_creation.go @@ -302,8 +302,7 @@ func prepareK8sProductCreation(templateProduct *templatemodels.Product, productO } func createSingleYamlProduct(templateProduct *templatemodels.Product, requestID, userName string, arg *CreateSingleProductArg, log *zap.SugaredLogger) error { - // debug - log.Infof("createSingleYamlProduct, arg: %v", arg) + productObj := &commonmodels.Product{ ProductName: templateProduct.ProductName, Revision: templateProduct.Revision, From b216029062eb2d75b9bf1993eed6e13b24846d0c Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Tue, 2 Jun 2026 11:44:01 +0800 Subject: [PATCH 12/18] fix: get correct clusterID Signed-off-by: YuTang Song <2313186065@qq.com> --- pkg/microservice/aslan/core/common/service/kube/render.go | 1 - pkg/microservice/aslan/core/common/service/version.go | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/pkg/microservice/aslan/core/common/service/kube/render.go b/pkg/microservice/aslan/core/common/service/kube/render.go index 7b07214d4e..db96963e87 100644 --- a/pkg/microservice/aslan/core/common/service/kube/render.go +++ b/pkg/microservice/aslan/core/common/service/kube/render.go @@ -1016,7 +1016,6 @@ func RenderEnvServiceWithTempl(prod *commonmodels.Product, serviceRender *templa return ApplyReplicaOverrides(parsedYaml, service.WorkLoads) } -// find the nil pointer error func GetCluster(clusterID string) (*commonmodels.K8SCluster, error) { clusterColl := commonrepo.NewK8SClusterColl() log.Infof("GetCluster called with clusterID=%q", clusterID) diff --git a/pkg/microservice/aslan/core/common/service/version.go b/pkg/microservice/aslan/core/common/service/version.go index e1d42a7523..64a27c91e0 100644 --- a/pkg/microservice/aslan/core/common/service/version.go +++ b/pkg/microservice/aslan/core/common/service/version.go @@ -137,12 +137,12 @@ func GetEnvServiceVersionYaml(ctx *internalhandler.Context, projectName, envName // for get clusterID env, err := mongodb.NewProductColl().Find(&mongodb.ProductFindOptions{ - Name: projectName, - EnvName: envName, - Production: &isProduction, + Name: envSvcRevision.ProductName, + EnvName: envSvcRevision.EnvName, + Production: &envSvcRevision.Production, }) if err != nil { - return resp, fmt.Errorf("failed to find %s/%s env, isProduction %v, error: %v", projectName, envName, isProduction, err) + return resp, fmt.Errorf("failed to find %s/%s env, isProduction %v, error: %v", envSvcRevision.ProductName, envSvcRevision.EnvName, envSvcRevision.Production, err) } if envSvcRevision.ProductFeature.IsHostProduct() { From 5b180cc43cae8e65961f91b32b8437c870770ca8 Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Tue, 2 Jun 2026 11:49:10 +0800 Subject: [PATCH 13/18] fix: get correct cluster Signed-off-by: YuTang Song <2313186065@qq.com> --- pkg/microservice/aslan/core/common/service/kube/render.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pkg/microservice/aslan/core/common/service/kube/render.go b/pkg/microservice/aslan/core/common/service/kube/render.go index db96963e87..5b08fc0333 100644 --- a/pkg/microservice/aslan/core/common/service/kube/render.go +++ b/pkg/microservice/aslan/core/common/service/kube/render.go @@ -1019,10 +1019,6 @@ func RenderEnvServiceWithTempl(prod *commonmodels.Product, serviceRender *templa func GetCluster(clusterID string) (*commonmodels.K8SCluster, error) { clusterColl := commonrepo.NewK8SClusterColl() log.Infof("GetCluster called with clusterID=%q", clusterID) - if clusterID == "" { - clusterID = setting.LocalClusterID - log.Infof("GetCluster fallback to local clusterID=%q", clusterID) - } log.Infof("GetCluster clusterID=%q is a valid object id, querying by id", clusterID) cluster, err := clusterColl.FindByID(clusterID) From 6e233d3cdb6447dcc017369e5932dede1dfc9ddd Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Tue, 2 Jun 2026 15:59:28 +0800 Subject: [PATCH 14/18] pref: remove debug logs Signed-off-by: YuTang Song <2313186065@qq.com> --- .../aslan/core/common/service/kube/render.go | 8 +------- .../aslan/core/common/service/version.go | 16 ++++++++-------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/pkg/microservice/aslan/core/common/service/kube/render.go b/pkg/microservice/aslan/core/common/service/kube/render.go index 5b08fc0333..b083cd2bbd 100644 --- a/pkg/microservice/aslan/core/common/service/kube/render.go +++ b/pkg/microservice/aslan/core/common/service/kube/render.go @@ -1017,15 +1017,9 @@ func RenderEnvServiceWithTempl(prod *commonmodels.Product, serviceRender *templa } func GetCluster(clusterID string) (*commonmodels.K8SCluster, error) { - clusterColl := commonrepo.NewK8SClusterColl() - log.Infof("GetCluster called with clusterID=%q", clusterID) - - log.Infof("GetCluster clusterID=%q is a valid object id, querying by id", clusterID) - cluster, err := clusterColl.FindByID(clusterID) + cluster, err := commonrepo.NewK8SClusterColl().FindByID(clusterID) if err != nil { - log.Errorf("GetCluster failed to find cluster by id, clusterID=%q, err=%v", clusterID, err) return nil, errors.Wrapf(err, "failed to find cluster by id %s", clusterID) } - log.Infof("GetCluster found cluster by id, clusterID=%q, clusterName=%q", clusterID, cluster.Name) return cluster, nil } diff --git a/pkg/microservice/aslan/core/common/service/version.go b/pkg/microservice/aslan/core/common/service/version.go index 64a27c91e0..4c9e42561a 100644 --- a/pkg/microservice/aslan/core/common/service/version.go +++ b/pkg/microservice/aslan/core/common/service/version.go @@ -135,18 +135,18 @@ func GetEnvServiceVersionYaml(ctx *internalhandler.Context, projectName, envName resp.DeployStrategy = envSvcRevision.DeployStrategy resp.Containers = envSvcRevision.Service.Containers + if envSvcRevision.ProductFeature.IsHostProduct() { + return resp, nil + } + // for get clusterID env, err := mongodb.NewProductColl().Find(&mongodb.ProductFindOptions{ - Name: envSvcRevision.ProductName, - EnvName: envSvcRevision.EnvName, - Production: &envSvcRevision.Production, + Name: projectName, + EnvName: envName, + Production: &isProduction, }) if err != nil { - return resp, fmt.Errorf("failed to find %s/%s env, isProduction %v, error: %v", envSvcRevision.ProductName, envSvcRevision.EnvName, envSvcRevision.Production, err) - } - - if envSvcRevision.ProductFeature.IsHostProduct() { - return resp, nil + return resp, fmt.Errorf("failed to find %s/%s env, isProduction %v, error: %v", projectName, envName, isProduction, err) } if envSvcRevision.Service.Type == setting.K8SDeployType { From 826489f28d3f6948032374bde475b033f6e97420 Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Fri, 5 Jun 2026 14:21:31 +0800 Subject: [PATCH 15/18] fix: add get previous version cluster info for rollback operation Signed-off-by: YuTang Song <2313186065@qq.com> --- .../repository/models/env_svc_version.go | 1 + .../aslan/core/common/service/version.go | 41 +++++++++++++++++-- .../aslan/core/common/util/version.go | 11 +++++ 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/pkg/microservice/aslan/core/common/repository/models/env_svc_version.go b/pkg/microservice/aslan/core/common/repository/models/env_svc_version.go index 81160fa5f2..e9342d83ef 100644 --- a/pkg/microservice/aslan/core/common/repository/models/env_svc_version.go +++ b/pkg/microservice/aslan/core/common/repository/models/env_svc_version.go @@ -30,6 +30,7 @@ type EnvServiceVersion struct { ProductName string `bson:"product_name" json:"product_name"` EnvName string `bson:"env_name" json:"env_name"` Namespace string `bson:"namespace" json:"namespace"` + ClusterName string `bson:"cluster_name,omitempty" json:"cluster_name,omitempty"` Production bool `bson:"production" json:"production"` Revision int64 `bson:"revision" json:"revision"` Operation config.EnvOperation `bson:"operation" json:"operation"` diff --git a/pkg/microservice/aslan/core/common/service/version.go b/pkg/microservice/aslan/core/common/service/version.go index 4c9e42561a..c66abc95f0 100644 --- a/pkg/microservice/aslan/core/common/service/version.go +++ b/pkg/microservice/aslan/core/common/service/version.go @@ -157,7 +157,24 @@ func GetEnvServiceVersionYaml(ctx *internalhandler.Context, projectName, envName Namespace: envSvcRevision.Namespace, Production: envSvcRevision.Production, } - parsedYaml, err := kube.RenderEnvService(fakeEnv, envSvcRevision.Service.GetServiceRender(), envSvcRevision.Service) + clusterName := envSvcRevision.ClusterName + if clusterName == "" { + cluster, err := kube.GetCluster(env.ClusterID) + if err != nil { + return resp, err + } + clusterName = cluster.Name + } + svcTmpl, err := repository.QueryTemplateService(&commonrepo.ServiceFindOption{ + ServiceName: envSvcRevision.Service.ServiceName, + ProductName: envSvcRevision.ProductName, + Type: envSvcRevision.Service.Type, + Revision: envSvcRevision.Service.Revision, + }, envSvcRevision.Production) + if err != nil { + return resp, fmt.Errorf("failed to find %s/%s/%d service template, isProduction %v, error: %v", envSvcRevision.ProductName, envSvcRevision.Service.ServiceName, envSvcRevision.Service.Revision, envSvcRevision.Production, err) + } + parsedYaml, err := kube.RenderEnvServiceWithTempl(fakeEnv, envSvcRevision.Service.GetServiceRender(), envSvcRevision.Service, svcTmpl, clusterName) if err != nil { err = fmt.Errorf("Failed to render env Service %s, error: %v", envSvcRevision.Service.ServiceName, err) return resp, err @@ -407,7 +424,8 @@ func RollbackEnvServiceVersion(ctx *internalhandler.Context, projectName, envNam VariableKVs: envSvcVersion.Service.GetServiceRender().OverrideYaml.RenderVariableKVs, Containers: envSvcVersion.Service.Containers, } - _, _, resources, err := kube.GenerateRenderedYaml(option) + var resources []*kube.WorkloadResource + _, _, resources, err = kube.GenerateRenderedYaml(option) if err != nil { return nil, e.ErrRollbackEnvServiceVersion.AddErr(fmt.Errorf("failed to generate service yaml, error: %v", err)) } @@ -434,7 +452,24 @@ func RollbackEnvServiceVersion(ctx *internalhandler.Context, projectName, envNam Namespace: envSvcVersion.Namespace, Production: envSvcVersion.Production, } - parsedYaml, err := kube.RenderEnvService(fakeEnv, envSvcVersion.Service.GetServiceRender(), envSvcVersion.Service) + clusterName := envSvcVersion.ClusterName + if clusterName == "" { + cluster, err := kube.GetCluster(env.ClusterID) + if err != nil { + return nil, e.ErrRollbackEnvServiceVersion.AddErr(err) + } + clusterName = cluster.Name + } + svcTmpl, err := repository.QueryTemplateService(&commonrepo.ServiceFindOption{ + ServiceName: envSvcVersion.Service.ServiceName, + ProductName: envSvcVersion.ProductName, + Type: envSvcVersion.Service.Type, + Revision: envSvcVersion.Service.Revision, + }, envSvcVersion.Production) + if err != nil { + return nil, e.ErrRollbackEnvServiceVersion.AddErr(fmt.Errorf("failed to find %s/%s/%d service template, isProduction %v, error: %v", envSvcVersion.ProductName, envSvcVersion.Service.ServiceName, envSvcVersion.Service.Revision, envSvcVersion.Production, err)) + } + parsedYaml, err := kube.RenderEnvServiceWithTempl(fakeEnv, envSvcVersion.Service.GetServiceRender(), envSvcVersion.Service, svcTmpl, clusterName) if err != nil { err = fmt.Errorf("Failed to render env %s, service %s, revision %d, error: %v", envSvcVersion.EnvName, envSvcVersion.Service.ServiceName, envSvcVersion.Service.Revision, err) return nil, e.ErrRollbackEnvServiceVersion.AddErr(err) diff --git a/pkg/microservice/aslan/core/common/util/version.go b/pkg/microservice/aslan/core/common/util/version.go index 206ffc15d1..f4126dbc03 100644 --- a/pkg/microservice/aslan/core/common/util/version.go +++ b/pkg/microservice/aslan/core/common/util/version.go @@ -50,11 +50,22 @@ func CreateEnvServiceVersion(env *models.Product, prodSvc *models.ProductService return fmt.Errorf("failed to find template product %s, error: %v", env.ProductName, err) } + clusterName := "" + var cluster *models.K8SCluster + if env.ClusterID != "" { + cluster, err = commonrepo.NewK8SClusterColl().FindByID(env.ClusterID) + if err != nil { + return fmt.Errorf("failed to find cluster by id %s, error: %v", env.ClusterID, err) + } + clusterName = cluster.Name + } + svcVersionColl := mongodb.NewEnvServiceVersionCollWithSession(session) version := &models.EnvServiceVersion{ ProductName: env.ProductName, EnvName: env.EnvName, Namespace: env.Namespace, + ClusterName: clusterName, Production: env.Production, Revision: revision, Service: prodSvc, From cf0a99bd7e48eed55b6736e659e3dca7a5d371e8 Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Tue, 9 Jun 2026 15:06:57 +0800 Subject: [PATCH 16/18] fix: show correct cluster name for update preview Signed-off-by: YuTang Song <2313186065@qq.com> --- .../aslan/core/common/service/kube/render.go | 52 ++++++++++++++----- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/pkg/microservice/aslan/core/common/service/kube/render.go b/pkg/microservice/aslan/core/common/service/kube/render.go index b083cd2bbd..b3b5ad689d 100644 --- a/pkg/microservice/aslan/core/common/service/kube/render.go +++ b/pkg/microservice/aslan/core/common/service/kube/render.go @@ -385,12 +385,6 @@ func FetchCurrentAppliedYaml(option *GeneSvcYamlOption) (string, int, error) { return "", 0, errors.Wrapf(err, "failed to find product %s", option.ProductName) } - // return structured cluster name - cluster, err := GetCluster(productInfo.ClusterID) - if err != nil { - return "", 0, errors.Wrapf(err, "failed to get cluster name by cluster id %s", productInfo.ClusterID) - } - curProductSvc := productInfo.GetServiceMap()[option.ServiceName] // service not installed, nothing to return @@ -398,6 +392,11 @@ func FetchCurrentAppliedYaml(option *GeneSvcYamlOption) (string, int, error) { return "", 0, nil } + clusterName, err := resolveCurrentAppliedClusterName(productInfo, option.ServiceName) + if err != nil { + return "", 0, err + } + prodSvcTemplate, err := repository.QueryTemplateService(&commonrepo.ServiceFindOption{ ProductName: option.ProductName, ServiceName: option.ServiceName, @@ -408,7 +407,7 @@ func FetchCurrentAppliedYaml(option *GeneSvcYamlOption) (string, int, error) { } if option.IsImportToDeploy { - importedAllManifests, _, err := FetchImportedAllManifests(productInfo, prodSvcTemplate, curProductSvc.GetServiceRender()) + importedAllManifests, _, err := FetchImportedAllManifests(productInfo, prodSvcTemplate, curProductSvc.GetServiceRender(), clusterName) if err != nil { return "", 0, err } @@ -418,7 +417,7 @@ func FetchCurrentAppliedYaml(option *GeneSvcYamlOption) (string, int, error) { if err != nil { return "", 0, err } - fullRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, cluster.Name, fullRenderedYaml) + fullRenderedYaml = ParseSysKeys(productInfo.Namespace, productInfo.EnvName, option.ProductName, option.ServiceName, clusterName, fullRenderedYaml) mergedContainers := mergeContainers(prodSvcTemplate.Containers, curProductSvc.Containers) fullRenderedYaml, _, err = ReplaceWorkloadImages(fullRenderedYaml, mergedContainers) if err != nil { @@ -431,17 +430,42 @@ func FetchCurrentAppliedYaml(option *GeneSvcYamlOption) (string, int, error) { } } -func FetchImportedAllManifests(envInfo *models.Product, serviceTmp *models.Service, svcRender *template.ServiceRender) (string, []*WorkloadResource, error) { - fullRenderedYaml, err := RenderServiceYaml(serviceTmp.Yaml, envInfo.ProductName, serviceTmp.ServiceName, svcRender) +func resolveCurrentAppliedClusterName(productInfo *models.Product, serviceName string) (string, error) { + + cluster, err := GetCluster(productInfo.ClusterID) if err != nil { - return "", nil, err + return "", errors.Wrapf(err, "failed to get cluster name by cluster id %s", productInfo.ClusterID) } - // get cluster name by cluster id - cluster, err := GetCluster(envInfo.ClusterID) + + // Use the latest stored service version as the source of truth for "current" preview yaml. + latestRevision, err := commonrepo.NewEnvServiceVersionColl().GetLatestRevision( + productInfo.ProductName, productInfo.EnvName, serviceName, false, productInfo.Production) + if err != nil { + return "", errors.Wrapf(err, "failed to find latest env service version for %s/%s/%s", productInfo.ProductName, productInfo.EnvName, serviceName) + } + if latestRevision == 0 { + return cluster.Name, nil + } + + envSvcVersion, err := commonrepo.NewEnvServiceVersionColl().Find( + productInfo.ProductName, productInfo.EnvName, serviceName, false, productInfo.Production, latestRevision) + if err != nil { + return "", errors.Wrapf(err, "failed to find env service version %s/%s/%s revision %d", productInfo.ProductName, productInfo.EnvName, serviceName, latestRevision) + } + // Older records may not have cluster_name populated, so keep a safe fallback. + if envSvcVersion.ClusterName != "" { + return envSvcVersion.ClusterName, nil + } + + return cluster.Name, nil +} + +func FetchImportedAllManifests(envInfo *models.Product, serviceTmp *models.Service, svcRender *template.ServiceRender, clusterName string) (string, []*WorkloadResource, error) { + fullRenderedYaml, err := RenderServiceYaml(serviceTmp.Yaml, envInfo.ProductName, serviceTmp.ServiceName, svcRender) if err != nil { return "", nil, err } - fullRenderedYaml = ParseSysKeys(envInfo.Namespace, envInfo.EnvName, envInfo.ProductName, serviceTmp.ServiceName, cluster.Name, fullRenderedYaml) + fullRenderedYaml = ParseSysKeys(envInfo.Namespace, envInfo.EnvName, envInfo.ProductName, serviceTmp.ServiceName, clusterName, fullRenderedYaml) manifests := util.SplitManifestsOrdered(fullRenderedYaml) From 780a9fb9722fa766ec848b795f86566663e9fe9c Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Tue, 9 Jun 2026 15:22:08 +0800 Subject: [PATCH 17/18] fix: update new svc yaml Signed-off-by: YuTang Song <2313186065@qq.com> --- .../aslan/core/environment/service/environment.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pkg/microservice/aslan/core/environment/service/environment.go b/pkg/microservice/aslan/core/environment/service/environment.go index 71749423ae..fd153777c7 100644 --- a/pkg/microservice/aslan/core/environment/service/environment.go +++ b/pkg/microservice/aslan/core/environment/service/environment.go @@ -3034,8 +3034,20 @@ func upsertService(env *commonmodels.Product, newService *commonmodels.ProductSe func getOldSvcYaml(env *commonmodels.Product, oldService *commonmodels.ProductService, log *zap.SugaredLogger) (string, error) { + // Use the current applied yaml as the update baseline so resource patching stays + // consistent with preview/export behavior after cluster name changes. + parsedYaml, _, err := kube.FetchCurrentAppliedYaml(&kube.GeneSvcYamlOption{ + ProductName: env.ProductName, + EnvName: env.EnvName, + ServiceName: oldService.ServiceName, + IsImportToDeploy: env.ServiceDeployStrategy[oldService.ServiceName] == setting.ServiceDeployStrategyImport, + }) + if err == nil { + return parsedYaml, nil + } + log.Warnf("failed to fetch current applied yaml for %s/%s/%s, fallback to rendered service yaml, err: %v", env.ProductName, env.EnvName, oldService.ServiceName, err) - parsedYaml, err := kube.RenderEnvService(env, oldService.GetServiceRender(), oldService) + parsedYaml, err = kube.RenderEnvService(env, oldService.GetServiceRender(), oldService) if err != nil { log.Errorf("failed to find old service revision %s/%d", oldService.ServiceName, oldService.Revision) return "", err From a38ab9bef1ee3198e4d8b9607deb122390ce7a71 Mon Sep 17 00:00:00 2001 From: YuTang Song <2313186065@qq.com> Date: Tue, 9 Jun 2026 15:54:59 +0800 Subject: [PATCH 18/18] fix: rollback issue Signed-off-by: YuTang Song <2313186065@qq.com> --- pkg/microservice/aslan/core/common/service/helm/helm.go | 8 +++++++- pkg/microservice/aslan/core/common/service/version.go | 2 +- pkg/microservice/aslan/core/common/util/version.go | 7 +++++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/pkg/microservice/aslan/core/common/service/helm/helm.go b/pkg/microservice/aslan/core/common/service/helm/helm.go index 340487b92f..8925648dfa 100644 --- a/pkg/microservice/aslan/core/common/service/helm/helm.go +++ b/pkg/microservice/aslan/core/common/service/helm/helm.go @@ -116,6 +116,12 @@ func CopyAndUploadService(projectName, serviceName, currentChartPath string, cop // Update Service and ServiceDeployStrategy for a single service in environment func UpdateServiceInEnv(product *commonmodels.Product, productSvc *commonmodels.ProductService, user string, operation config.EnvOperation, detail string) error { + return UpdateServiceInEnvWithClusterName(product, productSvc, user, operation, detail, "") +} + +// UpdateServiceInEnvWithClusterName keeps the created env service version snapshot aligned +// with the applied rollback target when cluster name should come from a historical version. +func UpdateServiceInEnvWithClusterName(product *commonmodels.Product, productSvc *commonmodels.ProductService, user string, operation config.EnvOperation, detail, clusterName string) error { session := mongo.Session() defer session.EndSession(context.TODO()) @@ -125,7 +131,7 @@ func UpdateServiceInEnv(product *commonmodels.Product, productSvc *commonmodels. } product.LintServices() - err = commonutil.CreateEnvServiceVersion(product, productSvc, user, operation, detail, session, log.SugaredLogger()) + err = commonutil.CreateEnvServiceVersionWithClusterName(product, productSvc, user, operation, detail, clusterName, session, log.SugaredLogger()) if err != nil { log.Errorf("failed to create helm service version, err: %v", err) } diff --git a/pkg/microservice/aslan/core/common/service/version.go b/pkg/microservice/aslan/core/common/service/version.go index c66abc95f0..a66054e26f 100644 --- a/pkg/microservice/aslan/core/common/service/version.go +++ b/pkg/microservice/aslan/core/common/service/version.go @@ -549,7 +549,7 @@ func RollbackEnvServiceVersion(ctx *internalhandler.Context, projectName, envNam } env.Services[groupIndex][svcIndex] = envSvcVersion.Service - err = helmservice.UpdateServiceInEnv(env, envSvcVersion.Service, ctx.UserName, config.EnvOperationRollback, detail) + err = helmservice.UpdateServiceInEnvWithClusterName(env, envSvcVersion.Service, ctx.UserName, config.EnvOperationRollback, detail, envSvcVersion.ClusterName) if err != nil { return nil, e.ErrRollbackEnvServiceVersion.AddErr(fmt.Errorf("failed to update service %s in env %s/%s, isProudction %v", envSvcVersion.Service.ServiceName, envSvcVersion.ProductName, envSvcVersion.EnvName, envSvcVersion.Production)) } diff --git a/pkg/microservice/aslan/core/common/util/version.go b/pkg/microservice/aslan/core/common/util/version.go index f4126dbc03..eeda77b635 100644 --- a/pkg/microservice/aslan/core/common/util/version.go +++ b/pkg/microservice/aslan/core/common/util/version.go @@ -22,6 +22,10 @@ func GenerateEnvServiceNextRevision(projectName, envName, serviceName string, is } func CreateEnvServiceVersion(env *models.Product, prodSvc *models.ProductService, createBy string, operation config.EnvOperation, detail string, session mongo.Session, log *zap.SugaredLogger) error { + return CreateEnvServiceVersionWithClusterName(env, prodSvc, createBy, operation, detail, "", session, log) +} + +func CreateEnvServiceVersionWithClusterName(env *models.Product, prodSvc *models.ProductService, createBy string, operation config.EnvOperation, detail, clusterName string, session mongo.Session, log *zap.SugaredLogger) error { name := prodSvc.ServiceName isHelmChart := !prodSvc.FromZadig() if isHelmChart { @@ -50,9 +54,8 @@ func CreateEnvServiceVersion(env *models.Product, prodSvc *models.ProductService return fmt.Errorf("failed to find template product %s, error: %v", env.ProductName, err) } - clusterName := "" var cluster *models.K8SCluster - if env.ClusterID != "" { + if clusterName == "" && env.ClusterID != "" { cluster, err = commonrepo.NewK8SClusterColl().FindByID(env.ClusterID) if err != nil { return fmt.Errorf("failed to find cluster by id %s, error: %v", env.ClusterID, err)