diff --git a/cmd/climc/shell/usages.go b/cmd/climc/shell/usages.go index 6a909cf124..41aa649f85 100644 --- a/cmd/climc/shell/usages.go +++ b/cmd/climc/shell/usages.go @@ -80,4 +80,16 @@ func init() { printObject(result) return nil }) + + R(&ResourceUsageOptions{}, "cloud-region-usage", "Show general usage of a cloud region", func(s *mcclient.ClientSession, args *ResourceUsageOptions) error { + params := fetchHostTypeOptions(&args.GeneralUsageOptions) + params.Add(jsonutils.NewString("cloudregions"), "range_type") + params.Add(jsonutils.NewString(args.ID), "range_id") + result, err := modules.Usages.GetGeneralUsage(s, params) + if err != nil { + return err + } + printObject(result) + return nil + }) } diff --git a/pkg/compute/models/elasticips.go b/pkg/compute/models/elasticips.go index 38f415cb14..61fd224233 100644 --- a/pkg/compute/models/elasticips.go +++ b/pkg/compute/models/elasticips.go @@ -741,11 +741,30 @@ func (u EipUsage) Total() int { return u.PublicIPCount + u.EIPCount } -func (manager *SElasticipManager) TotalCount(projectId string) EipUsage { +func (manager *SElasticipManager) usageQ(q *sqlchemy.SQuery, rangeObj db.IStandaloneModel, hostTypes []string) *sqlchemy.SQuery { + if rangeObj == nil { + return q + } + zones := ZoneManager.Query().SubQuery() + hosts := HostManager.Query().SubQuery() + sq := zones.Query(zones.Field("cloudregion_id")). + Join(hosts, sqlchemy.AND( + sqlchemy.IsFalse(hosts.Field("deleted")), + sqlchemy.IsTrue(hosts.Field("enabled")), + sqlchemy.Equals(hosts.Field("zone_id"), zones.Field("id")))) + sq = AttachUsageQuery(sq, hosts, hosts.Field("id"), hostTypes, rangeObj) + q = q.Filter(sqlchemy.In(q.Field("cloudregion_id"), sq.Distinct())) + return q +} + +func (manager *SElasticipManager) TotalCount(projectId string, rangeObj db.IStandaloneModel, hostTypes []string) EipUsage { usage := EipUsage{} q1 := manager.Query().Equals("mode", EIP_MODE_INSTANCE_PUBLICIP) + q1 = manager.usageQ(q1, rangeObj, hostTypes) q2 := manager.Query().Equals("mode", EIP_MODE_STANDALONE_EIP) + q2 = manager.usageQ(q2, rangeObj, hostTypes) q3 := manager.Query().Equals("mode", EIP_MODE_STANDALONE_EIP).IsNotEmpty("associate_id") + q3 = manager.usageQ(q3, rangeObj, hostTypes) if len(projectId) > 0 { q1 = q1.Equals("tenant_id", projectId) q2 = q2.Equals("tenant_id", projectId) diff --git a/pkg/compute/models/isolated_devices.go b/pkg/compute/models/isolated_devices.go index d1c7c26c21..d88332cf5c 100644 --- a/pkg/compute/models/isolated_devices.go +++ b/pkg/compute/models/isolated_devices.go @@ -346,6 +346,7 @@ func (manager *SIsolatedDeviceManager) totalCountQ( sqlchemy.IsFalse(hosts.Field("deleted")), sqlchemy.IsTrue(hosts.Field("enabled")), )) + q = q.Filter(sqlchemy.Equals(hosts.Field("id"), q.Field("host_id"))) if len(devType) != 0 { q.In("dev_type", devType) } diff --git a/pkg/compute/models/quotas.go b/pkg/compute/models/quotas.go index a648831646..f18d91ce89 100644 --- a/pkg/compute/models/quotas.go +++ b/pkg/compute/models/quotas.go @@ -71,7 +71,7 @@ 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, "") - eipUsage := ElasticipManager.TotalCount(projectId) + eipUsage := ElasticipManager.TotalCount(projectId, nil, nil) // XXX // keypair belongs to user // keypair := totalKeypairCount(projectId) diff --git a/pkg/compute/models/usage.go b/pkg/compute/models/usage.go index 6483fe6e7a..e45bce93de 100644 --- a/pkg/compute/models/usage.go +++ b/pkg/compute/models/usage.go @@ -42,6 +42,10 @@ func AttachUsageQuery( sqlchemy.Equals(hosts.Field("id"), aggHosts.Field("host_id")), sqlchemy.IsFalse(aggHosts.Field("deleted")))). Filter(sqlchemy.Equals(aggHosts.Field("schedtag_id"), rangeObjId)) + case "cloudregion": + zones := ZoneManager.Query().SubQuery() + q = q.Join(zones, sqlchemy.Equals(hosts.Field("zone_id"), zones.Field("id"))) + q = q.Filter(sqlchemy.Equals(zones.Field("cloudregion_id"), rangeObjId)) } return q } diff --git a/pkg/compute/usages/handler.go b/pkg/compute/usages/handler.go index 5f41c23aa7..b6212002df 100644 --- a/pkg/compute/usages/handler.go +++ b/pkg/compute/usages/handler.go @@ -98,12 +98,13 @@ func addHandler(prefix, rangeObjKey string, hf appsrv.FilterHandler, app *appsrv func AddUsageHandler(prefix string, app *appsrv.Application) { prefix = fmt.Sprintf("%s/usages", prefix) for key, f := range map[string]appsrv.FilterHandler{ - "": rangeObjHandler(nil, ReportGeneralUsage), - "zone": rangeObjHandler(models.ZoneManager, ReportZoneUsage), - "wire": rangeObjHandler(models.WireManager, ReportWireUsage), - "schedtag": rangeObjHandler(models.SchedtagManager, ReportSchedtagUsage), - "host": rangeObjHandler(models.HostManager, ReportHostUsage), - "vcenter": rangeObjHandler(models.VCenterManager, ReportVCenterUsage), + "": rangeObjHandler(nil, ReportGeneralUsage), + "zone": rangeObjHandler(models.ZoneManager, ReportZoneUsage), + "wire": rangeObjHandler(models.WireManager, ReportWireUsage), + "schedtag": rangeObjHandler(models.SchedtagManager, ReportSchedtagUsage), + "host": rangeObjHandler(models.HostManager, ReportHostUsage), + "vcenter": rangeObjHandler(models.VCenterManager, ReportVCenterUsage), + "cloudregion": rangeObjHandler(models.CloudregionManager, ReportCloudRegionUsage), } { addHandler(prefix, key, auth.Authenticate(f), app) } @@ -150,8 +151,11 @@ func ReportSchedtagUsage(userCred mcclient.TokenCredential, schedtag db.IStandal } func ReportZoneUsage(userCred mcclient.TokenCredential, zone db.IStandaloneModel, hostTypes []string) (Usage, error) { - //return - return nil, nil + return ReportGeneralUsage(userCred, zone, hostTypes) +} + +func ReportCloudRegionUsage(userCred mcclient.TokenCredential, cloudRegion db.IStandaloneModel, hostTypes []string) (Usage, error) { + return ReportGeneralUsage(userCred, cloudRegion, hostTypes) } //func ReportGuestUsage() @@ -212,7 +216,7 @@ func ReportGeneralUsage(userCred mcclient.TokenCredential, rangeObj db.IStandalo IsolatedDeviceUsage(rangeObj, hostTypes), WireUsage(rangeObj, hostTypes), NetworkUsage(userCred, rangeObj), - EipUsage(), + EipUsage(rangeObj, hostTypes), ) return @@ -338,12 +342,12 @@ func IsolatedDeviceUsage(rangeObj db.IStandaloneModel, hostType []string) Usage return count } -func EipUsage() Usage { - eipUsage := models.ElasticipManager.TotalCount("") +func EipUsage(rangeObj db.IStandaloneModel, hostTypes []string) Usage { + eipUsage := models.ElasticipManager.TotalCount("", rangeObj, hostTypes) count := make(map[string]interface{}) count["eip.all"] = eipUsage.Total() count["eip.public_ip"] = eipUsage.PublicIPCount count["eip.floating_ip"] = eipUsage.EIPCount count["eip.floating_ip.used"] = eipUsage.EIPUsedCount return count -} \ No newline at end of file +}