clean usages when resource deleted

This commit is contained in:
Qiu Jian
2019-12-11 09:08:32 +08:00
parent 0d487cd601
commit 9d6d28b36a
38 changed files with 646 additions and 101 deletions
+54
View File
@@ -244,4 +244,58 @@ func init() {
return nil
})
R(&QuotaListOptions{}, "region-quota-list", "List region quota of domains or projects of a domain", func(s *mcclient.ClientSession, args *QuotaListOptions) error {
params := jsonutils.Marshal(args)
result, e := modules.RegionQuotas.GetQuotaList(s, params)
if e != nil {
return e
}
printQuotaList(result)
return nil
})
R(&QuotaListOptions{}, "zone-quota-list", "List zone quota of domains or projects of a domain", func(s *mcclient.ClientSession, args *QuotaListOptions) error {
params := jsonutils.Marshal(args)
result, e := modules.ZoneQuotas.GetQuotaList(s, params)
if e != nil {
return e
}
printQuotaList(result)
return nil
})
R(&QuotaListOptions{}, "project-quota-list", "List project quota of domains or projects of a domain", func(s *mcclient.ClientSession, args *QuotaListOptions) error {
params := jsonutils.Marshal(args)
result, e := modules.ProjectQuotas.GetQuotaList(s, params)
if e != nil {
return e
}
printQuotaList(result)
return nil
})
R(&QuotaListOptions{}, "image-quota-list", "List image quota of domains or projects of a domain", func(s *mcclient.ClientSession, args *QuotaListOptions) error {
params := jsonutils.Marshal(args)
result, e := modules.ImageQuotas.GetQuotaList(s, params)
if e != nil {
return e
}
printQuotaList(result)
return nil
})
type CleanPendingUsageOptions struct {
Scope string `help:"scope" choices:"domain|project"`
Project string `help:"Tenant name or ID" json:"tenant"`
Domain string `help:"Domain name or ID" json:"domain"`
}
R(&CleanPendingUsageOptions{}, "clean-pending-usage", "Clean pending usage for project or domain", func(s *mcclient.ClientSession, args *CleanPendingUsageOptions) error {
params := jsonutils.Marshal(args)
log.Debugf("%s", params)
_, err := modules.Quotas.DoCleanPendingUsage(s, params)
if err != nil {
return err
}
return nil
})
}
+4 -1
View File
@@ -149,7 +149,10 @@ func ValidateCreateData(manager IModelManager, ctx context.Context, userCred mcc
if err := ValueToError(ret[1]); err != nil {
return nil, err
}
return ValueToJSONObject(resVal).(*jsonutils.JSONDict), nil
retJson := ValueToJSONObject(resVal).(*jsonutils.JSONDict)
// preserve the input info not returned by caller
data.Update(retJson)
return data, nil
}
func ListItemFilter(manager IModelManager, ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
+5
View File
@@ -43,6 +43,10 @@ import (
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
var (
CancelUsages func(ctx context.Context, userCred mcclient.TokenCredential, usages []IUsage)
)
type DBModelDispatcher struct {
modelManager IModelManager
}
@@ -1539,6 +1543,7 @@ func objectUpdateSpec(dispatcher *DBModelDispatcher, model IModel, modelValue re
func DeleteModel(ctx context.Context, userCred mcclient.TokenCredential, item IModel) error {
// log.Debugf("Ready to delete %s %s %#v", jsonutils.Marshal(item), item, manager)
cleanModelUsages(ctx, userCred, item)
_, err := Update(item, func() error {
return item.MarkDelete()
})
+7
View File
@@ -30,6 +30,11 @@ import (
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type IUsage interface {
FetchUsage(ctx context.Context) error
IsEmpty() bool
}
type IModelManager interface {
lockman.ILockedClass
object.IObject
@@ -182,6 +187,8 @@ type IModel interface {
CustomizedGetDetailsBody(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (jsonutils.JSONObject, error)
MarkDeletePreventionOn()
MarkDeletePreventionOff()
GetUsages() []IUsage
}
type IResourceModelManager interface {
+14 -1
View File
@@ -512,8 +512,17 @@ func (model *SModelBase) CustomizeDelete(ctx context.Context, userCred mcclient.
return nil
}
func cleanModelUsages(ctx context.Context, userCred mcclient.TokenCredential, model IModel) {
usages := model.GetIModel().GetUsages()
if CancelUsages != nil && len(usages) > 0 {
CancelUsages(ctx, userCred, usages)
}
}
func (model *SModelBase) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) {
// do nothing
// clean usage on predelete
// clean usage before fakedelete for pending delete models
cleanModelUsages(ctx, userCred, model)
}
func (model *SModelBase) PostDelete(ctx context.Context, userCred mcclient.TokenCredential) {
@@ -552,3 +561,7 @@ func (model *SModelBase) UpdateInContext(ctx context.Context, userCred mcclient.
func (model *SModelBase) DeleteInContext(ctx context.Context, userCred mcclient.TokenCredential, ctxObjs []IModel, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return nil, nil
}
func (model *SModelBase) GetUsages() []IUsage {
return nil
}
+54
View File
@@ -85,6 +85,17 @@ func AddQuotaHandler(manager *SQuotaBaseManager, prefix string, app *appsrv.Appl
fmt.Sprintf("%s/%s/projects/<tenantid>", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.setQuotaHanlder), nil, "set_quota_for_project", nil)
app.AddHandler2("DELETE",
fmt.Sprintf("%s/%s", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.cleanPendingUsageHanlder), nil, "clean_pending_usage", nil)
app.AddHandler2("DELETE",
fmt.Sprintf("%s/%s/domains/<domainid>", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.cleanPendingUsageHanlder), nil, "clean_pending_usage_for_domain", nil)
app.AddHandler2("DELETE",
fmt.Sprintf("%s/%s/projects/<tenantid>", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.cleanPendingUsageHanlder), nil, "clean_pending_usage_for_project", nil)
/*app.AddHandler2("POST",
fmt.Sprintf("%s/%s/<tenantid>/<action>", prefix, _manager.Keyword()),
auth.Authenticate(checkQuotaHanlder), nil, "check_quota", nil)*/
@@ -230,6 +241,49 @@ func (manager *SQuotaBaseManager) fetchSetQuotaScope(ctx context.Context, userCr
return ownerId, scope, ownerScope, nil
}
func (manager *SQuotaBaseManager) cleanPendingUsageHanlder(ctx context.Context, w http.ResponseWriter, r *http.Request) {
params, query, _ := appsrv.FetchEnv(ctx, w, r)
userCred := auth.FetchUserCredential(ctx, policy.FilterPolicyCredential)
var ownerId mcclient.IIdentityProvider
var scope rbacutils.TRbacScope
var err error
projectId := params["<tenantid>"]
domainId := params["<domainid>"]
if len(projectId) > 0 || len(domainId) > 0 {
data := jsonutils.NewDict()
if len(domainId) > 0 {
data.Add(jsonutils.NewString(domainId), "project_domain")
} else if len(projectId) > 0 {
data.Add(jsonutils.NewString(projectId), "project")
}
ownerId, scope, err = db.FetchCheckQueryOwnerScope(ctx, userCred, data, manager, policy.PolicyActionGet, true)
if err != nil {
httperrors.GeneralServerError(w, err)
return
}
} else {
scopeStr, _ := query.GetString("scope")
if scopeStr == "project" {
scope = rbacutils.ScopeProject
} else if scopeStr == "domain" {
scope = rbacutils.ScopeDomain
} else {
scope = rbacutils.ScopeProject
}
ownerId = userCred
}
keys := OwnerIdQuotaKeys(scope, ownerId)
err = manager.cleanPendingUsage(ctx, userCred, keys)
if err != nil {
httperrors.GeneralServerError(w, err)
return
}
rbody := jsonutils.NewDict()
appsrv.SendJSON(w, rbody)
}
func (manager *SQuotaBaseManager) setQuotaHanlder(ctx context.Context, w http.ResponseWriter, r *http.Request) {
params, _, body := appsrv.FetchEnv(ctx, w, r)
userCred := auth.FetchUserCredential(ctx, policy.FilterPolicyCredential)
+12 -2
View File
@@ -18,7 +18,9 @@ import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/object"
"yunion.io/x/onecloud/pkg/mcclient"
)
@@ -29,20 +31,24 @@ type IQuotaKeys interface {
}
type IQuota interface {
db.IUsage
GetKeys() IQuotaKeys
SetKeys(IQuotaKeys)
FetchSystemQuota()
FetchUsage(ctx context.Context) error
// FetchUsage(ctx context.Context) error
Update(quota IQuota)
Add(quota IQuota)
Sub(quota IQuota)
Exceed(request IQuota, quota IQuota) error
IsEmpty() bool
// IsEmpty() bool
ToJSON(prefix string) jsonutils.JSONObject
}
type IQuotaStore interface {
object.IObject
GetQuota(ctx context.Context, keys IQuotaKeys, quota IQuota) error
GetChildrenQuotas(ctx context.Context, keys IQuotaKeys) ([]IQuota, error)
GetParentQuotas(ctx context.Context, keys IQuotaKeys) ([]IQuota, error)
@@ -58,5 +64,9 @@ type IQuotaStore interface {
type IQuotaManager interface {
db.IResourceModelManager
checkSetPendingQuota(ctx context.Context, userCred mcclient.TokenCredential, quota IQuota) error
cancelPendingUsage(ctx context.Context, userCred mcclient.TokenCredential, localUsage IQuota, cancelUsage IQuota) error
cancelUsage(ctx context.Context, userCred mcclient.TokenCredential, usage IQuota) error
FetchIdNames(ctx context.Context, idMap map[string]map[string]string) (map[string]map[string]string, error)
}
+6 -4
View File
@@ -41,6 +41,8 @@ type SQuotaBaseManager struct {
}
func NewQuotaBaseManager(model interface{}, tableName string, pendingStore IQuotaStore, usageStore IQuotaStore, keyword, keywordPlural string) SQuotaBaseManager {
pendingStore.SetVirtualObject(pendingStore)
usageStore.SetVirtualObject(usageStore)
return SQuotaBaseManager{
SResourceBaseManager: db.NewResourceBaseManager(model, tableName, keyword, keywordPlural),
pendingStore: pendingStore,
@@ -151,13 +153,13 @@ func (manager *SQuotaBaseManager) setQuotaInternal(ctx context.Context, userCred
func (manager *SQuotaBaseManager) addQuotaInternal(ctx context.Context, userCred mcclient.TokenCredential, diff IQuota) error {
keys := diff.GetKeys()
quota := manager.newQuota()
quota.SetKeys(keys)
err := manager.getQuotaByKeys(ctx, keys, quota)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
// insert one
quota.SetKeys(keys)
} else {
return err
return errors.Wrap(err, "manager.getQuotaByKeys")
}
}
quota.Add(diff)
@@ -167,13 +169,13 @@ func (manager *SQuotaBaseManager) addQuotaInternal(ctx context.Context, userCred
func (manager *SQuotaBaseManager) subQuotaInternal(ctx context.Context, userCred mcclient.TokenCredential, diff IQuota) error {
keys := diff.GetKeys()
quota := manager.newQuota()
quota.SetKeys(keys)
err := manager.getQuotaByKeys(ctx, keys, quota)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
// insert one
quota.SetKeys(keys)
} else {
return err
return errors.Wrap(err, "manager.getQuotaByKeys")
}
}
quota.Sub(diff)
+53 -3
View File
@@ -18,6 +18,7 @@ import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
@@ -38,7 +39,28 @@ func (manager *SQuotaBaseManager) newQuota() IQuota {
return model.(IQuota)
}
func (manager *SQuotaBaseManager) CancelPendingUsage(ctx context.Context, userCred mcclient.TokenCredential, localUsage IQuota, cancelUsage IQuota) error {
func (manager *SQuotaBaseManager) cleanPendingUsage(ctx context.Context, userCred mcclient.TokenCredential, keys IQuotaKeys) error {
LockQuotaKeys(ctx, manager, keys)
defer ReleaseQuotaKeys(ctx, manager, keys)
return manager._cleanPendingUsage(ctx, userCred, keys)
}
func (manager *SQuotaBaseManager) _cleanPendingUsage(ctx context.Context, userCred mcclient.TokenCredential, keys IQuotaKeys) error {
pendings, err := manager.pendingStore.GetChildrenQuotas(ctx, keys)
if err != nil {
return errors.Wrap(err, "manager.pendingStore.GetChildrenQuotas")
}
for i := range pendings {
err := manager.pendingStore.SubQuota(ctx, userCred, pendings[i])
if err != nil {
return errors.Wrap(err, "manager.pendingStore.SubQuota")
}
}
return nil
}
func (manager *SQuotaBaseManager) cancelPendingUsage(ctx context.Context, userCred mcclient.TokenCredential, localUsage IQuota, cancelUsage IQuota) error {
LockQuota(ctx, manager, localUsage)
defer ReleaseQuota(ctx, manager, localUsage)
@@ -52,6 +74,7 @@ func (manager *SQuotaBaseManager) _cancelPendingUsage(ctx context.Context, userC
pendingUsage := manager.newQuota()
pendingUsage.SetKeys(originKeys)
pendingUsage.Update(cancelUsage)
log.Debugf("pending delete key %s %s", QuotaKeyString(originKeys), jsonutils.Marshal(pendingUsage))
err := manager.pendingStore.SubQuota(ctx, userCred, pendingUsage)
if err != nil {
return errors.Wrap(err, "manager.pendingStore.SubQuota")
@@ -63,6 +86,9 @@ func (manager *SQuotaBaseManager) _cancelPendingUsage(ctx context.Context, userC
if localUsage != nil {
localUsage.Sub(cancelUsage)
}
log.Debugf("cancelUsage: %s localUsage: %s", jsonutils.Marshal(cancelUsage), jsonutils.Marshal(localUsage))
// update usages
quotas, err := manager.usageStore.GetParentQuotas(ctx, currentKeys)
if err != nil {
@@ -78,6 +104,30 @@ func (manager *SQuotaBaseManager) _cancelPendingUsage(ctx context.Context, userC
return nil
}
func (manager *SQuotaBaseManager) cancelUsage(ctx context.Context, userCred mcclient.TokenCredential, usage IQuota) error {
LockQuota(ctx, manager, usage)
defer ReleaseQuota(ctx, manager, usage)
return manager._cancelUsage(ctx, userCred, usage)
}
func (manager *SQuotaBaseManager) _cancelUsage(ctx context.Context, userCred mcclient.TokenCredential, usage IQuota) error {
usages, err := manager.usageStore.GetParentQuotas(ctx, usage.GetKeys())
if err != nil {
return errors.Wrap(err, "manager.usageStore.GetParentQuotas")
}
subUsage := manager.newQuota()
subUsage.Update(usage)
for i := range usages {
subUsage.SetKeys(usages[i].GetKeys())
err := manager.usageStore.SubQuota(ctx, userCred, subUsage)
if err != nil {
return errors.Wrap(err, "manager.usageStore.AddQuota")
}
}
return nil
}
/*func (manager *SQuotaBaseManager) GetPendingUsage(ctx context.Context, keys SQuotaKeys, quota IQuota) error {
return manager.pendingStore.GetQuota(ctx, keys, quota)
}*/
@@ -145,7 +195,7 @@ func (manager *SQuotaBaseManager) DeleteAllQuotas(ctx context.Context, userCred
return manager.deleteAllQuotas(ctx, userCred, keys)
}
func (manager *SQuotaBaseManager) CheckQuota(ctx context.Context, request IQuota) error {
func (manager *SQuotaBaseManager) checkQuota(ctx context.Context, request IQuota) error {
LockQuota(ctx, manager, request)
defer ReleaseQuota(ctx, manager, request)
@@ -182,7 +232,7 @@ func (manager *SQuotaBaseManager) _checkQuota(ctx context.Context, request IQuot
return nil
}
func (manager *SQuotaBaseManager) CheckSetPendingQuota(ctx context.Context, userCred mcclient.TokenCredential, quota IQuota) error {
func (manager *SQuotaBaseManager) checkSetPendingQuota(ctx context.Context, userCred mcclient.TokenCredential, quota IQuota) error {
LockQuota(ctx, manager, quota)
defer ReleaseQuota(ctx, manager, quota)
+77
View File
@@ -0,0 +1,77 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package quotas
import (
"context"
"reflect"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/mcclient"
)
var (
quotaManagerTable map[reflect.Type]IQuotaManager
)
func init() {
quotaManagerTable = make(map[reflect.Type]IQuotaManager)
db.CancelUsages = CancelUsages
}
func Register(manager IQuotaManager) {
obj, _ := db.NewModelObject(manager)
ele := reflect.Indirect(reflect.ValueOf(obj))
quotaManagerTable[ele.Type()] = manager
manager.SetVirtualObject(manager)
}
func getQuotaManager(quota IQuota) IQuotaManager {
quotaType := reflect.Indirect(reflect.ValueOf(quota)).Type()
if m, ok := quotaManagerTable[quotaType]; ok {
return m
} else {
log.Fatalf("No manager for quota %s", quotaType.Name())
return nil
}
}
func CancelPendingUsage(ctx context.Context, userCred mcclient.TokenCredential, localUsage IQuota, cancelUsage IQuota) error {
manager := getQuotaManager(cancelUsage)
return manager.cancelPendingUsage(ctx, userCred, localUsage, cancelUsage)
}
func CheckSetPendingQuota(ctx context.Context, userCred mcclient.TokenCredential, quota IQuota) error {
manager := getQuotaManager(quota)
return manager.checkSetPendingQuota(ctx, userCred, quota)
}
func CancelUsages(ctx context.Context, userCred mcclient.TokenCredential, usages []db.IUsage) {
for _, usage := range usages {
cancelUsage(ctx, userCred, usage.(IQuota))
}
}
func cancelUsage(ctx context.Context, userCred mcclient.TokenCredential, usage IQuota) {
manager := getQuotaManager(usage)
err := manager.cancelUsage(ctx, userCred, usage)
if err != nil {
log.Errorf("cancelUsage %s fail: %s", jsonutils.Marshal(usage), err)
}
}
+1 -1
View File
@@ -436,7 +436,7 @@ func (model *SVirtualResourceBase) Delete(ctx context.Context, userCred mcclient
if !model.PendingDeleted {
model.DoPendingDelete(ctx, userCred)
}
return DeleteModel(ctx, userCred, model)
return DeleteModel(ctx, userCred, model.GetIVirtualModel())
}
func (model *SVirtualResourceBase) AllowPerformCancelDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
+22 -6
View File
@@ -426,7 +426,7 @@ func (manager *SBucketManager) ValidateCreateData(
managerV.Model.(*SCloudprovider))
pendingUsage := SRegionQuota{Bucket: 1}
pendingUsage.SetKeys(quotaKeys)
if err := RegionQuotaManager.CheckSetPendingQuota(ctx, userCred, &pendingUsage); err != nil {
if err := quotas.CheckSetPendingQuota(ctx, userCred, &pendingUsage); err != nil {
return input, httperrors.NewOutOfQuotaError("%s", err)
}
@@ -463,7 +463,7 @@ func (bucket *SBucket) PostCreate(
log.Errorf("bucket.GetQuotaKeys fail %s", err)
} else {
pendingUsage.SetKeys(keys)
err = RegionQuotaManager.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
err = quotas.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
if err != nil {
log.Errorf("CancelPendingUsage error %s", err)
}
@@ -761,7 +761,7 @@ func (bucket *SBucket) PerformMakedir(
return nil, httperrors.NewInternalServerError("bucket.GetQuotaKeys %s", err)
}
pendingUsage.SetKeys(keys)
if err := RegionQuotaManager.CheckSetPendingQuota(ctx, userCred, &pendingUsage); err != nil {
if err := quotas.CheckSetPendingQuota(ctx, userCred, &pendingUsage); err != nil {
return nil, httperrors.NewOutOfQuotaError("%s", err)
}
@@ -775,7 +775,7 @@ func (bucket *SBucket) PerformMakedir(
bucket.syncWithCloudBucket(ctx, userCred, iBucket, nil, true)
RegionQuotaManager.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
quotas.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
return nil, nil
}
@@ -930,7 +930,7 @@ func (bucket *SBucket) PerformUpload(
}
pendingUsage.SetKeys(keys)
if !pendingUsage.IsEmpty() {
if err := RegionQuotaManager.CheckSetPendingQuota(ctx, userCred, &pendingUsage); err != nil {
if err := quotas.CheckSetPendingQuota(ctx, userCred, &pendingUsage); err != nil {
return nil, httperrors.NewOutOfQuotaError("%s", err)
}
}
@@ -946,7 +946,7 @@ func (bucket *SBucket) PerformUpload(
bucket.syncWithCloudBucket(ctx, userCred, iBucket, nil, true)
if !pendingUsage.IsEmpty() {
RegionQuotaManager.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
quotas.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
}
return nil, nil
@@ -1251,3 +1251,19 @@ func (bucket *SBucket) GetDetailsAccessInfo(
info.(*jsonutils.JSONDict).Add(jsonutils.NewString(account.Brand), "PROVIDER")
return info, err
}
func (bucket *SBucket) GetUsages() []db.IUsage {
if bucket.PendingDeleted || bucket.Deleted {
return nil
}
usage := SRegionQuota{Bucket: 1}
keys, err := bucket.GetQuotaKeys()
if err != nil {
log.Errorf("bucket.GetQuotaKeys fail %s", err)
return nil
}
usage.SetKeys(keys)
return []db.IUsage{
&usage,
}
}
+22
View File
@@ -33,6 +33,7 @@ import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/cloudprovider"
@@ -1388,3 +1389,24 @@ func (man *SDBInstanceManager) TotalCount(
q = rangeObjectsFilter(q, rangeObjs, q.Field("cloudregion_id"), nil, q.Field("manager_id"))
return q.CountWithError()
}
func (dbinstance *SDBInstance) GetQuotaKeys() quotas.IQuotaKeys {
return fetchRegionalQuotaKeys(
rbacutils.ScopeProject,
dbinstance.GetOwnerId(),
dbinstance.GetRegion(),
dbinstance.GetCloudprovider(),
)
}
func (dbinstance *SDBInstance) GetUsages() []db.IUsage {
if dbinstance.PendingDeleted || dbinstance.Deleted {
return nil
}
usage := SRegionQuota{Rds: 1}
keys := dbinstance.GetQuotaKeys()
usage.SetKeys(keys)
return []db.IUsage{
&usage,
}
}
+18 -2
View File
@@ -507,7 +507,7 @@ func (manager *SDiskManager) ValidateCreateData(ctx context.Context, userCred mc
pendingUsage := SQuota{Storage: diskConfig.SizeMb}
pendingUsage.SetKeys(quotaKey)
if err := QuotaManager.CheckSetPendingQuota(ctx, userCred, &pendingUsage); err != nil {
if err := quotas.CheckSetPendingQuota(ctx, userCred, &pendingUsage); err != nil {
return nil, httperrors.NewOutOfQuotaError("%s", err)
}
return input.JSON(input), nil
@@ -919,7 +919,7 @@ func (disk *SDisk) doResize(ctx context.Context, userCred mcclient.TokenCredenti
return httperrors.NewInternalServerError("disk.GetQuotaKeys fail %s", err)
}
pendingUsage.SetKeys(keys)
err = QuotaManager.CheckSetPendingQuota(ctx, userCred, &pendingUsage)
err = quotas.CheckSetPendingQuota(ctx, userCred, &pendingUsage)
if err != nil {
return httperrors.NewGeneralError(err)
}
@@ -2434,3 +2434,19 @@ func (self *SDisk) PerformChangeOwner(ctx context.Context, userCred mcclient.Tok
}
return nil, nil
}
func (disk *SDisk) GetUsages() []db.IUsage {
if disk.PendingDeleted || disk.Deleted {
return nil
}
usage := SQuota{Storage: disk.DiskSize}
keys, err := disk.GetQuotaKeys()
if err != nil {
log.Errorf("disk.GetQuotaKeys fail %s", err)
return nil
}
usage.SetKeys(keys)
return []db.IUsage{
&usage,
}
}
@@ -33,6 +33,7 @@ import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/policy"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
@@ -1266,3 +1267,24 @@ func (man *SElasticcacheManager) TotalCount(
q = rangeObjectsFilter(q, rangeObjs, q.Field("cloudregion_id"), nil, q.Field("manager_id"))
return q.CountWithError()
}
func (cache *SElasticcache) GetQuotaKeys() quotas.IQuotaKeys {
return fetchRegionalQuotaKeys(
rbacutils.ScopeProject,
cache.GetOwnerId(),
cache.GetRegion(),
cache.GetCloudprovider(),
)
}
func (cache *SElasticcache) GetUsages() []db.IUsage {
if cache.PendingDeleted || cache.Deleted {
return nil
}
usage := SRegionQuota{Cache: 1}
keys := cache.GetQuotaKeys()
usage.SetKeys(keys)
return []db.IUsage{
&usage,
}
}
+19 -3
View File
@@ -723,7 +723,7 @@ func (manager *SElasticipManager) ValidateCreateData(ctx context.Context, userCr
eipPendingUsage := &SRegionQuota{Eip: 1}
quotaKeys := fetchRegionalQuotaKeys(rbacutils.ScopeProject, ownerId, region, provider)
eipPendingUsage.SetKeys(quotaKeys)
err = RegionQuotaManager.CheckSetPendingQuota(ctx, userCred, eipPendingUsage)
err = quotas.CheckSetPendingQuota(ctx, userCred, eipPendingUsage)
if err != nil {
return nil, err
}
@@ -753,7 +753,7 @@ func (self *SElasticip) PostCreate(ctx context.Context, userCred mcclient.TokenC
log.Errorf("GetQuotaKeys fail %s", err)
} else {
eipPendingUsage.SetKeys(keys)
err := RegionQuotaManager.CancelPendingUsage(ctx, userCred, eipPendingUsage, eipPendingUsage)
err := quotas.CancelPendingUsage(ctx, userCred, eipPendingUsage, eipPendingUsage)
if err != nil {
log.Errorf("SElasticip CancelPendingUsage error: %s", err)
}
@@ -1103,7 +1103,7 @@ func (manager *SElasticipManager) NewEipForVMOnHost(ctx context.Context, userCre
host.GetCloudprovider(),
)
eipPendingUsage.SetKeys(keys)
QuotaManager.CancelPendingUsage(ctx, userCred, pendingUsage, eipPendingUsage)
quotas.CancelPendingUsage(ctx, userCred, pendingUsage, eipPendingUsage)
return &eip, nil
}
@@ -1294,3 +1294,19 @@ func (self *SElasticip) getCloudProviderInfo() SCloudProviderInfo {
provider := self.GetCloudprovider()
return MakeCloudProviderInfo(region, nil, provider)
}
func (eip *SElasticip) GetUsages() []db.IUsage {
if eip.PendingDeleted || eip.Deleted {
return nil
}
usage := SRegionQuota{Eip: 1}
keys, err := eip.GetQuotaKeys()
if err != nil {
log.Errorf("disk.GetQuotaKeys fail %s", err)
return nil
}
usage.SetKeys(keys)
return []db.IUsage{
&usage,
}
}
+24 -24
View File
@@ -1533,7 +1533,7 @@ func (self *SGuest) PerformCreatedisk(ctx context.Context, userCred mcclient.Tok
return nil, err
}
pendingUsage.SetKeys(keys)
err = QuotaManager.CheckSetPendingQuota(ctx, userCred, pendingUsage)
err = quotas.CheckSetPendingQuota(ctx, userCred, pendingUsage)
if err != nil {
logclient.AddActionLogWithContext(ctx, self, logclient.ACT_CREATE, err.Error(), userCred, false)
return nil, httperrors.NewOutOfQuotaError(err.Error())
@@ -1544,7 +1544,7 @@ func (self *SGuest) PerformCreatedisk(ctx context.Context, userCred mcclient.Tok
err = self.CreateDisksOnHost(ctx, userCred, host, disksConf, pendingUsage, false, false, nil, nil, false)
if err != nil {
QuotaManager.CancelPendingUsage(ctx, userCred, pendingUsage, pendingUsage)
quotas.CancelPendingUsage(ctx, userCred, pendingUsage, pendingUsage)
logclient.AddActionLogWithContext(ctx, self, logclient.ACT_CREATE, err.Error(), userCred, false)
return nil, httperrors.NewBadRequestError(err.Error())
}
@@ -2109,14 +2109,14 @@ func (self *SGuest) PerformAttachnetwork(ctx context.Context, userCred mcclient.
return nil, err
}
pendingUsage.SetKeys(keys)
err = QuotaManager.CheckSetPendingQuota(ctx, userCred, pendingUsage)
err = quotas.CheckSetPendingQuota(ctx, userCred, pendingUsage)
if err != nil {
return nil, httperrors.NewOutOfQuotaError(err.Error())
}
host := self.GetHost()
_, err = self.attach2NetworkDesc(ctx, userCred, host, conf, pendingUsage, nil)
if err != nil {
QuotaManager.CancelPendingUsage(ctx, userCred, pendingUsage, pendingUsage)
quotas.CancelPendingUsage(ctx, userCred, pendingUsage, pendingUsage)
return nil, httperrors.NewBadRequestError(err.Error())
}
host.ClearSchedDescCache()
@@ -2396,7 +2396,7 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T
}
pendingUsage.SetKeys(keys)
if !pendingUsage.IsEmpty() {
err := QuotaManager.CheckSetPendingQuota(ctx, userCred, pendingUsage)
err := quotas.CheckSetPendingQuota(ctx, userCred, pendingUsage)
if err != nil {
return nil, err
}
@@ -2405,7 +2405,7 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T
if len(newDisks) > 0 {
err := self.CreateDisksOnHost(ctx, userCred, host, newDisks, pendingUsage, false, false, nil, nil, false)
if err != nil {
QuotaManager.CancelPendingUsage(ctx, userCred, pendingUsage, pendingUsage)
quotas.CancelPendingUsage(ctx, userCred, pendingUsage, pendingUsage)
return nil, httperrors.NewBadRequestError("Create disk on host error: %s", err)
}
confs.Add(jsonutils.Marshal(newDisks), "create")
@@ -2871,7 +2871,7 @@ func (self *SGuest) PerformCreateEip(ctx context.Context, userCred mcclient.Toke
return nil, err
}
eipPendingUsage.SetKeys(keys)
err = RegionQuotaManager.CheckSetPendingQuota(ctx, userCred, eipPendingUsage)
err = quotas.CheckSetPendingQuota(ctx, userCred, eipPendingUsage)
if err != nil {
return nil, httperrors.NewOutOfQuotaError("Out of eip quota: %s", err)
}
@@ -3226,7 +3226,7 @@ func (self *SGuest) PerformCreateBackup(ctx context.Context, userCred mcclient.T
return nil, err
}
req.SetKeys(keys)
err = QuotaManager.CheckSetPendingQuota(ctx, userCred, &req)
err = quotas.CheckSetPendingQuota(ctx, userCred, &req)
if err != nil {
return nil, httperrors.NewOutOfQuotaError(err.Error())
}
@@ -3235,7 +3235,7 @@ func (self *SGuest) PerformCreateBackup(ctx context.Context, userCred mcclient.T
params.Set("guest_status", jsonutils.NewString(self.Status))
task, err := taskman.TaskManager.NewTask(ctx, "GuestCreateBackupTask", self, userCred, params, "", "", &req)
if err != nil {
QuotaManager.CancelPendingUsage(ctx, userCred, &req, &req)
quotas.CancelPendingUsage(ctx, userCred, &req, &req)
log.Errorln(err)
return nil, err
} else {
@@ -4128,7 +4128,7 @@ func (self *SGuest) validateCreateInstanceSnapshot(
return nil, err
}
pendingUsage.SetKeys(keys)
err = RegionQuotaManager.CheckSetPendingQuota(ctx, userCred, pendingUsage)
err = quotas.CheckSetPendingQuota(ctx, userCred, pendingUsage)
if err != nil {
return nil, httperrors.NewOutOfQuotaError("Check set pending quota error %s", err)
}
@@ -4151,13 +4151,13 @@ func (self *SGuest) PerformInstanceSnapshot(
name, _ := data.GetString("name")
instanceSnapshot, err := InstanceSnapshotManager.CreateInstanceSnapshot(ctx, ownerId, self, name, false)
if err != nil {
QuotaManager.CancelPendingUsage(
quotas.CancelPendingUsage(
ctx, userCred, pendingUsage, pendingUsage)
return nil, httperrors.NewInternalServerError("create instance snapshot failed: %s", err)
}
err = self.InstaceCreateSnapshot(ctx, userCred, ownerId, instanceSnapshot, pendingUsage)
if err != nil {
RegionQuotaManager.CancelPendingUsage(
quotas.CancelPendingUsage(
ctx, userCred, pendingUsage, pendingUsage)
return nil, httperrors.NewInternalServerError("start create snapshot task failed: %s", err)
}
@@ -4257,24 +4257,24 @@ func (self *SGuest) PerformSnapshotAndClone(
pendingUsage, pendingRegionUsage, err := self.getGuestUsage(int(count))
keys, err := self.GetQuotaKeys()
if err != nil {
QuotaManager.CancelPendingUsage(ctx, userCred, snapshotUsage, snapshotUsage)
quotas.CancelPendingUsage(ctx, userCred, snapshotUsage, snapshotUsage)
return nil, err
}
pendingUsage.SetKeys(keys)
err = QuotaManager.CheckSetPendingQuota(ctx, userCred, &pendingUsage)
err = quotas.CheckSetPendingQuota(ctx, userCred, &pendingUsage)
if err != nil {
QuotaManager.CancelPendingUsage(ctx, userCred, snapshotUsage, snapshotUsage)
quotas.CancelPendingUsage(ctx, userCred, snapshotUsage, snapshotUsage)
return nil, httperrors.NewOutOfQuotaError("Check set pending quota error %s", err)
}
regionKeys, err := self.GetRegionalQuotaKeys()
if err != nil {
QuotaManager.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
quotas.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
return nil, err
}
pendingRegionUsage.SetKeys(regionKeys)
err = RegionQuotaManager.CheckSetPendingQuota(ctx, userCred, &pendingRegionUsage)
err = quotas.CheckSetPendingQuota(ctx, userCred, &pendingRegionUsage)
if err != nil {
QuotaManager.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
quotas.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
return nil, err
}
pendingRegionUsage.Snapshot = snapshotUsage.Snapshot
@@ -4282,24 +4282,24 @@ func (self *SGuest) PerformSnapshotAndClone(
instanceSnapshotName, err := db.GenerateName(InstanceSnapshotManager, self.GetOwnerId(),
fmt.Sprintf("%s-%s", newlyGuestName, rand.String(8)))
if err != nil {
QuotaManager.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
RegionQuotaManager.CancelPendingUsage(ctx, userCred, &pendingRegionUsage, &pendingRegionUsage)
quotas.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
quotas.CancelPendingUsage(ctx, userCred, &pendingRegionUsage, &pendingRegionUsage)
return nil, httperrors.NewInternalServerError("Generate snapshot name failed %s", err)
}
instanceSnapshot, err := InstanceSnapshotManager.CreateInstanceSnapshot(
ctx, self.GetOwnerId(), self, instanceSnapshotName,
jsonutils.QueryBoolean(data, "auto_delete_instance_snapshot", false))
if err != nil {
QuotaManager.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
RegionQuotaManager.CancelPendingUsage(ctx, userCred, &pendingRegionUsage, &pendingRegionUsage)
quotas.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
quotas.CancelPendingUsage(ctx, userCred, &pendingRegionUsage, &pendingRegionUsage)
return nil, httperrors.NewInternalServerError("create instance snapshot failed: %s", err)
}
err = self.StartInstanceSnapshotAndCloneTask(
ctx, userCred, newlyGuestName, &pendingUsage, &pendingRegionUsage, instanceSnapshot, data.(*jsonutils.JSONDict))
if err != nil {
QuotaManager.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
RegionQuotaManager.CancelPendingUsage(ctx, userCred, &pendingRegionUsage, &pendingRegionUsage)
quotas.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
quotas.CancelPendingUsage(ctx, userCred, &pendingRegionUsage, &pendingRegionUsage)
return nil, err
}
return nil, nil
+49 -13
View File
@@ -29,7 +29,6 @@ import (
"yunion.io/x/pkg/gotypes"
"yunion.io/x/pkg/tristate"
"yunion.io/x/pkg/util/compare"
// errors_aggr "yunion.io/x/pkg/util/errors"
"yunion.io/x/pkg/util/netutils"
"yunion.io/x/pkg/util/osprofile"
"yunion.io/x/pkg/util/regutils"
@@ -831,10 +830,13 @@ func (self *SGuest) ValidateUpdateData(ctx context.Context, userCred mcclient.To
}
if vcpuCount > 0 || vmemSize > 0 {
err = self.checkUpdateQuota(ctx, userCred, vcpuCount, vmemSize)
quota, err := self.checkUpdateQuota(ctx, userCred, vcpuCount, vmemSize)
if err != nil {
return nil, httperrors.NewOutOfQuotaError(err.Error())
}
if !quota.IsEmpty() {
data.Add(jsonutils.Marshal(quota), "pending_usage")
}
}
if data.Contains("name") {
@@ -908,8 +910,8 @@ func (manager *SGuestManager) BatchPreValidate(
quota.SetKeys(keys)
regionQuota.SetKeys(regionKeys)
return func() {
QuotaManager.CancelPendingUsage(ctx, userCred, quota, quota)
RegionQuotaManager.CancelPendingUsage(ctx, userCred, regionQuota, regionQuota)
quotas.CancelPendingUsage(ctx, userCred, quota, quota)
quotas.CancelPendingUsage(ctx, userCred, regionQuota, regionQuota)
}, nil
}
return nil, nil
@@ -1356,6 +1358,13 @@ func (manager *SGuestManager) validateEip(userCred mcclient.TokenCredential, inp
func (self *SGuest) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) {
self.SVirtualResourceBase.PostUpdate(ctx, userCred, query, data)
if data.Contains("pending_usage") {
quota := SQuota{}
data.Unmarshal(&quota, "pending_usage")
quotas.CancelPendingUsage(ctx, userCred, &quota, &quota)
}
self.StartSyncTask(ctx, userCred, true, "")
}
@@ -1368,18 +1377,18 @@ func (manager *SGuestManager) checkCreateQuota(
count int,
) (*SQuota, *SRegionQuota, error) {
req, regionReq := getGuestResourceRequirements(ctx, userCred, input, ownerId, count, hasBackup)
err := QuotaManager.CheckSetPendingQuota(ctx, userCred, &req)
err := quotas.CheckSetPendingQuota(ctx, userCred, &req)
if err != nil {
return nil, nil, err
}
err = RegionQuotaManager.CheckSetPendingQuota(ctx, userCred, &regionReq)
err = quotas.CheckSetPendingQuota(ctx, userCred, &regionReq)
if err != nil {
return nil, nil, err
}
return &req, &regionReq, nil
}
func (self *SGuest) checkUpdateQuota(ctx context.Context, userCred mcclient.TokenCredential, vcpuCount int, vmemSize int) error {
func (self *SGuest) checkUpdateQuota(ctx context.Context, userCred mcclient.TokenCredential, vcpuCount int, vmemSize int) (quotas.IQuota, error) {
req := SQuota{}
if vcpuCount > 0 && vcpuCount > int(self.VcpuCount) {
@@ -1392,12 +1401,15 @@ func (self *SGuest) checkUpdateQuota(ctx context.Context, userCred mcclient.Toke
keys, err := self.GetQuotaKeys()
if err != nil {
return errors.Wrap(err, "self.GetQuotaKeys")
return nil, errors.Wrap(err, "self.GetQuotaKeys")
}
req.SetKeys(keys)
err = QuotaManager.CheckQuota(ctx, &req)
err = quotas.CheckSetPendingQuota(ctx, userCred, &req)
if err != nil {
return nil, errors.Wrap(err, "quotas.CheckSetPendingQuota")
}
return err
return &req, nil
}
func getGuestResourceRequirements(
@@ -1471,6 +1483,7 @@ func getGuestResourceRequirements(
func (guest *SGuest) getGuestBackupResourceRequirements(ctx context.Context, userCred mcclient.TokenCredential) SQuota {
guestDisksSize := guest.getDiskSize()
return SQuota{
Count: 1,
Cpu: int(guest.VcpuCount),
Memory: guest.VmemSize,
Storage: guestDisksSize,
@@ -2562,7 +2575,7 @@ func (self *SGuest) attach2NetworkOnce(ctx context.Context, userCred mcclient.To
log.Warningf("self.GetRegionalQuotaKeys fail %s", err)
}
cancelUsage.SetKeys(keys)
err = RegionQuotaManager.CancelPendingUsage(ctx, userCred, pendingUsage, &cancelUsage)
err = quotas.CancelPendingUsage(ctx, userCred, pendingUsage, &cancelUsage)
if err != nil {
log.Warningf("QuotaManager.CancelPendingUsage fail %s", err)
}
@@ -3162,7 +3175,7 @@ func (self *SGuest) createDiskOnStorage(ctx context.Context, userCred mcclient.T
return nil, err
}
cancelUsage.SetKeys(keys)
err = QuotaManager.CancelPendingUsage(ctx, userCred, pendingUsage, &cancelUsage)
err = quotas.CancelPendingUsage(ctx, userCred, pendingUsage, &cancelUsage)
return disk, nil
}
@@ -3251,7 +3264,7 @@ func (self *SGuest) createIsolatedDeviceOnHost(ctx context.Context, userCred mcc
return err
}
cancelUsage.SetKeys(keys)
err = QuotaManager.CancelPendingUsage(ctx, userCred, pendingUsage, &cancelUsage)
err = quotas.CancelPendingUsage(ctx, userCred, pendingUsage, &cancelUsage)
return err
}
@@ -4899,6 +4912,7 @@ func (self *SGuest) GetDiskSnapshotsNotInInstanceSnapshots() ([]SSnapshot, error
func (self *SGuest) getGuestUsage(guestCount int) (SQuota, SRegionQuota, error) {
usage := SQuota{}
regionUsage := SRegionQuota{}
usage.Count = guestCount
usage.Cpu = int(self.VcpuCount) * guestCount
usage.Memory = int(self.VmemSize * guestCount)
diskSize := self.getDiskSize()
@@ -5030,3 +5044,25 @@ func (guest *SGuest) GetQuotaKeys() (quotas.IQuotaKeys, error) {
hypervisor,
), nil
}
func (guest *SGuest) GetUsages() []db.IUsage {
if guest.PendingDeleted || guest.Deleted {
return nil
}
usage, regionUsage, err := guest.getGuestUsage(1)
if err != nil {
log.Errorf("guest.getGuestUsage fail %s", err)
return nil
}
keys, err := guest.GetQuotaKeys()
if err != nil {
log.Errorf("guest.GetQuotaKeys fail %s", err)
return nil
}
usage.SetKeys(keys)
regionUsage.SetKeys(keys.(SComputeResourceKeys).SRegionalCloudResourceKeys)
return []db.IUsage{
&usage,
&regionUsage,
}
}
+22
View File
@@ -30,6 +30,7 @@ import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/cloudprovider"
@@ -883,3 +884,24 @@ func (man *SLoadbalancerManager) TotalCount(
q = rangeObjectsFilter(q, rangeObjs, nil, q.Field("zone_id"), q.Field("manager_id"))
return q.CountWithError()
}
func (lb *SLoadbalancer) GetQuotaKeys() quotas.IQuotaKeys {
return fetchZonalQuotaKeys(
rbacutils.ScopeProject,
lb.GetOwnerId(),
lb.GetZone(),
lb.GetCloudprovider(),
)
}
func (lb *SLoadbalancer) GetUsages() []db.IUsage {
if lb.PendingDeleted || lb.Deleted {
return nil
}
usage := SZoneQuota{Loadbalancer: 1}
keys := lb.GetQuotaKeys()
usage.SetKeys(keys)
return []db.IUsage{
&usage,
}
}
+1 -3
View File
@@ -44,7 +44,6 @@ func init() {
"project_quota_usages",
),
}
ProjectUsageManager.SetVirtualObject(ProjectUsageManager)
ProjectPendingUsageManager = &SQuotaManager{
SQuotaBaseManager: quotas.NewQuotaUsageManager(ProjectQuota,
"project_quota_pending_usage_tbl",
@@ -52,7 +51,6 @@ func init() {
"project_quota_pending_usages",
),
}
ProjectPendingUsageManager.SetVirtualObject(ProjectPendingUsageManager)
ProjectQuotaManager = &SQuotaManager{
SQuotaBaseManager: quotas.NewQuotaBaseManager(ProjectQuota,
"project_quota_tbl",
@@ -62,7 +60,7 @@ func init() {
"project_quotas",
),
}
ProjectQuotaManager.SetVirtualObject(ProjectQuotaManager)
quotas.Register(ProjectQuotaManager)
}
type SProjectQuota struct {
+1 -3
View File
@@ -57,7 +57,6 @@ func init() {
"quota_usages",
),
}
QuotaUsageManager.SetVirtualObject(QuotaUsageManager)
QuotaPendingUsageManager = &SQuotaManager{
SQuotaBaseManager: quotas.NewQuotaUsageManager(Quota,
"quota_pending_usage_tbl",
@@ -65,7 +64,6 @@ func init() {
"quota_pending_usages",
),
}
QuotaPendingUsageManager.SetVirtualObject(QuotaPendingUsageManager)
QuotaManager = &SQuotaManager{
SQuotaBaseManager: quotas.NewQuotaBaseManager(Quota,
"quota_tbl",
@@ -75,7 +73,7 @@ func init() {
"quotas",
),
}
QuotaManager.SetVirtualObject(QuotaManager)
quotas.Register(QuotaManager)
}
type SQuota struct {
+1 -3
View File
@@ -46,7 +46,6 @@ func init() {
"region_quota_usages",
),
}
RegionUsageManager.SetVirtualObject(RegionUsageManager)
RegionPendingUsageManager = &SQuotaManager{
SQuotaBaseManager: quotas.NewQuotaUsageManager(RegionQuota,
"region_quota_pending_usage_tbl",
@@ -54,7 +53,6 @@ func init() {
"region_quota_pending_usages",
),
}
RegionPendingUsageManager.SetVirtualObject(RegionPendingUsageManager)
RegionQuotaManager = &SQuotaManager{
SQuotaBaseManager: quotas.NewQuotaBaseManager(RegionQuota,
"region_quota_tbl",
@@ -64,7 +62,7 @@ func init() {
"region_quotas",
),
}
RegionQuotaManager.SetVirtualObject(RegionQuotaManager)
quotas.Register(RegionQuotaManager)
}
type SRegionQuota struct {
+19
View File
@@ -32,6 +32,7 @@ import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/cloudprovider"
@@ -865,3 +866,21 @@ func (self *SSecurityGroup) RealDelete(ctx context.Context, userCred mcclient.To
}
return self.SVirtualResourceBase.Delete(ctx, userCred)
}
func (sg *SSecurityGroup) GetQuotaKeys() quotas.IQuotaKeys {
return quotas.OwnerIdQuotaKeys(rbacutils.ScopeProject,
sg.GetOwnerId(),
)
}
func (sg *SSecurityGroup) GetUsages() []db.IUsage {
if sg.PendingDeleted || sg.Deleted {
return nil
}
usage := SProjectQuota{Secgroup: 1}
keys := sg.GetQuotaKeys()
usage.SetKeys(keys)
return []db.IUsage{
&usage,
}
}
+35 -1
View File
@@ -31,6 +31,7 @@ import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/cloudprovider"
@@ -268,7 +269,7 @@ func (manager *SSnapshotManager) ValidateCreateData(
return input, err
}
pendingUsage.SetKeys(keys.(SComputeResourceKeys).SRegionalCloudResourceKeys)
err = QuotaManager.CheckQuota(ctx, pendingUsage)
err = quotas.CheckSetPendingQuota(ctx, userCred, pendingUsage)
if err != nil {
return input, err
}
@@ -280,6 +281,18 @@ func (self *SSnapshot) CustomizeCreate(ctx context.Context, userCred mcclient.To
return self.SVirtualResourceBase.CustomizeCreate(ctx, userCred, ownerId, query, data)
}
func (snapshot *SSnapshot) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
snapshot.SVirtualResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
pendingUsage := SRegionQuota{Snapshot: 1}
keys := snapshot.GetQuotaKeys()
pendingUsage.SetKeys(keys)
err := quotas.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
if err != nil {
log.Errorf("quotas.CancelPendingUsage fail %s", err)
}
}
func (manager *SSnapshotManager) OnCreateComplete(ctx context.Context, items []db.IModel, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
snapshot := items[0].(*SSnapshot)
snapshot.StartSnapshotCreateTask(ctx, userCred, nil, "")
@@ -900,3 +913,24 @@ func (manager *SSnapshotManager) StartSnapshotCleanupTask(
task.ScheduleRun(nil)
return nil
}
func (snapshot *SSnapshot) GetQuotaKeys() quotas.IQuotaKeys {
return fetchRegionalQuotaKeys(
rbacutils.ScopeProject,
snapshot.GetOwnerId(),
snapshot.GetRegion(),
snapshot.GetCloudprovider(),
)
}
func (snapshot *SSnapshot) GetUsages() []db.IUsage {
if snapshot.PendingDeleted || snapshot.Deleted {
return nil
}
usage := SRegionQuota{Snapshot: 1}
keys := snapshot.GetQuotaKeys()
usage.SetKeys(keys)
return []db.IUsage{
&usage,
}
}
+1 -3
View File
@@ -46,7 +46,6 @@ func init() {
"zone_quota_usages",
),
}
ZoneUsageManager.SetVirtualObject(ZoneUsageManager)
ZonePendingUsageManager = &SQuotaManager{
SQuotaBaseManager: quotas.NewQuotaUsageManager(ZoneQuota,
"zone_quota_pending_usage_tbl",
@@ -54,7 +53,6 @@ func init() {
"zone_quota_pending_usages",
),
}
ZonePendingUsageManager.SetVirtualObject(ZonePendingUsageManager)
ZoneQuotaManager = &SQuotaManager{
SQuotaBaseManager: quotas.NewQuotaBaseManager(ZoneQuota,
"zone_quota_tbl",
@@ -64,7 +62,7 @@ func init() {
"zone_quotas",
),
}
ZoneQuotaManager.SetVirtualObject(ZoneQuotaManager)
quotas.Register(ZoneQuotaManager)
}
type SZoneQuota struct {
+2 -1
View File
@@ -17,6 +17,7 @@ package tasks
import (
"context"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
)
@@ -39,7 +40,7 @@ func (self *SDiskBaseTask) finalReleasePendingUsage(ctx context.Context) {
pendingUsage := models.SQuota{}
err := self.GetPendingUsage(&pendingUsage, 0)
if err == nil && !pendingUsage.IsEmpty() {
models.QuotaManager.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &pendingUsage)
quotas.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &pendingUsage)
}
}
+2 -1
View File
@@ -23,6 +23,7 @@ import (
api "yunion.io/x/onecloud/pkg/apis/compute"
schedapi "yunion.io/x/onecloud/pkg/apis/scheduler"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/compute/models"
@@ -144,7 +145,7 @@ func (self *DiskBatchCreateTask) startCreateDisk(ctx context.Context, disk *mode
log.Warningf("disk.GetQuotaKeys fail %s", err)
}
quotaStorage.SetKeys(keys)
models.QuotaManager.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &quotaStorage)
quotas.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &quotaStorage)
self.SetPendingUsage(&pendingUsage, 0)
disk.StartDiskCreateTask(ctx, self.GetUserCred(), false, "", self.GetTaskId())
+3 -2
View File
@@ -17,6 +17,7 @@ package tasks
import (
"context"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
)
@@ -39,11 +40,11 @@ func (self *SGuestBaseTask) finalReleasePendingUsage(ctx context.Context) {
pendingUsage := models.SQuota{}
err := self.GetPendingUsage(&pendingUsage, 0)
if err == nil && !pendingUsage.IsEmpty() {
models.QuotaManager.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &pendingUsage)
quotas.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &pendingUsage)
}
pendingRegionUsage := models.SRegionQuota{}
err = self.GetPendingUsage(&pendingRegionUsage, 1)
if err == nil && !pendingRegionUsage.IsEmpty() {
models.RegionQuotaManager.CancelPendingUsage(ctx, self.UserCred, &pendingRegionUsage, &pendingRegionUsage)
quotas.CancelPendingUsage(ctx, self.UserCred, &pendingRegionUsage, &pendingRegionUsage)
}
}
+2 -1
View File
@@ -23,6 +23,7 @@ import (
api "yunion.io/x/onecloud/pkg/apis/compute"
schedapi "yunion.io/x/onecloud/pkg/apis/scheduler"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/compute/models"
@@ -82,7 +83,7 @@ func (self *GuestBatchCreateTask) allocateGuestOnHost(ctx context.Context, guest
log.Errorf("guest.GetQuotaKeys fail %s", err)
}
quotaCpuMem.SetKeys(keys)
err = models.QuotaManager.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &quotaCpuMem)
err = quotas.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &quotaCpuMem)
self.SetPendingUsage(&pendingUsage, 0)
input, err := self.GetCreateInput()
@@ -24,6 +24,7 @@ import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
@@ -234,7 +235,7 @@ func (self *GuestChangeConfigTask) OnGuestChangeCpuMemSpecComplete(ctx context.C
lockman.LockClass(ctx, guest.GetModelManager(), guest.ProjectId)
defer lockman.ReleaseClass(ctx, guest.GetModelManager(), guest.ProjectId)
err = models.QuotaManager.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &cancelUsage)
err = quotas.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &cancelUsage)
if err != nil {
self.markStageFailed(ctx, guest, fmt.Sprintf("CancelPendingUsage fail %s", err))
return
@@ -23,6 +23,7 @@ import (
"yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
@@ -67,13 +68,13 @@ func (self *InstanceSnapshotAndCloneTask) finalReleasePendingUsage(ctx context.C
pendingUsage := models.SQuota{}
err := self.GetPendingUsage(&pendingUsage, 0)
if err == nil && !pendingUsage.IsEmpty() {
models.QuotaManager.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &pendingUsage)
quotas.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &pendingUsage)
}
pendingRegionUsage := models.SRegionQuota{}
err = self.GetPendingUsage(&pendingRegionUsage, 1)
if err == nil && !pendingRegionUsage.IsEmpty() {
models.QuotaManager.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &pendingUsage)
quotas.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &pendingUsage)
}
}
@@ -24,6 +24,7 @@ import (
"yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
"yunion.io/x/onecloud/pkg/compute/models"
@@ -48,7 +49,7 @@ func (self *InstanceSnapshotCreateTask) finalReleasePendingUsage(ctx context.Con
pendingUsage := models.SRegionQuota{}
err := self.GetPendingUsage(&pendingUsage, 0)
if err == nil && !pendingUsage.IsEmpty() {
models.RegionQuotaManager.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &pendingUsage)
quotas.CancelPendingUsage(ctx, self.UserCred, &pendingUsage, &pendingUsage)
}
}
+3 -2
View File
@@ -20,6 +20,7 @@ import (
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
)
@@ -33,7 +34,7 @@ func ClearTaskPendingUsage(ctx context.Context, task taskman.ITask) error {
return errors.Wrap(err, "task.GetPendingUsage")
}
err = models.QuotaManager.CancelPendingUsage(ctx, task.GetUserCred(), &pendingUsage, &pendingUsage)
err = quotas.CancelPendingUsage(ctx, task.GetUserCred(), &pendingUsage, &pendingUsage)
if err != nil {
return errors.Wrap(err, "models.QuotaManager.CancelPendingUsage")
}
@@ -57,7 +58,7 @@ func ClearTaskPendingRegionUsage(ctx context.Context, task taskman.ITask) error
return errors.Wrap(err, "task.GetPendingUsage")
}
err = models.RegionQuotaManager.CancelPendingUsage(ctx, task.GetUserCred(), &pendingUsage, &pendingUsage)
err = quotas.CancelPendingUsage(ctx, task.GetUserCred(), &pendingUsage, &pendingUsage)
if err != nil {
return errors.Wrap(err, "models.QuotaManager.CancelPendingUsage")
}
+2 -2
View File
@@ -165,7 +165,7 @@ func cancelPendingUsage(ctx context.Context, task IScheduleTask) {
return
}
if !pendingUsage.IsEmpty() {
err = models.QuotaManager.CancelPendingUsage(ctx, task.GetUserCred(), &pendingUsage, &pendingUsage)
err = quotas.CancelPendingUsage(ctx, task.GetUserCred(), &pendingUsage, &pendingUsage)
if err != nil {
log.Errorf("cancelpendingusage error %s", err)
}
@@ -178,7 +178,7 @@ func cancelPendingUsage(ctx context.Context, task IScheduleTask) {
return
}
if !pendingRegionUsage.IsEmpty() {
err = models.RegionQuotaManager.CancelPendingUsage(ctx, task.GetUserCred(), &pendingRegionUsage, &pendingRegionUsage)
err = quotas.CancelPendingUsage(ctx, task.GetUserCred(), &pendingRegionUsage, &pendingRegionUsage)
if err != nil {
log.Errorf("cancelpendingusage error %s", err)
}
+2 -2
View File
@@ -77,7 +77,7 @@ func (manager *SGuestImageManager) ValidateCreateData(ctx context.Context, userC
pendingUsage := SQuota{Image: int(imageNum)}
keys := quotas.OwnerIdQuotaKeys(rbacutils.ScopeProject, ownerId)
pendingUsage.SetKeys(keys)
if err := QuotaManager.CheckSetPendingQuota(ctx, userCred, &pendingUsage); err != nil {
if err := quotas.CheckSetPendingQuota(ctx, userCred, &pendingUsage); err != nil {
return nil, httperrors.NewOutOfQuotaError("%s", err)
}
@@ -150,7 +150,7 @@ func (gi *SGuestImage) PostCreate(ctx context.Context, userCred mcclient.TokenCr
pendingUsage := SQuota{Image: int(imageNumber)}
keys := quotas.OwnerIdQuotaKeys(rbacutils.ScopeProject, ownerId)
pendingUsage.SetKeys(keys)
QuotaManager.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
quotas.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
if !suc {
gi.SetStatus(userCred, api.IMAGE_STATUS_KILLED, "create subimage failed")
+25 -2
View File
@@ -375,7 +375,7 @@ func (manager *SImageManager) ValidateCreateData(ctx context.Context, userCred m
pendingUsage := SQuota{Image: 1}
keys := quotas.OwnerIdQuotaKeys(rbacutils.ScopeProject, ownerId)
pendingUsage.SetKeys(keys)
if err := QuotaManager.CheckSetPendingQuota(ctx, userCred, &pendingUsage); err != nil {
if err := quotas.CheckSetPendingQuota(ctx, userCred, &pendingUsage); err != nil {
return nil, httperrors.NewOutOfQuotaError("%s", err)
}
}
@@ -505,7 +505,7 @@ func (self *SImage) PostCreate(ctx context.Context, userCred mcclient.TokenCrede
pendingUsage := SQuota{Image: 1}
keys := quotas.OwnerIdQuotaKeys(rbacutils.ScopeProject, ownerId)
pendingUsage.SetKeys(keys)
QuotaManager.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
quotas.CancelPendingUsage(ctx, userCred, &pendingUsage, &pendingUsage)
}
if data.Contains("properties") {
@@ -1277,3 +1277,26 @@ func (self *SImage) CanUpdate(data jsonutils.JSONObject) bool {
// Only allow update description for now when Image is part of guest image
return self.IsGuestImage.IsFalse() || (dict.Length() == 1 && dict.Contains("description"))
}
func (img *SImage) GetQuotaKeys() quotas.IQuotaKeys {
keys := SImageQuotaKeys{}
keys.SBaseQuotaKeys = quotas.OwnerIdQuotaKeys(rbacutils.ScopeProject, img.GetOwnerId())
if img.GetImageType() == api.ImageTypeISO {
keys.Type = string(api.ImageTypeISO)
} else {
keys.Type = string(api.ImageTypeTemplate)
}
return keys
}
func (img *SImage) GetUsages() []db.IUsage {
if img.PendingDeleted || img.Deleted {
return nil
}
usage := SQuota{Image: 1}
keys := img.GetQuotaKeys()
usage.SetKeys(keys)
return []db.IUsage{
&usage,
}
}
+46 -11
View File
@@ -22,6 +22,7 @@ import (
"yunion.io/x/pkg/tristate"
identityapi "yunion.io/x/onecloud/pkg/apis/identity"
api "yunion.io/x/onecloud/pkg/apis/image"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
commonOptions "yunion.io/x/onecloud/pkg/cloudcommon/options"
"yunion.io/x/onecloud/pkg/image/options"
@@ -51,8 +52,6 @@ func init() {
"quota_pending_usages",
),
}
QuotaPendingUsageManager.SetVirtualObject(QuotaPendingUsageManager)
QuotaUsageManager = &SQuotaManager{
SQuotaBaseManager: quotas.NewQuotaUsageManager(SQuota{},
"quota_usage_tbl",
@@ -60,33 +59,32 @@ func init() {
"quota_usages",
),
}
QuotaUsageManager.SetVirtualObject(QuotaUsageManager)
QuotaManager = &SQuotaManager{
SQuotaBaseManager: quotas.NewQuotaBaseManager(SQuota{}, "quota_tbl", QuotaPendingUsageManager, QuotaUsageManager,
"image_quota", "image_quotas"),
}
QuotaManager.SetVirtualObject(QuotaManager)
quotas.Register(QuotaManager)
}
type SQuota struct {
quotas.SQuotaBase
quotas.SBaseQuotaKeys
SImageQuotaKeys
Image int
}
func (self *SQuota) GetKeys() quotas.IQuotaKeys {
return self.SBaseQuotaKeys
return self.SImageQuotaKeys
}
func (self *SQuota) SetKeys(keys quotas.IQuotaKeys) {
self.SBaseQuotaKeys = keys.(quotas.SBaseQuotaKeys)
self.SImageQuotaKeys = keys.(SImageQuotaKeys)
}
func (self *SQuota) FetchSystemQuota() {
keys := self.SBaseQuotaKeys
keys := self.SImageQuotaKeys
base := 0
switch options.Options.DefaultQuotaValue {
case commonOptions.DefaultQuotaUnlimit:
@@ -115,12 +113,21 @@ func (self *SQuota) FetchSystemQuota() {
}
func (self *SQuota) FetchUsage(ctx context.Context) error {
keys := self.SBaseQuotaKeys
keys := self.SImageQuotaKeys
scope := keys.Scope()
ownerId := keys.OwnerId()
count := ImageManager.count(scope, ownerId, "", tristate.None, false)
var isISO tristate.TriState
if keys.Type == string(api.ImageTypeISO) {
isISO = tristate.True
} else if keys.Type == string(api.ImageTypeTemplate) {
isISO = tristate.False
} else {
isISO = tristate.None
}
count := ImageManager.count(scope, ownerId, "", isISO, false)
self.Image = int(count["total"].Count)
return nil
}
@@ -190,3 +197,31 @@ func (manager *SQuotaManager) FetchIdNames(ctx context.Context, idMap map[string
}
return idMap, nil
}
type SImageQuotaKeys struct {
quotas.SBaseQuotaKeys
Type string `width:"16" charset:"ascii" nullable:"false" primary:"true" list:"user"`
}
func (k SImageQuotaKeys) Fields() []string {
return append(k.SBaseQuotaKeys.Fields(), "type")
}
func (k SImageQuotaKeys) Values() []string {
return append(k.SBaseQuotaKeys.Values(), k.Type)
}
func (k1 SImageQuotaKeys) Compare(ik quotas.IQuotaKeys) int {
k2 := ik.(SImageQuotaKeys)
r := k1.SBaseQuotaKeys.Compare(k2.SBaseQuotaKeys)
if r != 0 {
return r
}
if k1.Type < k2.Type {
return -1
} else if k1.Type > k2.Type {
return 1
}
return 0
}
+9
View File
@@ -66,6 +66,15 @@ func (this *QuotaManager) GetQuota(s *mcclient.ClientSession, params jsonutils.J
return ret, nil
}
func (this *QuotaManager) DoCleanPendingUsage(s *mcclient.ClientSession, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
url := this.getURL(params)
results, err := modulebase.Delete(this.ResourceManager, s, url, nil, "")
if err != nil {
return nil, err
}
return results, nil
}
func (this *QuotaManager) GetQuotaList(s *mcclient.ClientSession, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
var reqUrl string
domainId := jsonutils.GetAnyString(params, []string{"domain", "project_domain", "domain_id", "project_domain_id"})