From da559be138201df0ecf2629287f3dc69179bf09c Mon Sep 17 00:00:00 2001 From: TangBin Date: Tue, 11 Dec 2018 17:52:28 +0800 Subject: [PATCH 1/6] update sku create & update & list method --- cmd/climc/shell/skus.go | 8 +- pkg/appsrv/handlerinfo.go | 2 +- pkg/compute/models/hosts.go | 2 +- pkg/compute/models/skus.go | 156 ++++++++++++++++++++++++++++++++---- 4 files changed, 145 insertions(+), 23 deletions(-) diff --git a/cmd/climc/shell/skus.go b/cmd/climc/shell/skus.go index 3fae33b88c..794f052e49 100644 --- a/cmd/climc/shell/skus.go +++ b/cmd/climc/shell/skus.go @@ -50,10 +50,9 @@ func init() { }) type ServerSkusCreateOptions struct { - Name string `help:"Name ID of SKU" required:"true" positional:"true"` CpuCoreCount int `help:"Cpu Count" required:"true" positional:"true"` MemorySizeMB int `help:"Memory MB" required:"true" positional:"true"` - Provider string `help:"Provider name" choices:"kvm|esxi"` + Provider string `help:"Provider name" choices:"all|kvm|esxi"` OsName *string `help:"OS name/type" choices:"Linux|Windows|Any" default:"Any"` SkuFamily *string `help:"sku family"` @@ -95,9 +94,8 @@ func init() { type ServerSkusUpdateOptions struct { ID string `help:"Name or ID of SKU" json:"-"` - Name *string `help:"new name of SKU"` - CpuCoreCount *int `help:"Cpu Count"` - MemorySizeMB *int `help:"Memory MB"` + CpuCoreCount *int `help:"Cpu Count"` + MemorySizeMB *int `help:"Memory MB"` SkuFamily *string `help:"sku family"` SkuCategory *string `help:"sku category" choices:"general_purpose|compute_optimized|memory_optimized|storage_optimized|hardware_accelerated|high_memory|high_storage"` diff --git a/pkg/appsrv/handlerinfo.go b/pkg/appsrv/handlerinfo.go index 6a7234ca65..048a4124cd 100644 --- a/pkg/appsrv/handlerinfo.go +++ b/pkg/appsrv/handlerinfo.go @@ -110,4 +110,4 @@ func (hi *SHandlerInfo) GetAppParams(params map[string]string, path []string) *S appParams.Params = params appParams.Path = path return &appParams -} \ No newline at end of file +} diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index 9fa926df40..d9107bdbfe 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -23,6 +23,7 @@ import ( "yunion.io/x/pkg/utils" "yunion.io/x/sqlchemy" + "yunion.io/x/onecloud/pkg/appsrv" "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" @@ -35,7 +36,6 @@ import ( "yunion.io/x/onecloud/pkg/mcclient/modules" "yunion.io/x/onecloud/pkg/util/httputils" "yunion.io/x/onecloud/pkg/util/logclient" - "yunion.io/x/onecloud/pkg/appsrv" ) const ( diff --git a/pkg/compute/models/skus.go b/pkg/compute/models/skus.go index 7b953b445b..7606c156da 100644 --- a/pkg/compute/models/skus.go +++ b/pkg/compute/models/skus.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "encoding/json" + "fmt" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -25,6 +26,17 @@ const ( SkuCategoryHighMemory = "high_memory" // 高内存型 ) +var InstanceFamilies map[string]string = map[string]string{ + SkuCategoryGeneralPurpose: "g1", + SkuCategoryBurstable: "t1", + SkuCategoryComputeOptimized: "c1", + SkuCategoryMemoryOptimized: "r1", + SkuCategoryStorageIOOptimized: "i1", + SkuCategoryHardwareAccelerated: "", + SkuCategoryHighStorage: "hc1", + SkuCategoryHighMemory: "hr1", +} + type SServerSkuManager struct { db.SStandaloneResourceBaseManager } @@ -87,13 +99,25 @@ func inWhiteList(provider string) bool { return true } switch provider { - case HYPERVISOR_ESXI, HYPERVISOR_KVM: + case HYPERVISOR_ESXI, HYPERVISOR_KVM, "all": // 空或者all时。表示`通用`私用云instance type列表 return true default: return false } } +func genInstanceType(family string, cpu, mem_mb int64) (string, error) { + if cpu < 0 { + return "", fmt.Errorf("cpu_core_count should great than zero") + } + + if mem_mb < 0 || mem_mb%1024 != 0 { + return "", fmt.Errorf("memory_size_mb should great than zero. and should be integral multiple of 1024") + } + + return fmt.Sprintf("ecs.%s.c%dm%d", family, cpu, mem_mb/1024), nil +} + func (self *SServerSkuManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool { return true } @@ -143,6 +167,50 @@ func (self *SServerSkuManager) ValidateCreateData(ctx context.Context, } data.Add(jsonutils.NewString(zoneObj.GetId()), "zone_id") } + + // name 由服务器端生成 + _, err := data.GetString("name") + if err != nil { + data.Remove("name") + } + + cpu, err := data.Int("cpu_core_count") + if err != nil { + return nil, httperrors.NewInputParameterError("cpu_core_count should not be empty") + } + + mem, err := data.Int("memory_size_mb") + if err != nil { + return nil, httperrors.NewInputParameterError("memory_size_mb should not be empty") + } + + category, _ := data.GetString("instance_type_category") + family, exists := InstanceFamilies[category] + if !exists { + return nil, httperrors.NewInputParameterError("instance_type_category %s is invalid", category) + } + // 格式 ecs.g1.c1m1 + name, err := genInstanceType(family, cpu, mem) + if err != nil { + return nil, httperrors.NewInputParameterError(err.Error()) + } + + data.Set("name", jsonutils.NewString(name)) + + q := self.Query().Equals("name", name) + if len(provider) > 0 { + q = q.Equals("provider", provider) + } else { + q = q.Filter(sqlchemy.OR( + sqlchemy.IsNull(q.Field("provider")), + sqlchemy.IsEmpty(q.Field("provider")), + )) + } + + if q.Count() > 0 { + return nil, httperrors.NewDuplicateResourceError("Duplicate sku") + } + return self.SStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data) } @@ -184,7 +252,15 @@ func (self *SServerSkuManager) GetPropertyInstanceSpecs(ctx context.Context, use q := self.Query() zone, err := query.GetString("zone") if err == nil && len(zone) > 0 { - q = q.Equals("zone_id", zone) + zoneObj, err := ZoneManager.FetchByIdOrName(userCred, zone) + if err != nil { + if err == sql.ErrNoRows { + return nil, httperrors.NewResourceNotFoundError2(ZoneManager.Keyword(), zone) + } + return nil, httperrors.NewGeneralError(err) + } + + q = q.Equals("zone_id", zoneObj.GetId()) } else { return nil, httperrors.NewMissingParameterError("zone") } @@ -255,12 +331,12 @@ func (self *SServerSku) ValidateUpdateData( data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { if !inWhiteList(self.Provider) { - return nil, httperrors.NewForbiddenError("can not create instance_type for public cloud %s", self.Provider) + return nil, httperrors.NewForbiddenError("can not update instance_type for public cloud %s", self.Provider) } provider, err := data.GetString("provider") if err == nil && !inWhiteList(provider) { - return nil, httperrors.NewForbiddenError("can not create instance_type for public cloud %s", provider) + return nil, httperrors.NewForbiddenError("can not update instance_type for public cloud %s", provider) } zoneStr := jsonutils.GetAnyString(data, []string{"zone", "zone_id"}) @@ -274,6 +350,50 @@ func (self *SServerSku) ValidateUpdateData( } data.Add(jsonutils.NewString(zoneObj.GetId()), "zone_id") } + + // name 由服务器端生成 + _, err = data.GetString("name") + if err != nil { + data.Remove("name") + } + + cpu, err := data.Int("cpu_core_count") + if err != nil { + cpu = int64(self.CpuCoreCount) + } + + mem, err := data.Int("memory_size_mb") + if err != nil { + mem = int64(self.MemorySizeMB) + } + + category, _ := data.GetString("instance_type_category") + family, exists := InstanceFamilies[category] + if !exists { + return nil, httperrors.NewInputParameterError("instance_type_category %s is invalid", category) + } + // 格式 ecs.g1.c1m1 + name, err := genInstanceType(family, cpu, mem) + if err != nil { + return nil, httperrors.NewInputParameterError(err.Error()) + } + + data.Set("name", jsonutils.NewString(name)) + + q := self.GetModelManager().Query().Equals("name", name) + if len(provider) > 0 { + q = q.Equals("provider", provider) + } else { + q = q.Filter(sqlchemy.OR( + sqlchemy.IsNull(q.Field("provider")), + sqlchemy.IsEmpty(q.Field("provider")), + )) + } + + if q.Count() > 0 { + return nil, httperrors.NewDuplicateResourceError("sku cpu %s mem %s(Mb) already exists", cpu, mem) + } + return self.SStandaloneResourceBase.ValidateUpdateData(ctx, userCred, query, data) } @@ -303,20 +423,23 @@ func (self *SServerSku) GetZoneExternalId() (string, error) { } func (manager *SServerSkuManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) { - queryDict := query.(*jsonutils.JSONDict) - provider := jsonutils.GetAnyString(query, []string{"provider"}) - if len(provider) > 0 { - if provider != "all" { - q = q.Equals("provider", provider) + if inWhiteList(provider) { + // provider 参数为空或者all时。表示查询`通用`私用云instance type列表 + if provider == "" || provider == "all" { + q = q.Filter(sqlchemy.OR( + sqlchemy.IsNull(q.Field("provider")), + sqlchemy.IsEmpty(q.Field("provider")), + )) + } else { + q = q.Filter(sqlchemy.OR( + sqlchemy.IsNull(q.Field("provider")), + sqlchemy.IsEmpty(q.Field("provider")), + sqlchemy.Equals(q.Field("provider"), provider), + )) } - - queryDict.Remove("provider") } else { - q = q.Filter(sqlchemy.OR( - sqlchemy.IsNull(q.Field("provider")), - sqlchemy.IsEmpty(q.Field("provider")), - )) + q = q.Equals("provider", provider) } q, err := manager.SStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query) @@ -336,8 +459,9 @@ func (manager *SServerSkuManager) ListItemFilter(ctx context.Context, q *sqlchem q = q.Equals("cloudregion_id", regionObj.GetId()) } + // 当查询私有云时,需要忽略zone参数 zoneStr := jsonutils.GetAnyString(query, []string{"zone", "zone_id"}) - if len(zoneStr) > 0 { + if !inWhiteList(provider) && len(zoneStr) > 0 { zoneObj, err := ZoneManager.FetchByIdOrName(nil, zoneStr) if err != nil { if err == sql.ErrNoRows { From 9318bf6683cfd64f4cc40f84af74718d5f404b6b Mon Sep 17 00:00:00 2001 From: TangBin Date: Tue, 11 Dec 2018 19:36:21 +0800 Subject: [PATCH 2/6] update sku create & update & list method --- cmd/climc/shell/skus.go | 9 +++---- pkg/compute/models/skus.go | 50 +++++++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/cmd/climc/shell/skus.go b/cmd/climc/shell/skus.go index 794f052e49..28d7e56950 100644 --- a/cmd/climc/shell/skus.go +++ b/cmd/climc/shell/skus.go @@ -54,9 +54,8 @@ func init() { MemorySizeMB int `help:"Memory MB" required:"true" positional:"true"` Provider string `help:"Provider name" choices:"all|kvm|esxi"` - OsName *string `help:"OS name/type" choices:"Linux|Windows|Any" default:"Any"` - SkuFamily *string `help:"sku family"` - SkuCategory *string `help:"sku category" choices:"general_purpose|compute_optimized|memory_optimized|storage_optimized|hardware_accelerated|high_memory|high_storage"` + OsName *string `help:"OS name/type" choices:"Linux|Windows|Any" default:"Any"` + InstanceTypeCategory *string `help:"instance type category" choices:"general_purpose|compute_optimized|memory_optimized|storage_optimized|hardware_accelerated|high_memory|high_storage"` SysDiskResizable *bool `help:"system disk is resizable"` SysDiskType *string `help:"system disk type" default:"local" choices:"local"` @@ -97,8 +96,8 @@ func init() { CpuCoreCount *int `help:"Cpu Count"` MemorySizeMB *int `help:"Memory MB"` - SkuFamily *string `help:"sku family"` - SkuCategory *string `help:"sku category" choices:"general_purpose|compute_optimized|memory_optimized|storage_optimized|hardware_accelerated|high_memory|high_storage"` + Provider string `help:"Provider name" choices:"all|kvm|esxi"` + InstanceTypeCategory *string `help:"instance type category" choices:"general_purpose|compute_optimized|memory_optimized|storage_optimized|hardware_accelerated|high_memory|high_storage"` SysDiskResizable *bool `help:"system disk is resizable"` SysDiskMaxSizeGB *int `help:"system disk maximal size in gb"` diff --git a/pkg/compute/models/skus.go b/pkg/compute/models/skus.go index 7606c156da..e463b6bfd4 100644 --- a/pkg/compute/models/skus.go +++ b/pkg/compute/models/skus.go @@ -143,6 +143,10 @@ func (self *SServerSkuManager) ValidateCreateData(ctx context.Context, return nil, httperrors.NewForbiddenError("can not create instance_type for public cloud %s", provider) } + if provider == "all" { + data.Remove("provider") + } + regionStr := jsonutils.GetAnyString(data, []string{"region", "region_id", "cloudregion", "cloudregion_id"}) if len(regionStr) > 0 { regionObj, err := CloudregionManager.FetchByIdOrName(userCred, regionStr) @@ -177,11 +181,15 @@ func (self *SServerSkuManager) ValidateCreateData(ctx context.Context, cpu, err := data.Int("cpu_core_count") if err != nil { return nil, httperrors.NewInputParameterError("cpu_core_count should not be empty") + } else { + data.Set("cpu_core_count", jsonutils.NewInt(cpu)) } mem, err := data.Int("memory_size_mb") if err != nil { return nil, httperrors.NewInputParameterError("memory_size_mb should not be empty") + } else { + data.Set("cpu_core_count", jsonutils.NewInt(mem)) } category, _ := data.GetString("instance_type_category") @@ -189,6 +197,8 @@ func (self *SServerSkuManager) ValidateCreateData(ctx context.Context, if !exists { return nil, httperrors.NewInputParameterError("instance_type_category %s is invalid", category) } + + data.Set("instance_type_family", jsonutils.NewString(family)) // 格式 ecs.g1.c1m1 name, err := genInstanceType(family, cpu, mem) if err != nil { @@ -198,7 +208,7 @@ func (self *SServerSkuManager) ValidateCreateData(ctx context.Context, data.Set("name", jsonutils.NewString(name)) q := self.Query().Equals("name", name) - if len(provider) > 0 { + if len(provider) > 0 && provider != "all" { q = q.Equals("provider", provider) } else { q = q.Filter(sqlchemy.OR( @@ -208,7 +218,7 @@ func (self *SServerSkuManager) ValidateCreateData(ctx context.Context, } if q.Count() > 0 { - return nil, httperrors.NewDuplicateResourceError("Duplicate sku") + return nil, httperrors.NewDuplicateResourceError("Duplicate sku %s", name) } return self.SStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data) @@ -339,6 +349,10 @@ func (self *SServerSku) ValidateUpdateData( return nil, httperrors.NewForbiddenError("can not update instance_type for public cloud %s", provider) } + if provider == "all" { + data.Remove("provider") + } + zoneStr := jsonutils.GetAnyString(data, []string{"zone", "zone_id"}) if len(zoneStr) > 0 { zoneObj, err := ZoneManager.FetchByIdOrName(userCred, zoneStr) @@ -361,17 +375,28 @@ func (self *SServerSku) ValidateUpdateData( if err != nil { cpu = int64(self.CpuCoreCount) } + data.Set("cpu_core_count", jsonutils.NewInt(cpu)) mem, err := data.Int("memory_size_mb") if err != nil { mem = int64(self.MemorySizeMB) } + data.Set("memory_size_mb", jsonutils.NewInt(mem)) - category, _ := data.GetString("instance_type_category") - family, exists := InstanceFamilies[category] - if !exists { - return nil, httperrors.NewInputParameterError("instance_type_category %s is invalid", category) + category, err := data.GetString("instance_type_category") + family := "" + if err != nil { + family = self.InstanceTypeFamily + } else { + f, exists := InstanceFamilies[category] + if !exists { + return nil, httperrors.NewInputParameterError("instance_type_category %s is invalid", category) + } + + family = f } + + data.Set("instance_type_family", jsonutils.NewString(family)) // 格式 ecs.g1.c1m1 name, err := genInstanceType(family, cpu, mem) if err != nil { @@ -381,7 +406,7 @@ func (self *SServerSku) ValidateUpdateData( data.Set("name", jsonutils.NewString(name)) q := self.GetModelManager().Query().Equals("name", name) - if len(provider) > 0 { + if len(provider) > 0 && provider != "all" { q = q.Equals("provider", provider) } else { q = q.Filter(sqlchemy.OR( @@ -391,7 +416,7 @@ func (self *SServerSku) ValidateUpdateData( } if q.Count() > 0 { - return nil, httperrors.NewDuplicateResourceError("sku cpu %s mem %s(Mb) already exists", cpu, mem) + return nil, httperrors.NewDuplicateResourceError("sku cpu %d mem %d(Mb) already exists", cpu, mem) } return self.SStandaloneResourceBase.ValidateUpdateData(ctx, userCred, query, data) @@ -426,7 +451,14 @@ func (manager *SServerSkuManager) ListItemFilter(ctx context.Context, q *sqlchem provider := jsonutils.GetAnyString(query, []string{"provider"}) if inWhiteList(provider) { // provider 参数为空或者all时。表示查询`通用`私用云instance type列表 - if provider == "" || provider == "all" { + if provider == "" { + q = q.Filter(sqlchemy.OR( + sqlchemy.IsNull(q.Field("provider")), + sqlchemy.IsEmpty(q.Field("provider")), + sqlchemy.Equals(q.Field("provider"), HYPERVISOR_KVM), + sqlchemy.Equals(q.Field("provider"), HYPERVISOR_ESXI), + )) + } else if provider == "all" { q = q.Filter(sqlchemy.OR( sqlchemy.IsNull(q.Field("provider")), sqlchemy.IsEmpty(q.Field("provider")), From b8f3e6632dfed5724ed9551dc55e6c242ea62931 Mon Sep 17 00:00:00 2001 From: TangBin Date: Tue, 11 Dec 2018 20:55:21 +0800 Subject: [PATCH 3/6] update skus climc --- cmd/climc/shell/skus.go | 8 ++-- pkg/compute/models/skus.go | 84 ++++++++++++-------------------------- 2 files changed, 29 insertions(+), 63 deletions(-) diff --git a/cmd/climc/shell/skus.go b/cmd/climc/shell/skus.go index 28d7e56950..61e5392f87 100644 --- a/cmd/climc/shell/skus.go +++ b/cmd/climc/shell/skus.go @@ -11,7 +11,7 @@ import ( func init() { type ServerSkusListOptions struct { options.BaseListOptions - Provider string `help:"provider" choices:"all|kvm|esxi|xen|hyperv|aliyun|azure|aws|qcloud|huawei"` + Provider string `help:"provider" choices:"all|aliyun|azure|aws|qcloud|huawei" default:""` Region string `help:"region Id or name"` Zone string `help:"zone Id or name"` Cpu int `help:"Cpu core count"` @@ -50,9 +50,8 @@ func init() { }) type ServerSkusCreateOptions struct { - CpuCoreCount int `help:"Cpu Count" required:"true" positional:"true"` - MemorySizeMB int `help:"Memory MB" required:"true" positional:"true"` - Provider string `help:"Provider name" choices:"all|kvm|esxi"` + CpuCoreCount int `help:"Cpu Count" required:"true" positional:"true"` + MemorySizeMB int `help:"Memory MB" required:"true" positional:"true"` OsName *string `help:"OS name/type" choices:"Linux|Windows|Any" default:"Any"` InstanceTypeCategory *string `help:"instance type category" choices:"general_purpose|compute_optimized|memory_optimized|storage_optimized|hardware_accelerated|high_memory|high_storage"` @@ -96,7 +95,6 @@ func init() { CpuCoreCount *int `help:"Cpu Count"` MemorySizeMB *int `help:"Memory MB"` - Provider string `help:"Provider name" choices:"all|kvm|esxi"` InstanceTypeCategory *string `help:"instance type category" choices:"general_purpose|compute_optimized|memory_optimized|storage_optimized|hardware_accelerated|high_memory|high_storage"` SysDiskResizable *bool `help:"system disk is resizable"` diff --git a/pkg/compute/models/skus.go b/pkg/compute/models/skus.go index e463b6bfd4..ea5ec58b24 100644 --- a/pkg/compute/models/skus.go +++ b/pkg/compute/models/skus.go @@ -66,10 +66,10 @@ type SServerSku struct { CpuCoreCount int `nullable:"false" list:"user" create:"admin_required" update:"admin"` MemorySizeMB int `nullable:"false" list:"user" create:"admin_required" update:"admin"` - OsName string `width:"32" charset:"ascii" nullable:"false" list:"user" create:"admin_required" update:"admin" default:"Any"` // Windows|Linux|Any + OsName string `width:"32" charset:"ascii" nullable:"false" list:"user" create:"admin_optional" update:"admin" default:"Any"` // Windows|Linux|Any SysDiskResizable bool `default:"true" nullable:"false" list:"user" create:"admin_optional" update:"admin"` - SysDiskType string `width:"32" charset:"ascii" nullable:"false" list:"user" create:"admin_required" update:"admin"` + SysDiskType string `width:"32" charset:"ascii" nullable:"false" list:"user" create:"admin_optional" update:"admin"` SysDiskMinSizeGB int `nullable:"false" list:"user" create:"admin_optional" update:"admin"` // not required。 windows比较新的版本都是50G左右。 SysDiskMaxSizeGB int `nullable:"false" list:"user" create:"admin_optional" update:"admin"` // not required @@ -94,24 +94,20 @@ type SServerSku struct { } func inWhiteList(provider string) bool { - // 只有为true的hypervisor才进行创建和更新操作 + // provider 字段为空时表示私有云套餐 if len(provider) == 0 { return true - } - switch provider { - case HYPERVISOR_ESXI, HYPERVISOR_KVM, "all": // 空或者all时。表示`通用`私用云instance type列表 - return true - default: + } else { return false } } func genInstanceType(family string, cpu, mem_mb int64) (string, error) { - if cpu < 0 { + if cpu <= 0 { return "", fmt.Errorf("cpu_core_count should great than zero") } - if mem_mb < 0 || mem_mb%1024 != 0 { + if mem_mb <= 0 || mem_mb%1024 != 0 { return "", fmt.Errorf("memory_size_mb should great than zero. and should be integral multiple of 1024") } @@ -143,9 +139,7 @@ func (self *SServerSkuManager) ValidateCreateData(ctx context.Context, return nil, httperrors.NewForbiddenError("can not create instance_type for public cloud %s", provider) } - if provider == "all" { - data.Remove("provider") - } + data.Remove("provider") regionStr := jsonutils.GetAnyString(data, []string{"region", "region_id", "cloudregion", "cloudregion_id"}) if len(regionStr) > 0 { @@ -189,7 +183,7 @@ func (self *SServerSkuManager) ValidateCreateData(ctx context.Context, if err != nil { return nil, httperrors.NewInputParameterError("memory_size_mb should not be empty") } else { - data.Set("cpu_core_count", jsonutils.NewInt(mem)) + data.Set("memory_size_mb", jsonutils.NewInt(mem)) } category, _ := data.GetString("instance_type_category") @@ -207,15 +201,11 @@ func (self *SServerSkuManager) ValidateCreateData(ctx context.Context, data.Set("name", jsonutils.NewString(name)) - q := self.Query().Equals("name", name) - if len(provider) > 0 && provider != "all" { - q = q.Equals("provider", provider) - } else { - q = q.Filter(sqlchemy.OR( - sqlchemy.IsNull(q.Field("provider")), - sqlchemy.IsEmpty(q.Field("provider")), - )) - } + q := self.Query() + q = q.Equals("name", name).Filter(sqlchemy.OR( + sqlchemy.IsNull(q.Field("provider")), + sqlchemy.IsEmpty(q.Field("provider")), + )) if q.Count() > 0 { return nil, httperrors.NewDuplicateResourceError("Duplicate sku %s", name) @@ -348,10 +338,7 @@ func (self *SServerSku) ValidateUpdateData( if err == nil && !inWhiteList(provider) { return nil, httperrors.NewForbiddenError("can not update instance_type for public cloud %s", provider) } - - if provider == "all" { - data.Remove("provider") - } + data.Remove("provider") zoneStr := jsonutils.GetAnyString(data, []string{"zone", "zone_id"}) if len(zoneStr) > 0 { @@ -405,15 +392,11 @@ func (self *SServerSku) ValidateUpdateData( data.Set("name", jsonutils.NewString(name)) - q := self.GetModelManager().Query().Equals("name", name) - if len(provider) > 0 && provider != "all" { - q = q.Equals("provider", provider) - } else { - q = q.Filter(sqlchemy.OR( - sqlchemy.IsNull(q.Field("provider")), - sqlchemy.IsEmpty(q.Field("provider")), - )) - } + q := self.GetModelManager().Query() + q = q.Equals("name", name).Filter(sqlchemy.OR( + sqlchemy.IsNull(q.Field("provider")), + sqlchemy.IsEmpty(q.Field("provider")), + )) if q.Count() > 0 { return nil, httperrors.NewDuplicateResourceError("sku cpu %d mem %d(Mb) already exists", cpu, mem) @@ -449,28 +432,13 @@ func (self *SServerSku) GetZoneExternalId() (string, error) { func (manager *SServerSkuManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) { provider := jsonutils.GetAnyString(query, []string{"provider"}) - if inWhiteList(provider) { - // provider 参数为空或者all时。表示查询`通用`私用云instance type列表 - if provider == "" { - q = q.Filter(sqlchemy.OR( - sqlchemy.IsNull(q.Field("provider")), - sqlchemy.IsEmpty(q.Field("provider")), - sqlchemy.Equals(q.Field("provider"), HYPERVISOR_KVM), - sqlchemy.Equals(q.Field("provider"), HYPERVISOR_ESXI), - )) - } else if provider == "all" { - q = q.Filter(sqlchemy.OR( - sqlchemy.IsNull(q.Field("provider")), - sqlchemy.IsEmpty(q.Field("provider")), - )) - } else { - q = q.Filter(sqlchemy.OR( - sqlchemy.IsNull(q.Field("provider")), - sqlchemy.IsEmpty(q.Field("provider")), - sqlchemy.Equals(q.Field("provider"), provider), - )) - } - } else { + // provider 参数为all时。表示查询所有instance type + if provider == "" { + q = q.Filter(sqlchemy.OR( + sqlchemy.IsNull(q.Field("provider")), + sqlchemy.IsEmpty(q.Field("provider")), + )) + } else if provider != "all" { q = q.Equals("provider", provider) } From dd2ce41fa227d1344e6419a6ce67a2a919e73d94 Mon Sep 17 00:00:00 2001 From: TangBin Date: Wed, 12 Dec 2018 11:15:30 +0800 Subject: [PATCH 4/6] skus list bugfix --- pkg/compute/models/skus.go | 49 ++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/pkg/compute/models/skus.go b/pkg/compute/models/skus.go index ea5ec58b24..8906c85f4a 100644 --- a/pkg/compute/models/skus.go +++ b/pkg/compute/models/skus.go @@ -250,25 +250,38 @@ func (self *SServerSkuManager) AllowGetPropertyInstanceSpecs(ctx context.Context func (self *SServerSkuManager) GetPropertyInstanceSpecs(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (jsonutils.JSONObject, error) { q := self.Query() - zone, err := query.GetString("zone") - if err == nil && len(zone) > 0 { - zoneObj, err := ZoneManager.FetchByIdOrName(userCred, zone) - if err != nil { - if err == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(ZoneManager.Keyword(), zone) - } - return nil, httperrors.NewGeneralError(err) - } - - q = q.Equals("zone_id", zoneObj.GetId()) + provider, _ := query.GetString("provider") + if inWhiteList(provider) { + q = q.Filter(sqlchemy.OR( + sqlchemy.IsNull(q.Field("provider")), + sqlchemy.IsEmpty(q.Field("provider")), + )) } else { - return nil, httperrors.NewMissingParameterError("zone") + q = q.Equals("provider", provider) + } + + // 如果是查询私有云需要忽略zone参数 + zone := jsonutils.GetAnyString(query, []string{"zone", "zone_id"}) + if !inWhiteList(provider){ + if len(zone) > 0 { + zoneObj, err := ZoneManager.FetchByIdOrName(userCred, zone) + if err != nil { + if err == sql.ErrNoRows { + return nil, httperrors.NewResourceNotFoundError2(ZoneManager.Keyword(), zone) + } + return nil, httperrors.NewGeneralError(err) + } + + q = q.Equals("zone_id", zoneObj.GetId()) + } else { + return nil, httperrors.NewMissingParameterError("zone") + } } skus := make([]SServerSku, 0) q = q.GroupBy(q.Field("cpu_core_count"), q.Field("memory_size_mb")) q = q.Asc(q.Field("cpu_core_count"), q.Field("memory_size_mb")) - err = q.All(&skus) + err := q.All(&skus) if err != nil { log.Errorf("%s", err) return nil, httperrors.NewBadRequestError("instance specs list query error") @@ -432,13 +445,16 @@ func (self *SServerSku) GetZoneExternalId() (string, error) { func (manager *SServerSkuManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) { provider := jsonutils.GetAnyString(query, []string{"provider"}) - // provider 参数为all时。表示查询所有instance type + queryDict := query.(*jsonutils.JSONDict) if provider == "" { q = q.Filter(sqlchemy.OR( sqlchemy.IsNull(q.Field("provider")), sqlchemy.IsEmpty(q.Field("provider")), )) - } else if provider != "all" { + } else if provider == "all" { + // provider 参数为all时。表示查询所有instance type. + queryDict.Remove("provider") + } else { q = q.Equals("provider", provider) } @@ -470,6 +486,9 @@ func (manager *SServerSkuManager) ListItemFilter(ctx context.Context, q *sqlchem return nil, httperrors.NewGeneralError(err) } q = q.Equals("zone_id", zoneObj.GetId()) + } else { + queryDict.Remove("zone") + queryDict.Remove("zone_id") } return q, err From cb0823eb70de6531bf3edfcfa8559dfd9da70681 Mon Sep 17 00:00:00 2001 From: TangBin Date: Wed, 12 Dec 2018 15:41:22 +0800 Subject: [PATCH 5/6] name bugfix --- pkg/compute/models/skus.go | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/pkg/compute/models/skus.go b/pkg/compute/models/skus.go index 8906c85f4a..88fc8df1d2 100644 --- a/pkg/compute/models/skus.go +++ b/pkg/compute/models/skus.go @@ -167,11 +167,6 @@ func (self *SServerSkuManager) ValidateCreateData(ctx context.Context, } // name 由服务器端生成 - _, err := data.GetString("name") - if err != nil { - data.Remove("name") - } - cpu, err := data.Int("cpu_core_count") if err != nil { return nil, httperrors.NewInputParameterError("cpu_core_count should not be empty") @@ -262,7 +257,7 @@ func (self *SServerSkuManager) GetPropertyInstanceSpecs(ctx context.Context, use // 如果是查询私有云需要忽略zone参数 zone := jsonutils.GetAnyString(query, []string{"zone", "zone_id"}) - if !inWhiteList(provider){ + if !inWhiteList(provider) { if len(zone) > 0 { zoneObj, err := ZoneManager.FetchByIdOrName(userCred, zone) if err != nil { @@ -366,11 +361,6 @@ func (self *SServerSku) ValidateUpdateData( } // name 由服务器端生成 - _, err = data.GetString("name") - if err != nil { - data.Remove("name") - } - cpu, err := data.Int("cpu_core_count") if err != nil { cpu = int64(self.CpuCoreCount) From 779a588bcf9da4dc6482d89c525bb1938151afa7 Mon Sep 17 00:00:00 2001 From: TangBin Date: Wed, 12 Dec 2018 15:43:13 +0800 Subject: [PATCH 6/6] make fmt --- pkg/compute/models/capabilities.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/compute/models/capabilities.go b/pkg/compute/models/capabilities.go index f0bdff951f..4462fe4104 100644 --- a/pkg/compute/models/capabilities.go +++ b/pkg/compute/models/capabilities.go @@ -11,9 +11,9 @@ import ( ) type SCapabilities struct { - Hypervisors []string `json:",allowempty"` - StorageTypes []string `json:",allowempty"` - GPUModels []string `json:",allowempty"` + Hypervisors []string `json:",allowempty"` + StorageTypes []string `json:",allowempty"` + GPUModels []string `json:",allowempty"` MinNicCount int MaxNicCount int MinDataDiskCount int