sharablevirtual.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package db
  15. import (
  16. "context"
  17. "yunion.io/x/jsonutils"
  18. "yunion.io/x/pkg/errors"
  19. "yunion.io/x/pkg/util/rbacscope"
  20. "yunion.io/x/sqlchemy"
  21. "yunion.io/x/onecloud/pkg/apis"
  22. "yunion.io/x/onecloud/pkg/httperrors"
  23. "yunion.io/x/onecloud/pkg/mcclient"
  24. "yunion.io/x/onecloud/pkg/util/stringutils2"
  25. )
  26. type SSharableVirtualResourceBase struct {
  27. SVirtualResourceBase
  28. SSharableBaseResource `"is_public->create":"optional" "public_scope->create":"optional"`
  29. // IsPublic bool `default:"false" nullable:"false" create:"domain_optional" list:"user" json:"is_public"`
  30. // PublicScope string `width:"16" charset:"ascii" nullable:"false" default:"system" create:"domain_optional" list:"user" json:"public_scope"`
  31. }
  32. type SSharableVirtualResourceBaseManager struct {
  33. SVirtualResourceBaseManager
  34. SSharableBaseResourceManager
  35. }
  36. func NewSharableVirtualResourceBaseManager(dt interface{}, tableName string, keyword string, keywordPlural string) SSharableVirtualResourceBaseManager {
  37. return SSharableVirtualResourceBaseManager{SVirtualResourceBaseManager: NewVirtualResourceBaseManager(dt, tableName, keyword, keywordPlural)}
  38. }
  39. func (manager *SSharableVirtualResourceBaseManager) GetISharableVirtualModelManager() ISharableVirtualModelManager {
  40. return manager.GetVirtualObject().(ISharableVirtualModelManager)
  41. }
  42. func (manager *SSharableVirtualResourceBaseManager) FilterByOwner(ctx context.Context, q *sqlchemy.SQuery, man FilterByOwnerProvider, userCred mcclient.TokenCredential, owner mcclient.IIdentityProvider, scope rbacscope.TRbacScope) *sqlchemy.SQuery {
  43. return SharableManagerFilterByOwner(ctx, manager.GetISharableVirtualModelManager(), q, userCred, owner, scope)
  44. }
  45. func (model *SSharableVirtualResourceBase) IsSharable(reqUsrId mcclient.IIdentityProvider) bool {
  46. return SharableModelIsSharable(model.GetISharableVirtualModel(), reqUsrId)
  47. }
  48. func (model *SSharableVirtualResourceBase) IsShared() bool {
  49. return SharableModelIsShared(model)
  50. }
  51. func (model *SSharableVirtualResourceBase) PerformPublic(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformPublicProjectInput) (jsonutils.JSONObject, error) {
  52. err := SharablePerformPublic(model.GetISharableVirtualModel(), ctx, userCred, input)
  53. if err != nil {
  54. return nil, errors.Wrap(err, "SharablePerformPublic")
  55. }
  56. return nil, nil
  57. }
  58. func (model *SSharableVirtualResourceBase) PerformPrivate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformPrivateInput) (jsonutils.JSONObject, error) {
  59. err := SharablePerformPrivate(model.GetISharableVirtualModel(), ctx, userCred)
  60. if err != nil {
  61. return nil, errors.Wrap(err, "SharablePerformPrivate")
  62. }
  63. return nil, nil
  64. }
  65. func (model *SSharableVirtualResourceBase) GetISharableVirtualModel() ISharableVirtualModel {
  66. return model.GetVirtualObject().(ISharableVirtualModel)
  67. }
  68. func (manager *SSharableVirtualResourceBaseManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input apis.SharableVirtualResourceCreateInput) (apis.SharableVirtualResourceCreateInput, error) {
  69. var err error
  70. input.VirtualResourceCreateInput, err = manager.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.VirtualResourceCreateInput)
  71. if err != nil {
  72. return input, errors.Wrap(err, "manager.VirtualResourceBaseManager.ValidateCreateData")
  73. }
  74. input.SharableResourceBaseCreateInput, err = SharableManagerValidateCreateData(manager.GetISharableVirtualModelManager(), ctx, userCred, ownerId, query, input.SharableResourceBaseCreateInput)
  75. if err != nil {
  76. return input, errors.Wrap(err, "SharableManagerValidateCreateData")
  77. }
  78. return input, nil
  79. }
  80. func (manager *SSharableVirtualResourceBaseManager) ListItemFilter(
  81. ctx context.Context,
  82. q *sqlchemy.SQuery,
  83. userCred mcclient.TokenCredential,
  84. query apis.SharableVirtualResourceListInput,
  85. ) (*sqlchemy.SQuery, error) {
  86. q, err := manager.SVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, query.VirtualResourceListInput)
  87. if err != nil {
  88. return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemFilter")
  89. }
  90. q, err = manager.SSharableBaseResourceManager.ListItemFilter(ctx, q, userCred, query.SharableResourceBaseListInput)
  91. if err != nil {
  92. return nil, errors.Wrap(err, "SSharableBaseResourceManager.ListItemFilter")
  93. }
  94. return q, nil
  95. }
  96. func (manager *SSharableVirtualResourceBaseManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
  97. q, err := manager.SVirtualResourceBaseManager.QueryDistinctExtraField(q, field)
  98. if err == nil {
  99. return q, nil
  100. }
  101. return q, httperrors.ErrNotFound
  102. }
  103. func (manager *SSharableVirtualResourceBaseManager) OrderByExtraFields(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query apis.SharableVirtualResourceListInput) (*sqlchemy.SQuery, error) {
  104. q, err := manager.SVirtualResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.VirtualResourceListInput)
  105. if err != nil {
  106. return nil, errors.Wrap(err, "SVirtualResourceBaseManager.OrderByExtraFields")
  107. }
  108. return q, nil
  109. }
  110. func (manager *SSharableVirtualResourceBaseManager) FetchCustomizeColumns(
  111. ctx context.Context,
  112. userCred mcclient.TokenCredential,
  113. query jsonutils.JSONObject,
  114. objs []interface{},
  115. fields stringutils2.SSortedStrings,
  116. isList bool,
  117. ) []apis.SharableVirtualResourceDetails {
  118. rows := make([]apis.SharableVirtualResourceDetails, len(objs))
  119. virtRows := manager.SVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  120. shareRows := manager.SSharableBaseResourceManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  121. for i := range rows {
  122. rows[i] = apis.SharableVirtualResourceDetails{
  123. VirtualResourceDetails: virtRows[i],
  124. SharableResourceBaseInfo: shareRows[i],
  125. }
  126. }
  127. return rows
  128. }
  129. func (model *SSharableVirtualResourceBase) ValidateUpdateData(
  130. ctx context.Context,
  131. userCred mcclient.TokenCredential,
  132. query jsonutils.JSONObject,
  133. input apis.SharableVirtualResourceBaseUpdateInput,
  134. ) (apis.SharableVirtualResourceBaseUpdateInput, error) {
  135. var err error
  136. input.VirtualResourceBaseUpdateInput, err = model.SVirtualResourceBase.ValidateUpdateData(ctx, userCred, query, input.VirtualResourceBaseUpdateInput)
  137. if err != nil {
  138. return input, errors.Wrap(err, "SVirtualResourceBase.ValidateUpdateData")
  139. }
  140. return input, nil
  141. }
  142. func (model *SSharableVirtualResourceBase) GetSharedProjects() []string {
  143. return SharableGetSharedProjects(model, SharedTargetProject)
  144. }
  145. func (model *SSharableVirtualResourceBase) GetSharedDomains() []string {
  146. return SharableGetSharedProjects(model, SharedTargetDomain)
  147. }
  148. // 更改项目
  149. func (model *SSharableVirtualResourceBase) PerformChangeOwner(
  150. ctx context.Context,
  151. userCred mcclient.TokenCredential,
  152. query jsonutils.JSONObject,
  153. input apis.PerformChangeProjectOwnerInput,
  154. ) (jsonutils.JSONObject, error) {
  155. if model.IsShared() {
  156. return nil, errors.Wrap(httperrors.ErrInvalidStatus, "cannot change owner when shared!")
  157. }
  158. return model.SVirtualResourceBase.PerformChangeOwner(ctx, userCred, query, input)
  159. }
  160. func (model *SSharableVirtualResourceBase) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
  161. SharableModelCustomizeCreate(model.GetISharableVirtualModel(), ctx, userCred, ownerId, query, data)
  162. return model.SVirtualResourceBase.CustomizeCreate(ctx, userCred, ownerId, query, data)
  163. }
  164. func (model *SSharableVirtualResourceBase) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
  165. SharedResourceManager.CleanModelShares(ctx, userCred, model.GetISharableVirtualModel())
  166. return model.SVirtualResourceBase.Delete(ctx, userCred)
  167. }
  168. func (model *SSharableVirtualResourceBase) GetSharedInfo() apis.SShareInfo {
  169. ret := apis.SShareInfo{}
  170. ret.IsPublic = model.IsPublic
  171. ret.PublicScope = rbacscope.String2ScopeDefault(model.PublicScope, rbacscope.ScopeNone)
  172. ret.SharedDomains = model.GetSharedDomains()
  173. ret.SharedProjects = model.GetSharedProjects()
  174. // fix
  175. if len(ret.SharedDomains) > 0 {
  176. ret.PublicScope = rbacscope.ScopeDomain
  177. ret.SharedProjects = nil
  178. ret.IsPublic = true
  179. } else if len(ret.SharedProjects) > 0 {
  180. ret.PublicScope = rbacscope.ScopeProject
  181. ret.SharedDomains = nil
  182. ret.IsPublic = true
  183. } else if !ret.IsPublic {
  184. ret.PublicScope = rbacscope.ScopeNone
  185. }
  186. return ret
  187. }
  188. func (model *SSharableVirtualResourceBase) SaveSharedInfo(src apis.TOwnerSource, ctx context.Context, userCred mcclient.TokenCredential, si apis.SShareInfo) {
  189. diff, _ := Update(model, func() error {
  190. model.PublicSrc = string(src)
  191. model.IsPublic = si.IsPublic
  192. model.PublicScope = string(si.PublicScope)
  193. return nil
  194. })
  195. if len(diff) > 0 {
  196. OpsLog.LogEvent(model, ACT_SYNC_SHARE, diff, userCred)
  197. }
  198. SharedResourceManager.shareToTarget(ctx, userCred, model.GetISharableVirtualModel(), SharedTargetProject, si.SharedProjects, nil, nil)
  199. SharedResourceManager.shareToTarget(ctx, userCred, model.GetISharableVirtualModel(), SharedTargetDomain, si.SharedDomains, nil, nil)
  200. }
  201. func (model *SSharableVirtualResourceBase) SyncShareState(ctx context.Context, userCred mcclient.TokenCredential, shareInfo apis.SAccountShareInfo) {
  202. si := shareInfo.GetProjectShareInfo()
  203. if model.PublicSrc != string(apis.OWNER_SOURCE_LOCAL) {
  204. model.SaveSharedInfo(apis.OWNER_SOURCE_CLOUD, ctx, userCred, si)
  205. } else {
  206. localSi := model.GetSharedInfo()
  207. if localSi.IsViolate(si) {
  208. newSi := localSi.Intersect(si)
  209. newSi.FixProjectShare()
  210. // reset to cloud base public_src
  211. model.SaveSharedInfo(apis.OWNER_SOURCE_CLOUD, ctx, userCred, newSi)
  212. }
  213. }
  214. }
  215. func (model *SSharableVirtualResourceBase) GetSharableTargetDomainIds() []string {
  216. return model.GetISharableVirtualModel().GetChangeOwnerCandidateDomainIds()
  217. }
  218. func (model *SSharableVirtualResourceBase) GetRequiredSharedDomainIds() []string {
  219. return []string{model.DomainId}
  220. }
  221. /*func (model *SSharableVirtualResourceBase) ValidateDeleteCondition(ctx context.Context) error {
  222. if model.IsShared() {
  223. return httperrors.NewForbiddenError("%s %s is shared", model.Keyword(), model.Name)
  224. }
  225. return model.SVirtualResourceBase.ValidateDeleteCondition(ctx)
  226. }*/