1. allow replace set quota when action=replace

2. show when the project external resource was fetched
This commit is contained in:
Qiu Jian
2019-07-04 23:32:10 +08:00
parent 2d0e6bd763
commit b02214bb25
5 changed files with 31 additions and 12 deletions
+1 -1
View File
@@ -62,7 +62,7 @@ func init() {
type QuotaSetOptions struct {
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"`
Action string `help:"quota set action" choices:"add|reset|replace"`
Cascade bool `help:"cascade set quota so that auto increment domain quota if total project quota exceeds parent domain quota"`
QuotaBaseOptions
}
+1 -1
View File
@@ -33,7 +33,7 @@ quotas:
properties:
action:
type: string
description: 设置配额的方式,可能值为set,add和reset,分别代表设置,增加和重置为初始
description: 设置配额的方式,可能值为setreplace, add和reset,分别代表设置配额,替换配额,增加配额和重置为初始配额四种方式
default: set
cascade:
type: boolean
+5 -2
View File
@@ -37,8 +37,9 @@ import (
)
const (
QUOTA_ACTION_ADD = "add"
QUOTA_ACTION_RESET = "reset"
QUOTA_ACTION_ADD = "add"
QUOTA_ACTION_RESET = "reset"
QUOTA_ACTION_REPLACE = "replace"
)
func AddQuotaHandler(manager *SQuotaBaseManager, prefix string, app *appsrv.Application) {
@@ -244,6 +245,8 @@ func (manager *SQuotaBaseManager) setQuotaHanlder(ctx context.Context, w http.Re
oquota.Add(quota)
case QUOTA_ACTION_RESET:
oquota.FetchSystemQuota(scope, ownerId)
case QUOTA_ACTION_REPLACE:
oquota = quota
default:
oquota.Update(quota)
}
+13 -5
View File
@@ -16,6 +16,7 @@ package models
import (
"database/sql"
"time"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
@@ -49,32 +50,39 @@ type SProjectResource struct {
ServiceId string `width:"32" charset:"ascii" primary:"true"`
Resource string `width:"32" charset:"ascii" primary:"true"`
Count int
UpdatedAt time.Time `nullable:"true" updated_at:"true"`
}
type sProjectResourceCount struct {
Resource string
ResCount int
Resource string
ResCount int
LastUpdate time.Time
}
func (manager *SProjectResourceManager) getProjectResource(projId string) (map[string]int, error) {
func (manager *SProjectResourceManager) getProjectResource(projId string) (map[string]int, time.Time, error) {
resources := manager.Query().SubQuery()
q := resources.Query(
resources.Field("resource"),
sqlchemy.SUM("res_count", resources.Field("count")),
sqlchemy.MAX("last_update", resources.Field("updated_at")),
)
q = q.Filter(sqlchemy.Equals(resources.Field("project_id"), projId))
q = q.GroupBy(resources.Field("resource"))
resCnts := make([]sProjectResourceCount, 0)
err := q.All(&resCnts)
if err != nil && err != sql.ErrNoRows {
return nil, errors.Wrap(err, "query.All")
return nil, time.Time{}, errors.Wrap(err, "query.All")
}
ret := make(map[string]int)
lastUpdate := time.Time{}
for i := range resCnts {
if resCnts[i].ResCount == 0 {
continue
}
ret[resCnts[i].Resource] = resCnts[i].ResCount
if lastUpdate.IsZero() || lastUpdate.Before(resCnts[i].LastUpdate) {
lastUpdate = resCnts[i].LastUpdate
}
}
return ret, nil
return ret, lastUpdate, nil
}
+11 -3
View File
@@ -19,6 +19,7 @@ import (
"database/sql"
"fmt"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -29,6 +30,7 @@ import (
api "yunion.io/x/onecloud/pkg/apis/identity"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/keystone/options"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/pinyinutils"
)
@@ -258,7 +260,7 @@ func (proj *SProject) ValidateDeleteCondition(ctx context.Context) error {
if proj.IsAdminProject() {
return httperrors.NewForbiddenError("cannot delete system project")
}
external, _ := proj.getExternalResources()
external, _, _ := proj.getExternalResources()
if len(external) > 0 {
return httperrors.NewNotEmptyError("project contains external resources")
}
@@ -304,14 +306,20 @@ func projectExtra(proj *SProject, extra *jsonutils.JSONDict) *jsonutils.JSONDict
extra.Add(jsonutils.NewInt(int64(grpCnt)), "group_count")
usrCnt, _ := proj.GetUserCount()
extra.Add(jsonutils.NewInt(int64(usrCnt)), "user_count")
external, _ := proj.getExternalResources()
external, update, _ := proj.getExternalResources()
if len(external) > 0 {
extra.Add(jsonutils.Marshal(external), "ext_resources")
extra.Add(jsonutils.NewTimeString(update), "ext_resources_last_update")
if update.IsZero() {
update = time.Now()
}
nextUpdate := update.Add(time.Duration(options.Options.FetchProjectResourceCountIntervalSeconds) * time.Second)
extra.Add(jsonutils.NewTimeString(nextUpdate), "ext_resources_next_update")
}
return extra
}
func (proj *SProject) getExternalResources() (map[string]int, error) {
func (proj *SProject) getExternalResources() (map[string]int, time.Time, error) {
return ProjectResourceManager.getProjectResource(proj.Id)
}