From 369d7cba117c96709be5f4c586f8dfd4e9b46110 Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Thu, 4 Jul 2019 18:04:03 +0800 Subject: [PATCH] fix: add disk usage for domain and project --- pkg/compute/models/storages.go | 59 ++++++++++++++++++++++------------ pkg/compute/usages/handler.go | 21 +++++++++++- 2 files changed, 58 insertions(+), 22 deletions(-) diff --git a/pkg/compute/models/storages.go b/pkg/compute/models/storages.go index 65a43ce7df..5b9550304e 100644 --- a/pkg/compute/models/storages.go +++ b/pkg/compute/models/storages.go @@ -34,6 +34,7 @@ import ( "yunion.io/x/onecloud/pkg/compute/options" "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/onecloud/pkg/util/rbacutils" ) /* @@ -767,16 +768,29 @@ type StorageCapacityStat struct { TotalSizeVirtual float64 } -func (manager *SStorageManager) disksReadyQ() *sqlchemy.SSubQuery { - disks := DiskManager.Query().SubQuery() +func filterDisksByScope(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider) *sqlchemy.SSubQuery { + q := DiskManager.Query() + switch scope { + case rbacutils.ScopeSystem: + case rbacutils.ScopeDomain: + q = q.Filter(sqlchemy.Equals(q.Field("domain_id"), ownerId.GetProjectDomainId())) + case rbacutils.ScopeProject: + q = q.Filter(sqlchemy.Equals(q.Field("tenant_id"), ownerId.GetProjectId())) + } + return q.SubQuery() +} + +func (manager *SStorageManager) disksReadyQ(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider) *sqlchemy.SSubQuery { + disks := filterDisksByScope(scope, ownerId) q := disks.Query( disks.Field("storage_id"), sqlchemy.SUM("used_capacity", disks.Field("disk_size")), - ).Equals("status", api.DISK_READY).GroupBy(disks.Field("storage_id")).SubQuery() - return q + ).Equals("status", api.DISK_READY) + q = q.GroupBy(disks.Field("storage_id")) + return q.SubQuery() } -func (manager *SStorageManager) diskIsAttachedQ(isAttached bool) *sqlchemy.SSubQuery { +func (manager *SStorageManager) diskIsAttachedQ(isAttached bool, scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider) *sqlchemy.SSubQuery { sumKey := "attached_used_capacity" cond := sqlchemy.In if !isAttached { @@ -784,7 +798,7 @@ func (manager *SStorageManager) diskIsAttachedQ(isAttached bool) *sqlchemy.SSubQ cond = sqlchemy.NotIn } sq := GuestdiskManager.Query("disk_id").SubQuery() - disks := DiskManager.Query().SubQuery() + disks := filterDisksByScope(scope, ownerId) disks = disks.Query().Filter(cond(disks.Field("id"), sq)).SubQuery() q := disks.Query( disks.Field("storage_id"), @@ -793,31 +807,34 @@ func (manager *SStorageManager) diskIsAttachedQ(isAttached bool) *sqlchemy.SSubQ return q.SubQuery() } -func (manager *SStorageManager) diskAttachedQ() *sqlchemy.SSubQuery { - return manager.diskIsAttachedQ(true) +func (manager *SStorageManager) diskAttachedQ(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider) *sqlchemy.SSubQuery { + return manager.diskIsAttachedQ(true, scope, ownerId) } -func (manager *SStorageManager) diskDetachedQ() *sqlchemy.SSubQuery { - return manager.diskIsAttachedQ(false) +func (manager *SStorageManager) diskDetachedQ(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider) *sqlchemy.SSubQuery { + return manager.diskIsAttachedQ(false, scope, ownerId) } -func (manager *SStorageManager) disksFailedQ() *sqlchemy.SSubQuery { - disks := DiskManager.Query().SubQuery() +func (manager *SStorageManager) disksFailedQ(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider) *sqlchemy.SSubQuery { + disks := filterDisksByScope(scope, ownerId) q := disks.Query( disks.Field("storage_id"), sqlchemy.SUM("failed_capacity", disks.Field("disk_size")), - ).NotEquals("status", api.DISK_READY).GroupBy(disks.Field("storage_id")).SubQuery() - return q + ).NotEquals("status", api.DISK_READY) + q = q.GroupBy(disks.Field("storage_id")) + return q.SubQuery() } func (manager *SStorageManager) totalCapacityQ( rangeObj db.IStandaloneModel, hostTypes []string, - resourceTypes []string, providers []string, brands []string, cloudEnv string, + resourceTypes []string, + providers []string, brands []string, cloudEnv string, + scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider, ) *sqlchemy.SQuery { - stmt := manager.disksReadyQ() - stmt2 := manager.disksFailedQ() - attachedDisks := manager.diskAttachedQ() - detachedDisks := manager.diskDetachedQ() + stmt := manager.disksReadyQ(scope, ownerId) + stmt2 := manager.disksFailedQ(scope, ownerId) + attachedDisks := manager.diskAttachedQ(scope, ownerId) + detachedDisks := manager.diskDetachedQ(scope, ownerId) storages := manager.Query().SubQuery() q := storages.Query( storages.Field("capacity"), @@ -904,8 +921,8 @@ func (manager *SStorageManager) calculateCapacity(q *sqlchemy.SQuery) StoragesCa } } -func (manager *SStorageManager) TotalCapacity(rangeObj db.IStandaloneModel, hostTypes []string, resourceTypes []string, providers []string, brands []string, cloudEnv string) StoragesCapacityStat { - res1 := manager.calculateCapacity(manager.totalCapacityQ(rangeObj, hostTypes, resourceTypes, providers, brands, cloudEnv)) +func (manager *SStorageManager) TotalCapacity(rangeObj db.IStandaloneModel, hostTypes []string, resourceTypes []string, providers []string, brands []string, cloudEnv string, scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider) StoragesCapacityStat { + res1 := manager.calculateCapacity(manager.totalCapacityQ(rangeObj, hostTypes, resourceTypes, providers, brands, cloudEnv, scope, ownerId)) return res1 } diff --git a/pkg/compute/usages/handler.go b/pkg/compute/usages/handler.go index 87401836cc..80aa694ac6 100644 --- a/pkg/compute/usages/handler.go +++ b/pkg/compute/usages/handler.go @@ -290,6 +290,8 @@ func getCommonGeneralUsage(scope rbacutils.TRbacScope, cred mcclient.IIdentityPr snapshotUsage := SnapshotUsage(scope, cred, rangeObj, providers, brands, cloudEnv) + disksUsage := disksUsage("", rangeObj, nil, nil, providers, brands, cloudEnv, scope, cred) + count = guestNormalUsage.Include( GuestNormalUsage("servers.prepaid_pool", scope, cred, rangeObj, hostTypes, []string{api.HostResourceTypePrepaidRecycle}, providers, brands, cloudEnv), GuestNormalUsage("servers.any_pool", scope, cred, rangeObj, hostTypes, nil, providers, brands, cloudEnv), @@ -313,6 +315,8 @@ func getCommonGeneralUsage(scope rbacutils.TRbacScope, cred mcclient.IIdentityPr eipUsage, snapshotUsage, + + disksUsage, ) return } @@ -390,7 +394,7 @@ func StorageUsage(prefix string, rangeObj db.IStandaloneModel, hostTypes []strin dPrefix = fmt.Sprintf("%s.%s", dPrefix, prefix) } count := make(map[string]interface{}) - result := models.StorageManager.TotalCapacity(rangeObj, hostTypes, resourceTypes, providers, brands, cloudEnv) + result := models.StorageManager.TotalCapacity(rangeObj, hostTypes, resourceTypes, providers, brands, cloudEnv, rbacutils.ScopeSystem, nil) count[sPrefix] = result.Capacity count[fmt.Sprintf("%s.virtual", sPrefix)] = result.CapacityVirtual count[dPrefix] = result.CapacityUsed @@ -407,6 +411,21 @@ func StorageUsage(prefix string, rangeObj db.IStandaloneModel, hostTypes []strin return count } +func disksUsage(prefix string, rangeObj db.IStandaloneModel, hostTypes []string, resourceTypes []string, providers []string, brands []string, cloudEnv string, scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider) Usage { + dPrefix := "disks" + if len(prefix) > 0 { + dPrefix = fmt.Sprintf("%s.%s", dPrefix, prefix) + } + count := make(map[string]interface{}) + result := models.StorageManager.TotalCapacity(rangeObj, hostTypes, resourceTypes, providers, brands, cloudEnv, scope, ownerId) + count[dPrefix] = result.CapacityUsed + count[fmt.Sprintf("%s.unready", dPrefix)] = result.CapacityUnready + count[fmt.Sprintf("%s.attached", dPrefix)] = result.AttachedCapacity + count[fmt.Sprintf("%s.detached", dPrefix)] = result.DetachedCapacity + + return count +} + func WireUsage(rangeObj db.IStandaloneModel, hostTypes []string, providers []string, brands []string, cloudEnv string) Usage { count := make(map[string]interface{}) result := models.WireManager.TotalCount(rangeObj, hostTypes, providers, brands, cloudEnv, rbacutils.ScopeSystem, nil)