fix: pending delete identity projects (#17757)

Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
This commit is contained in:
Jian Qiu
2023-08-15 16:54:00 +08:00
committed by GitHub
parent 34d54f10e8
commit 82d50bb4b6
21 changed files with 456 additions and 222 deletions
+1 -2
View File
@@ -42,8 +42,7 @@ type IdentityBaseResourceListInput struct {
type EnabledIdentityBaseResourceListInput struct {
IdentityBaseResourceListInput
// filter by enabled status
Enabled *bool `json:"enabled"`
apis.EnabledResourceBaseListInput
}
type ProjectFilterListInput struct {
+12 -3
View File
@@ -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 {
+6 -2
View File
@@ -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
+2
View File
@@ -284,6 +284,8 @@ type IStandaloneModel interface {
// IsAlterNameUnique(name string, projectId string) bool
// GetExternalId() string
SetName(name string)
StandaloneModelManager() IStandaloneModelManager
GetIStandaloneModel() IStandaloneModel
+125
View File
@@ -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
}
+1
View File
@@ -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)
+4
View File
@@ -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)
}
+1 -1
View File
@@ -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 {
+2
View File
@@ -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")
+5
View File
@@ -31,3 +31,8 @@ func (s SCachedTenant) objType() string {
return "project"
}
}
type SCachedUser struct {
SCachedTenant
Lang string
}
+45 -8
View File
@@ -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++
}
}
+1
View File
@@ -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)
+14 -99
View File
@@ -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 {
+29 -3
View File
@@ -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)
}
+107 -73
View File
@@ -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
}
+31
View File
@@ -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
}
+53 -24
View File
@@ -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")
}
+1 -1
View File
@@ -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 {
+13 -2
View File
@@ -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)
}
+1 -1
View File
@@ -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(
+2 -3
View File
@@ -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
}