mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-06-20 23:26:13 +08:00
增加/capabilities接口,获取后端的总体能力信息,用于按需显示云端服务菜单
This commit is contained in:
20
cmd/climc/shell/capabilities.go
Normal file
20
cmd/climc/shell/capabilities.go
Normal 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
|
||||
})
|
||||
}
|
||||
1
pkg/compute/capabilities/doc.go
Normal file
1
pkg/compute/capabilities/doc.go
Normal file
@@ -0,0 +1 @@
|
||||
package capabilities // import "yunion.io/x/onecloud/pkg/compute/capabilities"
|
||||
22
pkg/compute/capabilities/handler.go
Normal file
22
pkg/compute/capabilities/handler.go
Normal 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))
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
|
||||
164
pkg/compute/models/capabilities.go
Normal file
164
pkg/compute/models/capabilities.go
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
30
pkg/mcclient/modules/mod_capabilities.go
Normal file
30
pkg/mcclient/modules/mod_capabilities.go
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user