From 210e8376d071405ee1fe3c8829332060d1d912cc Mon Sep 17 00:00:00 2001 From: CeerDecy <1748788674@qq.com> Date: Fri, 27 Sep 2024 10:44:44 +0800 Subject: [PATCH 1/9] feat: custom deploy should set version --- apistructs/addon.go | 7 +- .../conf/i18n/orchestrator-log-trans.yaml | 2 + .../dbclient/addon_instance_routing.go | 14 ++++ .../tools/orchestrator/endpoints/addon.go | 33 +++++++++ .../orchestrator/services/addon/addon.go | 60 +++++++++++++--- .../services/addon/addon_handler.go | 71 ++++++++++++------- 6 files changed, 153 insertions(+), 34 deletions(-) diff --git a/apistructs/addon.go b/apistructs/addon.go index 14ce444d803..5fb7b93abad 100644 --- a/apistructs/addon.go +++ b/apistructs/addon.go @@ -306,7 +306,7 @@ const ( // AddonConfigCenterAlias terminus-configcenter alias name AddonConfigCenterAlias = "configcenter" // AddonNewConfigCenter configcenter - AddonNewConfigCenter = "configcenter" + AddonNewConfigCenter = "config-center" //AddonTerminusRoost 注册中心 AddonTerminusRoost = "terminus-roost" // AddonMicroService micro-service @@ -329,6 +329,11 @@ const ( AddonSourcecov = "sourcecov" OriginalReplicas = "original_replicas" + + // registercenter + AddonRegisterCenter = "registercenter" + // mse-nacos + AddonMSENacos = "mse-nacos" ) // AddonRes addon信息 diff --git a/cmd/orchestrator/conf/i18n/orchestrator-log-trans.yaml b/cmd/orchestrator/conf/i18n/orchestrator-log-trans.yaml index f631d567694..fc39acf5322 100644 --- a/cmd/orchestrator/conf/i18n/orchestrator-log-trans.yaml +++ b/cmd/orchestrator/conf/i18n/orchestrator-log-trans.yaml @@ -21,6 +21,7 @@ zh: AddonPlanIllegal: "Addon %s 规格不合法, Basic 规格 Addon 无法在生产环境使用" AddonFormatIllegal: "Addon %s 格式不合法, 请检查 dice.yml 中 addon 部分是否正确" AddonDeprecated: "Addon %s 当前版本:%v 已被废弃,请在dice.yml中重新配置" + ClusterAddonRedeploy: "Addon %s 在集群中存在,请选择部署 %v 版本,来进行关联" en: WaitingForAddonTimeOut: "Waiting for the addon (%s)(%s) to be healthy timeout (%d min)" @@ -45,3 +46,4 @@ en: AddonPlanIllegal: "Addon %s plan is illegal, Basic plan addon cannot be used in production environment" AddonFormatIllegal: "Addon %s format is illegal, please check the dice.yml addon section" AddonDeprecated: "Addon %s current version: %v deprecated, please reconfigure in dice.yml" + ClusterAddonRedeploy: "Addon %s is existing,please select version: %v to link" diff --git a/internal/tools/orchestrator/dbclient/addon_instance_routing.go b/internal/tools/orchestrator/dbclient/addon_instance_routing.go index 211b46b2c83..dbfa20e1ebb 100644 --- a/internal/tools/orchestrator/dbclient/addon_instance_routing.go +++ b/internal/tools/orchestrator/dbclient/addon_instance_routing.go @@ -91,6 +91,20 @@ func (db *DBClient) GetInstanceRouting(id string) (*AddonInstanceRouting, error) return &instanceRouting, nil } +func (db *DBClient) GetInstanceRoutingByClusterAndName(addonName, clusterName string) ([]AddonInstanceRouting, error) { + var instanceRouting []AddonInstanceRouting + if err := db.Where("addon_name = ?", addonName). + Where("az = ?", clusterName). + Where("is_deleted = ?", apistructs.AddonNotDeleted). + Find(&instanceRouting).Error; err != nil { + if gorm.IsRecordNotFoundError(err) { + return nil, nil + } + return nil, err + } + return instanceRouting, nil +} + // GetInstanceRoutingByRealInstance 通过真实例Id查找routing信息 func (db *DBClient) GetInstanceRoutingByRealInstance(realIns string) (*[]AddonInstanceRouting, error) { var instanceRouting []AddonInstanceRouting diff --git a/internal/tools/orchestrator/endpoints/addon.go b/internal/tools/orchestrator/endpoints/addon.go index 773fd37cb2d..f052a6be89d 100644 --- a/internal/tools/orchestrator/endpoints/addon.go +++ b/internal/tools/orchestrator/endpoints/addon.go @@ -71,6 +71,39 @@ func (e *Endpoints) CreateAddonDirectly(ctx context.Context, r *http.Request, va // return apierrors.ErrCreateAddon.AccessDenied().ToResp(), nil // } // } + var hasRegister, hasConfig bool + var targetVersion string + for _, on := range addonCreateReq.Addons { + if strings.Contains(on.Plan, apistructs.AddonRegisterCenter) { + hasRegister = true + if on.Options != nil { + targetVersion = on.Options["version"] + } + } + if strings.Contains(on.Plan, apistructs.AddonNewConfigCenter) { + hasConfig = true + if on.Options != nil && targetVersion == "" { + targetVersion = on.Options["version"] + } + } + } + + if hasRegister && !hasConfig { + addonCreateReq.Addons["config-center"] = &diceyml.AddOn{ + Plan: fmt.Sprintf("%s:%s", apistructs.AddonNewConfigCenter, "basic"), + Options: map[string]string{ + "version": targetVersion, + }, + } + } else if !hasRegister && hasConfig { + addonCreateReq.Addons["register-center"] = &diceyml.AddOn{ + Plan: fmt.Sprintf("%s:%s", apistructs.AddonRegisterCenter, "basic"), + Options: map[string]string{ + "version": targetVersion, + }, + } + } + addonid, err := e.addon.AddonCreate(addonCreateReq) if err != nil { return apierrors.ErrCreateAddon.InternalError(err).ToResp(), nil diff --git a/internal/tools/orchestrator/services/addon/addon.go b/internal/tools/orchestrator/services/addon/addon.go index db83e27f47f..eafc66551e3 100644 --- a/internal/tools/orchestrator/services/addon/addon.go +++ b/internal/tools/orchestrator/services/addon/addon.go @@ -2633,13 +2633,32 @@ func (a *Addon) ListCustomAddon() (*[]map[string]interface{}, error) { basic := locale.Get("basicPlan") professional := locale.Get("professionalPlan") - createableAddons := []string{"api-gateway", "mysql", "canal", "monitor"} - createableAddonVersion := map[string]string{"api-gateway": "3.0.0", "mysql": "5.7.29", "canal": "1.1.0", "monitor": "3.6"} + createableAddons := []string{ + apistructs.AddonApiGateway, + apistructs.AddonMySQL, + apistructs.AddonMonitor, + apistructs.AddonRegisterCenter, + apistructs.AddonNewConfigCenter, + } + // if these addon-type is `custom` and they can't be deployed by user, skip it! + unCreateAbleAddons := []string{ + apistructs.AddonMSENacos, // mse-nacos only can be deployed by `config-center` or `register-center` + } + createableAddonVersion := map[string]string{ + apistructs.AddonApiGateway: "3.0.0", + apistructs.AddonMySQL: "5.7.29", + apistructs.AddonCanal: "1.1.0", + apistructs.AddonMonitor: "3.6", + apistructs.AddonRegisterCenter: "3.0.0", + apistructs.AddonNewConfigCenter: "3.0.0", + } createableAddonPlan := map[string][]map[string]string{ - "api-gateway": {{"label": basic, "value": "api-gateway:basic"}}, - "mysql": {{"label": basic, "value": "mysql:basic"}}, - "canal": {{"label": basic, "value": "canal:basic"}}, - "monitor": {{"label": professional, "value": "monitor:professional"}}, + apistructs.AddonApiGateway: {{"label": basic, "value": "api-gateway:basic"}}, + apistructs.AddonMySQL: {{"label": basic, "value": "mysql:basic"}}, + apistructs.AddonCanal: {{"label": basic, "value": "canal:basic"}}, + apistructs.AddonMonitor: {{"label": professional, "value": "monitor:professional"}}, + apistructs.AddonRegisterCenter: {{"label": basic, "value": "registercenter:basic"}}, + apistructs.AddonNewConfigCenter: {{"label": basic, "value": "config-center:basic"}}, } // 构建请求参数,请求extension @@ -2653,7 +2672,7 @@ func (a *Addon) ListCustomAddon() (*[]map[string]interface{}, error) { } extensionResult := make([]map[string]interface{}, 0, len(extensions)) for _, item := range extensions { - if item.Category != apistructs.AddonCustomCategory && !strutil.Exist(createableAddons, item.Name) { + if (item.Category != apistructs.AddonCustomCategory && !strutil.Exist(createableAddons, item.Name)) || strutil.Exist(unCreateAbleAddons, item.Name) { continue } version := createableAddonVersion[item.Name] @@ -2697,7 +2716,6 @@ func (a *Addon) ListCustomAddon() (*[]map[string]interface{}, error) { case "custom": addonMap["vars"] = []string{} } - addonMap["version"] = version addonMap["plan"] = createableAddonPlan[item.Name] // TODO: disable tenant support, we shall refactor later //switch item.Name { @@ -2707,6 +2725,21 @@ func (a *Addon) ListCustomAddon() (*[]map[string]interface{}, error) { //default: // addonMap["supportTenant"] = false //} + + versions := make([]string, 0, 1) + exts, err := a.bdl.QueryExtensionVersions(apistructs.ExtensionVersionQueryRequest{ + Name: item.Name, + All: true, + }) + if err != nil { + versions = append(versions, version) + } else { + for _, e := range exts { + versions = append(versions, e.Version) + } + } + addonMap["versions"] = versions + extensionResult = append(extensionResult, addonMap) } return &extensionResult, nil @@ -3501,6 +3534,17 @@ func sortPrebuild(prebuilds []dbclient.AddonPrebuild) []dbclient.AddonPrebuild { return append(others, canalPrebuilds...) } +func (a *Addon) GetClusterAddonRouting(addonName, clusterName string) (*dbclient.AddonInstanceRouting, error) { + addons, err := a.db.GetInstanceRoutingByClusterAndName(addonName, clusterName) + if err != nil || addons == nil { + return nil, err + } + if len(addons) > 0 { + return &addons[0], nil + } + return nil, nil +} + // ListInstanceRoutingByRuntime 根据 runtimeID 获取已创建 addon 实例列表 func (a *Addon) ListInstanceRoutingByRuntime(runtimeID uint64) (*[]dbclient.AddonInstanceRouting, error) { attachments, err := a.db.GetAttachMentsByRuntimeID(runtimeID) diff --git a/internal/tools/orchestrator/services/addon/addon_handler.go b/internal/tools/orchestrator/services/addon/addon_handler.go index cc85617e7b7..2e7a4c80811 100644 --- a/internal/tools/orchestrator/services/addon/addon_handler.go +++ b/internal/tools/orchestrator/services/addon/addon_handler.go @@ -57,6 +57,8 @@ const ( AddonDeprecated = "AddonDeprecated" ) +const I18nClusterAddonRedeploy = "ClusterAddonRedeploy" + // AttachAndCreate addon创建,runtime建立关系方法 func (a *Addon) AttachAndCreate(params *apistructs.AddonHandlerCreateItem) (*apistructs.AddonInstanceRes, error) { // 获取addon extension信息 @@ -281,15 +283,15 @@ func (a *Addon) AddonDelete(req apistructs.AddonDirectDeleteRequest) error { return nil } -func (a *Addon) AddonCreate(req apistructs.AddonDirectCreateRequest) (string, error) { +func (a *Addon) AddonCreate(req apistructs.AddonDirectCreateRequest) ([]string, error) { if len(req.Addons) != 1 { - return "", fmt.Errorf("len(req.Addons) != 1") + return nil, fmt.Errorf("len(req.Addons) != 1") } baseAddons := []apistructs.AddonCreateItem{} for name, a := range req.Addons { plan := strings.SplitN(a.Plan, ":", 2) if len(plan) != 2 { - return "", errors.Errorf("addon plan information is not compliant") + return nil, errors.Errorf("addon plan information is not compliant") } baseAddons = append(baseAddons, apistructs.AddonCreateItem{ Name: name, @@ -298,30 +300,41 @@ func (a *Addon) AddonCreate(req apistructs.AddonDirectCreateRequest) (string, er Options: a.Options, }) } - addonItem := apistructs.AddonHandlerCreateItem{ - InstanceName: baseAddons[0].Name, - AddonName: addonutil.TransAddonName(baseAddons[0].Type), - Plan: baseAddons[0].Plan, - ClusterName: req.ClusterName, - Workspace: strutil.ToUpper(req.Workspace), - OrgID: strconv.FormatUint(req.OrgID, 10), - ProjectID: strconv.FormatUint(req.ProjectID, 10), - ApplicationID: strconv.FormatUint(req.ApplicationID, 10), - OperatorID: req.Operator, - InsideAddon: "N", - ShareScope: req.ShareScope, - Options: baseAddons[0].Options, - } - addonSpec, addonDice, err := a.GetAddonExtention(&addonItem) - if err != nil { - logrus.Errorf("failed to GetAddonExtention err: %v", err) - return "", err - } - if err := a.checkAddonDeployable(addonItem, addonSpec); err != nil { - return "", err + routingIds := make([]string, 0, len(baseAddons)) + + for i := range baseAddons { + addonItem := apistructs.AddonHandlerCreateItem{ + InstanceName: baseAddons[i].Name, + AddonName: addonutil.TransAddonName(baseAddons[i].Type), + Plan: baseAddons[i].Plan, + ClusterName: req.ClusterName, + Workspace: strutil.ToUpper(req.Workspace), + OrgID: strconv.FormatUint(req.OrgID, 10), + ProjectID: strconv.FormatUint(req.ProjectID, 10), + ApplicationID: strconv.FormatUint(req.ApplicationID, 10), + OperatorID: req.Operator, + InsideAddon: "N", + ShareScope: req.ShareScope, + Options: baseAddons[i].Options, + } + addonSpec, addonDice, err := a.GetAddonExtention(&addonItem) + if err != nil { + logrus.Errorf("failed to GetAddonExtention err: %v", err) + return nil, err + } + + if err := a.checkAddonDeployable(addonItem, addonSpec); err != nil { + return nil, err + } + + id, err := a.addonCreateAux(addonSpec, addonDice, &addonItem) + if err != nil { + return nil, err + } + routingIds = append(routingIds, id) } - return a.addonCreateAux(addonSpec, addonDice, &addonItem) + return routingIds, nil } // checkAddonDeployable 检查 addon 是否能部署 @@ -335,6 +348,14 @@ func (a *Addon) checkAddonDeployable(addon apistructs.AddonHandlerCreateItem, sp return fmt.Errorf("[project(%s)/workspace(%s)] 已存在 microservice(%s), 无法再新建", addon.ProjectID, addon.Workspace, addon.AddonName) } + routing, err := a.GetClusterAddonRouting(addon.AddonName, addon.ClusterName) + if err != nil { + logrus.Errorf("%v", err) + return errors.New("failed to get addon routing from database") + } + if routing != nil && (addon.Options == nil || routing.Version != addon.Options["version"]) { + return errors.New(i18n.OrgSprintf(addon.OrgID, I18nClusterAddonRedeploy, addon.AddonName, routing.Version)) + } } switch strutil.ToLower(addon.AddonName) { From d8c294925fc2f9ac10996a4dc1e6323b2e7af116 Mon Sep 17 00:00:00 2001 From: CeerDecy <1748788674@qq.com> Date: Fri, 27 Sep 2024 14:53:48 +0800 Subject: [PATCH 2/9] feat: log error Signed-off-by: CeerDecy <1748788674@qq.com> --- internal/tools/orchestrator/services/addon/addon.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/tools/orchestrator/services/addon/addon.go b/internal/tools/orchestrator/services/addon/addon.go index eafc66551e3..dfc9cd0e1f8 100644 --- a/internal/tools/orchestrator/services/addon/addon.go +++ b/internal/tools/orchestrator/services/addon/addon.go @@ -2732,6 +2732,7 @@ func (a *Addon) ListCustomAddon() (*[]map[string]interface{}, error) { All: true, }) if err != nil { + logrus.Errorf("query error: %v", err) versions = append(versions, version) } else { for _, e := range exts { From d7b6a49f81719027382a013e498bdae7c11c6e6f Mon Sep 17 00:00:00 2001 From: CeerDecy <1748788674@qq.com> Date: Fri, 27 Sep 2024 16:28:22 +0800 Subject: [PATCH 3/9] polish: find from addon instance Signed-off-by: CeerDecy <1748788674@qq.com> --- .../dbclient/addon_instance_routing.go | 14 -------------- .../tools/orchestrator/services/addon/addon.go | 11 ----------- .../orchestrator/services/addon/addon_handler.go | 8 ++++---- 3 files changed, 4 insertions(+), 29 deletions(-) diff --git a/internal/tools/orchestrator/dbclient/addon_instance_routing.go b/internal/tools/orchestrator/dbclient/addon_instance_routing.go index dbfa20e1ebb..211b46b2c83 100644 --- a/internal/tools/orchestrator/dbclient/addon_instance_routing.go +++ b/internal/tools/orchestrator/dbclient/addon_instance_routing.go @@ -91,20 +91,6 @@ func (db *DBClient) GetInstanceRouting(id string) (*AddonInstanceRouting, error) return &instanceRouting, nil } -func (db *DBClient) GetInstanceRoutingByClusterAndName(addonName, clusterName string) ([]AddonInstanceRouting, error) { - var instanceRouting []AddonInstanceRouting - if err := db.Where("addon_name = ?", addonName). - Where("az = ?", clusterName). - Where("is_deleted = ?", apistructs.AddonNotDeleted). - Find(&instanceRouting).Error; err != nil { - if gorm.IsRecordNotFoundError(err) { - return nil, nil - } - return nil, err - } - return instanceRouting, nil -} - // GetInstanceRoutingByRealInstance 通过真实例Id查找routing信息 func (db *DBClient) GetInstanceRoutingByRealInstance(realIns string) (*[]AddonInstanceRouting, error) { var instanceRouting []AddonInstanceRouting diff --git a/internal/tools/orchestrator/services/addon/addon.go b/internal/tools/orchestrator/services/addon/addon.go index dfc9cd0e1f8..c41000610d0 100644 --- a/internal/tools/orchestrator/services/addon/addon.go +++ b/internal/tools/orchestrator/services/addon/addon.go @@ -3535,17 +3535,6 @@ func sortPrebuild(prebuilds []dbclient.AddonPrebuild) []dbclient.AddonPrebuild { return append(others, canalPrebuilds...) } -func (a *Addon) GetClusterAddonRouting(addonName, clusterName string) (*dbclient.AddonInstanceRouting, error) { - addons, err := a.db.GetInstanceRoutingByClusterAndName(addonName, clusterName) - if err != nil || addons == nil { - return nil, err - } - if len(addons) > 0 { - return &addons[0], nil - } - return nil, nil -} - // ListInstanceRoutingByRuntime 根据 runtimeID 获取已创建 addon 实例列表 func (a *Addon) ListInstanceRoutingByRuntime(runtimeID uint64) (*[]dbclient.AddonInstanceRouting, error) { attachments, err := a.db.GetAttachMentsByRuntimeID(runtimeID) diff --git a/internal/tools/orchestrator/services/addon/addon_handler.go b/internal/tools/orchestrator/services/addon/addon_handler.go index 2e7a4c80811..dd2fa2c3810 100644 --- a/internal/tools/orchestrator/services/addon/addon_handler.go +++ b/internal/tools/orchestrator/services/addon/addon_handler.go @@ -348,13 +348,13 @@ func (a *Addon) checkAddonDeployable(addon apistructs.AddonHandlerCreateItem, sp return fmt.Errorf("[project(%s)/workspace(%s)] 已存在 microservice(%s), 无法再新建", addon.ProjectID, addon.Workspace, addon.AddonName) } - routing, err := a.GetClusterAddonRouting(addon.AddonName, addon.ClusterName) + instance, err := a.db.GetAddonInstanceByNameAndCluster(addon.AddonName, addon.ClusterName) if err != nil { logrus.Errorf("%v", err) - return errors.New("failed to get addon routing from database") + return errors.New("failed to get addon instance from database") } - if routing != nil && (addon.Options == nil || routing.Version != addon.Options["version"]) { - return errors.New(i18n.OrgSprintf(addon.OrgID, I18nClusterAddonRedeploy, addon.AddonName, routing.Version)) + if instance != nil && (addon.Options == nil || instance.Version != addon.Options["version"]) { + return errors.New(i18n.OrgSprintf(addon.OrgID, I18nClusterAddonRedeploy, addon.AddonName, instance.Version)) } } From 8b674b6f7e751b273002cec35f33561b814d1800 Mon Sep 17 00:00:00 2001 From: CeerDecy <1748788674@qq.com> Date: Sun, 29 Sep 2024 10:47:51 +0800 Subject: [PATCH 4/9] feat: create addon test Signed-off-by: CeerDecy <1748788674@qq.com> --- .../orchestrator/endpoints/addon_test.go | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/internal/tools/orchestrator/endpoints/addon_test.go b/internal/tools/orchestrator/endpoints/addon_test.go index bd4eaff9122..0f43e6e73aa 100644 --- a/internal/tools/orchestrator/endpoints/addon_test.go +++ b/internal/tools/orchestrator/endpoints/addon_test.go @@ -15,8 +15,11 @@ package endpoints import ( + "context" "math/rand" + "net/http" "reflect" + "strings" "sync" "testing" @@ -212,3 +215,66 @@ func TestConcurrentReadWriteProjectInfos(t *testing.T) { assert.Equal(t, true, ok) } } + +func TestCreateAddonDirectly(t *testing.T) { + e := Endpoints{} + + for _, test := range []struct { + payload string + orgid string + userid string + }{ + { + payload: `{ + "addons": { + "registercenter": { + "plan": "registercenter:basic", + "options": { + "version": "2.0.0" + } + } + }, + "workspace": "TEST", + "shareScope": "PROJECT", + "projectId": 88888, + "clusterName": "test" +}`, + orgid: "666", + userid: "666", + }, + + { + payload: `{ + "addons": { + "config-center": { + "plan": "config-center:basic", + "options": { + "version": "2.0.0" + } + } + }, + "workspace": "TEST", + "shareScope": "PROJECT", + "projectId": 88888, + "clusterName": "test" +}`, + orgid: "666", + userid: "666", + }, + } { + payload := strings.NewReader(test.payload) + req, err := http.NewRequest("", "", payload) + if err != nil { + t.Fatal(err) + } + req.Header.Add("org-id", test.orgid) + req.Header.Add("USER-ID", test.userid) + + monkey.PatchInstanceMethod(reflect.TypeOf(e.addon), "AddonCreate", func(a *addon.Addon, req apistructs.AddonDirectCreateRequest) ([]string, error) { + return []string{"test success!"}, nil + }) + + _, _ = e.CreateAddonDirectly(context.Background(), req, nil) + } + +} From cfc6c9a5865927652bf5ec647245c761a79b96c3 Mon Sep 17 00:00:00 2001 From: CeerDecy <1748788674@qq.com> Date: Wed, 23 Oct 2024 11:40:07 +0800 Subject: [PATCH 5/9] feat: remove cluster-addon vars Signed-off-by: CeerDecy <1748788674@qq.com> --- cmd/orchestrator/conf/i18n/orchestrator-log-trans.yaml | 4 ++-- internal/tools/orchestrator/services/addon/addon.go | 2 +- .../tools/orchestrator/services/addon/addon_handler.go | 7 ++----- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/cmd/orchestrator/conf/i18n/orchestrator-log-trans.yaml b/cmd/orchestrator/conf/i18n/orchestrator-log-trans.yaml index fc39acf5322..d33ec23015e 100644 --- a/cmd/orchestrator/conf/i18n/orchestrator-log-trans.yaml +++ b/cmd/orchestrator/conf/i18n/orchestrator-log-trans.yaml @@ -21,7 +21,7 @@ zh: AddonPlanIllegal: "Addon %s 规格不合法, Basic 规格 Addon 无法在生产环境使用" AddonFormatIllegal: "Addon %s 格式不合法, 请检查 dice.yml 中 addon 部分是否正确" AddonDeprecated: "Addon %s 当前版本:%v 已被废弃,请在dice.yml中重新配置" - ClusterAddonRedeploy: "Addon %s 在集群中存在,请选择部署 %v 版本,来进行关联" + ClusterAddonRedeploy: "Addon %s 在集群中存在,请选择部署 %v 版本,来进行关联,您当前部署的版本为:%v" en: WaitingForAddonTimeOut: "Waiting for the addon (%s)(%s) to be healthy timeout (%d min)" @@ -46,4 +46,4 @@ en: AddonPlanIllegal: "Addon %s plan is illegal, Basic plan addon cannot be used in production environment" AddonFormatIllegal: "Addon %s format is illegal, please check the dice.yml addon section" AddonDeprecated: "Addon %s current version: %v deprecated, please reconfigure in dice.yml" - ClusterAddonRedeploy: "Addon %s is existing,please select version: %v to link" + ClusterAddonRedeploy: "Addon %s is existing, please select version: %v to link, your deploy version is %v" diff --git a/internal/tools/orchestrator/services/addon/addon.go b/internal/tools/orchestrator/services/addon/addon.go index c41000610d0..069e8f2c8a6 100644 --- a/internal/tools/orchestrator/services/addon/addon.go +++ b/internal/tools/orchestrator/services/addon/addon.go @@ -2705,7 +2705,7 @@ func (a *Addon) ListCustomAddon() (*[]map[string]interface{}, error) { addonMap["addonName"] = item.Name addonMap["vars"] = addonSpec.ConfigVars switch item.Name { - case "mysql", "api-gateway", "monitor": + case "mysql", "api-gateway", "monitor", apistructs.AddonRegisterCenter, apistructs.AddonNewConfigCenter: addonMap["vars"] = nil case "canal": addonMap["vars"] = []string{ diff --git a/internal/tools/orchestrator/services/addon/addon_handler.go b/internal/tools/orchestrator/services/addon/addon_handler.go index dd2fa2c3810..01ce3b4fc67 100644 --- a/internal/tools/orchestrator/services/addon/addon_handler.go +++ b/internal/tools/orchestrator/services/addon/addon_handler.go @@ -284,10 +284,7 @@ func (a *Addon) AddonDelete(req apistructs.AddonDirectDeleteRequest) error { } func (a *Addon) AddonCreate(req apistructs.AddonDirectCreateRequest) ([]string, error) { - if len(req.Addons) != 1 { - return nil, fmt.Errorf("len(req.Addons) != 1") - } - baseAddons := []apistructs.AddonCreateItem{} + var baseAddons []apistructs.AddonCreateItem for name, a := range req.Addons { plan := strings.SplitN(a.Plan, ":", 2) if len(plan) != 2 { @@ -354,7 +351,7 @@ func (a *Addon) checkAddonDeployable(addon apistructs.AddonHandlerCreateItem, sp return errors.New("failed to get addon instance from database") } if instance != nil && (addon.Options == nil || instance.Version != addon.Options["version"]) { - return errors.New(i18n.OrgSprintf(addon.OrgID, I18nClusterAddonRedeploy, addon.AddonName, instance.Version)) + return errors.New(i18n.OrgSprintf(addon.OrgID, I18nClusterAddonRedeploy, addon.AddonName, instance.Version, addon.Options["version"])) } } From ce7a4a2be23de655ec189f1c99d076041cb17480 Mon Sep 17 00:00:00 2001 From: CeerDecy <1748788674@qq.com> Date: Thu, 24 Oct 2024 11:24:57 +0800 Subject: [PATCH 6/9] polish: nice node Signed-off-by: CeerDecy <1748788674@qq.com> --- .../tools/orchestrator/endpoints/addon.go | 33 +------------------ .../orchestrator/services/addon/addon.go | 2 +- .../services/addon/addon_handler.go | 1 + 3 files changed, 3 insertions(+), 33 deletions(-) diff --git a/internal/tools/orchestrator/endpoints/addon.go b/internal/tools/orchestrator/endpoints/addon.go index f052a6be89d..fce82512e6b 100644 --- a/internal/tools/orchestrator/endpoints/addon.go +++ b/internal/tools/orchestrator/endpoints/addon.go @@ -71,38 +71,7 @@ func (e *Endpoints) CreateAddonDirectly(ctx context.Context, r *http.Request, va // return apierrors.ErrCreateAddon.AccessDenied().ToResp(), nil // } // } - var hasRegister, hasConfig bool - var targetVersion string - for _, on := range addonCreateReq.Addons { - if strings.Contains(on.Plan, apistructs.AddonRegisterCenter) { - hasRegister = true - if on.Options != nil { - targetVersion = on.Options["version"] - } - } - if strings.Contains(on.Plan, apistructs.AddonNewConfigCenter) { - hasConfig = true - if on.Options != nil && targetVersion == "" { - targetVersion = on.Options["version"] - } - } - } - - if hasRegister && !hasConfig { - addonCreateReq.Addons["config-center"] = &diceyml.AddOn{ - Plan: fmt.Sprintf("%s:%s", apistructs.AddonNewConfigCenter, "basic"), - Options: map[string]string{ - "version": targetVersion, - }, - } - } else if !hasRegister && hasConfig { - addonCreateReq.Addons["register-center"] = &diceyml.AddOn{ - Plan: fmt.Sprintf("%s:%s", apistructs.AddonRegisterCenter, "basic"), - Options: map[string]string{ - "version": targetVersion, - }, - } - } + e.bindingDeploy(&addonCreateReq) addonid, err := e.addon.AddonCreate(addonCreateReq) if err != nil { diff --git a/internal/tools/orchestrator/services/addon/addon.go b/internal/tools/orchestrator/services/addon/addon.go index 069e8f2c8a6..d6f4e1012ad 100644 --- a/internal/tools/orchestrator/services/addon/addon.go +++ b/internal/tools/orchestrator/services/addon/addon.go @@ -2705,7 +2705,7 @@ func (a *Addon) ListCustomAddon() (*[]map[string]interface{}, error) { addonMap["addonName"] = item.Name addonMap["vars"] = addonSpec.ConfigVars switch item.Name { - case "mysql", "api-gateway", "monitor", apistructs.AddonRegisterCenter, apistructs.AddonNewConfigCenter: + case apistructs.AddonMySQL, apistructs.AddonApiGateway, apistructs.AddonMonitor, apistructs.AddonRegisterCenter, apistructs.AddonNewConfigCenter: addonMap["vars"] = nil case "canal": addonMap["vars"] = []string{ diff --git a/internal/tools/orchestrator/services/addon/addon_handler.go b/internal/tools/orchestrator/services/addon/addon_handler.go index 01ce3b4fc67..bc87da1a6f0 100644 --- a/internal/tools/orchestrator/services/addon/addon_handler.go +++ b/internal/tools/orchestrator/services/addon/addon_handler.go @@ -322,6 +322,7 @@ func (a *Addon) AddonCreate(req apistructs.AddonDirectCreateRequest) ([]string, } if err := a.checkAddonDeployable(addonItem, addonSpec); err != nil { + logrus.Error(err) return nil, err } From 0bd970b94b473a6ccdcf3ad787cb690af07f43b7 Mon Sep 17 00:00:00 2001 From: CeerDecy <1748788674@qq.com> Date: Thu, 24 Oct 2024 14:57:13 +0800 Subject: [PATCH 7/9] remove useless log Signed-off-by: CeerDecy <1748788674@qq.com> --- .../scheduler/executor/plugins/k8s/instanceinfosync/pod.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/tools/orchestrator/scheduler/executor/plugins/k8s/instanceinfosync/pod.go b/internal/tools/orchestrator/scheduler/executor/plugins/k8s/instanceinfosync/pod.go index 53436ba43d6..dde28213991 100644 --- a/internal/tools/orchestrator/scheduler/executor/plugins/k8s/instanceinfosync/pod.go +++ b/internal/tools/orchestrator/scheduler/executor/plugins/k8s/instanceinfosync/pod.go @@ -498,7 +498,6 @@ func updatePodAndInstance(dbclient *instanceinfo.Client, podlist *corev1.PodList } } } else { - logrus.Infof("get [currentContainerID] from mainContainer") currentTerminatedContainer := mainContainer.State.Terminated if currentTerminatedContainer != nil { if len(strings.Split(mainContainer.ContainerID, "://")) == 2 { From 714ed1104cf41f034b4019654a3c698cd218220c Mon Sep 17 00:00:00 2001 From: CeerDecy <1748788674@qq.com> Date: Thu, 24 Oct 2024 14:59:24 +0800 Subject: [PATCH 8/9] polish: registercenter and configcenter binding deploy Signed-off-by: CeerDecy <1748788674@qq.com> --- .../tools/orchestrator/endpoints/endpoints.go | 34 +++++++++++++++++++ .../services/addon/addon_handler.go | 3 +- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/internal/tools/orchestrator/endpoints/endpoints.go b/internal/tools/orchestrator/endpoints/endpoints.go index 8652ff46a79..f0bd9a49784 100644 --- a/internal/tools/orchestrator/endpoints/endpoints.go +++ b/internal/tools/orchestrator/endpoints/endpoints.go @@ -17,8 +17,10 @@ package endpoints import ( "context" + "fmt" "net/http" "strconv" + "strings" "time" "github.com/pkg/errors" @@ -27,6 +29,7 @@ import ( "golang.org/x/text/message" "github.com/erda-project/erda-proto-go/core/dicehub/release/pb" + "github.com/erda-project/erda/apistructs" "github.com/erda-project/erda/bundle" "github.com/erda-project/erda/internal/tools/orchestrator/dbclient" "github.com/erda-project/erda/internal/tools/orchestrator/events" @@ -44,6 +47,7 @@ import ( "github.com/erda-project/erda/pkg/crypto/encryption" "github.com/erda-project/erda/pkg/goroutinepool" "github.com/erda-project/erda/pkg/http/httpserver" + "github.com/erda-project/erda/pkg/parser/diceyml" "github.com/erda-project/erda/pkg/strutil" ) @@ -507,3 +511,33 @@ func (e *Endpoints) FullGCLoop(ctx context.Context) { } } } + +func (e *Endpoints) inspectAddonVersions(addOns diceyml.AddOns) (versions map[string]string) { + versions = make(map[string]string) + for _, addOn := range addOns { + addonInfo := strings.SplitN(addOn.Plan, ":", 2) + versions[addonInfo[0]] = addOn.Options["version"] + } + return +} + +func (e *Endpoints) bindingDeploy(req *apistructs.AddonDirectCreateRequest) { + versions := e.inspectAddonVersions(req.Addons) + registerVersion, hasR := versions[apistructs.AddonRegisterCenter] + configVersion, hasC := versions[apistructs.AddonNewConfigCenter] + if hasR && !hasC { + e.appendAddon(req, apistructs.AddonNewConfigCenter, registerVersion) + } else if !hasR && hasC { + e.appendAddon(req, apistructs.AddonRegisterCenter, configVersion) + } +} + +func (e *Endpoints) appendAddon(req *apistructs.AddonDirectCreateRequest, addonType string, version string) { + name := addonType + strutil.RandStr(5) + req.Addons[name] = &diceyml.AddOn{ + Plan: fmt.Sprintf("%s:%s", addonType, apistructs.AddonBasic), + Options: map[string]string{ + "version": version, + }, + } +} diff --git a/internal/tools/orchestrator/services/addon/addon_handler.go b/internal/tools/orchestrator/services/addon/addon_handler.go index bc87da1a6f0..fbd50e4783a 100644 --- a/internal/tools/orchestrator/services/addon/addon_handler.go +++ b/internal/tools/orchestrator/services/addon/addon_handler.go @@ -322,7 +322,7 @@ func (a *Addon) AddonCreate(req apistructs.AddonDirectCreateRequest) ([]string, } if err := a.checkAddonDeployable(addonItem, addonSpec); err != nil { - logrus.Error(err) + logrus.Errorf("%s", err) return nil, err } @@ -354,6 +354,7 @@ func (a *Addon) checkAddonDeployable(addon apistructs.AddonHandlerCreateItem, sp if instance != nil && (addon.Options == nil || instance.Version != addon.Options["version"]) { return errors.New(i18n.OrgSprintf(addon.OrgID, I18nClusterAddonRedeploy, addon.AddonName, instance.Version, addon.Options["version"])) } + logrus.Infof("no deployed %s addon found", addon.AddonName) } switch strutil.ToLower(addon.AddonName) { From 2cef038a8bdf8f37563d5555a7b5bf21911bbecd Mon Sep 17 00:00:00 2001 From: CeerDecy <1748788674@qq.com> Date: Thu, 24 Oct 2024 15:13:43 +0800 Subject: [PATCH 9/9] polish: use constant addon name Signed-off-by: CeerDecy <1748788674@qq.com> --- apistructs/addon.go | 2 ++ internal/tools/orchestrator/services/addon/addon.go | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apistructs/addon.go b/apistructs/addon.go index 5fb7b93abad..c69c343961e 100644 --- a/apistructs/addon.go +++ b/apistructs/addon.go @@ -334,6 +334,8 @@ const ( AddonRegisterCenter = "registercenter" // mse-nacos AddonMSENacos = "mse-nacos" + // custom + AddonCustom = "custom" ) // AddonRes addon信息 diff --git a/internal/tools/orchestrator/services/addon/addon.go b/internal/tools/orchestrator/services/addon/addon.go index d6f4e1012ad..ab6b448dfdd 100644 --- a/internal/tools/orchestrator/services/addon/addon.go +++ b/internal/tools/orchestrator/services/addon/addon.go @@ -2707,13 +2707,13 @@ func (a *Addon) ListCustomAddon() (*[]map[string]interface{}, error) { switch item.Name { case apistructs.AddonMySQL, apistructs.AddonApiGateway, apistructs.AddonMonitor, apistructs.AddonRegisterCenter, apistructs.AddonNewConfigCenter: addonMap["vars"] = nil - case "canal": + case apistructs.AddonCanal: addonMap["vars"] = []string{ "canal.instance.master.address", "canal.instance.dbUsername", "canal.instance.dbPassword", "mysql"} - case "custom": + case apistructs.AddonCustom: addonMap["vars"] = []string{} } addonMap["plan"] = createableAddonPlan[item.Name]