mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 02:37:24 +08:00
feature: allow cascade quota set
This commit is contained in:
@@ -63,6 +63,7 @@ func init() {
|
||||
Tenant string `help:"Tenant name or ID to set quota" json:"tenant,omitempty"`
|
||||
ProjectDomain string `help:"Domain name or ID to set quota" json:"domain,omitempty"`
|
||||
Action string `help:"quota set action" choices:"add|reset"`
|
||||
Cascade bool `help:"cascade set quota so that auto increment domain quota if total project quota exceeds parent domain quota"`
|
||||
QuotaBaseOptions
|
||||
}
|
||||
R(&QuotaSetOptions{}, "quota-set", "Set quota for tenant", func(s *mcclient.ClientSession, args *QuotaSetOptions) error {
|
||||
|
||||
@@ -35,6 +35,9 @@ quotas:
|
||||
type: string
|
||||
description: 设置配额的方式,可能值为set,add和reset,分别代表设置,增加和重置为初始值
|
||||
default: set
|
||||
cascade:
|
||||
type: boolean
|
||||
description: 设置项目配额时,如果项目总配额超过域配额,则自动调整域配额
|
||||
cpu:
|
||||
type: integer
|
||||
description: 设置CPU配额,单位为个
|
||||
|
||||
@@ -167,15 +167,15 @@ func (manager *SQuotaBaseManager) getQuotaHanlder(ctx context.Context, w http.Re
|
||||
appsrv.SendJSON(w, body)
|
||||
}
|
||||
|
||||
func FetchSetQuotaScope(ctx context.Context, userCred mcclient.TokenCredential, data jsonutils.JSONObject) (mcclient.IIdentityProvider, rbacutils.TRbacScope, error) {
|
||||
func FetchSetQuotaScope(ctx context.Context, userCred mcclient.TokenCredential, data jsonutils.JSONObject) (mcclient.IIdentityProvider, rbacutils.TRbacScope, rbacutils.TRbacScope, error) {
|
||||
var scope rbacutils.TRbacScope
|
||||
ownerId, err := db.FetchProjectInfo(ctx, data)
|
||||
if err != nil {
|
||||
return nil, scope, err
|
||||
return nil, scope, scope, err
|
||||
}
|
||||
var requestScope rbacutils.TRbacScope
|
||||
ownerScope := policy.PolicyManager.AllowScope(userCred, consts.GetServiceType(), quotaKeywords, policy.PolicyActionUpdate)
|
||||
if ownerId != nil {
|
||||
var requestScope rbacutils.TRbacScope
|
||||
if len(ownerId.GetProjectId()) > 0 {
|
||||
// project level
|
||||
scope = rbacutils.ScopeProject
|
||||
@@ -189,14 +189,15 @@ func FetchSetQuotaScope(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
scope = rbacutils.ScopeDomain
|
||||
requestScope = rbacutils.ScopeSystem
|
||||
}
|
||||
if requestScope.HigherThan(ownerScope) {
|
||||
return nil, scope, httperrors.NewForbiddenError("not enough privilleges")
|
||||
}
|
||||
} else {
|
||||
ownerId = userCred
|
||||
scope = rbacutils.ScopeProject
|
||||
requestScope = rbacutils.ScopeDomain
|
||||
}
|
||||
return ownerId, scope, nil
|
||||
if requestScope.HigherThan(ownerScope) {
|
||||
return nil, scope, scope, httperrors.NewForbiddenError("not enough privilleges")
|
||||
}
|
||||
return ownerId, scope, ownerScope, nil
|
||||
}
|
||||
|
||||
func (manager *SQuotaBaseManager) setQuotaHanlder(ctx context.Context, w http.ResponseWriter, r *http.Request) {
|
||||
@@ -211,7 +212,7 @@ func (manager *SQuotaBaseManager) setQuotaHanlder(ctx context.Context, w http.Re
|
||||
} else if len(domainId) > 0 {
|
||||
data.Add(jsonutils.NewString(domainId), "project_domain")
|
||||
}
|
||||
ownerId, scope, err := FetchSetQuotaScope(ctx, userCred, data)
|
||||
ownerId, scope, allowScope, err := FetchSetQuotaScope(ctx, userCred, data)
|
||||
if err != nil {
|
||||
httperrors.GeneralServerError(w, err)
|
||||
return
|
||||
@@ -266,9 +267,26 @@ func (manager *SQuotaBaseManager) setQuotaHanlder(ctx context.Context, w http.Re
|
||||
total.Add(oquota)
|
||||
err = total.Exceed(quota, domainQuota)
|
||||
if err != nil {
|
||||
log.Errorf("project quota exeed domain quota: %s", err)
|
||||
httperrors.OutOfQuotaError(w, "project quota exeed domain quota")
|
||||
return
|
||||
// exeed domain quota
|
||||
cascade, _ := body.Bool(manager.KeywordPlural(), "cascade")
|
||||
if !cascade {
|
||||
log.Errorf("project quota exeed domain quota: %s", err)
|
||||
httperrors.OutOfQuotaError(w, "project quota exeed domain quota")
|
||||
return
|
||||
} else {
|
||||
if allowScope != rbacutils.ScopeSystem {
|
||||
httperrors.OutOfQuotaError(w, "project quota exeed domain quota, no previlige to cascade set")
|
||||
return
|
||||
} else {
|
||||
// cascade set domain quota
|
||||
err = manager.SetQuota(ctx, userCred, rbacutils.ScopeDomain, ownerId, nil, total)
|
||||
if err != nil {
|
||||
log.Errorf("cascade set quota fail %s", err)
|
||||
httperrors.GeneralServerError(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
total, err := manager.getDomainTotalQuota(ctx, ownerId.GetProjectDomainId(), nil)
|
||||
|
||||
Reference in New Issue
Block a user