feature: domain resource quota

This commit is contained in:
Qiu Jian
2020-04-03 02:03:55 +08:00
parent ff73856573
commit d1346771aa
60 changed files with 2004 additions and 203 deletions
+14
View File
@@ -16,6 +16,7 @@ package db
import (
"fmt"
"regexp"
"yunion.io/x/pkg/util/stringutils"
@@ -112,3 +113,16 @@ func GenerateName2(manager IModelManager, ownerId mcclient.IIdentityProvider, hi
baseIndex += 1
}
}
var (
dnsNameREG = regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9-]*$`)
)
type SDnsNameValidatorManager struct{}
func (manager *SDnsNameValidatorManager) ValidateName(name string) error {
if dnsNameREG.MatchString(name) {
return nil
}
return httperrors.NewInputParameterError("name starts with letter, and contains letter, number and - only")
}
+61 -35
View File
@@ -75,10 +75,6 @@ func AddQuotaHandler(manager *SQuotaBaseManager, prefix string, app *appsrv.Appl
fmt.Sprintf("%s/%s", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.getQuotaHandler), nil, "get_quota", nil)
app.AddHandler2("GET",
fmt.Sprintf("%s/%s/<tenantid>", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.getQuotaHandler), nil, "get_quota_for_project", nil)
app.AddHandler2("GET",
fmt.Sprintf("%s/%s/domains", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.listDomainQuotaHandler), nil, "list_quotas_for_all_domains", nil)
@@ -87,30 +83,14 @@ func AddQuotaHandler(manager *SQuotaBaseManager, prefix string, app *appsrv.Appl
fmt.Sprintf("%s/%s/domains/<domainid>", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.getQuotaHandler), nil, "get_quota_for_domain", nil)
app.AddHandler2("GET",
fmt.Sprintf("%s/%s/projects", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.listProjectQuotaHandler), nil, "list_quotas_for_all_projects", nil)
app.AddHandler2("GET",
fmt.Sprintf("%s/%s/projects/<tenantid>", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.getQuotaHandler), nil, "get_quota_for_project", nil)
app.AddHandler2("POST",
fmt.Sprintf("%s/%s", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.setQuotaHandler), nil, "set_quota", nil)
app.AddHandler2("POST",
fmt.Sprintf("%s/%s/<tenantid>", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.setQuotaHandler), nil, "set_quota_for_project", nil)
app.AddHandler2("POST",
fmt.Sprintf("%s/%s/domains/<domainid>", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.setQuotaHandler), nil, "set_quota_for_domain", nil)
app.AddHandler2("POST",
fmt.Sprintf("%s/%s/projects/<tenantid>", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.setQuotaHandler), nil, "set_quota_for_project", nil)
app.AddHandler2("DELETE",
fmt.Sprintf("%s/%s/pending", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.cleanPendingUsageHandler), nil, "clean_pending_usage", nil)
@@ -119,9 +99,31 @@ func AddQuotaHandler(manager *SQuotaBaseManager, prefix string, app *appsrv.Appl
fmt.Sprintf("%s/%s/domains/<domainid>/pending", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.cleanPendingUsageHandler), nil, "clean_pending_usage_for_domain", nil)
app.AddHandler2("DELETE",
fmt.Sprintf("%s/%s/projects/<tenantid>/pending", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.cleanPendingUsageHandler), nil, "clean_pending_usage_for_project", nil)
if manager.scope == rbacutils.ScopeProject {
app.AddHandler2("GET",
fmt.Sprintf("%s/%s/<tenantid>", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.getQuotaHandler), nil, "get_quota_for_project", nil)
app.AddHandler2("GET",
fmt.Sprintf("%s/%s/projects", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.listProjectQuotaHandler), nil, "list_quotas_for_all_projects", nil)
app.AddHandler2("GET",
fmt.Sprintf("%s/%s/projects/<tenantid>", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.getQuotaHandler), nil, "get_quota_for_project", nil)
app.AddHandler2("POST",
fmt.Sprintf("%s/%s/<tenantid>", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.setQuotaHandler), nil, "set_quota_for_project", nil)
app.AddHandler2("POST",
fmt.Sprintf("%s/%s/projects/<tenantid>", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.setQuotaHandler), nil, "set_quota_for_project", nil)
app.AddHandler2("DELETE",
fmt.Sprintf("%s/%s/projects/<tenantid>/pending", prefix, manager.KeywordPlural()),
auth.Authenticate(manager.cleanPendingUsageHandler), nil, "clean_pending_usage_for_project", nil)
}
}
func (manager *SQuotaBaseManager) queryQuota(ctx context.Context, quota IQuota, refresh bool) (*jsonutils.JSONDict, error) {
@@ -181,24 +183,24 @@ func (manager *SQuotaBaseManager) getQuotaHandler(ctx context.Context, w http.Re
} else if len(projectId) > 0 {
data.Add(jsonutils.NewString(projectId), "project")
}
ownerId, scope, err = db.FetchCheckQueryOwnerScope(ctx, userCred, data, manager, policy.PolicyActionGet, true)
ownerId, scope, err = db.FetchCheckQueryOwnerScope(ctx, userCred, data, manager.GetIQuotaManager(), policy.PolicyActionGet, true)
if err != nil {
httperrors.GeneralServerError(w, err)
return
}
} else {
scopeStr, _ := query.GetString("scope")
if scopeStr == "project" {
if scopeStr == "project" && manager.scope == rbacutils.ScopeProject {
scope = rbacutils.ScopeProject
} else if scopeStr == "domain" {
scope = rbacutils.ScopeDomain
} else {
scope = rbacutils.ScopeProject
scope = manager.scope
}
ownerId = userCred
}
keys := OwnerIdQuotaKeys(scope, ownerId)
keys := OwnerIdProjectQuotaKeys(scope, ownerId)
refresh := jsonutils.QueryBoolean(query, "refresh", false)
primary := jsonutils.QueryBoolean(query, "primary", false)
quotaList, err := manager.listQuotas(ctx, userCred, keys.DomainId, keys.ProjectId, scope == rbacutils.ScopeDomain, primary, refresh)
@@ -208,7 +210,12 @@ func (manager *SQuotaBaseManager) getQuotaHandler(ctx context.Context, w http.Re
}
if len(quotaList) == 0 {
quota := manager.newQuota()
baseKeys := OwnerIdQuotaKeys(scope, ownerId)
var baseKeys IQuotaKeys
if manager.scope == rbacutils.ScopeProject {
baseKeys = OwnerIdProjectQuotaKeys(scope, ownerId)
} else {
baseKeys = OwnerIdDomainQuotaKeys(ownerId)
}
reflectutils.FillEmbededStructValue(reflect.Indirect(reflect.ValueOf(quota)), reflect.ValueOf(baseKeys))
quota.FetchSystemQuota()
manager.SetQuota(ctx, userCred, quota)
@@ -303,11 +310,16 @@ func (manager *SQuotaBaseManager) cleanPendingUsageHandler(ctx context.Context,
} else if scopeStr == "domain" {
scope = rbacutils.ScopeDomain
} else {
scope = rbacutils.ScopeProject
scope = manager.scope
}
ownerId = userCred
}
keys := OwnerIdQuotaKeys(scope, ownerId)
var keys IQuotaKeys
if manager.scope == rbacutils.ScopeProject {
keys = OwnerIdProjectQuotaKeys(scope, ownerId)
} else {
keys = OwnerIdDomainQuotaKeys(ownerId)
}
err = manager.cleanPendingUsage(ctx, userCred, keys)
if err != nil {
httperrors.GeneralServerError(w, err)
@@ -339,7 +351,12 @@ func (manager *SQuotaBaseManager) setQuotaHandler(ctx context.Context, w http.Re
}
// check is there any nonempty key other than domain_id and project_id
isBaseQuota := IsBaseQuotaKeys(quota.GetKeys())
isBaseQuota := false
if manager.scope == rbacutils.ScopeDomain {
isBaseQuota = IsBaseDomainQuotaKeys(quota.GetKeys())
} else {
isBaseQuota = IsBaseProjectQuotaKeys(quota.GetKeys())
}
ownerId, scope, requestScope, err := manager.fetchSetQuotaScope(ctx, userCred, data, isBaseQuota)
if err != nil {
httperrors.GeneralServerError(w, err)
@@ -347,7 +364,12 @@ func (manager *SQuotaBaseManager) setQuotaHandler(ctx context.Context, w http.Re
}
// fill project_id and domain_id
baseKeys := OwnerIdQuotaKeys(scope, ownerId)
var baseKeys IQuotaKeys
if manager.scope == rbacutils.ScopeDomain {
baseKeys = OwnerIdDomainQuotaKeys(ownerId)
} else {
baseKeys = OwnerIdProjectQuotaKeys(scope, ownerId)
}
reflectutils.FillEmbededStructValue(reflect.Indirect(reflect.ValueOf(quota)), reflect.ValueOf(baseKeys))
keys := quota.GetKeys()
@@ -427,7 +449,7 @@ func (manager *SQuotaBaseManager) setQuotaHandler(ctx context.Context, w http.Re
}
}
quotaList, err := manager.listQuotas(ctx, userCred, baseKeys.DomainId, baseKeys.ProjectId, scope == rbacutils.ScopeDomain, false, true)
quotaList, err := manager.listQuotas(ctx, userCred, baseKeys.OwnerId().GetProjectDomainId(), baseKeys.OwnerId().GetProjectId(), scope == rbacutils.ScopeDomain, false, true)
if err != nil {
httperrors.GeneralServerError(w, err)
return
@@ -510,7 +532,9 @@ func (manager *SQuotaBaseManager) listQuotas(ctx context.Context, userCred mccli
if len(targetDomainId) > 0 {
q = q.Equals("domain_id", targetDomainId)
if domainOnly {
q = q.IsEmpty("tenant_id")
if manager.scope == rbacutils.ScopeProject {
q = q.IsEmpty("tenant_id")
}
} else {
if len(targetProjectId) > 0 {
q = q.Equals("tenant_id", targetProjectId)
@@ -524,7 +548,9 @@ func (manager *SQuotaBaseManager) listQuotas(ctx context.Context, userCred mccli
} else {
// domain only
q = q.IsNotEmpty("domain_id")
q = q.IsNullOrEmpty("tenant_id")
if manager.scope == rbacutils.ScopeProject {
q = q.IsNullOrEmpty("tenant_id")
}
}
if primaryOnly {
// list primary quota for domain or project
+12 -3
View File
@@ -38,9 +38,11 @@ type SQuotaBaseManager struct {
usageStore IQuotaStore
nonNegative bool
scope rbacutils.TRbacScope
}
func NewQuotaBaseManager(model interface{}, tableName string, pendingStore IQuotaStore, usageStore IQuotaStore, keyword, keywordPlural string) SQuotaBaseManager {
func NewQuotaBaseManager(model interface{}, scope rbacutils.TRbacScope, tableName string, pendingStore IQuotaStore, usageStore IQuotaStore, keyword, keywordPlural string) SQuotaBaseManager {
pendingStore.SetVirtualObject(pendingStore)
usageStore.SetVirtualObject(usageStore)
return SQuotaBaseManager{
@@ -48,13 +50,15 @@ func NewQuotaBaseManager(model interface{}, tableName string, pendingStore IQuot
pendingStore: pendingStore,
usageStore: usageStore,
nonNegative: false,
scope: scope,
}
}
func NewQuotaUsageManager(model interface{}, tableName string, keyword, keywordPlural string) SQuotaBaseManager {
func NewQuotaUsageManager(model interface{}, scope rbacutils.TRbacScope, tableName string, keyword, keywordPlural string) SQuotaBaseManager {
return SQuotaBaseManager{
SResourceBaseManager: db.NewResourceBaseManager(model, tableName, keyword, keywordPlural),
nonNegative: true,
scope: scope,
}
}
@@ -271,7 +275,12 @@ func (manager *SQuotaBaseManager) InitializeData() error {
}
quota := manager.newQuota()
baseKeys := OwnerIdQuotaKeys(scope, ownerId)
var baseKeys IQuotaKeys
if manager.scope == rbacutils.ScopeDomain {
baseKeys = OwnerIdDomainQuotaKeys(ownerId)
} else {
baseKeys = OwnerIdProjectQuotaKeys(scope, ownerId)
}
if !reflectutils.FillEmbededStructValue(reflect.Indirect(reflect.ValueOf(quota)), reflect.ValueOf(baseKeys)) {
log.Fatalf("invalid quota??? fail to find SBaseQuotaKey")
}
+114 -30
View File
@@ -23,22 +23,30 @@ import (
"yunion.io/x/onecloud/pkg/util/rbacutils"
)
type SBaseQuotaKeys struct {
// 配额适用的项目的域ID
type SBaseDomainQuotaKeys struct {
// 配额适用的域ID
DomainId string `width:"64" charset:"ascii" nullable:"false" primary:"true" list:"user" json:"domain_id"`
}
type SBaseProjectQuotaKeys struct {
SBaseDomainQuotaKeys
// 配额适用的项目ID
ProjectId string `name:"tenant_id" width:"64" charset:"ascii" nullable:"false" primary:"true" list:"user" json:"project_id"`
}
type SBaseQuotaDetailKeys struct {
type SBaseDomainQuotaDetailKeys struct {
// 配额适用的项目的域名称
Domain string `json:"domain"`
}
type SBaseProjectQuotaDetailKeys struct {
SBaseDomainQuotaDetailKeys
// 配额适用的项目名称
Project string `json:"project"`
}
type SCloudResourceKeys struct {
SBaseQuotaKeys
type SCloudResourceBaseKeys struct {
// 配额适用的平台名称,参考List接口的平台列表
Provider string `width:"32" charset:"ascii" nullable:"false" primary:"true" list:"user" json:"provider"`
// 配额适用的品牌名称,参考List接口的品牌列表
@@ -51,28 +59,56 @@ type SCloudResourceKeys struct {
ManagerId string `width:"64" charset:"ascii" nullable:"false" primary:"true" list:"user" json:"manager_id"`
}
type SCloudResourceDetailKeys struct {
SBaseQuotaDetailKeys
type SCloudResourceKeys struct {
SBaseProjectQuotaKeys
SCloudResourceBaseKeys
}
type SCloudResourceDetailKeys struct {
SBaseProjectQuotaDetailKeys
SCloudResourceDetailBaseKeys
}
type SCloudResourceDetailBaseKeys struct {
// 配额适用的云账号名称
Account string `json:"account"`
// 配额适用的云订阅名称
Manager string `json:"manager"`
}
type SRegionalCloudResourceKeys struct {
SCloudResourceKeys
type SRegionalBaseKeys struct {
// 配额适用的区域ID
RegionId string `width:"64" charset:"ascii" nullable:"false" primary:"true" list:"user" json:"region_id"`
}
type SRegionalCloudResourceKeys struct {
SCloudResourceKeys
SRegionalBaseKeys
}
type SRegionalCloudResourceDetailKeys struct {
SCloudResourceDetailKeys
SRegionalCloudResourceDetailBaseKeys
}
type SRegionalCloudResourceDetailBaseKeys struct {
// 配额适用的区域名称
Region string `json:"region"`
}
type SDomainRegionalCloudResourceKeys struct {
SBaseProjectQuotaKeys
SCloudResourceBaseKeys
SRegionalBaseKeys
}
type SDomainRegionalCloudResourceDetailKeys struct {
SBaseDomainQuotaDetailKeys
SCloudResourceDetailBaseKeys
SRegionalCloudResourceDetailBaseKeys
}
type SZonalCloudResourceKeys struct {
SRegionalCloudResourceKeys
// 配额适用的可用区ID
@@ -86,15 +122,20 @@ type SZonalCloudResourceDetailKeys struct {
Zone string `json:"zone"`
}
func (k SBaseQuotaKeys) Fields() []string {
func (k SBaseDomainQuotaKeys) Fields() []string {
return []string{
"domain_id",
"tenant_id",
}
}
func (k SBaseProjectQuotaKeys) Fields() []string {
return append(k.SBaseDomainQuotaKeys.Fields(),
"tenant_id",
)
}
func (k SCloudResourceKeys) Fields() []string {
return append(k.SBaseQuotaKeys.Fields(),
return append(k.SBaseProjectQuotaKeys.Fields(),
"provider",
"brand",
"cloud_env",
@@ -115,15 +156,20 @@ func (k SZonalCloudResourceKeys) Fields() []string {
)
}
func (k SBaseQuotaKeys) Values() []string {
func (k SBaseDomainQuotaKeys) Values() []string {
return []string{
k.DomainId,
k.ProjectId,
}
}
func (k SBaseProjectQuotaKeys) Values() []string {
return append(k.SBaseDomainQuotaKeys.Values(),
k.ProjectId,
)
}
func (k SCloudResourceKeys) Values() []string {
return append(k.SBaseQuotaKeys.Values(),
return append(k.SBaseProjectQuotaKeys.Values(),
k.Provider,
k.Brand,
k.CloudEnv,
@@ -144,13 +190,22 @@ func (k SZonalCloudResourceKeys) Values() []string {
)
}
func (k1 SBaseQuotaKeys) Compare(ik IQuotaKeys) int {
k2 := ik.(SBaseQuotaKeys)
func (k1 SBaseDomainQuotaKeys) Compare(ik IQuotaKeys) int {
k2 := ik.(SBaseDomainQuotaKeys)
if k1.DomainId < k2.DomainId {
return -1
} else if k1.DomainId > k2.DomainId {
return 1
}
return 0
}
func (k1 SBaseProjectQuotaKeys) Compare(ik IQuotaKeys) int {
k2 := ik.(SBaseProjectQuotaKeys)
r := k1.SBaseDomainQuotaKeys.Compare(k2.SBaseDomainQuotaKeys)
if r != 0 {
return r
}
if k1.ProjectId < k2.ProjectId {
return -1
} else if k1.ProjectId > k2.ProjectId {
@@ -161,7 +216,7 @@ func (k1 SBaseQuotaKeys) Compare(ik IQuotaKeys) int {
func (k1 SCloudResourceKeys) Compare(ik IQuotaKeys) int {
k2 := ik.(SCloudResourceKeys)
r := k1.SBaseQuotaKeys.Compare(k2.SBaseQuotaKeys)
r := k1.SBaseProjectQuotaKeys.Compare(k2.SBaseProjectQuotaKeys)
if r != 0 {
return r
}
@@ -221,7 +276,15 @@ func QuotaKeyWeight(k IQuotaKeys) uint64 {
return w
}
func (k SBaseQuotaKeys) Scope() rbacutils.TRbacScope {
func (k SBaseDomainQuotaKeys) Scope() rbacutils.TRbacScope {
if len(k.DomainId) > 0 {
return rbacutils.ScopeDomain
} else {
return rbacutils.ScopeSystem
}
}
func (k SBaseProjectQuotaKeys) Scope() rbacutils.TRbacScope {
if len(k.DomainId) > 0 && len(k.ProjectId) > 0 {
return rbacutils.ScopeProject
} else if len(k.DomainId) > 0 && len(k.ProjectId) == 0 {
@@ -233,7 +296,11 @@ func (k SBaseQuotaKeys) Scope() rbacutils.TRbacScope {
}
}
func (k SBaseQuotaKeys) OwnerId() mcclient.IIdentityProvider {
func (k SBaseDomainQuotaKeys) OwnerId() mcclient.IIdentityProvider {
return &db.SOwnerId{DomainId: k.DomainId}
}
func (k SBaseProjectQuotaKeys) OwnerId() mcclient.IIdentityProvider {
return &db.SOwnerId{
DomainId: k.DomainId,
ProjectId: k.ProjectId,
@@ -252,7 +319,7 @@ func QuotaKeyString(k IQuotaKeys) string {
return strings.Join(parts, ",")
}
func IsBaseQuotaKeys(k IQuotaKeys) bool {
func IsBaseProjectQuotaKeys(k IQuotaKeys) bool {
fields := k.Fields()
values := k.Values()
for i := range fields {
@@ -263,19 +330,36 @@ func IsBaseQuotaKeys(k IQuotaKeys) bool {
return true
}
func OwnerIdQuotaKeys(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider) SBaseQuotaKeys {
switch scope {
case rbacutils.ScopeDomain:
return SBaseQuotaKeys{
DomainId: ownerId.GetProjectDomainId(),
func IsBaseDomainQuotaKeys(k IQuotaKeys) bool {
fields := k.Fields()
values := k.Values()
for i := range fields {
if fields[i] != "domain_id" && len(values[i]) > 0 {
return false
}
case rbacutils.ScopeProject:
return SBaseQuotaKeys{
DomainId: ownerId.GetProjectDomainId(),
}
return true
}
func OwnerIdProjectQuotaKeys(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider) SBaseProjectQuotaKeys {
if scope == rbacutils.ScopeDomain {
return SBaseProjectQuotaKeys{
SBaseDomainQuotaKeys: SBaseDomainQuotaKeys{
DomainId: ownerId.GetProjectDomainId(),
},
}
} else {
return SBaseProjectQuotaKeys{
SBaseDomainQuotaKeys: SBaseDomainQuotaKeys{
DomainId: ownerId.GetProjectDomainId(),
},
ProjectId: ownerId.GetProjectId(),
}
}
return SBaseQuotaKeys{}
}
func OwnerIdDomainQuotaKeys(ownerId mcclient.IIdentityProvider) SBaseDomainQuotaKeys {
return SBaseDomainQuotaKeys{DomainId: ownerId.GetProjectDomainId()}
}
type TQuotaKeysRelation string
+51 -23
View File
@@ -26,8 +26,10 @@ func TestRelation(t *testing.T) {
{
SRegionalCloudResourceKeys: SRegionalCloudResourceKeys{
SCloudResourceKeys: SCloudResourceKeys{
SBaseQuotaKeys: SBaseQuotaKeys{
DomainId: "domain1",
SBaseProjectQuotaKeys: SBaseProjectQuotaKeys{
SBaseDomainQuotaKeys: SBaseDomainQuotaKeys{
DomainId: "domain1",
},
},
},
},
@@ -36,8 +38,10 @@ func TestRelation(t *testing.T) {
{
SRegionalCloudResourceKeys: SRegionalCloudResourceKeys{
SCloudResourceKeys: SCloudResourceKeys{
SBaseQuotaKeys: SBaseQuotaKeys{
DomainId: "domain2",
SBaseProjectQuotaKeys: SBaseProjectQuotaKeys{
SBaseDomainQuotaKeys: SBaseDomainQuotaKeys{
DomainId: "domain2",
},
},
},
},
@@ -46,8 +50,10 @@ func TestRelation(t *testing.T) {
{
SRegionalCloudResourceKeys: SRegionalCloudResourceKeys{
SCloudResourceKeys: SCloudResourceKeys{
SBaseQuotaKeys: SBaseQuotaKeys{
DomainId: "domain1",
SBaseProjectQuotaKeys: SBaseProjectQuotaKeys{
SBaseDomainQuotaKeys: SBaseDomainQuotaKeys{
DomainId: "domain1",
},
ProjectId: "project1",
},
},
@@ -57,8 +63,10 @@ func TestRelation(t *testing.T) {
{
SRegionalCloudResourceKeys: SRegionalCloudResourceKeys{
SCloudResourceKeys: SCloudResourceKeys{
SBaseQuotaKeys: SBaseQuotaKeys{
DomainId: "domain1",
SBaseProjectQuotaKeys: SBaseProjectQuotaKeys{
SBaseDomainQuotaKeys: SBaseDomainQuotaKeys{
DomainId: "domain1",
},
ProjectId: "project2",
},
},
@@ -68,8 +76,10 @@ func TestRelation(t *testing.T) {
{
SRegionalCloudResourceKeys: SRegionalCloudResourceKeys{
SCloudResourceKeys: SCloudResourceKeys{
SBaseQuotaKeys: SBaseQuotaKeys{
DomainId: "domain2",
SBaseProjectQuotaKeys: SBaseProjectQuotaKeys{
SBaseDomainQuotaKeys: SBaseDomainQuotaKeys{
DomainId: "domain2",
},
ProjectId: "project1",
},
},
@@ -79,35 +89,47 @@ func TestRelation(t *testing.T) {
{
SRegionalCloudResourceKeys: SRegionalCloudResourceKeys{
SCloudResourceKeys: SCloudResourceKeys{
SBaseQuotaKeys: SBaseQuotaKeys{
DomainId: "domain1",
SBaseProjectQuotaKeys: SBaseProjectQuotaKeys{
SBaseDomainQuotaKeys: SBaseDomainQuotaKeys{
DomainId: "domain1",
},
ProjectId: "project1",
},
},
RegionId: "region1",
SRegionalBaseKeys: SRegionalBaseKeys{
RegionId: "region1",
},
},
},
// Project11Region2 :=
{
SRegionalCloudResourceKeys: SRegionalCloudResourceKeys{
SCloudResourceKeys: SCloudResourceKeys{
SBaseQuotaKeys: SBaseQuotaKeys{
DomainId: "domain1",
SBaseProjectQuotaKeys: SBaseProjectQuotaKeys{
SBaseDomainQuotaKeys: SBaseDomainQuotaKeys{
DomainId: "domain1",
},
ProjectId: "project1",
},
},
RegionId: "region2",
SRegionalBaseKeys: SRegionalBaseKeys{
RegionId: "region2",
},
},
},
// Project11Aliyun :=
{
SRegionalCloudResourceKeys: SRegionalCloudResourceKeys{
SCloudResourceKeys: SCloudResourceKeys{
SBaseQuotaKeys: SBaseQuotaKeys{
DomainId: "domain1",
SBaseProjectQuotaKeys: SBaseProjectQuotaKeys{
SBaseDomainQuotaKeys: SBaseDomainQuotaKeys{
DomainId: "domain1",
},
ProjectId: "project1",
},
Provider: "Aliyun",
SCloudResourceBaseKeys: SCloudResourceBaseKeys{
Provider: "Aliyun",
},
},
},
},
@@ -115,13 +137,19 @@ func TestRelation(t *testing.T) {
{
SRegionalCloudResourceKeys: SRegionalCloudResourceKeys{
SCloudResourceKeys: SCloudResourceKeys{
SBaseQuotaKeys: SBaseQuotaKeys{
DomainId: "domain1",
SBaseProjectQuotaKeys: SBaseProjectQuotaKeys{
SBaseDomainQuotaKeys: SBaseDomainQuotaKeys{
DomainId: "domain1",
},
ProjectId: "project1",
},
Provider: "Aliyun",
SCloudResourceBaseKeys: SCloudResourceBaseKeys{
Provider: "Aliyun",
},
},
SRegionalBaseKeys: SRegionalBaseKeys{
RegionId: "region1",
},
RegionId: "region1",
},
},
}
+1 -1
View File
@@ -29,7 +29,7 @@ import (
)
func (manager *SQuotaBaseManager) ResourceScope() rbacutils.TRbacScope {
return rbacutils.ScopeProject
return manager.scope
}
func (manager *SQuotaBaseManager) FetchOwnerId(ctx context.Context, data jsonutils.JSONObject) (mcclient.IIdentityProvider, error) {
+3
View File
@@ -17,6 +17,7 @@ package quotas
import (
"context"
"reflect"
"runtime/debug"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -82,6 +83,8 @@ func cancelUsage(ctx context.Context, userCred mcclient.TokenCredential, usage I
if err != nil {
log.Errorf("cancelUsage %s fail: %s", jsonutils.Marshal(usage), err)
}
log.Infof("cancelUsage %s", jsonutils.Marshal(usage))
debug.PrintStack()
}
func GetQuotaCount(ctx context.Context, request IQuota, pendingKeys IQuotaKeys) (int, error) {