diff --git a/pkg/cloudcommon/db/sharablevirtual.go b/pkg/cloudcommon/db/sharablevirtual.go index 2b3c96ead1..6b48483e53 100644 --- a/pkg/cloudcommon/db/sharablevirtual.go +++ b/pkg/cloudcommon/db/sharablevirtual.go @@ -144,6 +144,9 @@ func (model *SSharableVirtualResourceBase) PerformPublic(ctx context.Context, us if tenant.DomainId != model.DomainId { return nil, httperrors.NewBadRequestError("can't shared project to other domain") } + if tenant.GetId() == model.ProjectId { + return nil, httperrors.NewBadRequestError("Can't share project to yourself") + } nps = append(nps, tenant.GetId()) if _, ok := ops[tenant.GetId()]; !ok { addProjects = append(addProjects, tenant.GetId()) @@ -232,21 +235,9 @@ func (model *SSharableVirtualResourceBase) PerformPrivate(ctx context.Context, u return nil, httperrors.NewInternalServerError("Update shared resource error: %s", err) } } - srs := make([]SSharedResource, 0) - q := SharedResourceManager.Query() - err := q.Filter(sqlchemy.AND( - sqlchemy.Equals(q.Field("owner_project_id"), model.ProjectId), - sqlchemy.Equals(q.Field("resource_id"), model.GetId()), - sqlchemy.Equals(q.Field("resource_type"), model.GetModelManager().Keyword()), - )).All(&srs) - if err != nil { - return nil, httperrors.NewInternalServerError("Fetch project error %s", err) - } - for i := 0; i < len(srs); i++ { - srs[i].SetModelManager(SharedResourceManager, &srs[i]) - if err := srs[i].Delete(ctx, userCred); err != nil { - return nil, httperrors.NewInternalServerError("Unshare project failed %s", err) - } + + if err := SharedResourceManager.CleanModelSharedProjects(ctx, userCred, &model.SVirtualResourceBase); err != nil { + return nil, err } model.GetIStandaloneModel().ClearSchedDescCache() return nil, nil diff --git a/pkg/cloudcommon/db/sharedresource.go b/pkg/cloudcommon/db/sharedresource.go index 292f636867..c3f55f1fe5 100644 --- a/pkg/cloudcommon/db/sharedresource.go +++ b/pkg/cloudcommon/db/sharedresource.go @@ -1,5 +1,13 @@ package db +import ( + "context" + + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/sqlchemy" +) + // sharing resoure between project type SSharedResource struct { SResourceBase @@ -28,3 +36,23 @@ func init() { ), } } + +func (manager *SSharedResourceManager) CleanModelSharedProjects(ctx context.Context, userCred mcclient.TokenCredential, model *SVirtualResourceBase) error { + srs := make([]SSharedResource, 0) + q := manager.Query() + err := q.Filter(sqlchemy.AND( + sqlchemy.Equals(q.Field("owner_project_id"), model.ProjectId), + sqlchemy.Equals(q.Field("resource_id"), model.GetId()), + sqlchemy.Equals(q.Field("resource_type"), model.GetModelManager().Keyword()), + )).All(&srs) + if err != nil { + return httperrors.NewInternalServerError("Fetch project error %s", err) + } + for i := 0; i < len(srs); i++ { + srs[i].SetModelManager(manager, &srs[i]) + if err := srs[i].Delete(ctx, userCred); err != nil { + return httperrors.NewInternalServerError("Unshare project failed %s", err) + } + } + return nil +} diff --git a/pkg/cloudcommon/db/virtualresource.go b/pkg/cloudcommon/db/virtualresource.go index 21a5f05618..b5482830f6 100644 --- a/pkg/cloudcommon/db/virtualresource.go +++ b/pkg/cloudcommon/db/virtualresource.go @@ -329,6 +329,12 @@ func (model *SVirtualResourceBase) PerformChangeOwner(ctx context.Context, userC formerObj := NewTenant(model.ProjectId, "unknown", model.DomainId, "unknown") former = &formerObj } + + // clean shared projects before update project id + if err := SharedResourceManager.CleanModelSharedProjects(ctx, userCred, model); err != nil { + return nil, err + } + _, err = Update(model, func() error { model.DomainId = ownerId.GetProjectDomainId() model.ProjectId = ownerId.GetProjectId() @@ -338,6 +344,7 @@ func (model *SVirtualResourceBase) PerformChangeOwner(ctx context.Context, userC if err != nil { return nil, err } + OpsLog.SyncOwner(model, former, userCred) notes := struct { OldProjectId string