diff --git a/assets/k8sclusterinfo.yaml b/assets/k8sclusterinfo.yaml index b161cc39..932ed0ad 100644 --- a/assets/k8sclusterinfo.yaml +++ b/assets/k8sclusterinfo.yaml @@ -6,13 +6,66 @@ # : Name of the CSP # nodegroupsWithCluster: # version: -# - region: [region1, region2, all(special keyword)] +# - region: [region1, region2, common(special keyword: most of regions)] +# k8scluster: + azure: + nodegroupsWithCluster: true + nodeImageDesignation: false + version: + - region: [westeurope,westus] + available: + - name: 1.29 + id: 1.29.4 + - name: 1.28 + id: 1.28.9 + - name: 1.27 + id: 1.27.13 + - region: [common] + available: + - name: 1.29 + id: 1.29.5 + - name: 1.28 + id: 1.28.10 + - name: 1.27 + id: 1.27.14 + rootDisk: + - region: [common] + type: + - name: default + id: default + size: + min: 10 + max: 40 + gcp: + nodegroupsWithCluster: true + nodeImageDesignation: true + version: + - region: [common] + available: + - name: 1.29 + id: 1.29.6-gke.1038001 + - name: 1.28 + id: 1.28.11-gke.1019001 + - name: 1.26 + id: 1.27.14-gke.1059002 + rootDisk: + - region: [common] + type: + - name: default + id: default + size: + min: 10 + max: 40 alibaba: nodegroupsWithCluster: false + nodeImageDesignation: true version: - - region: [ap-northeast-1,ap-northeast-2,ap-southeast-1,ap-southeast-3,ap-southeast-5,us-west-1,us-east-1,eu-central-1,eu-west-1,cn-beijing,cn-hongkong,cn-shanghai,cn-huhehaote,cn-heyuan,cn-wulanchabu,cn-guangzhou] + # ServiceUnavailable or NotSupportedSLB + - region: [me-east-1, cn-zhangjiakou, cn-hangzhou, cn-shenzhen, cn-chengdu, ap-south-1, ap-sourtheast-2] + # ap-northeast-1,ap-northeast-2,ap-southeast-1,ap-southeast-3,ap-southeast-5,us-west-1,us-east-1,eu-central-1,eu-west-1,cn-beijing,cn-hongkong,cn-shanghai,cn-huhehaote,cn-heyuan,cn-wulanchabu,cn-guangzhou + - region: [common] available: - name: 1.30 id: 1.30.1-aliyun.1 @@ -21,7 +74,7 @@ k8scluster: - name: 1.26 id: 1.26.15-aliyun.1 rootDisk: - - region: [all] + - region: [common] type: - name: cloud_essd id: cloud_essd @@ -30,6 +83,7 @@ k8scluster: max: 40 nhncloud: nodegroupsWithCluster: true + nodeImageDesignation: true version: - region: [kr1, kr2] available: @@ -42,7 +96,7 @@ k8scluster: - name: 1.26 id: v1.26.3 rootDisk: - - region: [all] + - region: [common] type: - name: default id: default @@ -51,8 +105,9 @@ k8scluster: max: 40 tencent: nodegroupsWithCluster: false + nodeImageDesignation: true version: - - region: [all] + - region: [common] available: - name: 1.28 id: 1.28.3 @@ -61,7 +116,7 @@ k8scluster: - name: 1.24 id: 1.24.4 rootDisk: - - region: [all] + - region: [common] type: - name: default id: default diff --git a/src/core/common/common.go b/src/core/common/common.go index 3805704d..0ebff622 100644 --- a/src/core/common/common.go +++ b/src/core/common/common.go @@ -91,6 +91,8 @@ const ( StrK8s string = "k8s" StrKubernetes string = "kubernetes" StrContainer string = "container" + StrCommon string = "common" + StrEmpty string = "empty" StrDefaultResourceName string = "-systemdefault-" // StrFirewallRule string = "firewallRule" diff --git a/src/core/common/utility.go b/src/core/common/utility.go index 4a37a541..6045cdfc 100644 --- a/src/core/common/utility.go +++ b/src/core/common/utility.go @@ -1307,10 +1307,11 @@ func getK8sClusterDetail(providerName string) *K8sClusterDetail { // GetAvailableK8sClusterVersion is func to get available kubernetes cluster versions for provider and region from K8sClusterInfo func GetAvailableK8sClusterVersion(providerName string, regionName string) (*[]K8sClusterVersionDetailAvailable, error) { // - // Check available K8sCluster version and node image in k8sclusterinfo.yaml + // Check available K8sCluster version in k8sclusterinfo.yaml // providerName = strings.ToLower(providerName) + regionName = strings.ToLower(regionName) // Get K8sClusterDetail for providerName k8sClusterDetail := getK8sClusterDetail(providerName) @@ -1318,19 +1319,38 @@ func GetAvailableK8sClusterVersion(providerName string, regionName string) (*[]K return nil, fmt.Errorf("unsupported provider(%s) for kubernetes cluster", providerName) } - // Get Available Versions for regionName + // Check if 'regionName' exists var availableVersion *[]K8sClusterVersionDetailAvailable = nil for _, versionDetail := range k8sClusterDetail.Version { for _, region := range versionDetail.Region { region = strings.ToLower(region) - if region == "all" || region == regionName { - availableVersion = &versionDetail.Available + if strings.EqualFold(region, regionName) { + if len(versionDetail.Available) == 0 { + availableVersion = &[]K8sClusterVersionDetailAvailable{{StrEmpty, StrEmpty}} + } else { + availableVersion = &versionDetail.Available + } + return availableVersion, nil + } + } + } + + // Check if 'common' exists + for _, versionDetail := range k8sClusterDetail.Version { + for _, region := range versionDetail.Region { + region = strings.ToLower(region) + if strings.EqualFold(region, StrCommon) { + if len(versionDetail.Available) == 0 { + availableVersion = &[]K8sClusterVersionDetailAvailable{{StrEmpty, StrEmpty}} + } else { + availableVersion = &versionDetail.Available + } return availableVersion, nil } } } - return nil, fmt.Errorf("no available kubernetes cluster version for provider(%s):region(%s)", providerName, regionName) + return nil, fmt.Errorf("no entry for provider(%s):region(%s)", providerName, regionName) } // GetAvailableK8sClusterNodeImage is func to get available kubernetes cluster node images for provider and region from K8sClusterInfo @@ -1340,6 +1360,7 @@ func GetAvailableK8sClusterNodeImage(providerName string, regionName string) (*[ // providerName = strings.ToLower(providerName) + regionName = strings.ToLower(regionName) // Get K8sClusterDetail for providerName k8sClusterDetail := getK8sClusterDetail(providerName) @@ -1347,13 +1368,34 @@ func GetAvailableK8sClusterNodeImage(providerName string, regionName string) (*[ return nil, fmt.Errorf("unsupported provider(%s) for kubernetes cluster", providerName) } - // Get Available Node Image for regionName + // Check if 'regionName' exists var availableNodeImage *[]K8sClusterNodeImageDetailAvailable = nil for _, nodeImageDetail := range k8sClusterDetail.NodeImage { for _, region := range nodeImageDetail.Region { region = strings.ToLower(region) - if region == "all" || region == regionName { - availableNodeImage = &nodeImageDetail.Available + if strings.EqualFold(region, regionName) { + if len(nodeImageDetail.Available) == 0 { + availableNodeImage = &[]K8sClusterNodeImageDetailAvailable{{StrEmpty, StrEmpty}} + break + } else { + availableNodeImage = &nodeImageDetail.Available + } + return availableNodeImage, nil + } + } + } + + // Check if 'common' exists + for _, nodeImageDetail := range k8sClusterDetail.NodeImage { + for _, region := range nodeImageDetail.Region { + region = strings.ToLower(region) + if strings.EqualFold(region, StrCommon) { + if len(nodeImageDetail.Available) == 0 { + availableNodeImage = &[]K8sClusterNodeImageDetailAvailable{{StrEmpty, StrEmpty}} + break + } else { + availableNodeImage = &nodeImageDetail.Available + } return availableNodeImage, nil } } diff --git a/src/core/mcis/k8scluster.go b/src/core/mcis/k8scluster.go index bbce69ca..604aeee7 100644 --- a/src/core/mcis/k8scluster.go +++ b/src/core/mcis/k8scluster.go @@ -485,38 +485,8 @@ func CreateK8sCluster(nsId string, u *TbK8sClusterReq, option string) (TbK8sClus /* * Check for K8sCluster Enablement from K8sClusterSetting */ - - connConfig, err := common.GetConnConfig(u.ConnectionName) + err = checkK8sClusterEnablement(u.ConnectionName) if err != nil { - err := fmt.Errorf("Failed to get the connConfig " + u.ConnectionName + ": " + err.Error()) - log.Err(err).Msg("Failed to Create a K8sCluster") - return emptyObj, err - } - - cloudType := connConfig.ProviderName - - // Convert cloud type to field name (e.g., AWS to Aws, OPENSTACK to Openstack) - lowercase := strings.ToLower(cloudType) - fnCloudType := strings.ToUpper(string(lowercase[0])) + lowercase[1:] - - // Get cloud setting with field name - cloudSetting := common.CloudSetting{} - - getCloudSetting := func() { - defer func() { - if err := recover(); err != nil { - log.Error().Msgf("%v", err) - cloudSetting = reflect.ValueOf(&common.RuntimeConf.Cloud).Elem().FieldByName("Common").Interface().(common.CloudSetting) - } - }() - - cloudSetting = reflect.ValueOf(&common.RuntimeConf.Cloud).Elem().FieldByName(fnCloudType).Interface().(common.CloudSetting) - } - - getCloudSetting() - - if cloudSetting.K8sCluster.Enable != "y" { - err := fmt.Errorf("The K8sCluster Management function is not enabled for Cloud(" + fnCloudType + ")") log.Err(err).Msg("Failed to Create a K8sCluster") return emptyObj, err } @@ -527,8 +497,8 @@ func CreateK8sCluster(nsId string, u *TbK8sClusterReq, option string) (TbK8sClus spName := fmt.Sprintf("%s-%s", nsId, u.Id) - // Validate K8sCluster Version - err = validateK8sClusterVersion(connConfig.ProviderName, connConfig.RegionDetail.RegionName, u.Version) + // Validate + err = validateAtCreateK8sCluster(u) if err != nil { log.Err(err).Msgf("Failed to Create a K8sCluster: Requested K8sVersion(%s)", u.Version) return emptyObj, err @@ -796,37 +766,8 @@ func AddK8sNodeGroup(nsId string, k8sClusterId string, u *TbK8sNodeGroupReq) (Tb * Check for K8sCluster Enablement from ClusterSetting */ - connConfig, err := common.GetConnConfig(oldTbK8sCInfo.ConnectionName) + err = checkK8sClusterEnablement(oldTbK8sCInfo.ConnectionName) if err != nil { - err := fmt.Errorf("failed to get the connConfig " + oldTbK8sCInfo.ConnectionName + ": " + err.Error()) - log.Err(err).Msg("Failed to Add K8sNodeGroup") - return emptyObj, err - } - - cloudType := connConfig.ProviderName - - // Convert cloud type to field name (e.g., AWS to Aws, OPENSTACK to Openstack) - lowercase := strings.ToLower(cloudType) - fnCloudType := strings.ToUpper(string(lowercase[0])) + lowercase[1:] - - // Get cloud setting with field name - cloudSetting := common.CloudSetting{} - - getCloudSetting := func() { - defer func() { - if err := recover(); err != nil { - log.Error().Msgf("%v", err) - cloudSetting = reflect.ValueOf(&common.RuntimeConf.Cloud).Elem().FieldByName("Common").Interface().(common.CloudSetting) - } - }() - - cloudSetting = reflect.ValueOf(&common.RuntimeConf.Cloud).Elem().FieldByName(fnCloudType).Interface().(common.CloudSetting) - } - - getCloudSetting() - - if cloudSetting.K8sCluster.Enable != "y" { - err := fmt.Errorf("The K8sCluster Management function is not enabled for Cloud(" + fnCloudType + ")") log.Err(err).Msg("Failed to Add K8sNodeGroup") return emptyObj, err } @@ -1629,7 +1570,7 @@ func UpgradeK8sCluster(nsId string, k8sClusterId string, u *TbUpgradeK8sClusterR err := validate.Struct(u) if err != nil { if _, ok := err.(*validator.InvalidValidationError); ok { - log.Err(err).Msg("Failed to Upgrade K8sCluster") + log.Err(err).Msg("Failed to Upgrade a K8sCluster") return emptyObj, err } @@ -1638,13 +1579,13 @@ func UpgradeK8sCluster(nsId string, k8sClusterId string, u *TbUpgradeK8sClusterR check, err := CheckK8sCluster(nsId, k8sClusterId) if err != nil { - log.Err(err).Msg("Failed to Upgrade K8sCluster") + log.Err(err).Msg("Failed to Upgrade a K8sCluster") return emptyObj, err } if !check { err := fmt.Errorf("The K8sCluster " + k8sClusterId + " does not exist.") - log.Err(err).Msg("Failed to Upgrade K8sCluster") + log.Err(err).Msg("Failed to Upgrade a K8sCluster") return emptyObj, err } @@ -1656,7 +1597,7 @@ func UpgradeK8sCluster(nsId string, k8sClusterId string, u *TbUpgradeK8sClusterR kv, err := kvstore.GetKv(k) if err != nil { err = fmt.Errorf("In UpgradeK8sCluster(); kvstore.GetKv() returned an error: " + err.Error()) - log.Err(err).Msg("Failed to Upgrade K8sCluster") + log.Err(err).Msg("Failed to Upgrade a K8sCluster") return emptyObj, err } @@ -1664,7 +1605,7 @@ func UpgradeK8sCluster(nsId string, k8sClusterId string, u *TbUpgradeK8sClusterR err = json.Unmarshal([]byte(kv.Value), &oldTbK8sCInfo) if err != nil { - log.Err(err).Msg("Failed to Upgrade K8sCluster") + log.Err(err).Msg("Failed to Upgrade a K8sCluster") return emptyObj, err } @@ -1672,38 +1613,9 @@ func UpgradeK8sCluster(nsId string, k8sClusterId string, u *TbUpgradeK8sClusterR * Check for K8sCluster Enablement from K8sClusterSetting */ - connConfig, err := common.GetConnConfig(oldTbK8sCInfo.ConnectionName) + err = checkK8sClusterEnablement(oldTbK8sCInfo.ConnectionName) if err != nil { - err := fmt.Errorf("failed to get the connConfig " + oldTbK8sCInfo.ConnectionName + ": " + err.Error()) - log.Err(err).Msg("Failed to Upgrade K8sCluster") - return emptyObj, err - } - - cloudType := connConfig.ProviderName - - // Convert cloud type to field name (e.g., AWS to Aws, OPENSTACK to Openstack) - lowercase := strings.ToLower(cloudType) - fnCloudType := strings.ToUpper(string(lowercase[0])) + lowercase[1:] - - // Get cloud setting with field name - cloudSetting := common.CloudSetting{} - - getCloudSetting := func() { - defer func() { - if err := recover(); err != nil { - log.Error().Msgf("%v", err) - cloudSetting = reflect.ValueOf(&common.RuntimeConf.Cloud).Elem().FieldByName("Common").Interface().(common.CloudSetting) - } - }() - - cloudSetting = reflect.ValueOf(&common.RuntimeConf.Cloud).Elem().FieldByName(fnCloudType).Interface().(common.CloudSetting) - } - - getCloudSetting() - - if cloudSetting.K8sCluster.Enable != "y" { - err := fmt.Errorf("The K8sCluster Management function is not enabled for Cloud(" + fnCloudType + ")") - log.Err(err).Msg("Failed to Upgrade K8sCluster") + log.Err(err).Msg("Failed to Upgrade a K8sCluster") return emptyObj, err } @@ -1711,10 +1623,10 @@ func UpgradeK8sCluster(nsId string, k8sClusterId string, u *TbUpgradeK8sClusterR * Build RequestBody for SpiderUpgradeClusterReq{} */ - // Validate K8sCluster Version - err = validateK8sClusterVersion(connConfig.ProviderName, connConfig.RegionDetail.RegionName, u.Version) + // Validate + err = validateAtUpgradeK8sCluster(oldTbK8sCInfo.ConnectionName, u) if err != nil { - log.Err(err).Msg("Failed to Upgrade K8sCluster") + log.Err(err).Msg("Failed to Upgrade a K8sCluster") return emptyObj, err } spVersion := u.Version @@ -1744,7 +1656,7 @@ func UpgradeK8sCluster(nsId string, k8sClusterId string, u *TbUpgradeK8sClusterR ) if err != nil { - log.Err(err).Msg("Failed to Upgrade K8sCluster") + log.Err(err).Msg("Failed to Upgrade a K8sCluster") return emptyObj, err } @@ -1762,7 +1674,7 @@ func UpgradeK8sCluster(nsId string, k8sClusterId string, u *TbUpgradeK8sClusterR err = kvstore.Put(k, string(Val)) if err != nil { - log.Err(err).Msg("Failed to Upgrade K8sCluster") + log.Err(err).Msg("Failed to Upgrade a K8sCluster") return emptyObj, err } @@ -1933,6 +1845,70 @@ func convertSpiderNodeGroupStatusToTbK8sNodeGroupStatus(spNodeGroupStatus Spider return TbK8sNodeGroupInactive } +// checkK8sClusterEnablement returns the enablement status(nil or error) for K8sCluster related to Connection. +func checkK8sClusterEnablement(connectionName string) error { + connConfig, err := common.GetConnConfig(connectionName) + if err != nil { + err := fmt.Errorf("failed to get the connConfig " + connectionName + ": " + err.Error()) + return err + } + + cloudType := connConfig.ProviderName + + // Convert cloud type to field name (e.g., AWS to Aws, OPENSTACK to Openstack) + lowercase := strings.ToLower(cloudType) + fnCloudType := strings.ToUpper(string(lowercase[0])) + lowercase[1:] + + // Get cloud setting with field name + cloudSetting := common.CloudSetting{} + + getCloudSetting := func() { + defer func() { + if err := recover(); err != nil { + log.Error().Msgf("%v", err) + cloudSetting = reflect.ValueOf(&common.RuntimeConf.Cloud).Elem().FieldByName("Common").Interface().(common.CloudSetting) + } + }() + + cloudSetting = reflect.ValueOf(&common.RuntimeConf.Cloud).Elem().FieldByName(fnCloudType).Interface().(common.CloudSetting) + } + + getCloudSetting() + + if cloudSetting.K8sCluster.Enable != "y" { + err := fmt.Errorf("k8scluster management function is not enabled for cloud(" + fnCloudType + ")") + return err + } + + return nil +} + +func validateAtCreateK8sCluster(tbK8sClusterReq *TbK8sClusterReq) error { + connConfig, err := common.GetConnConfig(tbK8sClusterReq.ConnectionName) + + // Validate K8sCluster Version + err = validateK8sClusterVersion(connConfig.ProviderName, connConfig.RegionDetail.RegionName, tbK8sClusterReq.Version) + if err != nil { + log.Err(err).Msgf("Failed to Create a K8sCluster: Requested K8sVersion(%s)", tbK8sClusterReq.Version) + return err + } + + return nil +} + +func validateAtUpgradeK8sCluster(connectionName string, tbUpgradeK8sClusterReq *TbUpgradeK8sClusterReq) error { + connConfig, err := common.GetConnConfig(connectionName) + + // Validate K8sCluster Version + err = validateK8sClusterVersion(connConfig.ProviderName, connConfig.RegionDetail.RegionName, tbUpgradeK8sClusterReq.Version) + if err != nil { + log.Err(err).Msgf("Failed to Create a K8sCluster: Requested K8sVersion(%s)", tbUpgradeK8sClusterReq.Version) + return err + } + + return nil +} + func validateK8sClusterVersion(providerName, regionName, version string) error { availableVersion, err := common.GetAvailableK8sClusterVersion(providerName, regionName) if err != nil {