cloudprovider.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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. "yunion.io/x/cloudmux/pkg/cloudprovider"
  19. "yunion.io/x/jsonutils"
  20. "yunion.io/x/log"
  21. "yunion.io/x/pkg/errors"
  22. "yunion.io/x/sqlchemy"
  23. "yunion.io/x/onecloud/pkg/apis"
  24. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  25. "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
  26. "yunion.io/x/onecloud/pkg/cloudid/options"
  27. "yunion.io/x/onecloud/pkg/mcclient"
  28. "yunion.io/x/onecloud/pkg/mcclient/auth"
  29. "yunion.io/x/onecloud/pkg/mcclient/informer"
  30. modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
  31. )
  32. // +onecloud:swagger-gen-ignore
  33. type SCloudproviderManager struct {
  34. db.SStandaloneResourceBaseManager
  35. }
  36. var CloudproviderManager *SCloudproviderManager
  37. func init() {
  38. CloudproviderManager = &SCloudproviderManager{
  39. SStandaloneResourceBaseManager: db.NewStandaloneResourceBaseManager(
  40. SCloudprovider{},
  41. "cloudproviders_tbl",
  42. "cloudprovider",
  43. "cloudproviders",
  44. ),
  45. }
  46. CloudproviderManager.SetVirtualObject(CloudproviderManager)
  47. }
  48. type SCloudprovider struct {
  49. db.SStandaloneResourceBase
  50. Provider string `width:"64" charset:"ascii" list:"domain"`
  51. CloudaccountId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
  52. }
  53. func (m *SCloudproviderManager) FetchProvier(id string) (*SCloudprovider, error) {
  54. ret, err := m.FetchById(id)
  55. if err != nil {
  56. return nil, err
  57. }
  58. return ret.(*SCloudprovider), nil
  59. }
  60. func (self *SCloudprovider) GetRole(ctx context.Context, userId string) (*SCloudrole, error) {
  61. groups := CloudgroupManager.Query().Equals("manager_id", self.Id).SubQuery()
  62. sq := SamluserManager.Query("cloudrole_id").Equals("owner_id", userId)
  63. sq = sq.Join(groups, sqlchemy.Equals(groups.Field("id"), sq.Field("cloudgroup_id")))
  64. ret := &SCloudrole{}
  65. ret.SetModelManager(CloudroleManager, ret)
  66. err := CloudroleManager.Query().In("id", sq.SubQuery()).IsNotEmpty("external_id").First(ret)
  67. if err != nil {
  68. return nil, err
  69. }
  70. return ret, nil
  71. }
  72. func (self *SCloudprovider) GetSamlUser(userId string) (*SSamluser, error) {
  73. groups := CloudgroupManager.Query("id").Equals("manager_id", self.Id).SubQuery()
  74. q := SamluserManager.Query().Equals("owner_id", userId).In("cloudgroup_id", groups)
  75. ret := &SSamluser{}
  76. ret.SetModelManager(SamluserManager, ret)
  77. err := q.First(ret)
  78. if err != nil {
  79. return nil, err
  80. }
  81. return ret, nil
  82. }
  83. func (self *SCloudprovider) GetSamlProvider() (*SSAMLProvider, error) {
  84. q := SAMLProviderManager.Query().Equals("status", apis.STATUS_AVAILABLE).
  85. Equals("entity_id", options.Options.ApiServer).Equals("manager_id", self.Id).IsNotEmpty("external_id")
  86. ret := &SSAMLProvider{}
  87. ret.SetModelManager(SAMLProviderManager, ret)
  88. err := q.First(ret)
  89. if err != nil {
  90. return nil, err
  91. }
  92. return ret, nil
  93. }
  94. func (self *SCloudprovider) GetProvider() (cloudprovider.ICloudProvider, error) {
  95. ctx := context.Background()
  96. s := auth.GetAdminSession(ctx, options.Options.Region)
  97. return modules.Cloudproviders.GetProvider(ctx, s, self.Id)
  98. }
  99. func (self *SCloudprovider) GetCloudaccount() (*SCloudaccount, error) {
  100. account, err := CloudaccountManager.FetchById(self.CloudaccountId)
  101. if err != nil {
  102. return nil, errors.Wrapf(err, "FetchById(%s)", self.CloudaccountId)
  103. }
  104. return account.(*SCloudaccount), nil
  105. }
  106. func (self *SCloudprovider) GetDriver() (IProviderDriver, error) {
  107. return GetProviderDriver(self.Provider)
  108. }
  109. func (self *SCloudprovider) StartCloudproviderSyncResourcesTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
  110. params := jsonutils.NewDict()
  111. task, err := taskman.TaskManager.NewTask(ctx, "CloudproviderSyncResourcesTask", self, userCred, params, parentTaskId, "", nil)
  112. if err != nil {
  113. return errors.Wrap(err, "NewTask")
  114. }
  115. return task.ScheduleRun(nil)
  116. }
  117. func (manager *SCloudproviderManager) GetCloudproviders() ([]SCloudprovider, error) {
  118. ret := []SCloudprovider{}
  119. q := manager.Query()
  120. err := db.FetchModelObjects(manager, q, &ret)
  121. if err != nil {
  122. return nil, errors.Wrapf(err, "db.FetchModelObjects")
  123. }
  124. return ret, nil
  125. }
  126. func (manager *SCloudproviderManager) SyncCloudproviderResources(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
  127. managers, err := manager.GetCloudproviders()
  128. if err != nil {
  129. log.Errorf("GetCloudproviders error: %v", err)
  130. return
  131. }
  132. for i := range managers {
  133. err = managers[i].StartCloudproviderSyncResourcesTask(ctx, userCred, "")
  134. if err != nil {
  135. log.Errorf("StartCloudproviderSyncResourcesTask for manager %s(%s) error: %v", managers[i].Name, managers[i].Provider, err)
  136. }
  137. }
  138. }
  139. func (m *SCloudproviderManager) StartWatchInRegion() error {
  140. adminSession := auth.GetAdminSession(context.Background(), "")
  141. watchMan, err := informer.NewWatchManagerBySession(adminSession)
  142. if err != nil {
  143. return err
  144. }
  145. resMan := &modules.Cloudproviders
  146. return watchMan.For(resMan).AddEventHandler(context.Background(), m)
  147. }
  148. func (m *SCloudproviderManager) OnAdd(obj *jsonutils.JSONDict) {
  149. model := &SCloudprovider{}
  150. model.SetModelManager(m, model)
  151. ctx := context.Background()
  152. err := obj.Unmarshal(model)
  153. if err != nil {
  154. return
  155. }
  156. if len(model.Provider) == 0 || len(model.CloudaccountId) == 0 {
  157. s := auth.GetAdminSession(ctx, options.Options.Region)
  158. data, err := modules.Cloudproviders.GetById(s, model.Id, nil)
  159. if err != nil {
  160. return
  161. }
  162. err = data.Unmarshal(model)
  163. if err != nil {
  164. return
  165. }
  166. }
  167. err = m.TableSpec().InsertOrUpdate(ctx, model)
  168. if err != nil {
  169. return
  170. }
  171. model.StartCloudproviderSyncResourcesTask(ctx, auth.AdminCredential(), "")
  172. }
  173. func (self *SCloudprovider) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
  174. return self.purge(ctx)
  175. }
  176. func (m *SCloudproviderManager) OnDelete(obj *jsonutils.JSONDict) {
  177. provider, err := func() (*SCloudprovider, error) {
  178. id, err := obj.GetString("id")
  179. if err != nil {
  180. return nil, errors.Wrapf(err, "get id")
  181. }
  182. provider, err := m.FetchById(id)
  183. if err != nil {
  184. return nil, errors.Wrapf(err, "fetch by id %s", id)
  185. }
  186. return provider.(*SCloudprovider), nil
  187. }()
  188. if err != nil {
  189. log.Errorf("fetch manager error: %v", err)
  190. return
  191. }
  192. err = provider.Delete(context.Background(), nil)
  193. if err != nil {
  194. log.Errorf("purge account error: %v", err)
  195. return
  196. }
  197. }
  198. func (m *SCloudproviderManager) OnUpdate(oldObj, newObj *jsonutils.JSONDict) {
  199. info := struct {
  200. Id string
  201. Name string
  202. }{}
  203. newObj.Unmarshal(&info)
  204. log.Debugf("OnUpdate %s", jsonutils.Marshal(info).String())
  205. _, err := m.FetchProvier(info.Id)
  206. if err != nil && errors.Cause(err) == sql.ErrNoRows {
  207. m.OnAdd(newObj)
  208. return
  209. }
  210. }