增加/capabilities接口,获取后端的总体能力信息,用于按需显示云端服务菜单

This commit is contained in:
Qiu Jian
2018-09-07 11:42:37 +08:00
parent 62e269b20f
commit 3c8ea2cddf
8 changed files with 242 additions and 100 deletions

View File

@@ -0,0 +1,20 @@
package shell
import (
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules"
)
func init() {
type CapabilitiesOptions struct {
}
R(&CapabilitiesOptions{}, "capabilities", "Show backend capabilities", func(s *mcclient.ClientSession, args *CapabilitiesOptions) error {
result, err := modules.Capabilities.List(s, nil)
if err != nil {
return err
}
printObject(result.Data[0])
return nil
})
}

View File

@@ -0,0 +1 @@
package capabilities // import "yunion.io/x/onecloud/pkg/compute/capabilities"

View File

@@ -0,0 +1,22 @@
package capabilities
import (
"fmt"
"context"
"net/http"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/compute/models"
)
func AddCapabilityHandler(prefix string, app *appsrv.Application) {
app.AddHandler2("GET", fmt.Sprintf("%s/capabilities", prefix), auth.Authenticate(capaHandler), nil, "get_capabilities", nil)
}
func capaHandler(context context.Context, w http.ResponseWriter, r *http.Request) {
capa := models.GetCapabilities(nil)
appsrv.SendJSON(w, jsonutils.Marshal(capa))
}

View File

@@ -10,6 +10,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/compute/usages"
"yunion.io/x/onecloud/pkg/compute/capabilities"
)
func InitHandlers(app *appsrv.Application) {
@@ -17,6 +18,7 @@ func InitHandlers(app *appsrv.Application) {
quotas.AddQuotaHandler(models.QuotaManager, "", app)
usages.AddUsageHandler("", app)
capabilities.AddCapabilityHandler("", app)
taskman.AddTaskHandler("", app)

View File

@@ -0,0 +1,164 @@
package models
import (
"fmt"
"yunion.io/x/sqlchemy"
)
type SCapabilities struct {
Hypervisors []string
StorageTypes []string
GPUModels []string
MinNicCount int
MaxNicCount int
MinDataDiskCount int
MaxDataDiskCount int
SchedPolicySupport bool
Usable bool
}
func GetCapabilities(zone *SZone) SCapabilities {
capa := SCapabilities{}
capa.Hypervisors = getHypervisors(zone)
capa.StorageTypes = getStorageTypes(zone)
capa.GPUModels = getGPUs(zone)
capa.SchedPolicySupport = isSchedPolicySupported(zone)
capa.MinNicCount = getMinNicCount(zone)
capa.MaxNicCount = getMaxNicCount(zone)
capa.MinDataDiskCount = getMinDataDiskCount(zone)
capa.MaxDataDiskCount = getMaxDataDiskCount(zone)
capa.Usable = isUsable(zone)
return capa
}
func getHypervisors(zone *SZone) []string {
q := HostManager.Query("host_type")
if zone != nil {
q = q.Equals("zone_id", zone.Id)
}
q = q.Distinct()
rows, err := q.Rows()
if err != nil {
return nil
}
hypervisors := make([]string, 0)
for rows.Next() {
var hostType string
rows.Scan(&hostType)
if len(hostType) > 0 {
hypervisors = append(hypervisors, HOSTTYPE_HYPERVISOR[hostType])
}
}
return hypervisors
}
func getStorageTypes(zone *SZone) []string {
q := StorageManager.Query("storage_type", "medium_type")
if zone != nil {
q = q.Equals("zone_id", zone.Id)
}
q = q.Distinct()
rows, err := q.Rows()
if err != nil {
return nil
}
storageTypes := make([]string, 0)
for rows.Next() {
var storageType, mediumType string
rows.Scan(&storageType, &mediumType)
if len(storageType) > 0 && len(mediumType) > 0 {
storageTypes = append(storageTypes, fmt.Sprintf("%s/%s", storageType, mediumType))
}
}
return storageTypes
}
func getGPUs(zone *SZone) []string {
devices := IsolatedDeviceManager.Query().SubQuery()
hosts := HostManager.Query().SubQuery()
q := devices.Query(devices.Field("model"))
if zone != nil {
q = q.Join(hosts, sqlchemy.Equals(devices.Field("host_id"), hosts.Field("id")))
q = q.Filter(sqlchemy.Equals(hosts.Field("zone_id"), zone.Id))
}
q = q.Distinct()
rows, err := q.Rows()
if err != nil {
return nil
}
gpus := make([]string, 0)
for rows.Next() {
var model string
rows.Scan(&model)
if len(model) > 0 {
gpus = append(gpus, model)
}
}
return gpus
}
func getNetworkCount(zone *SZone) int {
networks := NetworkManager.Query().SubQuery()
q := networks.Query()
if zone != nil {
wires := WireManager.Query().SubQuery()
q = q.Join(wires, sqlchemy.Equals(networks.Field("wire_id"), wires.Field("id")))
q = q.Filter(sqlchemy.Equals(wires.Field("zone_id"), zone.Id))
}
q = q.Filter(sqlchemy.Equals(networks.Field("status"), NETWORK_STATUS_AVAILABLE))
return q.Count()
}
func isSchedPolicySupported(zone *SZone) bool {
if zone != nil {
return !zone.isManaged()
} else {
return true
}
}
func getMinNicCount(zone *SZone) int {
if zone != nil {
return zone.getMinNicCount()
} else {
return 0
}
}
func getMaxNicCount(zone *SZone) int {
if zone != nil {
return zone.getMaxNicCount()
} else {
return 0
}
}
func getMinDataDiskCount(zone *SZone) int {
if zone != nil {
return zone.getMinDataDiskCount()
} else {
return 0
}
}
func getMaxDataDiskCount(zone *SZone) int {
if zone != nil {
return zone.getMaxDataDiskCount()
} else {
return 0
}
}
func isUsable(zone *SZone) bool {
if getNetworkCount(zone) > 0 {
return true
} else {
return false
}
}

View File

@@ -3,8 +3,6 @@ package models
import (
"context"
"database/sql"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
@@ -181,15 +179,7 @@ func (zone *SZone) getStorageCount() int {
}
func (zone *SZone) getNetworkCount() int {
networks := NetworkManager.Query().SubQuery()
wires := WireManager.Query().SubQuery()
q := networks.Query()
q = q.Join(wires, sqlchemy.Equals(networks.Field("wire_id"), wires.Field("id")))
q = q.Filter(sqlchemy.Equals(wires.Field("zone_id"), zone.Id))
q = q.Filter(sqlchemy.Equals(networks.Field("status"), NETWORK_STATUS_AVAILABLE))
return q.Count()
return getNetworkCount(zone)
}
/*def host_count(self, status=None, host_status=None, enabled=None, host_type=None, is_baremetal=None):
@@ -488,90 +478,11 @@ func (self *SZone) AllowGetDetailsCapabilities(ctx context.Context, userCred mcc
return true
}
type SZoneCapabilities struct {
Hypervisors []string
StorageTypes []string
GPUModels []string
MinNicCount int
MaxNicCount int
MinDataDiskCount int
MaxDataDiskCount int
SchedPolicySupport bool
Usable bool
}
func (self *SZone) GetDetailsCapabilities(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
capa := SZoneCapabilities{}
capa.Hypervisors = self.getHypervisors()
capa.StorageTypes = self.getStorageTypes()
capa.GPUModels = self.getGPUs()
capa.SchedPolicySupport = self.isSchedPolicySupported()
capa.MinNicCount = self.getMinNicCount()
capa.MaxNicCount = self.getMaxNicCount()
capa.MinDataDiskCount = self.getMinDataDiskCount()
capa.MaxDataDiskCount = self.getMaxDataDiskCount()
capa.Usable = self.isUsable()
capa := GetCapabilities(self)
return jsonutils.Marshal(&capa), nil
}
func (self *SZone) getHypervisors() []string {
q := HostManager.Query("host_type").Equals("zone_id", self.Id).Distinct()
rows, err := q.Rows()
if err != nil {
return nil
}
hypervisors := make([]string, 0)
for rows.Next() {
var hostType string
rows.Scan(&hostType)
if len(hostType) > 0 {
hypervisors = append(hypervisors, HOSTTYPE_HYPERVISOR[hostType])
}
}
return hypervisors
}
func (self *SZone) getStorageTypes() []string {
q := StorageManager.Query("storage_type", "medium_type").Equals("zone_id", self.Id).Distinct()
rows, err := q.Rows()
if err != nil {
return nil
}
storageTypes := make([]string, 0)
for rows.Next() {
var storageType, mediumType string
rows.Scan(&storageType, &mediumType)
if len(storageType) > 0 && len(mediumType) > 0 {
storageTypes = append(storageTypes, fmt.Sprintf("%s/%s", storageType, mediumType))
}
}
return storageTypes
}
func (self *SZone) getGPUs() []string {
devices := IsolatedDeviceManager.Query().SubQuery()
hosts := HostManager.Query().SubQuery()
q := devices.Query(devices.Field("model"))
q = q.Join(hosts, sqlchemy.Equals(devices.Field("host_id"), hosts.Field("id")))
q = q.Filter(sqlchemy.Equals(hosts.Field("zone_id"), self.Id))
q = q.Distinct()
rows, err := q.Rows()
if err != nil {
return nil
}
gpus := make([]string, 0)
for rows.Next() {
var model string
rows.Scan(&model)
if len(model) > 0 {
gpus = append(gpus, model)
}
}
return gpus
}
func (self *SZone) isManaged() bool {
region := self.GetRegion()
if region != nil && len(region.ExternalId) == 0 {
@@ -605,14 +516,6 @@ func (self *SZone) getMaxDataDiskCount() int {
return 6
}
func (self *SZone) isUsable() bool {
if self.getNetworkCount() > 0 {
return true
} else {
return false
}
}
func (manager *SZoneManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
regionStr := jsonutils.GetAnyString(query, []string{"region", "region_id", "cloudregion", "cloudregion_id"})
var regionId string

View File

@@ -105,7 +105,7 @@ func AddUsageHandler(prefix string, app *appsrv.Application) {
"host": rangeObjHandler(models.HostManager, ReportHostUsage),
"vcenter": rangeObjHandler(models.VCenterManager, ReportVCenterUsage),
} {
addHandler(prefix, key, f, app)
addHandler(prefix, key, auth.Authenticate(f), app)
}
}

View File

@@ -0,0 +1,30 @@
package modules
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SCapabilityManager struct {
ResourceManager
}
func (this *SCapabilityManager) List(s *mcclient.ClientSession, params jsonutils.JSONObject) (*ListResult, error) {
body, err := this._get(s, "/capabilities", "")
if err != nil {
return nil, err
}
result := ListResult{Data: []jsonutils.JSONObject{body}}
return &result, nil
}
var (
Capabilities SCapabilityManager
)
func init() {
Capabilities = SCapabilityManager{
ResourceManager: NewComputeManager("capability", "capabilities", []string{}, []string{}),
}
registerCompute(&Capabilities)
}