Merge pull request #1121 in YUNIONIO/onecloud from ~TANGBIN/onecloud:feature/tb-add-sku-list-query-condition to release/2.7.0

* commit 'ff26e3f1e60d615f2a193e4fc7a5f6da812e9c2b':
  skus extra details querys add cache
  sku list add more query
This commit is contained in:
邱剑
2019-02-26 20:58:38 +08:00
3 changed files with 112 additions and 44 deletions
+6 -5
View File
@@ -9,11 +9,12 @@ import (
func init() {
type ServerSkusListOptions struct {
options.BaseListOptions
Region string `help:"region Id or name"`
Zone string `help:"zone Id or name"`
Cpu *int `help:"Cpu core count" json:"cpu_core_count"`
Mem *int `help:"Memory size in MB" json:"memory_size_mb"`
Name string `help:"Name of Sku"`
Region string `help:"region Id or name"`
Zone string `help:"zone Id or name"`
City *string `help:"city name,eg. BeiJing"`
Cpu *int `help:"Cpu core count" json:"cpu_core_count"`
Mem *int `help:"Memory size in MB" json:"memory_size_mb"`
Name string `help:"Name of Sku"`
}
R(&ServerSkusListOptions{}, "server-sku-list", "List all avaiable Server SKU", func(s *mcclient.ClientSession, args *ServerSkusListOptions) error {
params, err := options.ListStructToParams(args)
+105 -38
View File
@@ -6,9 +6,11 @@ import (
"fmt"
"sort"
"strconv"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/util/hashcache"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/sqlchemy"
@@ -45,6 +47,8 @@ var InstanceFamilies = map[string]string{
SkuCategoryHighMemory: "hr1",
}
var Cache *hashcache.Cache
type SServerSkuManager struct {
db.SStandaloneResourceBaseManager
}
@@ -61,6 +65,8 @@ func init() {
),
}
ServerSkuManager.NameRequireAscii = false
Cache = hashcache.NewCache(2048, time.Second*300)
}
// SServerSku 实际对应的是instance type清单. 这里的Sku实际指的是instance type。
@@ -167,8 +173,50 @@ func (self *SServerSku) AllowGetDetails(ctx context.Context, userCred mcclient.T
func (self *SServerSku) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict {
extra := self.SStandaloneResourceBase.GetCustomizeColumns(ctx, userCred, query)
count := skuRelatedGuestCount(self)
// count
var count int
countKey := self.GetId() + ".total_guest_count"
v := Cache.Get(countKey)
if v == nil {
count = skuRelatedGuestCount(self)
Cache.Set(countKey, count)
} else {
count = v.(int)
}
extra.Add(jsonutils.NewInt(int64(count)), "total_guest_count")
// zone
if len(self.ZoneId) > 0 {
var zoneName string
v := Cache.Get(self.ZoneId)
if v == nil {
zone, err := ZoneManager.FetchById(self.ZoneId)
if err == nil {
zoneName = zone.GetName()
Cache.Set(zone.GetId(), zoneName)
}
} else {
zoneName = v.(string)
}
extra.Add(jsonutils.NewString(zoneName), "zone_name")
}
// region
var regionName string
v = Cache.Get(self.CloudregionId)
if v == nil {
region, err := CloudregionManager.FetchById(self.CloudregionId)
if err == nil {
regionName = region.GetName()
Cache.Set(region.GetId(), regionName)
}
} else {
regionName = v.(string)
}
extra.Add(jsonutils.NewString(regionName), "region_name")
return extra
}
@@ -305,32 +353,32 @@ 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()
// 未明确指定provider或者public_cloud时,默认查询私有云
provider, _ := query.GetString("provider")
if inWhiteList(provider) {
public_cloud, _ := query.Bool("public_cloud")
if len(provider) > 0 {
q = q.Equals("provider", provider)
} else if public_cloud {
q = q.IsNotEmpty("provider")
} else {
q = q.Filter(sqlchemy.OR(
sqlchemy.IsNull(q.Field("provider")),
sqlchemy.IsEmpty(q.Field("provider")),
))
} else {
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)
if public_cloud && len(zone) > 0 {
zoneObj, err := ZoneManager.FetchByIdOrName(userCred, zone)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2(ZoneManager.Keyword(), zone)
}
q = q.Equals("zone_id", zoneObj.GetId())
} else {
return nil, httperrors.NewMissingParameterError("zone")
return nil, httperrors.NewGeneralError(err)
}
q = q.Equals("zone_id", zoneObj.GetId())
}
skus := make([]SServerSku, 0)
@@ -520,17 +568,20 @@ 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"})
public_cloud, _ := query.Bool("public_cloud")
queryDict := query.(*jsonutils.JSONDict)
if provider == "" {
if provider == "all" {
// provider 参数为all时。表示查询所有instance type.
queryDict.Remove("provider")
} else if len(provider) > 0 {
q = q.Equals("provider", provider)
} else if public_cloud {
q = q.IsNotEmpty("provider")
} else {
q = q.Filter(sqlchemy.OR(
sqlchemy.IsNull(q.Field("provider")),
sqlchemy.IsEmpty(q.Field("provider")),
))
} else if provider == "all" {
// provider 参数为all时。表示查询所有instance type.
queryDict.Remove("provider")
} else {
q = q.Equals("provider", provider)
}
q, err := manager.SStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query)
@@ -538,6 +589,12 @@ func (manager *SServerSkuManager) ListItemFilter(ctx context.Context, q *sqlchem
return nil, err
}
regionTable := CloudregionManager.Query().SubQuery()
zoneTable := ZoneManager.Query().SubQuery()
q = q.Join(regionTable, sqlchemy.Equals(regionTable.Field("id"), q.Field("cloudregion_id")))
q = q.Join(zoneTable, sqlchemy.Equals(zoneTable.Field("id"), q.Field("zone_id")))
// region filter
regionStr := jsonutils.GetAnyString(query, []string{"region", "cloudregion", "region_id", "cloudregion_id"})
if len(regionStr) > 0 {
regionObj, err := CloudregionManager.FetchByIdOrName(nil, regionStr)
@@ -550,6 +607,32 @@ func (manager *SServerSkuManager) ListItemFilter(ctx context.Context, q *sqlchem
q = q.Equals("cloudregion_id", regionObj.GetId())
}
zoneStr := jsonutils.GetAnyString(query, []string{"zone", "zone_id"})
var zoneObj db.IModel
if len(zoneStr) > 0 {
zoneObj, err = ZoneManager.FetchByIdOrName(nil, zoneStr)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2(ZoneManager.Keyword(), zoneStr)
}
return nil, httperrors.NewGeneralError(err)
}
// 当查询私有云时,需要忽略zone参数
if len(zoneObj.(*SZone).ExternalId) > 0 {
q = q.Equals("zone_id", zoneObj.GetId())
}
}
queryDict.Remove("zone")
queryDict.Remove("zone_id")
// city filter
city, _ := query.GetString("city")
if len(city) > 0 {
q = q.Filter(sqlchemy.Equals(regionTable.Field("city"), city))
}
// 可用资源状态
postpaid, _ := query.GetString("postpaid_status")
if len(postpaid) > 0 {
@@ -561,22 +644,6 @@ func (manager *SServerSkuManager) ListItemFilter(ctx context.Context, q *sqlchem
q.Equals("prepaid_status", prepaid)
}
// 当查询私有云时,需要忽略zone参数
zoneStr := jsonutils.GetAnyString(query, []string{"zone", "zone_id"})
if !inWhiteList(provider) && len(zoneStr) > 0 {
zoneObj, err := ZoneManager.FetchByIdOrName(nil, zoneStr)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2(ZoneManager.Keyword(), zoneStr)
}
return nil, httperrors.NewGeneralError(err)
}
q = q.Equals("zone_id", zoneObj.GetId())
} else {
queryDict.Remove("zone")
queryDict.Remove("zone_id")
}
q = q.Asc(q.Field("cpu_core_count"), q.Field("memory_size_mb"))
return q, err
}
+1 -1
View File
@@ -31,7 +31,7 @@ func init() {
"Sys_disk_min_size_mb", "Sys_disk_max_size_mb", "Attached_disk_type",
"Attached_disk_size_gb", "Attached_disk_count", "Data_disk_types",
"Data_disk_max_count", "Nic_max_count", "Cloudregion_id", "Zone_id",
"Provider", "Postpaid_status", "Prepaid_status"},
"Provider", "Postpaid_status", "Prepaid_status", "region_name", "Zone_name"},
[]string{"Total_guest_count"})}
register(&CloudmetaSkus)