tablestores.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  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 models
  15. import (
  16. "context"
  17. "yunion.io/x/cloudmux/pkg/cloudprovider"
  18. "yunion.io/x/jsonutils"
  19. "yunion.io/x/pkg/errors"
  20. "yunion.io/x/pkg/util/compare"
  21. "yunion.io/x/pkg/util/rbacscope"
  22. "yunion.io/x/sqlchemy"
  23. "yunion.io/x/onecloud/pkg/apis"
  24. api "yunion.io/x/onecloud/pkg/apis/compute"
  25. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  26. "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
  27. "yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
  28. "yunion.io/x/onecloud/pkg/cloudcommon/policy"
  29. "yunion.io/x/onecloud/pkg/compute/options"
  30. "yunion.io/x/onecloud/pkg/httperrors"
  31. "yunion.io/x/onecloud/pkg/mcclient"
  32. "yunion.io/x/onecloud/pkg/util/stringutils2"
  33. )
  34. type STablestoreManager struct {
  35. db.SVirtualResourceBaseManager
  36. db.SExternalizedResourceBaseManager
  37. SCloudregionResourceBaseManager
  38. SManagedResourceBaseManager
  39. }
  40. var TablestoreManager *STablestoreManager
  41. func init() {
  42. TablestoreManager = &STablestoreManager{
  43. SVirtualResourceBaseManager: db.NewVirtualResourceBaseManager(
  44. STablestore{},
  45. "tablestores_tbl",
  46. "tablestore",
  47. "tablestores",
  48. ),
  49. }
  50. TablestoreManager.SetVirtualObject(TablestoreManager)
  51. }
  52. type STablestore struct {
  53. db.SVirtualResourceBase
  54. db.SExternalizedResourceBase
  55. SCloudregionResourceBase
  56. SManagedResourceBase
  57. }
  58. func (manager *STablestoreManager) GetContextManagers() [][]db.IModelManager {
  59. return [][]db.IModelManager{
  60. {CloudregionManager},
  61. }
  62. }
  63. func (self *STablestore) ValidateDeleteCondition(ctx context.Context, data *api.TablestoreDetails) error {
  64. return self.SVirtualResourceBase.ValidateDeleteCondition(ctx, nil)
  65. }
  66. func (self *SCloudregion) GetTablestores() ([]STablestore, error) {
  67. q := TablestoreManager.Query().Equals("cloudregion_id", self.Id)
  68. ret := []STablestore{}
  69. err := db.FetchModelObjects(TablestoreManager, q, &ret)
  70. return ret, err
  71. }
  72. func (self *SCloudregion) SyncTablestores(
  73. ctx context.Context,
  74. userCred mcclient.TokenCredential,
  75. exts []cloudprovider.ICloudTablestore,
  76. provider *SCloudprovider,
  77. xor bool,
  78. ) compare.SyncResult {
  79. lockman.LockRawObject(ctx, TablestoreManager.Keyword(), self.Id)
  80. defer lockman.ReleaseRawObject(ctx, TablestoreManager.Keyword(), self.Id)
  81. result := compare.SyncResult{}
  82. dbRes, err := self.GetTablestores()
  83. if err != nil {
  84. result.Error(err)
  85. return result
  86. }
  87. removed := make([]STablestore, 0)
  88. commondb := make([]STablestore, 0)
  89. commonext := make([]cloudprovider.ICloudTablestore, 0)
  90. added := make([]cloudprovider.ICloudTablestore, 0)
  91. err = compare.CompareSets(dbRes, exts, &removed, &commondb, &commonext, &added)
  92. if err != nil {
  93. result.Error(err)
  94. return result
  95. }
  96. for i := 0; i < len(removed); i += 1 {
  97. err = removed[i].syncRemoveCloudTablestore(ctx, userCred)
  98. if err != nil {
  99. result.DeleteError(err)
  100. } else {
  101. result.Delete()
  102. }
  103. }
  104. if !xor {
  105. for i := 0; i < len(commondb); i += 1 {
  106. err = commondb[i].SyncWithCloudTablestore(ctx, userCred, commonext[i], provider)
  107. if err != nil {
  108. result.UpdateError(err)
  109. continue
  110. }
  111. result.Update()
  112. }
  113. }
  114. for i := 0; i < len(added); i += 1 {
  115. _, err := self.newFromCloudTablestore(ctx, userCred, added[i], provider)
  116. if err != nil {
  117. result.AddError(err)
  118. continue
  119. }
  120. result.Add()
  121. }
  122. return result
  123. }
  124. func (self *STablestore) syncRemoveCloudTablestore(ctx context.Context, userCred mcclient.TokenCredential) error {
  125. lockman.LockObject(ctx, self)
  126. defer lockman.ReleaseObject(ctx, self)
  127. err := self.ValidateDeleteCondition(ctx, nil)
  128. if err != nil { // cannot delete
  129. self.SetStatus(ctx, userCred, api.TABLESTORE_STATUS_UNKNOWN, "Sync to remove")
  130. return err
  131. }
  132. return self.RealDelete(ctx, userCred)
  133. }
  134. func (self *STablestore) SyncWithCloudTablestore(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudTablestore, provider *SCloudprovider) error {
  135. diff, err := db.Update(self, func() error {
  136. if options.Options.EnableSyncName {
  137. newName, _ := db.GenerateAlterName(self, ext.GetName())
  138. if len(newName) > 0 {
  139. self.Name = newName
  140. }
  141. }
  142. self.Status = ext.GetStatus()
  143. return nil
  144. })
  145. if err != nil {
  146. return errors.Wrapf(err, "db.Update")
  147. }
  148. db.OpsLog.LogSyncUpdate(self, diff, userCred)
  149. if len(diff) > 0 {
  150. notifyclient.EventNotify(ctx, userCred, notifyclient.SEventNotifyParam{
  151. Obj: self,
  152. Action: notifyclient.ActionSyncUpdate,
  153. })
  154. }
  155. if account, _ := provider.GetCloudaccount(); account != nil {
  156. syncVirtualResourceMetadata(ctx, userCred, self, ext, account.ReadOnly)
  157. }
  158. SyncCloudProject(ctx, userCred, self, provider.GetOwnerId(), ext, provider)
  159. return nil
  160. }
  161. func (self *SCloudregion) newFromCloudTablestore(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudTablestore, provider *SCloudprovider) (*STablestore, error) {
  162. ret := &STablestore{}
  163. ret.SetModelManager(TablestoreManager, ret)
  164. ret.Status = ext.GetStatus()
  165. ret.ExternalId = ext.GetGlobalId()
  166. ret.CloudregionId = self.Id
  167. ret.ManagerId = provider.Id
  168. if createdAt := ext.GetCreatedAt(); !createdAt.IsZero() {
  169. ret.CreatedAt = createdAt
  170. }
  171. var err = func() error {
  172. lockman.LockRawObject(ctx, TablestoreManager.Keyword(), "name")
  173. defer lockman.ReleaseRawObject(ctx, TablestoreManager.Keyword(), "name")
  174. newName, err := db.GenerateName(ctx, TablestoreManager, provider.GetOwnerId(), ext.GetName())
  175. if err != nil {
  176. return err
  177. }
  178. ret.Name = newName
  179. return TablestoreManager.TableSpec().Insert(ctx, ret)
  180. }()
  181. if err != nil {
  182. return nil, errors.Wrapf(err, "Insert")
  183. }
  184. syncVirtualResourceMetadata(ctx, userCred, ret, ext, false)
  185. SyncCloudProject(ctx, userCred, ret, provider.GetOwnerId(), ext, provider)
  186. db.OpsLog.LogEvent(ret, db.ACT_CREATE, ret.GetShortDesc(ctx), userCred)
  187. notifyclient.EventNotify(ctx, userCred, notifyclient.SEventNotifyParam{
  188. Obj: ret,
  189. Action: notifyclient.ActionSyncCreate,
  190. })
  191. return ret, nil
  192. }
  193. func (manager *STablestoreManager) FetchCustomizeColumns(
  194. ctx context.Context,
  195. userCred mcclient.TokenCredential,
  196. query jsonutils.JSONObject,
  197. objs []interface{},
  198. fields stringutils2.SSortedStrings,
  199. isList bool,
  200. ) []api.TablestoreDetails {
  201. rows := make([]api.TablestoreDetails, len(objs))
  202. virRows := manager.SVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  203. managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  204. regionRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  205. for i := range rows {
  206. rows[i] = api.TablestoreDetails{
  207. VirtualResourceDetails: virRows[i],
  208. ManagedResourceInfo: managerRows[i],
  209. CloudregionResourceInfo: regionRows[i],
  210. }
  211. }
  212. return rows
  213. }
  214. func (manager *STablestoreManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.TablestoreCreateInput) (api.TablestoreCreateInput, error) {
  215. return input, httperrors.NewNotImplementedError("ValidateCreateData")
  216. }
  217. func (self *STablestore) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.TablestoreUpdateInput) (api.TablestoreUpdateInput, error) {
  218. return input, httperrors.NewNotImplementedError("ValidateCreateData")
  219. }
  220. func (self *STablestore) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
  221. self.SetStatus(ctx, userCred, apis.STATUS_DELETING, "")
  222. return nil
  223. }
  224. func (self *STablestore) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
  225. db.OpsLog.LogEvent(self, db.ACT_DELOCATE, self.GetShortDesc(ctx), userCred)
  226. return self.SVirtualResourceBase.Delete(ctx, userCred)
  227. }
  228. // Tablestore列表
  229. func (manager *STablestoreManager) ListItemFilter(
  230. ctx context.Context,
  231. q *sqlchemy.SQuery,
  232. userCred mcclient.TokenCredential,
  233. input api.TablestoreListInput,
  234. ) (*sqlchemy.SQuery, error) {
  235. var err error
  236. q, err = manager.SVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, input.VirtualResourceListInput)
  237. if err != nil {
  238. return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemFilter")
  239. }
  240. q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, input.ExternalizedResourceBaseListInput)
  241. if err != nil {
  242. return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
  243. }
  244. q, err = manager.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, input.ManagedResourceListInput)
  245. if err != nil {
  246. return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
  247. }
  248. q, err = manager.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, input.RegionalFilterListInput)
  249. if err != nil {
  250. return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
  251. }
  252. return q, nil
  253. }
  254. func (manager *STablestoreManager) OrderByExtraFields(
  255. ctx context.Context,
  256. q *sqlchemy.SQuery,
  257. userCred mcclient.TokenCredential,
  258. input api.TablestoreListInput,
  259. ) (*sqlchemy.SQuery, error) {
  260. var err error
  261. q, err = manager.SVirtualResourceBaseManager.OrderByExtraFields(ctx, q, userCred, input.VirtualResourceListInput)
  262. if err != nil {
  263. return nil, errors.Wrap(err, "SVirtualResourceBaseManager.OrderByExtraFields")
  264. }
  265. q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, input.ManagedResourceListInput)
  266. if err != nil {
  267. return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
  268. }
  269. q, err = manager.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, input.RegionalFilterListInput)
  270. if err != nil {
  271. return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
  272. }
  273. return q, nil
  274. }
  275. func (manager *STablestoreManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
  276. var err error
  277. q, err = manager.SVirtualResourceBaseManager.QueryDistinctExtraField(q, field)
  278. if err == nil {
  279. return q, nil
  280. }
  281. q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
  282. if err == nil {
  283. return q, nil
  284. }
  285. q, err = manager.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
  286. if err == nil {
  287. return q, nil
  288. }
  289. return q, httperrors.ErrNotFound
  290. }
  291. func (manager *STablestoreManager) QueryDistinctExtraFields(q *sqlchemy.SQuery, resource string, fields []string) (*sqlchemy.SQuery, error) {
  292. var err error
  293. q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraFields(q, resource, fields)
  294. if err == nil {
  295. return q, nil
  296. }
  297. return q, httperrors.ErrNotFound
  298. }
  299. func (self *STablestore) ValidateUpdateCondition(ctx context.Context) error {
  300. return self.SVirtualResourceBase.ValidateUpdateCondition(ctx)
  301. }
  302. func (manager *STablestoreManager) ListItemExportKeys(ctx context.Context,
  303. q *sqlchemy.SQuery,
  304. userCred mcclient.TokenCredential,
  305. keys stringutils2.SSortedStrings,
  306. ) (*sqlchemy.SQuery, error) {
  307. var err error
  308. q, err = manager.SVirtualResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  309. if err != nil {
  310. return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemExportKeys")
  311. }
  312. if keys.ContainsAny(manager.SCloudregionResourceBaseManager.GetExportKeys()...) {
  313. q, err = manager.SCloudregionResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  314. if err != nil {
  315. return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemExportKeys")
  316. }
  317. }
  318. if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) {
  319. q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  320. if err != nil {
  321. return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
  322. }
  323. }
  324. return q, nil
  325. }
  326. func (manager *STablestoreManager) AllowScope(userCred mcclient.TokenCredential) rbacscope.TRbacScope {
  327. scope, _ := policy.PolicyManager.AllowScope(userCred, api.SERVICE_TYPE, TablestoreManager.KeywordPlural(), policy.PolicyActionGet)
  328. return scope
  329. }