Merge pull request #219 in YUNIONIO/onecloud from ~LIZEXI/onecloud:feature/lzx-user-usage to release/2.1.0

* commit '1c01d7b45f28698e78d47d2433edcde6c794d65f':
  region: user usage
This commit is contained in:
邱剑
2018-09-15 18:03:07 +08:00
3 changed files with 101 additions and 42 deletions
+26 -19
View File
@@ -100,7 +100,7 @@ const (
VM_RESTORE_STATE = "restore_state"
VM_RESTORE_FAILED = "restore_failed"
VM_ASSOCIATE_EIP = "associate_eip"
VM_ASSOCIATE_EIP = "associate_eip"
VM_DISSOCIATE_EIP = "dissociate_eip"
VM_REMOVE_STATEFILE = "remove_state"
@@ -276,8 +276,8 @@ func (manager *SGuestManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQ
if count > 0 {
sgq := guestdisks.Query(guestdisks.Field("guest_id")).
Filter(sqlchemy.AND(
sqlchemy.Equals(guestdisks.Field("disk_id"), disk.Id),
sqlchemy.IsFalse(guestdisks.Field("deleted"))))
sqlchemy.Equals(guestdisks.Field("disk_id"), disk.Id),
sqlchemy.IsFalse(guestdisks.Field("deleted"))))
q = q.Filter(sqlchemy.In(q.Field("id"), sgq))
} else {
hosts := HostManager.Query().SubQuery()
@@ -285,11 +285,11 @@ func (manager *SGuestManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQ
storages := StorageManager.Query().SubQuery()
sq := hosts.Query(hosts.Field("id")).
Join(hoststorages, sqlchemy.AND(
sqlchemy.Equals(hoststorages.Field("host_id"), hosts.Field("id")),
sqlchemy.IsFalse(hoststorages.Field("deleted")))).
sqlchemy.Equals(hoststorages.Field("host_id"), hosts.Field("id")),
sqlchemy.IsFalse(hoststorages.Field("deleted")))).
Join(storages, sqlchemy.AND(
sqlchemy.Equals(storages.Field("id"), hoststorages.Field("storage_id")),
sqlchemy.IsFalse(storages.Field("deleted")))).
sqlchemy.Equals(storages.Field("id"), hoststorages.Field("storage_id")),
sqlchemy.IsFalse(storages.Field("deleted")))).
Filter(sqlchemy.Equals(storages.Field("id"), disk.StorageId)).SubQuery()
q = q.In("host_id", sq)
}
@@ -343,8 +343,8 @@ func (manager *SGuestManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQ
isodev := IsolatedDeviceManager.Query().SubQuery()
sgq := isodev.Query(isodev.Field("guest_id")).
Filter(sqlchemy.AND(
sqlchemy.IsNotNull(isodev.Field("guest_id")),
sqlchemy.Startswith(isodev.Field("dev_type"), "GPU")))
sqlchemy.IsNotNull(isodev.Field("guest_id")),
sqlchemy.Startswith(isodev.Field("dev_type"), "GPU")))
showGpu := utils.ToBool(gpu)
cond := sqlchemy.NotIn
if showGpu {
@@ -568,7 +568,7 @@ func (manager *SGuestManager) ValidateCreateData(ctx context.Context, userCred m
resetPassword := jsonutils.QueryBoolean(data, "reset_password", true)
passwd, _ := data.GetString("password")
if resetPassword && len(passwd) > 0 {
if ! seclib2.MeetComplxity(passwd) {
if !seclib2.MeetComplxity(passwd) {
return nil, httperrors.NewWeakPasswordError()
}
}
@@ -1394,10 +1394,10 @@ func (manager *SGuestManager) newCloudVM(ctx context.Context, userCred mcclient.
func (manager *SGuestManager) TotalCount(
projectId string, rangeObj db.IStandaloneModel,
status []string, hypervisor string,
status []string, hypervisors []string,
includeSystem bool, pendingDelete bool, hostType string,
) SGuestCountStat {
return totalGuestResourceCount(projectId, rangeObj, status, hypervisor, includeSystem, pendingDelete, hostType)
return totalGuestResourceCount(projectId, rangeObj, status, hypervisors, includeSystem, pendingDelete, hostType)
}
func (self *SGuest) detachNetwork(ctx context.Context, userCred mcclient.TokenCredential, network *SNetwork, reserve bool, deploy bool) error {
@@ -1910,8 +1910,15 @@ type SGuestCountStat struct {
TotalIsolatedCount int
}
func totalGuestResourceCount(projectId string, rangeObj db.IStandaloneModel, status []string, hypervisor string,
includeSystem bool, pendingDelete bool, hostType string) SGuestCountStat {
func totalGuestResourceCount(
projectId string,
rangeObj db.IStandaloneModel,
status []string,
hypervisors []string,
includeSystem bool,
pendingDelete bool,
hostType string,
) SGuestCountStat {
guestdisks := GuestdiskManager.Query().SubQuery()
disks := DiskManager.Query().SubQuery()
@@ -1951,8 +1958,8 @@ func totalGuestResourceCount(projectId string, rangeObj db.IStandaloneModel, sta
if len(status) > 0 {
q = q.Filter(sqlchemy.In(guests.Field("status"), status))
}
if len(hypervisor) > 0 {
q = q.Filter(sqlchemy.Equals(guests.Field("hypervisor"), hypervisor))
if len(hypervisors) > 0 {
q = q.Filter(sqlchemy.In(guests.Field("hypervisor"), hypervisors))
}
if !includeSystem {
q = q.Filter(sqlchemy.OR(sqlchemy.IsNull(guests.Field("is_system")), sqlchemy.IsFalse(guests.Field("is_system"))))
@@ -2440,7 +2447,7 @@ func (self *SGuest) AllowPerformRebuildRoot(ctx context.Context, userCred mcclie
func (self *SGuest) PerformRebuildRoot(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
imageId, _ := data.GetString("image_id")
if ! utils.IsInStringArray(self.Status, []string{VM_READY, VM_RUNNING, VM_ADMIN}) {
if !utils.IsInStringArray(self.Status, []string{VM_READY, VM_RUNNING, VM_ADMIN}) {
return nil, httperrors.NewInvalidStatusError("Cannot reset root in status %s", self.Status)
}
@@ -2469,7 +2476,7 @@ func (self *SGuest) PerformRebuildRoot(ctx context.Context, userCred mcclient.To
resetPasswd := jsonutils.QueryBoolean(data, "reset_password", true)
passwd, _ := data.GetString("password")
if len(passwd) > 0 {
if ! seclib2.MeetComplxity(passwd) {
if !seclib2.MeetComplxity(passwd) {
return nil, httperrors.NewWeakPasswordError()
}
}
@@ -4008,7 +4015,7 @@ func (manager *SGuestManager) GetIpInProjectWithName(projectId, name string, isE
sqlchemy.IsFalse(guests.Field("pending_deleted"))),
sqlchemy.IsFalse(guests.Field("deleted")))).
Join(networks, sqlchemy.AND(sqlchemy.Equals(networks.Field("id"), guestnics.Field("network_id")),
sqlchemy.IsFalse(networks.Field("deleted")))).
sqlchemy.IsFalse(networks.Field("deleted")))).
Filter(sqlchemy.Equals(guests.Field("name"), name)).
Filter(sqlchemy.NotEquals(guestnics.Field("ip_addr"), "")).
Filter(sqlchemy.IsNotNull(guestnics.Field("ip_addr"))).
+1 -1
View File
@@ -70,7 +70,7 @@ func (self *SQuota) FetchSystemQuota() {
func (self *SQuota) FetchUsage(projectId string) error {
diskSize := totalDiskSize(projectId, tristate.None, tristate.None, false)
net := totalGuestNicCount(projectId, nil, false)
guest := totalGuestResourceCount(projectId, nil, nil, "", false, false, "")
guest := totalGuestResourceCount(projectId, nil, nil, nil, false, false, "")
eipUsage := ElasticipManager.TotalCount(projectId, nil, nil)
// XXX
// keypair belongs to user
+74 -22
View File
@@ -7,6 +7,10 @@ import (
json "yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/tristate"
"yunion.io/x/pkg/util/sets"
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/appctx"
"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
@@ -14,8 +18,6 @@ import (
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/pkg/tristate"
"yunion.io/x/pkg/utils"
)
type Usage map[string]interface{}
@@ -160,12 +162,8 @@ func ReportCloudRegionUsage(userCred mcclient.TokenCredential, cloudRegion db.IS
//func ReportGuestUsage()
func ReportGeneralUsage(userCred mcclient.TokenCredential, rangeObj db.IStandaloneModel, hostTypes []string) (count Usage, err error) {
func getAdminGeneralUsage(userCred mcclient.TokenCredential, rangeObj db.IStandaloneModel, hostTypes []string) (count Usage, err error) {
count = ZoneUsage()
if !userCred.IsSystemAdmin() {
return
}
var pmemTotal float64
var pcpuTotal float64
@@ -181,9 +179,14 @@ func ReportGeneralUsage(userCred mcclient.TokenCredential, rangeObj db.IStandalo
count.Add("memory.virtual", host.GetVirtualMemorySize())
count.Add("cpu.virtual", host.GetVirtualCPUCount())
}
guestRunningUsage := GuestRunningUsage(userCred, rangeObj, hostTypes)
guestRunningUsage := GuestRunningUsage("all.running_servers", nil, rangeObj, hostTypes)
runningMem := guestRunningUsage.Get("all.running_servers.memory").(int)
runningCpu := guestRunningUsage.Get("all.running_servers.cpu").(int)
containerRunningUsage := containerUsage("all.containers", nil, rangeObj)
containerRunningMem := containerRunningUsage.Get("all.containers.memory").(int)
containerRunningCpu := containerRunningUsage.Get("all.containers.cpu").(int)
runningMem += containerRunningMem
runningCpu += containerRunningCpu
runningCpuCmtRate := 0.0
runningMemCmtRate := 0.0
if pmemTotal > 0 {
@@ -209,19 +212,50 @@ func ReportGeneralUsage(userCred mcclient.TokenCredential, rangeObj db.IStandalo
hostEnabledUsage,
BaremetalUsage(userCred, rangeObj, hostTypes),
storageUsage,
GuestNormalUsage(userCred, rangeObj, hostTypes),
GuestPendingDeleteUsage(userCred, rangeObj, hostTypes),
GuestReadyUsage(userCred, rangeObj, hostTypes),
GuestNormalUsage("all.servers", nil, rangeObj, hostTypes),
GuestPendingDeleteUsage("all.pending_delete_servers", nil, rangeObj, hostTypes),
GuestReadyUsage("all.ready_servers", nil, rangeObj, hostTypes),
guestRunningUsage,
containerRunningUsage,
IsolatedDeviceUsage(rangeObj, hostTypes),
WireUsage(rangeObj, hostTypes),
NetworkUsage(userCred, rangeObj),
EipUsage(rangeObj, hostTypes),
)
return
}
func getCommonGeneralUsage(cred mcclient.TokenCredential, rangeObj db.IStandaloneModel, hostTypes []string) (count Usage, err error) {
guestNormalUsage := GuestNormalUsage("servers", cred, rangeObj, hostTypes)
guestRunningUsage := GuestRunningUsage("running_servers", cred, rangeObj, hostTypes)
guestPendingDeleteUsage := GuestPendingDeleteUsage("pending_delete_servers", cred, rangeObj, hostTypes)
guestReadyUsage := GuestReadyUsage("ready_servers", cred, rangeObj, hostTypes)
containerUsage := containerUsage("containers", cred, rangeObj)
count = guestNormalUsage.Include(
guestRunningUsage,
guestPendingDeleteUsage,
guestReadyUsage,
containerUsage,
)
return
}
func ReportGeneralUsage(userCred mcclient.TokenCredential, rangeObj db.IStandaloneModel, hostTypes []string) (count Usage, err error) {
count = make(map[string]interface{})
if userCred.IsSystemAdmin() {
count, err = getAdminGeneralUsage(userCred, rangeObj, hostTypes)
if err != nil {
return
}
}
commonUsage, err := getCommonGeneralUsage(userCred, rangeObj, hostTypes)
if err != nil {
return
}
count.Include(commonUsage)
return
}
func ZoneUsage() Usage {
count := make(map[string]interface{})
count["zones"] = models.ZoneManager.Count()
@@ -294,27 +328,29 @@ func hostUsage(
return count
}
func GuestNormalUsage(cred mcclient.TokenCredential, rangeObj db.IStandaloneModel, hostTypes []string) Usage {
prefix := "all.servers"
func GuestNormalUsage(prefix string, cred mcclient.TokenCredential, rangeObj db.IStandaloneModel, hostTypes []string) Usage {
return guestUsage(prefix, cred, rangeObj, hostTypes, nil, false)
}
func GuestPendingDeleteUsage(cred mcclient.TokenCredential, rangeObj db.IStandaloneModel, hostTypes []string) Usage {
prefix := "all.pending_delete_servers"
func GuestPendingDeleteUsage(prefix string, cred mcclient.TokenCredential, rangeObj db.IStandaloneModel, hostTypes []string) Usage {
return guestUsage(prefix, cred, rangeObj, hostTypes, nil, true)
}
func GuestRunningUsage(cred mcclient.TokenCredential, rangeObj db.IStandaloneModel, hostTypes []string) Usage {
prefix := "all.running_servers"
func GuestRunningUsage(prefix string, cred mcclient.TokenCredential, rangeObj db.IStandaloneModel, hostTypes []string) Usage {
return guestUsage(prefix, cred, rangeObj, hostTypes, []string{models.VM_RUNNING}, false)
}
func GuestReadyUsage(cred mcclient.TokenCredential, rangeObj db.IStandaloneModel, hostTypes []string) Usage {
prefix := "all.ready_servers"
func GuestReadyUsage(prefix string, cred mcclient.TokenCredential, rangeObj db.IStandaloneModel, hostTypes []string) Usage {
return guestUsage(prefix, cred, rangeObj, hostTypes, []string{models.VM_READY}, false)
}
func guestUsage(prefix string, userCred mcclient.TokenCredential, rangeObj db.IStandaloneModel, hostTypes, status []string, pendingDelete bool) Usage {
func guestHypervisorsUsage(
prefix string,
userCred mcclient.TokenCredential,
rangeObj db.IStandaloneModel,
hostTypes, status, hypervisors []string,
pendingDelete bool,
) Usage {
hostType := ""
if len(hostTypes) != 0 {
hostType = hostTypes[0]
@@ -323,17 +359,33 @@ func guestUsage(prefix string, userCred mcclient.TokenCredential, rangeObj db.IS
if userCred != nil {
projectId = userCred.GetProjectId()
}
guest := models.GuestManager.TotalCount(projectId, rangeObj, status, "", true, pendingDelete, hostType)
guest := models.GuestManager.TotalCount(projectId, rangeObj, status, hypervisors, true, pendingDelete, hostType)
count := make(map[string]interface{})
count[prefix] = guest.TotalGuestCount
count[fmt.Sprintf("%s.cpu", prefix)] = guest.TotalCpuCount
count[fmt.Sprintf("%s.memory", prefix)] = guest.TotalMemSize
if len(hypervisors) == 1 && hypervisors[0] == models.HYPERVISOR_CONTAINER {
return count
}
count[fmt.Sprintf("%s.disk", prefix)] = guest.TotalDiskSize
count[fmt.Sprintf("%s.isolated_devices", prefix)] = guest.TotalIsolatedCount
return count
}
func guestUsage(prefix string, userCred mcclient.TokenCredential, rangeObj db.IStandaloneModel, hostTypes, status []string, pendingDelete bool) Usage {
hypervisors := sets.NewString(models.HYPERVISORS...)
hypervisors.Delete(models.HYPERVISOR_CONTAINER)
return guestHypervisorsUsage(prefix, userCred, rangeObj, hostTypes, status, hypervisors.List(), pendingDelete)
}
func containerUsage(prefix string, userCred mcclient.TokenCredential, rangeObj db.IStandaloneModel) Usage {
hypervisors := []string{models.HYPERVISOR_CONTAINER}
return guestHypervisorsUsage(prefix, userCred, rangeObj, nil, nil, hypervisors, false)
}
func IsolatedDeviceUsage(rangeObj db.IStandaloneModel, hostType []string) Usage {
prefix := "isolated_devices"
ret := models.IsolatedDeviceManager.TotalCount(hostType, rangeObj)