cloudproviderregions.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  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. "database/sql"
  18. "fmt"
  19. "time"
  20. "yunion.io/x/jsonutils"
  21. "yunion.io/x/log"
  22. "yunion.io/x/pkg/errors"
  23. "yunion.io/x/pkg/util/compare"
  24. "yunion.io/x/pkg/util/timeutils"
  25. "yunion.io/x/pkg/utils"
  26. "yunion.io/x/sqlchemy"
  27. api "yunion.io/x/onecloud/pkg/apis/compute"
  28. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  29. "yunion.io/x/onecloud/pkg/httperrors"
  30. "yunion.io/x/onecloud/pkg/mcclient"
  31. "yunion.io/x/onecloud/pkg/util/logclient"
  32. "yunion.io/x/onecloud/pkg/util/stringutils2"
  33. )
  34. type SCloudproviderregionManager struct {
  35. db.SJointResourceBaseManager
  36. SSyncableBaseResourceManager
  37. SCloudregionResourceBaseManager
  38. SManagedResourceBaseManager
  39. }
  40. var CloudproviderRegionManager *SCloudproviderregionManager
  41. func init() {
  42. db.InitManager(func() {
  43. CloudproviderRegionManager = &SCloudproviderregionManager{
  44. SJointResourceBaseManager: db.NewJointResourceBaseManager(
  45. SCloudproviderregion{},
  46. "cloud_provider_regions_tbl",
  47. "cloudproviderregion",
  48. "cloudproviderregions",
  49. CloudproviderManager,
  50. CloudregionManager,
  51. ),
  52. SManagedResourceBaseManager: SManagedResourceBaseManager{
  53. managerIdFieldName: "cloudprovider_id",
  54. },
  55. }
  56. CloudproviderRegionManager.SetVirtualObject(CloudproviderRegionManager)
  57. })
  58. }
  59. type SCloudproviderregion struct {
  60. db.SJointResourceBase
  61. SSyncableBaseResource
  62. SCloudregionResourceBase `width:"36" charset:"ascii" nullable:"false" list:"domain"`
  63. // 云订阅ID
  64. CloudproviderId string `width:"36" charset:"ascii" nullable:"false" list:"domain"`
  65. //CloudregionId string `width:"36" charset:"ascii" nullable:"false" list:"domain"`
  66. Enabled bool `nullable:"false" list:"domain" update:"domain"`
  67. // SyncIntervalSeconds int `list:"domain"`
  68. SyncResults jsonutils.JSONObject `list:"domain"`
  69. LastDeepSyncAt time.Time `list:"domain"`
  70. LastAutoSyncAt time.Time `list:"domain"`
  71. }
  72. func (manager *SCloudproviderregionManager) GetMasterFieldName() string {
  73. return "cloudprovider_id"
  74. }
  75. func (manager *SCloudproviderregionManager) GetSlaveFieldName() string {
  76. return "cloudregion_id"
  77. }
  78. func (self *SCloudproviderregion) GetProvider() (*SCloudprovider, error) {
  79. providerObj, err := CloudproviderManager.FetchById(self.CloudproviderId)
  80. if err != nil {
  81. return nil, errors.Wrapf(err, "CloudproviderManager.FetchById(%s)", self.CloudproviderId)
  82. }
  83. return providerObj.(*SCloudprovider), nil
  84. }
  85. func (self *SCloudproviderregion) GetAccount() (*SCloudaccount, error) {
  86. provider, err := self.GetProvider()
  87. if err != nil {
  88. return nil, err
  89. }
  90. return provider.GetCloudaccount()
  91. }
  92. func (manager *SCloudproviderregionManager) FetchCustomizeColumns(
  93. ctx context.Context,
  94. userCred mcclient.TokenCredential,
  95. query jsonutils.JSONObject,
  96. objs []interface{},
  97. fields stringutils2.SSortedStrings,
  98. isList bool,
  99. ) []api.CloudproviderregionDetails {
  100. rows := make([]api.CloudproviderregionDetails, len(objs))
  101. jointRows := manager.SJointResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  102. regionRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  103. managerIds := make([]string, len(rows))
  104. for i := range rows {
  105. rows[i].JointResourceBaseDetails = jointRows[i]
  106. rows[i].CloudregionResourceInfo = regionRows[i]
  107. rows[i].Capabilities, _ = objs[i].(*SCloudproviderregion).getCapabilities()
  108. cpr := objs[i].(*SCloudproviderregion)
  109. managerIds[i] = cpr.CloudproviderId
  110. rows[i].LastSyncCost = cpr.GetLastSyncCost()
  111. }
  112. managers := make(map[string]SCloudprovider)
  113. err := db.FetchStandaloneObjectsByIds(CloudproviderManager, managerIds, &managers)
  114. if err != nil {
  115. log.Errorf("FetchStandaloneObjectsByIds fail %s", err)
  116. return rows
  117. }
  118. for i := range rows {
  119. if manager, ok := managers[managerIds[i]]; ok {
  120. rows[i].Cloudprovider = manager.Name
  121. rows[i].CloudproviderSyncStatus = manager.SyncStatus
  122. account, _ := manager.GetCloudaccount()
  123. if account != nil {
  124. rows[i].CloudaccountId = account.Id
  125. rows[i].Cloudaccount = account.Name
  126. rows[i].CloudaccountDomainId = account.DomainId
  127. }
  128. }
  129. }
  130. return rows
  131. }
  132. func (self *SCloudproviderregion) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) {
  133. self.SJointResourceBase.PostUpdate(ctx, userCred, query, data)
  134. if data.Contains("enabled") {
  135. enabled, _ := data.Bool("enabled")
  136. provider, _ := self.GetProvider()
  137. if provider != nil {
  138. action := logclient.ACT_DISABLE
  139. if enabled {
  140. action = logclient.ACT_ENABLE
  141. }
  142. region, err := self.GetRegion()
  143. if err == nil {
  144. notes := map[string]string{
  145. "region_name": region.Name,
  146. "region_id": region.Id,
  147. }
  148. logclient.AddSimpleActionLog(provider, action, notes, userCred, true)
  149. }
  150. }
  151. }
  152. }
  153. func (manager *SCloudproviderregion) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
  154. return nil, httperrors.NewForbiddenError("not allow to create")
  155. }
  156. func (self *SCloudproviderregion) ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error {
  157. return nil
  158. }
  159. func (self *SCloudproviderregion) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
  160. return db.DeleteModel(ctx, userCred, self)
  161. }
  162. func (self *SCloudproviderregion) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
  163. return db.DetachJoint(ctx, userCred, self)
  164. }
  165. /*
  166. 过滤出指定cloudAccountId || providerIds || cloudAccountId+providerIds关联的region id
  167. */
  168. func (manager *SCloudproviderregionManager) QueryRelatedRegionIds(cloudAccounts []string, providerIds ...string) *sqlchemy.SSubQuery {
  169. q := manager.Query("cloudregion_id")
  170. if len(providerIds) > 0 {
  171. q = q.Filter(sqlchemy.In(q.Field("cloudprovider_id"), providerIds))
  172. }
  173. if len(cloudAccounts) > 0 {
  174. cpq := CloudaccountManager.Query().SubQuery()
  175. subcpq := cpq.Query(cpq.Field("id")).Filter(sqlchemy.OR(
  176. sqlchemy.In(cpq.Field("id"), stringutils2.RemoveUtf8Strings(cloudAccounts)),
  177. sqlchemy.In(cpq.Field("name"), cloudAccounts),
  178. )).SubQuery()
  179. providers := CloudproviderManager.Query().SubQuery()
  180. q = q.Join(providers, sqlchemy.Equals(providers.Field("id"), q.Field("cloudprovider_id")))
  181. q.Filter(sqlchemy.In(providers.Field("cloudaccount_id"), subcpq))
  182. }
  183. return q.Distinct().SubQuery()
  184. }
  185. func (manager *SCloudproviderregionManager) FetchByIds(providerId string, regionId string) (*SCloudproviderregion, error) {
  186. q := manager.Query().Equals("cloudprovider_id", providerId).Equals("cloudregion_id", regionId)
  187. obj, err := db.NewModelObject(manager)
  188. if err != nil {
  189. return nil, errors.Wrapf(err, "NewModelObject")
  190. }
  191. err = q.First(obj)
  192. if err != nil {
  193. return nil, errors.Wrapf(err, "First")
  194. }
  195. return obj.(*SCloudproviderregion), nil
  196. }
  197. func (manager *SCloudproviderregionManager) FetchByIdsOrCreate(providerId string, regionId string) (*SCloudproviderregion, error) {
  198. cpr, err := manager.FetchByIds(providerId, regionId)
  199. if err == nil {
  200. return cpr, nil
  201. }
  202. if errors.Cause(err) != sql.ErrNoRows {
  203. return nil, errors.Wrapf(err, "FetchByIds")
  204. }
  205. cpr = &SCloudproviderregion{}
  206. cpr.SetModelManager(manager, cpr)
  207. cpr.CloudproviderId = providerId
  208. cpr.CloudregionId = regionId
  209. cpr.Enabled = true
  210. cpr.SyncStatus = api.CLOUD_PROVIDER_SYNC_STATUS_IDLE
  211. err = manager.TableSpec().Insert(context.Background(), cpr)
  212. if err != nil {
  213. return nil, errors.Wrapf(err, "Insert")
  214. }
  215. return cpr, nil
  216. }
  217. func (self *SCloudproviderregion) markStartingSync(userCred mcclient.TokenCredential, syncRange *SSyncRange) error {
  218. if !self.Enabled {
  219. return fmt.Errorf("Cloudprovider(%s)region(%s) disabled", self.CloudproviderId, self.CloudregionId)
  220. }
  221. regionIds := []string{}
  222. if syncRange != nil {
  223. regionIds, _ = syncRange.GetRegionIds()
  224. }
  225. if syncRange == nil || len(regionIds) == 0 || utils.IsInStringArray(self.CloudregionId, regionIds) {
  226. _, err := db.Update(self, func() error {
  227. self.SyncStatus = api.CLOUD_PROVIDER_SYNC_STATUS_QUEUING
  228. return nil
  229. })
  230. if err != nil {
  231. log.Errorf("Failed to markStartingSync error: %v", err)
  232. return err
  233. }
  234. }
  235. return nil
  236. }
  237. func (self *SCloudproviderregion) markStartSync(userCred mcclient.TokenCredential) error {
  238. if !self.Enabled {
  239. return fmt.Errorf("Cloudprovider(%s)region(%s) disabled", self.CloudproviderId, self.CloudregionId)
  240. }
  241. _, err := db.Update(self, func() error {
  242. self.SyncStatus = api.CLOUD_PROVIDER_SYNC_STATUS_QUEUED
  243. return nil
  244. })
  245. if err != nil {
  246. log.Errorf("Failed to markStartSync error: %v", err)
  247. return err
  248. }
  249. return nil
  250. }
  251. func (self *SCloudproviderregion) markSyncing(userCred mcclient.TokenCredential) error {
  252. if !self.Enabled {
  253. return fmt.Errorf("Cloudprovider(%s)region(%s) disabled", self.CloudproviderId, self.CloudregionId)
  254. }
  255. _, err := db.Update(self, func() error {
  256. self.SyncStatus = api.CLOUD_PROVIDER_SYNC_STATUS_SYNCING
  257. self.LastSync = timeutils.UtcNow()
  258. self.LastSyncEndAt = time.Time{}
  259. return nil
  260. })
  261. if err != nil {
  262. log.Errorf("Failed to markSyncing error: %v", err)
  263. return err
  264. }
  265. return nil
  266. }
  267. func (self *SCloudproviderregion) markEndSync(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, deepSync *bool) error {
  268. log.Debugf("markEndSync deepSync %v", *deepSync)
  269. err := self.markEndSyncInternal(userCred, syncResults, deepSync)
  270. if err != nil {
  271. return errors.Wrapf(err, "markEndSyncInternal")
  272. }
  273. provider, err := self.GetProvider()
  274. if err != nil {
  275. return errors.Wrapf(err, "GetProvider")
  276. }
  277. err = provider.markEndSyncWithLock(ctx, userCred, *deepSync)
  278. if err != nil {
  279. return errors.Wrapf(err, "markEndSyncWithLock")
  280. }
  281. return nil
  282. }
  283. func (self *SCloudproviderregion) markEndSyncInternal(userCred mcclient.TokenCredential, syncResults SSyncResultSet, deepSync *bool) error {
  284. _, err := db.Update(self, func() error {
  285. self.SyncStatus = api.CLOUD_PROVIDER_SYNC_STATUS_IDLE
  286. self.LastSyncEndAt = timeutils.UtcNow()
  287. self.SyncResults = jsonutils.Marshal(syncResults)
  288. if deepSync != nil && *deepSync {
  289. self.LastDeepSyncAt = timeutils.UtcNow()
  290. }
  291. return nil
  292. })
  293. if err != nil {
  294. return errors.Wrapf(err, "db.Update")
  295. }
  296. return nil
  297. }
  298. func (self *SCloudproviderregion) cancelStartingSync(userCred mcclient.TokenCredential) error {
  299. if self.SyncStatus == api.CLOUD_PROVIDER_SYNC_STATUS_QUEUING {
  300. _, err := db.Update(self, func() error {
  301. self.SyncStatus = api.CLOUD_PROVIDER_SYNC_STATUS_IDLE
  302. return nil
  303. })
  304. if err != nil {
  305. return errors.Wrap(err, "db.Update")
  306. }
  307. }
  308. return nil
  309. }
  310. type SyncResult struct {
  311. RequestCost string
  312. rc time.Duration
  313. SqlCost string
  314. sc time.Duration
  315. compare.SyncResult
  316. }
  317. type SSyncResultSet map[string]*SyncResult
  318. func (set SSyncResultSet) AddRequestCost(manager db.IModelManager) func() {
  319. start := time.Now()
  320. key := manager.KeywordPlural()
  321. if _, ok := set[key]; !ok {
  322. set[key] = &SyncResult{}
  323. }
  324. res := set[key]
  325. return func() {
  326. res.rc += time.Since(start)
  327. res.RequestCost = res.rc.String()
  328. }
  329. }
  330. func (set SSyncResultSet) AddSqlCost(manager db.IModelManager) func() {
  331. start := time.Now()
  332. key := manager.KeywordPlural()
  333. if _, ok := set[key]; !ok {
  334. set[key] = &SyncResult{}
  335. }
  336. res := set[key]
  337. return func() {
  338. res.sc += time.Since(start)
  339. res.SqlCost = res.sc.String()
  340. }
  341. }
  342. func (set SSyncResultSet) Add(manager db.IModelManager, result compare.SyncResult) {
  343. key := manager.KeywordPlural()
  344. if _, ok := set[key]; !ok {
  345. set[key] = &SyncResult{}
  346. }
  347. res := set[key]
  348. res.AddCnt += result.AddCnt
  349. res.AddErrCnt += result.AddErrCnt
  350. res.UpdateCnt += result.UpdateCnt
  351. res.UpdateErrCnt += result.UpdateErrCnt
  352. res.DelCnt += result.DelCnt
  353. res.DelErrCnt += result.DelErrCnt
  354. }
  355. func (self *SCloudproviderregion) DoSync(ctx context.Context, userCred mcclient.TokenCredential, syncRange SSyncRange) error {
  356. syncResults := SSyncResultSet{}
  357. localRegion, err := self.GetRegion()
  358. if err != nil {
  359. return errors.Wrapf(err, "GetRegion")
  360. }
  361. provider, err := self.GetProvider()
  362. if err != nil {
  363. return errors.Wrapf(err, "GetProvider")
  364. }
  365. self.markSyncing(userCred)
  366. defer func() {
  367. err := self.markEndSync(ctx, userCred, syncResults, &syncRange.DeepSync)
  368. if err != nil {
  369. log.Errorf("markEndSync for %s(%s) : %v", localRegion.Name, provider.Name, err)
  370. }
  371. }()
  372. driver, err := provider.GetProvider(ctx)
  373. if err != nil {
  374. log.Errorf("Failed to get driver, connection problem?")
  375. return err
  376. }
  377. if !syncRange.DeepSync {
  378. log.Debugf("no need to do deep sync, check...")
  379. if self.LastDeepSyncAt.IsZero() || time.Now().Sub(self.LastDeepSyncAt) > time.Hour*24 {
  380. syncRange.DeepSync = true
  381. }
  382. }
  383. log.Debugf("need to do deep sync? ... %v, xor? ... %v", syncRange.DeepSync, syncRange.Xor)
  384. if localRegion.isManaged() {
  385. remoteRegion, err := driver.GetIRegionById(localRegion.ExternalId)
  386. if err != nil {
  387. return errors.Wrap(err, "GetIRegionById")
  388. }
  389. err = syncPublicCloudProviderInfo(ctx, userCred, syncResults, provider, driver, localRegion, remoteRegion, &syncRange)
  390. } else {
  391. err = syncOnPremiseCloudProviderInfo(ctx, userCred, syncResults, provider, driver, &syncRange)
  392. }
  393. if err != nil {
  394. log.Errorf("dosync fail %s", err)
  395. }
  396. log.Debugf("dosync result: %s", jsonutils.Marshal(syncResults))
  397. return err
  398. }
  399. func (self *SCloudproviderregion) getSyncTaskKey() string {
  400. return fmt.Sprintf("%d", self.RowId)
  401. }
  402. func (self *SCloudproviderregion) submitSyncTask(ctx context.Context, userCred mcclient.TokenCredential, syncRange SSyncRange) {
  403. self.markStartSync(userCred)
  404. RunSyncCloudproviderRegionTask(ctx, self.getSyncTaskKey(), func() {
  405. ctx = context.WithValue(ctx, "provider-region", fmt.Sprintf("%d", self.RowId))
  406. err := self.DoSync(ctx, userCred, syncRange)
  407. if err != nil {
  408. log.Errorf("DoSync faild %v", err)
  409. }
  410. })
  411. }
  412. func (cpr *SCloudproviderregion) resetAutoSync() {
  413. _, err := db.Update(cpr, func() error {
  414. cpr.LastAutoSyncAt = time.Time{}
  415. return nil
  416. })
  417. if err != nil {
  418. log.Errorf("reset LastAutoSyncAt fail %s", err)
  419. }
  420. }
  421. func (cprm *SCloudproviderregionManager) fetchRecordsByCloudproviderId(providerId string) ([]SCloudproviderregion, error) {
  422. q := cprm.Query().Equals("cloudprovider_id", providerId)
  423. recs := make([]SCloudproviderregion, 0)
  424. err := db.FetchModelObjects(cprm, q, &recs)
  425. if err != nil {
  426. return nil, err
  427. }
  428. return recs, nil
  429. }
  430. func (manager *SCloudproviderregionManager) ListItemFilter(
  431. ctx context.Context,
  432. q *sqlchemy.SQuery,
  433. userCred mcclient.TokenCredential,
  434. query api.CloudproviderregionListInput,
  435. ) (*sqlchemy.SQuery, error) {
  436. var err error
  437. q, err = manager.SJointResourceBaseManager.ListItemFilter(ctx, q, userCred, query.JointResourceBaseListInput)
  438. if err != nil {
  439. return nil, errors.Wrap(err, "SJointResourceBaseManager.ListItemFilter")
  440. }
  441. q, err = manager.SSyncableBaseResourceManager.ListItemFilter(ctx, q, userCred, query.SyncableBaseResourceListInput)
  442. if err != nil {
  443. return nil, errors.Wrap(err, "SSyncableBaseResourceManager.ListItemFilter")
  444. }
  445. q, err = manager.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
  446. if err != nil {
  447. return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
  448. }
  449. q, err = manager.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput)
  450. if err != nil {
  451. return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
  452. }
  453. if query.Enabled != nil {
  454. if *query.Enabled {
  455. q = q.IsTrue("enabled")
  456. } else {
  457. q = q.IsFalse("enabled")
  458. }
  459. }
  460. if len(query.Capability) > 0 {
  461. subq := CloudproviderCapabilityManager.Query().SubQuery()
  462. q = q.Join(subq, sqlchemy.AND(
  463. sqlchemy.Equals(q.Field("cloudprovider_id"), subq.Field("cloudprovider_id")),
  464. sqlchemy.Equals(q.Field("cloudregion_id"), subq.Field("cloudregion_id")),
  465. ))
  466. q = q.Filter(sqlchemy.In(subq.Field("capability"), query.Capability))
  467. }
  468. return q, nil
  469. }
  470. func (manager *SCloudproviderregionManager) OrderByExtraFields(
  471. ctx context.Context,
  472. q *sqlchemy.SQuery,
  473. userCred mcclient.TokenCredential,
  474. query api.CloudproviderregionListInput,
  475. ) (*sqlchemy.SQuery, error) {
  476. var err error
  477. q, err = manager.SJointResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.JointResourceBaseListInput)
  478. if err != nil {
  479. return nil, errors.Wrap(err, "SJointResourceBaseManager.OrderByExtraFields")
  480. }
  481. q, err = manager.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
  482. if err != nil {
  483. return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
  484. }
  485. q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
  486. if err != nil {
  487. return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
  488. }
  489. return q, nil
  490. }
  491. func (manager *SCloudproviderregionManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
  492. var err error
  493. q, err = manager.SJointResourceBaseManager.QueryDistinctExtraField(q, field)
  494. if err == nil {
  495. return q, nil
  496. }
  497. q, err = manager.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
  498. if err == nil {
  499. return q, nil
  500. }
  501. q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
  502. if err == nil {
  503. return q, nil
  504. }
  505. return q, httperrors.ErrNotFound
  506. }
  507. func (manager *SCloudproviderregionManager) QueryDistinctExtraFields(q *sqlchemy.SQuery, resource string, fields []string) (*sqlchemy.SQuery, error) {
  508. var err error
  509. q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraFields(q, resource, fields)
  510. if err == nil {
  511. return q, nil
  512. }
  513. return q, httperrors.ErrNotFound
  514. }
  515. func (cpr *SCloudproviderregion) setCapabilities(ctx context.Context, userCred mcclient.TokenCredential, capa []string) error {
  516. return CloudproviderCapabilityManager.setRegionCapabilities(ctx, userCred, cpr.CloudproviderId, cpr.CloudregionId, capa)
  517. }
  518. func (cpr *SCloudproviderregion) removeCapabilities(ctx context.Context, userCred mcclient.TokenCredential) error {
  519. return CloudproviderCapabilityManager.removeRegionCapabilities(ctx, userCred, cpr.CloudproviderId, cpr.CloudregionId)
  520. }
  521. func (cpr *SCloudproviderregion) getCapabilities() ([]string, error) {
  522. return CloudproviderCapabilityManager.getRegionCapabilities(cpr.CloudproviderId, cpr.CloudregionId)
  523. }
  524. func (manager *SCloudproviderregionManager) ListItemExportKeys(ctx context.Context,
  525. q *sqlchemy.SQuery,
  526. userCred mcclient.TokenCredential,
  527. keys stringutils2.SSortedStrings,
  528. ) (*sqlchemy.SQuery, error) {
  529. var err error
  530. q, err = manager.SJointResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  531. if err != nil {
  532. return nil, errors.Wrap(err, "SJointResourceBaseManager.ListItemExportKeys")
  533. }
  534. if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) {
  535. q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  536. if err != nil {
  537. return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
  538. }
  539. }
  540. if keys.ContainsAny(manager.SCloudregionResourceBaseManager.GetExportKeys()...) {
  541. q, err = manager.SCloudregionResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  542. if err != nil {
  543. return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemExportKeys")
  544. }
  545. }
  546. return q, nil
  547. }
  548. func (manager *SCloudproviderregionManager) FetchCloudproviderRegions(filter func(q *sqlchemy.SQuery) (*sqlchemy.SQuery, error)) ([]SCloudproviderregion, error) {
  549. q := manager.Query()
  550. var err error
  551. q, err = filter(q)
  552. if err != nil {
  553. return nil, errors.Wrap(err, "filter")
  554. }
  555. ret := make([]SCloudproviderregion, 0)
  556. err = db.FetchModelObjects(manager, q, &ret)
  557. if err != nil {
  558. return nil, errors.Wrap(err, "FetchModelObjects")
  559. }
  560. return ret, nil
  561. }