mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-01 04:27:15 +08:00
fix: pending delete identity projects (#17757)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
This commit is contained in:
@@ -42,8 +42,7 @@ type IdentityBaseResourceListInput struct {
|
||||
type EnabledIdentityBaseResourceListInput struct {
|
||||
IdentityBaseResourceListInput
|
||||
|
||||
// filter by enabled status
|
||||
Enabled *bool `json:"enabled"`
|
||||
apis.EnabledResourceBaseListInput
|
||||
}
|
||||
|
||||
type ProjectFilterListInput struct {
|
||||
|
||||
@@ -59,7 +59,10 @@ func IsValidOrgType(orgType TOrgType) bool {
|
||||
}
|
||||
|
||||
type OrganizationListInput struct {
|
||||
apis.EnabledStatusInfrasResourceBaseListInput
|
||||
EnabledIdentityBaseResourceListInput
|
||||
apis.SharableResourceBaseListInput
|
||||
apis.StatusResourceBaseListInput
|
||||
// apis.EnabledStatusInfrasResourceBaseListInput
|
||||
|
||||
Type []TOrgType `json:"type"`
|
||||
|
||||
@@ -67,7 +70,10 @@ type OrganizationListInput struct {
|
||||
}
|
||||
|
||||
type OrganizationCreateInput struct {
|
||||
apis.EnabledStatusInfrasResourceBaseCreateInput
|
||||
EnabledIdentityBaseResourceCreateInput
|
||||
apis.SharableResourceBaseCreateInput
|
||||
apis.StatusBaseResourceCreateInput
|
||||
// apis.EnabledStatusInfrasResourceBaseCreateInput
|
||||
|
||||
Type TOrgType `json:"type"`
|
||||
|
||||
@@ -96,7 +102,10 @@ func (info *SOrganizationInfo) String() string {
|
||||
}
|
||||
|
||||
type OrganizationUpdateInput struct {
|
||||
apis.EnabledStatusInfrasResourceBaseUpdateInput
|
||||
EnabledIdentityBaseUpdateInput
|
||||
// apis.SharableResourceBaseUpdateInput
|
||||
// apis.StatusResourceBaseUpdateInput
|
||||
// apis.EnabledStatusInfrasResourceBaseUpdateInput
|
||||
}
|
||||
|
||||
type OrganizationPerformAddLevelsInput struct {
|
||||
|
||||
@@ -33,12 +33,16 @@ type SEnabledResourceBase struct {
|
||||
Enabled tristate.TriState `default:"false" list:"user" create:"optional"`
|
||||
}
|
||||
|
||||
type IEnabledBase interface {
|
||||
IModel
|
||||
type IEnabledBaseInterface interface {
|
||||
SetEnabled(enabled bool)
|
||||
GetEnabled() bool
|
||||
}
|
||||
|
||||
type IEnabledBase interface {
|
||||
IModel
|
||||
IEnabledBaseInterface
|
||||
}
|
||||
|
||||
func (m *SEnabledResourceBase) SetEnabled(enabled bool) {
|
||||
if enabled {
|
||||
m.Enabled = tristate.True
|
||||
|
||||
@@ -284,6 +284,8 @@ type IStandaloneModel interface {
|
||||
// IsAlterNameUnique(name string, projectId string) bool
|
||||
// GetExternalId() string
|
||||
|
||||
SetName(name string)
|
||||
|
||||
StandaloneModelManager() IStandaloneModelManager
|
||||
|
||||
GetIStandaloneModel() IStandaloneModel
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
// 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 db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/rbacscope"
|
||||
"yunion.io/x/pkg/util/timeutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/policy"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
)
|
||||
|
||||
type SPendingDeletedBaseManager struct{}
|
||||
|
||||
type SPendingDeletedBase struct {
|
||||
// 资源放入回收站时间
|
||||
PendingDeletedAt time.Time `json:"pending_deleted_at" list:"user" update:"admin"`
|
||||
// 资源是否处于回收站中
|
||||
PendingDeleted bool `nullable:"false" default:"false" index:"true" get:"user" list:"user" json:"pending_deleted"`
|
||||
}
|
||||
|
||||
// GetPendingDeleted implements IPendingDeltable
|
||||
func (base *SPendingDeletedBase) GetPendingDeleted() bool {
|
||||
return base.PendingDeleted
|
||||
}
|
||||
|
||||
// GetPendingDeletedAt implements IPendingDeltable
|
||||
func (base *SPendingDeletedBase) GetPendingDeletedAt() time.Time {
|
||||
return base.PendingDeletedAt
|
||||
}
|
||||
|
||||
func (base *SPendingDeletedBaseManager) FilterBySystemAttributes(manager IStandaloneModelManager, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject, scope rbacscope.TRbacScope) *sqlchemy.SQuery {
|
||||
var pendingDelete string
|
||||
if query != nil {
|
||||
pendingDelete, _ = query.GetString("pending_delete")
|
||||
}
|
||||
pendingDeleteLower := strings.ToLower(pendingDelete)
|
||||
if pendingDeleteLower == "all" || pendingDeleteLower == "any" || utils.ToBool(pendingDeleteLower) {
|
||||
var isAllow bool
|
||||
allowScope, result := policy.PolicyManager.AllowScope(userCred, consts.GetServiceType(), manager.KeywordPlural(), policy.PolicyActionList, "pending_delete")
|
||||
if result.Result.IsAllow() && !scope.HigherThan(allowScope) {
|
||||
isAllow = true
|
||||
}
|
||||
if !isAllow {
|
||||
pendingDeleteLower = ""
|
||||
}
|
||||
}
|
||||
|
||||
if pendingDeleteLower == "all" || pendingDeleteLower == "any" {
|
||||
} else if utils.ToBool(pendingDeleteLower) {
|
||||
q = q.IsTrue("pending_deleted")
|
||||
} else {
|
||||
q = q.Filter(sqlchemy.OR(sqlchemy.IsNull(q.Field("pending_deleted")), sqlchemy.IsFalse(q.Field("pending_deleted"))))
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
func (base *SPendingDeletedBase) MarkPendingDelete(model IStandaloneModel, ctx context.Context, userCred mcclient.TokenCredential, newName string) error {
|
||||
if !base.PendingDeleted {
|
||||
_, err := Update(model, func() error {
|
||||
if len(newName) > 0 {
|
||||
model.SetName(newName)
|
||||
}
|
||||
base.PendingDeleted = true
|
||||
base.PendingDeletedAt = timeutils.UtcNow()
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("MarkPendingDelete update fail %s", err)
|
||||
return errors.Wrap(err, "MarkPendingDelete.Update")
|
||||
}
|
||||
OpsLog.LogEvent(model, ACT_PENDING_DELETE, model.GetShortDesc(ctx), userCred)
|
||||
logclient.AddSimpleActionLog(model, logclient.ACT_PENDING_DELETE, model.GetShortDesc(ctx), userCred, true)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (base *SPendingDeletedBase) MarkCancelPendingDelete(model IStandaloneModel, ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
manager := model.GetModelManager()
|
||||
ownerId := model.GetOwnerId()
|
||||
|
||||
lockman.LockRawObject(ctx, manager.Keyword(), "name")
|
||||
defer lockman.ReleaseRawObject(ctx, manager.Keyword(), "name")
|
||||
|
||||
newName, err := GenerateName(ctx, manager, ownerId, model.GetName())
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GenerateNam")
|
||||
}
|
||||
_, err = Update(model, func() error {
|
||||
model.SetName(newName)
|
||||
base.PendingDeleted = false
|
||||
base.PendingDeletedAt = time.Time{}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "MarkCancelPendingDelete.Update")
|
||||
}
|
||||
OpsLog.LogEvent(model, ACT_CANCEL_DELETE, model.GetShortDesc(ctx), userCred)
|
||||
logclient.AddSimpleActionLog(model, logclient.ACT_CANCEL_DELETE, model.GetShortDesc(ctx), userCred, true)
|
||||
return nil
|
||||
}
|
||||
@@ -122,6 +122,7 @@ func (manager *SRoleCacheManager) FetchRoleFromKeystone(ctx context.Context, idS
|
||||
query := jsonutils.NewDict()
|
||||
query.Set("scope", jsonutils.NewString("system"))
|
||||
query.Set("system", jsonutils.JSONTrue)
|
||||
query.Set("pending_delete", jsonutils.NewString("all"))
|
||||
|
||||
s := auth.GetAdminSession(ctx, consts.GetRegion())
|
||||
role, err := modules.RolesV3.GetById(s, idStr, query)
|
||||
|
||||
@@ -139,6 +139,10 @@ func (model *SStandaloneResourceBase) GetName() string {
|
||||
return model.Name
|
||||
}
|
||||
|
||||
func (model *SStandaloneResourceBase) SetName(name string) {
|
||||
model.Name = name
|
||||
}
|
||||
|
||||
func (model *SStandaloneResourceBase) GetIStandaloneModel() IStandaloneModel {
|
||||
return model.GetVirtualObject().(IStandaloneModel)
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ func StatusBasePerformStatus(model IStatusBaseModel, userCred mcclient.TokenCred
|
||||
}
|
||||
|
||||
func (model *SStatusResourceBase) IsInStatus(status ...string) bool {
|
||||
return utils.IsInStringArray(model.Status, status)
|
||||
return utils.IsInArray(model.Status, status)
|
||||
}
|
||||
|
||||
/*func (model *SStatusStandaloneResourceBase) AllowGetDetailsStatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
|
||||
@@ -236,6 +236,7 @@ func (manager *STenantCacheManager) fetchTenantFromKeystone(ctx context.Context,
|
||||
if len(domainId) > 0 {
|
||||
query.Set("domain_id", jsonutils.NewString(domainId))
|
||||
}
|
||||
query.Set("pending_delete", jsonutils.NewString("all"))
|
||||
|
||||
s := auth.GetAdminSession(ctx, consts.GetRegion())
|
||||
tenant, err := modules.Projects.GetById(s, idStr, query)
|
||||
@@ -431,6 +432,7 @@ func (manager *STenantCacheManager) fetchDomainTenantsFromKeystone(ctx context.C
|
||||
params := jsonutils.NewDict()
|
||||
params.Add(jsonutils.NewString(domainId), "domain_id")
|
||||
params.Add(jsonutils.JSONTrue, "details")
|
||||
params.Add(jsonutils.NewString("all"), "pending_delete")
|
||||
tenants, err := modules.Projects.List(s, params)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Projects.List")
|
||||
|
||||
@@ -31,3 +31,8 @@ func (s SCachedTenant) objType() string {
|
||||
return "project"
|
||||
}
|
||||
}
|
||||
|
||||
type SCachedUser struct {
|
||||
SCachedTenant
|
||||
Lang string
|
||||
}
|
||||
|
||||
@@ -62,6 +62,10 @@ func (w *tenantCacheSyncWorker) Run() {
|
||||
if err != nil {
|
||||
log.Errorf("fail to syncProjects %s", err)
|
||||
}
|
||||
err = syncUsers(w.ctx)
|
||||
if err != nil {
|
||||
log.Errorf("fail to syncUsers %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *tenantCacheSyncWorker) Dump() string {
|
||||
@@ -74,23 +78,25 @@ func syncDomains(ctx context.Context) error {
|
||||
query.Add(jsonutils.NewInt(1024), "limit")
|
||||
query.Add(jsonutils.NewString(string(rbacscope.ScopeSystem)), "scope")
|
||||
query.Add(jsonutils.JSONTrue, "details")
|
||||
query.Add(jsonutils.NewString("all"), "pending_delete")
|
||||
total := -1
|
||||
offset := 0
|
||||
for total < 0 || offset < total {
|
||||
query.Set("offset", jsonutils.NewInt(int64(offset)))
|
||||
results, err := modules.Domains.List(s, query)
|
||||
if err != nil {
|
||||
log.Errorf("syncDomain error %s", err)
|
||||
return errors.Wrap(err, "Domains.List")
|
||||
}
|
||||
total = results.Total
|
||||
for i := range results.Data {
|
||||
// update domain cache
|
||||
item := SCachedTenant{}
|
||||
results.Data[i].Unmarshal(&item)
|
||||
item.ProjectDomain = identityapi.KeystoneDomainRoot
|
||||
item.DomainId = identityapi.KeystoneDomainRoot
|
||||
TenantCacheManager.Save(ctx, item, true)
|
||||
err := results.Data[i].Unmarshal(&item)
|
||||
if err == nil {
|
||||
item.ProjectDomain = identityapi.KeystoneDomainRoot
|
||||
item.DomainId = identityapi.KeystoneDomainRoot
|
||||
TenantCacheManager.Save(ctx, item, true)
|
||||
}
|
||||
offset++
|
||||
}
|
||||
}
|
||||
@@ -103,21 +109,52 @@ func syncProjects(ctx context.Context) error {
|
||||
query.Add(jsonutils.NewInt(1024), "limit")
|
||||
query.Add(jsonutils.NewString(string(rbacscope.ScopeSystem)), "scope")
|
||||
query.Add(jsonutils.JSONTrue, "details")
|
||||
query.Add(jsonutils.NewString("all"), "pending_delete")
|
||||
total := -1
|
||||
offset := 0
|
||||
for total < 0 || offset < total {
|
||||
query.Set("offset", jsonutils.NewInt(int64(offset)))
|
||||
results, err := modules.Projects.List(s, query)
|
||||
if err != nil {
|
||||
log.Errorf("syncProjects error %s", err)
|
||||
return errors.Wrap(err, "Projects.List")
|
||||
}
|
||||
total = results.Total
|
||||
for i := range results.Data {
|
||||
// update project cache
|
||||
item := SCachedTenant{}
|
||||
results.Data[i].Unmarshal(&item)
|
||||
TenantCacheManager.Save(ctx, item, true)
|
||||
err := results.Data[i].Unmarshal(&item)
|
||||
if err != nil {
|
||||
TenantCacheManager.Save(ctx, item, true)
|
||||
}
|
||||
offset++
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func syncUsers(ctx context.Context) error {
|
||||
s := auth.GetAdminSession(ctx, consts.GetRegion())
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewInt(1024), "limit")
|
||||
query.Add(jsonutils.NewString(string(rbacscope.ScopeSystem)), "scope")
|
||||
query.Add(jsonutils.JSONTrue, "details")
|
||||
query.Add(jsonutils.NewString("all"), "pending_delete")
|
||||
total := -1
|
||||
offset := 0
|
||||
for total < 0 || offset < total {
|
||||
query.Set("offset", jsonutils.NewInt(int64(offset)))
|
||||
results, err := modules.UsersV3.List(s, query)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "UsersV3.List")
|
||||
}
|
||||
total = results.Total
|
||||
for i := range results.Data {
|
||||
// update user cache
|
||||
item := SCachedUser{}
|
||||
err := results.Data[i].Unmarshal(&item)
|
||||
if err != nil {
|
||||
UserCacheManager.Save(ctx, item.Id, item.Name, item.DomainId, item.ProjectDomain, item.Lang)
|
||||
}
|
||||
offset++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +124,7 @@ func (manager *SUserCacheManager) FetchUserFromKeystone(ctx context.Context, idS
|
||||
query := jsonutils.NewDict()
|
||||
query.Set("scope", jsonutils.NewString("system"))
|
||||
query.Set("system", jsonutils.JSONTrue)
|
||||
query.Set("pending_delete", jsonutils.NewString("all"))
|
||||
|
||||
s := auth.GetAdminSession(ctx, consts.GetRegion())
|
||||
user, err := modules.UsersV3.GetById(s, idStr, query)
|
||||
|
||||
@@ -16,20 +16,16 @@ package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/rbacscope"
|
||||
"yunion.io/x/pkg/util/timeutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/policy"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
@@ -40,6 +36,7 @@ import (
|
||||
type SVirtualResourceBaseManager struct {
|
||||
SStatusStandaloneResourceBaseManager
|
||||
SProjectizedResourceBaseManager
|
||||
SPendingDeletedBaseManager
|
||||
}
|
||||
|
||||
func NewVirtualResourceBaseManager(dt interface{}, tableName string, keyword string, keywordPlural string) SVirtualResourceBaseManager {
|
||||
@@ -52,6 +49,7 @@ func NewVirtualResourceBaseManager(dt interface{}, tableName string, keyword str
|
||||
type SVirtualResourceBase struct {
|
||||
SStatusStandaloneResourceBase
|
||||
SProjectizedResourceBase
|
||||
SPendingDeletedBase
|
||||
|
||||
// 云上同步资源是否在本地被更改过配置, local: 更改过, cloud: 未更改过
|
||||
// example: local
|
||||
@@ -60,10 +58,6 @@ type SVirtualResourceBase struct {
|
||||
// 是否是系统资源
|
||||
IsSystem bool `nullable:"true" default:"false" list:"admin" create:"optional" json:"is_system"`
|
||||
|
||||
// 资源放入回收站时间
|
||||
PendingDeletedAt time.Time `json:"pending_deleted_at" list:"user" update:"admin"`
|
||||
// 资源是否处于回收站中
|
||||
PendingDeleted bool `nullable:"false" default:"false" index:"true" get:"user" list:"user" json:"pending_deleted"`
|
||||
// 资源是否被冻结
|
||||
Freezed bool `nullable:"false" default:"false" get:"user" list:"user" json:"freezed"`
|
||||
}
|
||||
@@ -215,29 +209,7 @@ func (model *SVirtualResourceBase) SetProjectInfo(ctx context.Context, userCred
|
||||
|
||||
func (manager *SVirtualResourceBaseManager) FilterBySystemAttributes(q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject, scope rbacscope.TRbacScope) *sqlchemy.SQuery {
|
||||
q = manager.SStatusStandaloneResourceBaseManager.FilterBySystemAttributes(q, userCred, query, scope)
|
||||
|
||||
var pendingDelete string
|
||||
if query != nil {
|
||||
pendingDelete, _ = query.GetString("pending_delete")
|
||||
}
|
||||
pendingDeleteLower := strings.ToLower(pendingDelete)
|
||||
if pendingDeleteLower == "all" || pendingDeleteLower == "any" || utils.ToBool(pendingDeleteLower) {
|
||||
var isAllow bool
|
||||
allowScope, result := policy.PolicyManager.AllowScope(userCred, consts.GetServiceType(), manager.KeywordPlural(), policy.PolicyActionList, "pending_delete")
|
||||
if result.Result.IsAllow() && !scope.HigherThan(allowScope) {
|
||||
isAllow = true
|
||||
}
|
||||
if !isAllow {
|
||||
pendingDeleteLower = ""
|
||||
}
|
||||
}
|
||||
|
||||
if pendingDeleteLower == "all" || pendingDeleteLower == "any" {
|
||||
} else if utils.ToBool(pendingDeleteLower) {
|
||||
q = q.IsTrue("pending_deleted")
|
||||
} else {
|
||||
q = q.Filter(sqlchemy.OR(sqlchemy.IsNull(q.Field("pending_deleted")), sqlchemy.IsFalse(q.Field("pending_deleted"))))
|
||||
}
|
||||
q = manager.SPendingDeletedBaseManager.FilterBySystemAttributes(manager.GetIStandaloneModelManager(), q, userCred, query, scope)
|
||||
return q
|
||||
}
|
||||
|
||||
@@ -501,30 +473,16 @@ func (model *SVirtualResourceBase) PerformChangeOwner(ctx context.Context, userC
|
||||
}
|
||||
|
||||
func (model *SVirtualResourceBase) DoPendingDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
return model.MarkPendingDelete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (model *SVirtualResourceBase) MarkPendingDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
if !model.PendingDeleted {
|
||||
_, err := Update(model, func() error {
|
||||
model.PendingDeleted = true
|
||||
model.PendingDeletedAt = timeutils.UtcNow()
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("MarkPendingDelete update fail %s", err)
|
||||
return err
|
||||
}
|
||||
vm := model.GetIVirtualModel()
|
||||
OpsLog.LogEvent(model, ACT_PENDING_DELETE, vm.GetShortDesc(ctx), userCred)
|
||||
logclient.AddSimpleActionLog(model, logclient.ACT_PENDING_DELETE, vm.GetShortDesc(ctx), userCred, true)
|
||||
return model.SPendingDeletedBase.MarkPendingDelete(model.GetIStandaloneModel(), ctx, userCred, "")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (model *SVirtualResourceBase) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
if !model.PendingDeleted {
|
||||
model.DoPendingDelete(ctx, userCred)
|
||||
err := model.DoPendingDelete(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "DoPendingDelete")
|
||||
}
|
||||
return DeleteModel(ctx, userCred, model.GetIVirtualModel())
|
||||
}
|
||||
@@ -545,11 +503,13 @@ func (model *SVirtualResourceBase) PerformCancelDelete(ctx context.Context, user
|
||||
}
|
||||
|
||||
func (model *SVirtualResourceBase) DoCancelPendingDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
err := model.CancelPendingDelete(ctx, userCred)
|
||||
//if err == nil {
|
||||
// OpsLog.LogEvent(model, ACT_CANCEL_DELETE, model.GetShortDesc(ctx), userCred)
|
||||
//}
|
||||
return err
|
||||
if model.PendingDeleted && !model.Deleted {
|
||||
err := model.SPendingDeletedBase.MarkCancelPendingDelete(model.GetIStandaloneModel(), ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "MarkCancelPendingDelete")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (model *SVirtualResourceBase) VirtualModelManager() IVirtualModelManager {
|
||||
@@ -560,41 +520,6 @@ func (model *SVirtualResourceBase) GetIVirtualModel() IVirtualModel {
|
||||
return model.GetVirtualObject().(IVirtualModel)
|
||||
}
|
||||
|
||||
func (model *SVirtualResourceBase) CancelPendingDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
if model.PendingDeleted && !model.Deleted {
|
||||
err := model.MarkCancelPendingDelete(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "MarkCancelPendingDelete")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (model *SVirtualResourceBase) MarkCancelPendingDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
manager := model.GetModelManager()
|
||||
ownerId := model.GetOwnerId()
|
||||
|
||||
lockman.LockRawObject(ctx, manager.Keyword(), "name")
|
||||
defer lockman.ReleaseRawObject(ctx, manager.Keyword(), "name")
|
||||
|
||||
newName, err := GenerateName(ctx, manager, ownerId, model.Name)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GenerateNam")
|
||||
}
|
||||
_, err = Update(model, func() error {
|
||||
model.Name = newName
|
||||
model.PendingDeleted = false
|
||||
model.PendingDeletedAt = time.Time{}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "MarkCancelPendingDelete.Update")
|
||||
}
|
||||
vm := model.GetIVirtualModel()
|
||||
OpsLog.LogEvent(model, ACT_CANCEL_DELETE, vm.GetShortDesc(ctx), userCred)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (model *SVirtualResourceBase) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
|
||||
desc := model.SStatusStandaloneResourceBase.GetShortDesc(ctx)
|
||||
desc.Add(jsonutils.NewString(model.ProjectId), "owner_tenant_id")
|
||||
@@ -621,16 +546,6 @@ func (model *SVirtualResourceBase) SyncCloudProjectId(userCred mcclient.TokenCre
|
||||
}
|
||||
}
|
||||
|
||||
// GetPendingDeleted implements IPendingDeltable
|
||||
func (model *SVirtualResourceBase) GetPendingDeleted() bool {
|
||||
return model.PendingDeleted
|
||||
}
|
||||
|
||||
// GetPendingDeletedAt implements IPendingDeltable
|
||||
func (model *SVirtualResourceBase) GetPendingDeletedAt() time.Time {
|
||||
return model.PendingDeletedAt
|
||||
}
|
||||
|
||||
func (manager *SVirtualResourceBaseManager) OrderByExtraFields(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query apis.VirtualResourceListInput) (*sqlchemy.SQuery, error) {
|
||||
q, err := manager.SStatusStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusStandaloneResourceListInput)
|
||||
if err != nil {
|
||||
|
||||
@@ -17,12 +17,15 @@ package models
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/tristate"
|
||||
"yunion.io/x/pkg/util/rbacscope"
|
||||
"yunion.io/x/pkg/util/timeutils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/identity"
|
||||
@@ -37,6 +40,7 @@ import (
|
||||
|
||||
type SDomainManager struct {
|
||||
db.SStandaloneResourceBaseManager
|
||||
db.SPendingDeletedBaseManager
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -57,6 +61,7 @@ func init() {
|
||||
|
||||
type SDomain struct {
|
||||
db.SStandaloneResourceBase
|
||||
db.SPendingDeletedBase
|
||||
|
||||
// 额外信息
|
||||
Extra *jsonutils.JSONDict `nullable:"true"`
|
||||
@@ -336,10 +341,10 @@ func (domain *SDomain) ValidatePurgeCondition(ctx context.Context) error {
|
||||
if policyCnt > 0 {
|
||||
return httperrors.NewNotEmptyError("domain is in use by policy")
|
||||
}
|
||||
external, _, _ := domain.getExternalResources()
|
||||
/*external, _, _ := domain.getExternalResources()
|
||||
if len(external) > 0 {
|
||||
return httperrors.NewNotEmptyError("domain contains external resources")
|
||||
}
|
||||
}*/
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -483,7 +488,15 @@ func (domain *SDomain) Delete(ctx context.Context, userCred mcclient.TokenCreden
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "domain.DeleteUserGroups")
|
||||
}
|
||||
return domain.SStandaloneResourceBase.Delete(ctx, userCred)
|
||||
// return domain.SStandaloneResourceBase.Delete(ctx, userCred)
|
||||
if !domain.PendingDeleted {
|
||||
newName := fmt.Sprintf("%s-deleted-%s", domain.Name, timeutils.ShortDate(timeutils.UtcNow()))
|
||||
err := domain.SPendingDeletedBase.MarkPendingDelete(domain, ctx, userCred, newName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "MarkPendingDelete")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (domain *SDomain) getIdmapping() (*SIdmapping, error) {
|
||||
@@ -588,3 +601,16 @@ func (domain *SDomain) PerformUnlinkIdp(
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (manager *SDomainManager) FilterBySystemAttributes(q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject, scope rbacscope.TRbacScope) *sqlchemy.SQuery {
|
||||
q = manager.SStandaloneResourceBaseManager.FilterBySystemAttributes(q, userCred, query, scope)
|
||||
q = manager.SPendingDeletedBaseManager.FilterBySystemAttributes(manager.GetIStandaloneModelManager(), q, userCred, query, scope)
|
||||
return q
|
||||
}
|
||||
|
||||
func (manager *SDomainManager) FilterByOwner(q *sqlchemy.SQuery, man db.FilterByOwnerProvider, userCred mcclient.TokenCredential, owner mcclient.IIdentityProvider, scope rbacscope.TRbacScope) *sqlchemy.SQuery {
|
||||
if userCred != nil && scope != rbacscope.ScopeSystem {
|
||||
q = q.Equals("id", owner.GetProjectDomainId())
|
||||
}
|
||||
return manager.SStandaloneResourceBaseManager.FilterByOwner(q, man, userCred, owner, scope)
|
||||
}
|
||||
|
||||
@@ -16,14 +16,16 @@ package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/tristate"
|
||||
"yunion.io/x/pkg/util/rbacscope"
|
||||
"yunion.io/x/pkg/util/timeutils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
api "yunion.io/x/onecloud/pkg/apis/identity"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
@@ -40,16 +42,36 @@ type IIdentityModelManager interface {
|
||||
|
||||
type IIdentityModel interface {
|
||||
db.IStandaloneModel
|
||||
db.IPendingDeletable
|
||||
|
||||
GetDomain() *SDomain
|
||||
|
||||
GetIIdentityModelManager() IIdentityModelManager
|
||||
|
||||
GetIIdentityModel() IIdentityModel
|
||||
}
|
||||
|
||||
type IEnabledIdentityModelManager interface {
|
||||
IIdentityModelManager
|
||||
|
||||
GetIEnabledIdentityModelManager() IEnabledIdentityModelManager
|
||||
}
|
||||
|
||||
type IEnabledIdentityModel interface {
|
||||
IIdentityModel
|
||||
|
||||
db.IEnabledBaseInterface
|
||||
|
||||
GetIEnabledIdentityModelManager() IEnabledIdentityModelManager
|
||||
|
||||
GetIEnabledIdentityModel() IEnabledIdentityModel
|
||||
}
|
||||
|
||||
// +onecloud:swagger-gen-ignore
|
||||
type SIdentityBaseResourceManager struct {
|
||||
db.SStandaloneResourceBaseManager
|
||||
db.SDomainizedResourceBaseManager
|
||||
db.SPendingDeletedBaseManager
|
||||
}
|
||||
|
||||
func NewIdentityBaseResourceManager(dt interface{}, tableName string, keyword string, keywordPlural string) SIdentityBaseResourceManager {
|
||||
@@ -61,15 +83,16 @@ func NewIdentityBaseResourceManager(dt interface{}, tableName string, keyword st
|
||||
type SIdentityBaseResource struct {
|
||||
db.SStandaloneResourceBase
|
||||
db.SDomainizedResourceBase
|
||||
db.SPendingDeletedBase
|
||||
|
||||
// 额外信息
|
||||
Extra *jsonutils.JSONDict `nullable:"true"`
|
||||
// DomainId string `width:"64" charset:"ascii" default:"default" nullable:"false" index:"true" list:"user"`
|
||||
}
|
||||
|
||||
// +onecloud:swagger-gen-ignore
|
||||
type SEnabledIdentityBaseResourceManager struct {
|
||||
SIdentityBaseResourceManager
|
||||
db.SEnabledResourceBaseManager
|
||||
}
|
||||
|
||||
func NewEnabledIdentityBaseResourceManager(dt interface{}, tableName string, keyword string, keywordPlural string) SEnabledIdentityBaseResourceManager {
|
||||
@@ -81,7 +104,7 @@ func NewEnabledIdentityBaseResourceManager(dt interface{}, tableName string, key
|
||||
type SEnabledIdentityBaseResource struct {
|
||||
SIdentityBaseResource
|
||||
|
||||
Enabled tristate.TriState `default:"true" list:"user" update:"domain" create:"domain_optional"`
|
||||
db.SEnabledResourceBase `enabled=>default:"true" list:"user" enabled=>update:"domain" enabled=>create:"domain_optional"`
|
||||
}
|
||||
|
||||
func (model *SIdentityBaseResource) GetIIdentityModelManager() IIdentityModelManager {
|
||||
@@ -92,10 +115,6 @@ func (model *SIdentityBaseResource) GetIIdentityModel() IIdentityModel {
|
||||
return model.GetVirtualObject().(IIdentityModel)
|
||||
}
|
||||
|
||||
// func (model *SIdentityBaseResource) IsOwner(userCred mcclient.TokenCredential) bool {
|
||||
// return userCred.GetProjectDomainId() == model.DomainId
|
||||
// }
|
||||
|
||||
func (model *SIdentityBaseResource) GetDomain() *SDomain {
|
||||
if len(model.DomainId) > 0 && model.DomainId != api.KeystoneDomainRoot {
|
||||
domain, err := DomainManager.FetchDomainById(model.DomainId)
|
||||
@@ -119,6 +138,12 @@ func (manager *SIdentityBaseResourceManager) FetchByIdOrName(userCred mcclient.I
|
||||
return db.FetchByIdOrName(manager.GetIIdentityModelManager(), userCred, idStr)
|
||||
}
|
||||
|
||||
func (manager *SIdentityBaseResourceManager) FilterBySystemAttributes(q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject, scope rbacscope.TRbacScope) *sqlchemy.SQuery {
|
||||
q = manager.SStandaloneResourceBaseManager.FilterBySystemAttributes(q, userCred, query, scope)
|
||||
q = manager.SPendingDeletedBaseManager.FilterBySystemAttributes(manager.GetIStandaloneModelManager(), q, userCred, query, scope)
|
||||
return q
|
||||
}
|
||||
|
||||
func (manager *SIdentityBaseResourceManager) ListItemFilter(
|
||||
ctx context.Context,
|
||||
q *sqlchemy.SQuery,
|
||||
@@ -147,12 +172,9 @@ func (manager *SEnabledIdentityBaseResourceManager) ListItemFilter(
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SIdentityBaseResourceManager.ListItemFilter")
|
||||
}
|
||||
if query.Enabled != nil {
|
||||
if *query.Enabled {
|
||||
q = q.IsTrue("enabled")
|
||||
} else {
|
||||
q = q.IsFalse("enabled")
|
||||
}
|
||||
q, err = manager.SEnabledResourceBaseManager.ListItemFilter(ctx, q, userCred, query.EnabledResourceBaseListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SEnabledResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
@@ -218,28 +240,6 @@ func (manager *SEnabledIdentityBaseResourceManager) QueryDistinctExtraField(q *s
|
||||
return q, httperrors.ErrNotFound
|
||||
}
|
||||
|
||||
/*func fetchDomainInfo(data jsonutils.JSONObject) (mcclient.IIdentityProvider, error) {
|
||||
domainId, key := jsonutils.GetAnyString2(data, []string{"domain_id", "project_domain", "project_domain_id"})
|
||||
if len(domainId) > 0 {
|
||||
data.(*jsonutils.JSONDict).Remove(key)
|
||||
domain, err := DomainManager.FetchDomainByIdOrName(domainId)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError2(DomainManager.Keyword(), domainId)
|
||||
}
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
owner := db.SOwnerId{DomainId: domain.Id, Domain: domain.Name}
|
||||
data.(*jsonutils.JSONDict).Set("project_domain", jsonutils.NewString(domain.Id))
|
||||
return &owner, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (manager *SIdentityBaseResourceManager) FetchOwnerId(ctx context.Context, data jsonutils.JSONObject) (mcclient.IIdentityProvider, error) {
|
||||
return fetchDomainInfo(data)
|
||||
}*/
|
||||
|
||||
func (manager *SIdentityBaseResourceManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.IdentityBaseResourceCreateInput) (api.IdentityBaseResourceCreateInput, error) {
|
||||
domain, _ := DomainManager.FetchDomainById(ownerId.GetProjectDomainId())
|
||||
if domain.Enabled.IsFalse() {
|
||||
@@ -307,33 +307,13 @@ func (manager *SIdentityBaseResourceManager) FetchCustomizeColumns(
|
||||
stdRows := manager.SStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
domainRows := manager.SDomainizedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
|
||||
// domainIds := stringutils2.SSortedStrings{}
|
||||
for i := range rows {
|
||||
rows[i] = api.IdentityBaseResourceDetails{
|
||||
StandaloneResourceDetails: stdRows[i],
|
||||
DomainizedResourceInfo: domainRows[i],
|
||||
}
|
||||
/*var base *SIdentityBaseResource
|
||||
reflectutils.FindAnonymouStructPointer(objs[i], &base)
|
||||
if base != nil && len(base.DomainId) > 0 && base.DomainId != api.KeystoneDomainRoot {
|
||||
domainIds = stringutils2.Append(domainIds, base.DomainId)
|
||||
}*/
|
||||
}
|
||||
|
||||
/*if len(fields) == 0 || fields.Contains("project_domain") {
|
||||
domains := fetchDomain(domainIds)
|
||||
if domains != nil {
|
||||
for i := range rows {
|
||||
var base *SIdentityBaseResource
|
||||
reflectutils.FindAnonymouStructPointer(objs[i], &base)
|
||||
if base != nil && len(base.DomainId) > 0 && base.DomainId != api.KeystoneDomainRoot {
|
||||
if domain, ok := domains[base.DomainId]; ok {
|
||||
rows[i].ProjectDomain = domain.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
return rows
|
||||
}
|
||||
|
||||
@@ -358,21 +338,6 @@ func (manager *SEnabledIdentityBaseResourceManager) FetchCustomizeColumns(
|
||||
return rows
|
||||
}
|
||||
|
||||
/*
|
||||
func fetchDomain(domainIds []string) map[string]SDomain {
|
||||
q := DomainManager.Query().In("id", domainIds)
|
||||
domains := make([]SDomain, 0)
|
||||
err := db.FetchModelObjects(DomainManager, q, &domains)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
ret := make(map[string]SDomain)
|
||||
for i := range domains {
|
||||
ret[domains[i].Id] = domains[i]
|
||||
}
|
||||
return ret
|
||||
}*/
|
||||
|
||||
func (model *SIdentityBaseResource) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
||||
model.DomainId = ownerId.GetProjectDomainId()
|
||||
return model.SStandaloneResourceBase.CustomizeCreate(ctx, userCred, ownerId, query, data)
|
||||
@@ -388,11 +353,11 @@ func (self *SIdentityBaseResource) ValidateUpdateData(ctx context.Context, userC
|
||||
}
|
||||
*/
|
||||
|
||||
func (self *SEnabledIdentityBaseResource) ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error {
|
||||
if self.Enabled.IsTrue() {
|
||||
func (ident *SEnabledIdentityBaseResource) ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error {
|
||||
if ident.Enabled.IsTrue() {
|
||||
return httperrors.NewResourceBusyError("resource is enabled")
|
||||
}
|
||||
return self.SIdentityBaseResource.ValidateDeleteCondition(ctx, nil)
|
||||
return ident.SIdentityBaseResource.ValidateDeleteCondition(ctx, nil)
|
||||
}
|
||||
|
||||
func (model *SIdentityBaseResource) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
@@ -457,3 +422,72 @@ func (manager *SIdentityBaseResourceManager) GetPropertyDomainTagValueTree(
|
||||
query,
|
||||
)
|
||||
}
|
||||
|
||||
func (model *SIdentityBaseResource) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
if !model.PendingDeleted {
|
||||
newName := fmt.Sprintf("%s-deleted-%s", model.Name, timeutils.ShortDate(timeutils.UtcNow()))
|
||||
err := model.SPendingDeletedBase.MarkPendingDelete(model.GetIStandaloneModel(), ctx, userCred, newName)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "MarkPendingDelete")
|
||||
}
|
||||
}
|
||||
return nil // DeleteModel(ctx, userCred, model.GetIVirtualModel())
|
||||
}
|
||||
|
||||
func (model *SIdentityBaseResource) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
if !model.PendingDeleted {
|
||||
err := model.SPendingDeletedBase.MarkPendingDelete(model.GetIStandaloneModel(), ctx, userCred, "")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "MarkPendingDelete")
|
||||
}
|
||||
}
|
||||
return db.DeleteModel(ctx, userCred, model.GetIIdentityModel())
|
||||
}
|
||||
|
||||
func (manager *SEnabledIdentityBaseResourceManager) GetIEnabledIdentityModelManager() IEnabledIdentityModelManager {
|
||||
return manager.GetVirtualObject().(IEnabledIdentityModelManager)
|
||||
}
|
||||
|
||||
func (model *SEnabledIdentityBaseResource) GetIEnabledIdentityModelManager() IEnabledIdentityModelManager {
|
||||
return model.GetModelManager().(IEnabledIdentityModelManager)
|
||||
}
|
||||
|
||||
func (model *SEnabledIdentityBaseResource) GetIEnabledIdentityModel() IEnabledIdentityModel {
|
||||
return model.GetVirtualObject().(IEnabledIdentityModel)
|
||||
}
|
||||
|
||||
// 启用资源
|
||||
func (model *SEnabledIdentityBaseResource) PerformEnable(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformEnableInput) (jsonutils.JSONObject, error) {
|
||||
err := db.EnabledPerformEnable(model.GetIEnabledIdentityModel(), ctx, userCred, true)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "EnabledPerformEnable")
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// 禁用资源
|
||||
func (model *SEnabledIdentityBaseResource) PerformDisable(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformDisableInput) (jsonutils.JSONObject, error) {
|
||||
err := db.EnabledPerformEnable(model.GetIEnabledIdentityModel(), ctx, userCred, false)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "EnabledPerformEnable")
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (model *SIdentityBaseResource) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
|
||||
desc := model.SStandaloneAnonResourceBase.GetShortDesc(ctx)
|
||||
if model.DomainId != api.KeystoneDomainRoot {
|
||||
desc.Add(jsonutils.NewString(model.DomainId), "domain_id")
|
||||
domain := model.GetIIdentityModel().GetDomain()
|
||||
if domain != nil {
|
||||
desc.Add(jsonutils.NewString(domain.Name), "domain")
|
||||
}
|
||||
}
|
||||
return desc
|
||||
}
|
||||
|
||||
func (model *SEnabledIdentityBaseResource) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
|
||||
desc := model.SIdentityBaseResource.GetShortDesc(ctx)
|
||||
desc.Add(jsonutils.NewBool(model.Enabled.Bool()), "enabled")
|
||||
return desc
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/rbacscope"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
@@ -41,6 +42,7 @@ import (
|
||||
|
||||
type SOrganizationNodeManager struct {
|
||||
db.SStandaloneResourceBaseManager
|
||||
db.SPendingDeletedBaseManager
|
||||
}
|
||||
|
||||
var OrganizationNodeManager *SOrganizationNodeManager
|
||||
@@ -60,6 +62,7 @@ func init() {
|
||||
|
||||
type SOrganizationNode struct {
|
||||
db.SStandaloneResourceBase `name:""`
|
||||
db.SPendingDeletedBase
|
||||
|
||||
OrgId string `width:"36" charset:"ascii" list:"user" create:"admin_required"`
|
||||
|
||||
@@ -400,3 +403,31 @@ func (manager *SOrganizationNodeManager) FetchCustomizeColumns(
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
func (manager *SOrganizationNodeManager) FilterBySystemAttributes(q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject, scope rbacscope.TRbacScope) *sqlchemy.SQuery {
|
||||
q = manager.SStandaloneResourceBaseManager.FilterBySystemAttributes(q, userCred, query, scope)
|
||||
q = manager.SPendingDeletedBaseManager.FilterBySystemAttributes(manager.GetIStandaloneModelManager(), q, userCred, query, scope)
|
||||
return q
|
||||
}
|
||||
|
||||
func (orgNode *SOrganizationNode) ValidateDeleteCondition(ctx context.Context, info *api.ProjectDetails) error {
|
||||
childCnt, err := orgNode.GetDirectChildCount()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetDirectChildCount")
|
||||
}
|
||||
if childCnt > 0 {
|
||||
return errors.Wrapf(httperrors.ErrNotEmpty, "childnodes %d", childCnt)
|
||||
}
|
||||
return orgNode.SStandaloneResourceBase.ValidateDeleteCondition(ctx, nil)
|
||||
}
|
||||
|
||||
// fake delete
|
||||
func (orgNode *SOrganizationNode) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
if !orgNode.PendingDeleted {
|
||||
err := orgNode.SPendingDeletedBase.MarkPendingDelete(orgNode.GetIStandaloneModel(), ctx, userCred, "")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "MarkPendingDelete")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -40,7 +40,9 @@ import (
|
||||
)
|
||||
|
||||
type SOrganizationManager struct {
|
||||
db.SEnabledStatusInfrasResourceBaseManager
|
||||
SEnabledIdentityBaseResourceManager
|
||||
db.SSharableBaseResourceManager
|
||||
db.SStatusResourceBaseManager
|
||||
|
||||
cache *db.SCacheManager[SOrganization]
|
||||
}
|
||||
@@ -49,7 +51,7 @@ var OrganizationManager *SOrganizationManager
|
||||
|
||||
func init() {
|
||||
OrganizationManager = &SOrganizationManager{
|
||||
SEnabledStatusInfrasResourceBaseManager: db.NewEnabledStatusInfrasResourceBaseManager(
|
||||
SEnabledIdentityBaseResourceManager: NewEnabledIdentityBaseResourceManager(
|
||||
SOrganization{},
|
||||
"organizations_tbl",
|
||||
"organization",
|
||||
@@ -61,7 +63,9 @@ func init() {
|
||||
}
|
||||
|
||||
type SOrganization struct {
|
||||
db.SEnabledStatusInfrasResourceBase
|
||||
SEnabledIdentityBaseResource
|
||||
db.SSharableBaseResource
|
||||
db.SStatusResourceBase
|
||||
|
||||
Type api.TOrgType `width:"32" charset:"ascii" list:"user" create:"admin_required"`
|
||||
|
||||
@@ -96,9 +100,17 @@ func (manager *SOrganizationManager) ListItemFilter(
|
||||
) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
|
||||
q, err = manager.SEnabledStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
|
||||
q, err = manager.SEnabledIdentityBaseResourceManager.ListItemFilter(ctx, q, userCred, query.EnabledIdentityBaseResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.ListItemFilter")
|
||||
return nil, errors.Wrap(err, "SEnabledIdentityBaseResourceManager.ListItemFilter")
|
||||
}
|
||||
q, err = manager.SSharableBaseResourceManager.ListItemFilter(ctx, q, userCred, query.SharableResourceBaseListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SSharableBaseResourceManager.ListItemFilter")
|
||||
}
|
||||
q, err = manager.SStatusResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusResourceBaseListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SStatusResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
|
||||
if len(query.Type) > 0 {
|
||||
@@ -129,9 +141,13 @@ func (manager *SOrganizationManager) OrderByExtraFields(
|
||||
) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
|
||||
q, err = manager.SEnabledStatusInfrasResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
|
||||
q, err = manager.SEnabledIdentityBaseResourceManager.OrderByExtraFields(ctx, q, userCred, query.EnabledIdentityBaseResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.OrderByExtraFields")
|
||||
return nil, errors.Wrap(err, "SEnabledIdentityBaseResourceManager.OrderByExtraFields")
|
||||
}
|
||||
q, err = manager.SStatusResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusResourceBaseListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SStatusResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
|
||||
return q, nil
|
||||
@@ -140,7 +156,7 @@ func (manager *SOrganizationManager) OrderByExtraFields(
|
||||
func (manager *SOrganizationManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
|
||||
q, err = manager.SEnabledStatusInfrasResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
q, err = manager.SEnabledIdentityBaseResourceManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
@@ -149,7 +165,8 @@ func (manager *SOrganizationManager) QueryDistinctExtraField(q *sqlchemy.SQuery,
|
||||
}
|
||||
|
||||
type SOrganizationDetails struct {
|
||||
apis.EnabledStatusInfrasResourceBaseDetails
|
||||
api.EnabledIdentityBaseResourceDetails
|
||||
apis.SharableResourceBaseInfo
|
||||
|
||||
SOrganization
|
||||
}
|
||||
@@ -163,11 +180,13 @@ func (manager *SOrganizationManager) FetchCustomizeColumns(
|
||||
isList bool,
|
||||
) []SOrganizationDetails {
|
||||
rows := make([]SOrganizationDetails, len(objs))
|
||||
infRows := manager.SEnabledStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
infRows := manager.SEnabledIdentityBaseResourceManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
sharedRows := manager.SSharableBaseResourceManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
for i := range rows {
|
||||
// org := objs[i].(*SOrganization)
|
||||
rows[i] = SOrganizationDetails{
|
||||
EnabledStatusInfrasResourceBaseDetails: infRows[i],
|
||||
EnabledIdentityBaseResourceDetails: infRows[i],
|
||||
SharableResourceBaseInfo: sharedRows[i],
|
||||
}
|
||||
}
|
||||
return rows
|
||||
@@ -223,7 +242,7 @@ func (org *SOrganization) ValidateDeleteCondition(ctx context.Context, info *api
|
||||
if org.GetEnabled() {
|
||||
return errors.Wrap(httperrors.ErrInvalidStatus, "organization enabled")
|
||||
}
|
||||
return org.SInfrasResourceBase.ValidateDeleteCondition(ctx, nil)
|
||||
return org.SEnabledIdentityBaseResource.ValidateDeleteCondition(ctx, nil)
|
||||
}
|
||||
|
||||
func (org *SOrganization) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
@@ -231,11 +250,12 @@ func (org *SOrganization) Delete(ctx context.Context, userCred mcclient.TokenCre
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "removeAll")
|
||||
}
|
||||
err = org.SEnabledStatusInfrasResourceBase.Delete(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "SResourceBase.Delete")
|
||||
}
|
||||
OrganizationManager.cache.Delete(org)
|
||||
// pending delete
|
||||
err = org.SEnabledIdentityBaseResource.Delete(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "SEnabledIdentityBaseResource.Delete")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -248,9 +268,13 @@ func (manager *SOrganizationManager) ValidateCreateData(
|
||||
) (api.OrganizationCreateInput, error) {
|
||||
var err error
|
||||
|
||||
input.EnabledStatusInfrasResourceBaseCreateInput, err = manager.SEnabledStatusInfrasResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.EnabledStatusInfrasResourceBaseCreateInput)
|
||||
input.EnabledIdentityBaseResourceCreateInput, err = manager.SEnabledIdentityBaseResourceManager.ValidateCreateData(ctx, userCred, ownerId, query, input.EnabledIdentityBaseResourceCreateInput)
|
||||
if err != nil {
|
||||
return input, errors.Wrap(err, "SEnableStatusInfrasResourceBaseManager.ValidateCreateData")
|
||||
return input, errors.Wrap(err, "SEnabledIdentityBaseResourceManager.ValidateCreateData")
|
||||
}
|
||||
input.SharableResourceBaseCreateInput, err = db.SharableManagerValidateCreateData(manager, ctx, userCred, ownerId, query, input.SharableResourceBaseCreateInput)
|
||||
if err != nil {
|
||||
return input, errors.Wrap(err, "SharableManagerValidateCreateData")
|
||||
}
|
||||
|
||||
if !api.IsValidOrgType(input.Type) {
|
||||
@@ -287,7 +311,7 @@ func (org *SOrganization) CustomizeCreate(
|
||||
org.SetShare(rbacscope.ScopeSystem)
|
||||
org.Enabled = tristate.False
|
||||
org.Status = api.OrganizationStatusReady
|
||||
return org.SEnabledStatusInfrasResourceBase.CustomizeCreate(ctx, userCred, ownerId, query, data)
|
||||
return org.SEnabledIdentityBaseResource.CustomizeCreate(ctx, userCred, ownerId, query, data)
|
||||
}
|
||||
|
||||
func (org *SOrganization) PostCreate(
|
||||
@@ -297,7 +321,7 @@ func (org *SOrganization) PostCreate(
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject,
|
||||
) {
|
||||
org.SEnabledStatusInfrasResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
|
||||
org.SEnabledIdentityBaseResource.PostCreate(ctx, userCred, ownerId, query, data)
|
||||
OrganizationManager.cache.Update(org)
|
||||
}
|
||||
|
||||
@@ -316,7 +340,7 @@ func (org *SOrganization) PostUpdate(
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject,
|
||||
) {
|
||||
org.SEnabledStatusInfrasResourceBase.PostUpdate(ctx, userCred, query, data)
|
||||
org.SEnabledIdentityBaseResource.PostUpdate(ctx, userCred, query, data)
|
||||
OrganizationManager.cache.Update(org)
|
||||
}
|
||||
|
||||
@@ -375,7 +399,8 @@ func (org *SOrganization) PerformAddLevel(
|
||||
}
|
||||
|
||||
func (org *SOrganization) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
|
||||
desc := org.SEnabledStatusInfrasResourceBase.GetShortDesc(ctx)
|
||||
desc := org.SEnabledIdentityBaseResource.GetShortDesc(ctx)
|
||||
desc.Set("status", jsonutils.NewString(org.Status))
|
||||
desc.Set("keys", jsonutils.NewString(org.Keys))
|
||||
desc.Set("level", jsonutils.NewInt(int64(org.Level)))
|
||||
return desc
|
||||
@@ -450,6 +475,10 @@ func (org *SOrganization) removeAll(ctx context.Context, userCred mcclient.Token
|
||||
return nil
|
||||
}
|
||||
|
||||
func (org *SOrganization) SetStatus(userCred mcclient.TokenCredential, status string, reason string) error {
|
||||
return db.StatusBaseSetStatus(org, userCred, status, reason)
|
||||
}
|
||||
|
||||
func (org *SOrganization) startOrganizationSyncTask(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
@@ -561,7 +590,7 @@ func (org *SOrganization) PerformEnable(
|
||||
input apis.PerformEnableInput,
|
||||
) (jsonutils.JSONObject, error) {
|
||||
if !org.GetEnabled() {
|
||||
_, err := org.SEnabledStatusInfrasResourceBase.PerformEnable(ctx, userCred, query, input)
|
||||
_, err := org.SEnabledIdentityBaseResource.PerformEnable(ctx, userCred, query, input)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBase.PerformEnable")
|
||||
}
|
||||
@@ -593,7 +622,7 @@ func (org *SOrganization) PerformDisable(
|
||||
input apis.PerformDisableInput,
|
||||
) (jsonutils.JSONObject, error) {
|
||||
if org.GetEnabled() {
|
||||
_, err := org.SEnabledStatusInfrasResourceBase.PerformDisable(ctx, userCred, query, input)
|
||||
_, err := org.SEnabledIdentityBaseResource.PerformDisable(ctx, userCred, query, input)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBase.PerformDisable")
|
||||
}
|
||||
|
||||
@@ -465,7 +465,7 @@ func (policy *SPolicy) CustomizeCreate(ctx context.Context, userCred mcclient.To
|
||||
|
||||
func (policy *SPolicy) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
db.SharedResourceManager.CleanModelShares(ctx, userCred, policy)
|
||||
return policy.SEnabledIdentityBaseResource.Delete(ctx, userCred)
|
||||
return policy.SEnabledIdentityBaseResource.RealDelete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (policy *SPolicy) ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error {
|
||||
|
||||
@@ -370,9 +370,9 @@ func (proj *SProject) ValidateDeleteCondition(ctx context.Context, info *api.Pro
|
||||
if proj.IsAdminProject() {
|
||||
return httperrors.NewForbiddenError("cannot delete system project")
|
||||
}
|
||||
if len(info.ExtResource) > 0 {
|
||||
/*if len(info.ExtResource) > 0 {
|
||||
return httperrors.NewNotEmptyError("project contains external resources")
|
||||
}
|
||||
}*/
|
||||
if info.UserCount > 0 {
|
||||
return httperrors.NewNotEmptyError("project contains user")
|
||||
}
|
||||
@@ -382,6 +382,10 @@ func (proj *SProject) ValidateDeleteCondition(ctx context.Context, info *api.Pro
|
||||
return proj.SIdentityBaseResource.ValidateDeleteCondition(ctx, nil)
|
||||
}
|
||||
|
||||
func (proj *SProject) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
return proj.SIdentityBaseResource.Delete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (proj *SProject) IsAdminProject() bool {
|
||||
return proj.Name == api.SystemAdminProject && proj.DomainId == api.DEFAULT_DOMAIN_ID
|
||||
}
|
||||
@@ -906,3 +910,10 @@ func (project *SProject) matchOrganizationNodes() (*api.SProjectOrganization, er
|
||||
}
|
||||
return projOrg, nil
|
||||
}
|
||||
|
||||
func (manager *SProjectManager) FilterByOwner(q *sqlchemy.SQuery, man db.FilterByOwnerProvider, userCred mcclient.TokenCredential, owner mcclient.IIdentityProvider, scope rbacscope.TRbacScope) *sqlchemy.SQuery {
|
||||
if userCred != nil && scope != rbacscope.ScopeSystem && scope != rbacscope.ScopeDomain {
|
||||
q = q.Equals("id", owner.GetProjectId())
|
||||
}
|
||||
return manager.SIdentityBaseResourceManager.FilterByOwner(q, man, userCred, owner, scope)
|
||||
}
|
||||
|
||||
@@ -466,7 +466,7 @@ func (role *SRole) CustomizeCreate(ctx context.Context, userCred mcclient.TokenC
|
||||
|
||||
func (role *SRole) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
db.SharedResourceManager.CleanModelShares(ctx, userCred, role)
|
||||
return role.SIdentityBaseResource.Delete(ctx, userCred)
|
||||
return role.SIdentityBaseResource.RealDelete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (manager *SRoleManager) ValidateCreateData(
|
||||
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/gotypes"
|
||||
"yunion.io/x/pkg/tristate"
|
||||
"yunion.io/x/pkg/util/rbacscope"
|
||||
"yunion.io/x/sqlchemy"
|
||||
@@ -873,7 +872,7 @@ func (user *SUser) ValidatePurgeCondition(ctx context.Context, info *api.UserDet
|
||||
if user.IsAdminUser() {
|
||||
return httperrors.NewForbiddenError("cannot delete system user")
|
||||
}
|
||||
if gotypes.IsNil(info) {
|
||||
/*if gotypes.IsNil(info) {
|
||||
info = &api.UserDetails{}
|
||||
scopResource, err := UserManager.FetchScopeResources([]string{user.Id})
|
||||
if err != nil {
|
||||
@@ -887,7 +886,7 @@ func (user *SUser) ValidatePurgeCondition(ctx context.Context, info *api.UserDet
|
||||
return httperrors.NewNotEmptyError("user contains %d external resources %s", cnt, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user