inter_vpc_network.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  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. "gopkg.in/fatih/set.v0"
  20. "yunion.io/x/cloudmux/pkg/cloudprovider"
  21. "yunion.io/x/jsonutils"
  22. "yunion.io/x/pkg/errors"
  23. "yunion.io/x/pkg/tristate"
  24. "yunion.io/x/pkg/util/compare"
  25. "yunion.io/x/sqlchemy"
  26. api "yunion.io/x/onecloud/pkg/apis/compute"
  27. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  28. "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
  29. "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
  30. "yunion.io/x/onecloud/pkg/cloudcommon/validators"
  31. "yunion.io/x/onecloud/pkg/compute/options"
  32. "yunion.io/x/onecloud/pkg/httperrors"
  33. "yunion.io/x/onecloud/pkg/mcclient"
  34. "yunion.io/x/onecloud/pkg/util/stringutils2"
  35. )
  36. type SInterVpcNetworkManager struct {
  37. db.SEnabledStatusInfrasResourceBaseManager
  38. db.SExternalizedResourceBaseManager
  39. SManagedResourceBaseManager
  40. }
  41. var InterVpcNetworkManager *SInterVpcNetworkManager
  42. func init() {
  43. InterVpcNetworkManager = &SInterVpcNetworkManager{
  44. SEnabledStatusInfrasResourceBaseManager: db.NewEnabledStatusInfrasResourceBaseManager(
  45. SInterVpcNetwork{},
  46. "inter_vpc_networks_tbl",
  47. "inter_vpc_network",
  48. "inter_vpc_networks",
  49. ),
  50. }
  51. InterVpcNetworkManager.SetVirtualObject(InterVpcNetworkManager)
  52. }
  53. type SInterVpcNetwork struct {
  54. db.SEnabledStatusInfrasResourceBase
  55. db.SExternalizedResourceBase
  56. SManagedResourceBase
  57. }
  58. func (manager *SInterVpcNetworkManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
  59. q, err := manager.SEnabledStatusInfrasResourceBaseManager.QueryDistinctExtraField(q, field)
  60. if err == nil {
  61. return q, nil
  62. }
  63. q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
  64. if err == nil {
  65. return q, nil
  66. }
  67. return q, httperrors.ErrNotFound
  68. }
  69. func (manager *SInterVpcNetworkManager) QueryDistinctExtraFields(q *sqlchemy.SQuery, resource string, fields []string) (*sqlchemy.SQuery, error) {
  70. var err error
  71. q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraFields(q, resource, fields)
  72. if err == nil {
  73. return q, nil
  74. }
  75. return q, httperrors.ErrNotFound
  76. }
  77. func (manager *SInterVpcNetworkManager) OrderByExtraFields(
  78. ctx context.Context,
  79. q *sqlchemy.SQuery,
  80. userCred mcclient.TokenCredential,
  81. query api.InterVpcNetworkManagerListInput,
  82. ) (*sqlchemy.SQuery, error) {
  83. q, err := manager.SEnabledStatusInfrasResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
  84. if err != nil {
  85. return nil, errors.Wrap(err, "SInfrasResourceBaseManager.OrderByExtraFields")
  86. }
  87. q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
  88. if err != nil {
  89. return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
  90. }
  91. if db.NeedOrderQuery([]string{query.OrderByVpcCount}) {
  92. vpcNetVpcQ := InterVpcNetworkVpcManager.Query()
  93. vpcNetVpcQ = vpcNetVpcQ.AppendField(vpcNetVpcQ.Field("inter_vpc_network_id"), sqlchemy.COUNT("vpc_count", vpcNetVpcQ.Field("vpc_id")))
  94. vpcNetVpcQ = vpcNetVpcQ.GroupBy(vpcNetVpcQ.Field("inter_vpc_network_id"))
  95. vpcNetVpcSQ := vpcNetVpcQ.SubQuery()
  96. q = q.LeftJoin(vpcNetVpcSQ, sqlchemy.Equals(vpcNetVpcSQ.Field("inter_vpc_network_id"), q.Field("id")))
  97. q = q.AppendField(q.QueryFields()...)
  98. q = q.AppendField(vpcNetVpcSQ.Field("vpc_count"))
  99. q = db.OrderByFields(q, []string{query.OrderByVpcCount}, []sqlchemy.IQueryField{q.Field("vpc_count")})
  100. }
  101. return q, nil
  102. }
  103. // 列表
  104. func (manager *SInterVpcNetworkManager) ListItemFilter(
  105. ctx context.Context,
  106. q *sqlchemy.SQuery,
  107. userCred mcclient.TokenCredential,
  108. query api.InterVpcNetworkListInput,
  109. ) (*sqlchemy.SQuery, error) {
  110. var err error
  111. q, err = manager.SEnabledStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
  112. if err != nil {
  113. return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.ListItemFilter")
  114. }
  115. q, err = manager.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput)
  116. if err != nil {
  117. return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
  118. }
  119. return q, nil
  120. }
  121. func (manager *SInterVpcNetworkManager) ListItemExportKeys(ctx context.Context,
  122. q *sqlchemy.SQuery,
  123. userCred mcclient.TokenCredential,
  124. keys stringutils2.SSortedStrings,
  125. ) (*sqlchemy.SQuery, error) {
  126. var err error
  127. q, err = manager.SEnabledStatusInfrasResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  128. if err != nil {
  129. return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.ListItemExportKeys")
  130. }
  131. if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) {
  132. q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  133. if err != nil {
  134. return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
  135. }
  136. }
  137. return q, nil
  138. }
  139. func (manager *SInterVpcNetworkManager) ValidateCreateData(
  140. ctx context.Context,
  141. userCred mcclient.TokenCredential,
  142. ownerId mcclient.IIdentityProvider,
  143. query jsonutils.JSONObject,
  144. input api.InterVpcNetworkCreateInput,
  145. ) (api.InterVpcNetworkCreateInput, error) {
  146. return input, nil
  147. }
  148. func (self *SInterVpcNetwork) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
  149. params := jsonutils.NewDict()
  150. task, err := taskman.TaskManager.NewTask(ctx, "InterVpcNetworkCreateTask", self, userCred, params, "", "", nil)
  151. if err != nil {
  152. return
  153. }
  154. self.SetStatus(ctx, userCred, api.INTER_VPC_NETWORK_STATUS_CREATING, "")
  155. task.ScheduleRun(nil)
  156. }
  157. func (manager *SInterVpcNetworkManager) FetchCustomizeColumns(
  158. ctx context.Context,
  159. userCred mcclient.TokenCredential,
  160. query jsonutils.JSONObject,
  161. objs []interface{},
  162. fields stringutils2.SSortedStrings,
  163. isList bool,
  164. ) []api.InterVpcNetworkDetails {
  165. rows := make([]api.InterVpcNetworkDetails, len(objs))
  166. stdRows := manager.SEnabledStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  167. manRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  168. vpcNetworkIds := make([]string, len(objs))
  169. for i := range rows {
  170. rows[i] = api.InterVpcNetworkDetails{
  171. EnabledStatusInfrasResourceBaseDetails: stdRows[i],
  172. ManagedResourceInfo: manRows[i],
  173. }
  174. vpcNetwork := objs[i].(*SInterVpcNetwork)
  175. vpcNetworkIds[i] = vpcNetwork.Id
  176. }
  177. vpcNetworkVpcs := []SInterVpcNetworkVpc{}
  178. q := InterVpcNetworkVpcManager.Query().In("inter_vpc_network_id", vpcNetworkIds)
  179. err := db.FetchModelObjects(InterVpcNetworkVpcManager, q, &vpcNetworkVpcs)
  180. if err != nil {
  181. return rows
  182. }
  183. vpcMap := map[string][]string{}
  184. for i := range vpcNetworkVpcs {
  185. if _, ok := vpcMap[vpcNetworkVpcs[i].InterVpcNetworkId]; !ok {
  186. vpcMap[vpcNetworkVpcs[i].InterVpcNetworkId] = []string{}
  187. }
  188. vpcMap[vpcNetworkVpcs[i].InterVpcNetworkId] = append(vpcMap[vpcNetworkVpcs[i].InterVpcNetworkId], vpcNetworkVpcs[i].VpcId)
  189. }
  190. for i := range rows {
  191. rows[i].VpcCount = len(vpcMap[vpcNetworkIds[i]])
  192. }
  193. return rows
  194. }
  195. func (manager *SInterVpcNetworkManager) newFromCloudInterVpcNetwork(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudInterVpcNetwork, provider *SCloudprovider) (*SInterVpcNetwork, error) {
  196. externalVpcIds, err := ext.GetICloudVpcIds()
  197. if err != nil {
  198. return nil, errors.Wrapf(err, "GetICloudVpcIds")
  199. }
  200. vpcIds := []string{}
  201. for i := range externalVpcIds {
  202. vpc, err := db.FetchByExternalIdAndManagerId(VpcManager, externalVpcIds[i], func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
  203. managerQ := CloudproviderManager.Query("id").Equals("provider", provider.Provider)
  204. return q.In("manager_id", managerQ.SubQuery())
  205. })
  206. if err != nil {
  207. if errors.Cause(err) != sql.ErrNoRows {
  208. return nil, errors.Wrapf(err, "vpc.FetchByExternalIdAndManagerId(%s)", externalVpcIds[i])
  209. }
  210. continue
  211. }
  212. vpcIds = append(vpcIds, vpc.GetId())
  213. }
  214. interVpcNetwork := &SInterVpcNetwork{}
  215. interVpcNetwork.SetModelManager(manager, interVpcNetwork)
  216. interVpcNetwork.Name = ext.GetName()
  217. interVpcNetwork.Enabled = tristate.True
  218. interVpcNetwork.Status = ext.GetStatus()
  219. interVpcNetwork.ManagerId = provider.Id
  220. interVpcNetwork.ExternalId = ext.GetGlobalId()
  221. err = manager.TableSpec().Insert(ctx, interVpcNetwork)
  222. if err != nil {
  223. return nil, errors.Wrapf(err, "interVpcNetwork.Insert")
  224. }
  225. for i := range vpcIds {
  226. err := interVpcNetwork.AddVpc(ctx, vpcIds[i])
  227. if err != nil {
  228. return nil, errors.Wrapf(err, "interVpcNetwork.AddVpc(%s)", vpcIds[i])
  229. }
  230. }
  231. SyncCloudDomain(userCred, interVpcNetwork, provider.GetOwnerId())
  232. interVpcNetwork.SyncShareState(ctx, userCred, provider.getAccountShareInfo())
  233. return interVpcNetwork, nil
  234. }
  235. func (self *SInterVpcNetwork) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
  236. task, err := taskman.TaskManager.NewTask(ctx, "InterVpcNetworkDeleteTask", self, userCred, nil, "", "", nil)
  237. if err != nil {
  238. return errors.Wrap(err, "NewTask")
  239. }
  240. self.SetStatus(ctx, userCred, api.INTER_VPC_NETWORK_STATUS_DELETING, "")
  241. task.ScheduleRun(nil)
  242. return nil
  243. }
  244. func (self *SInterVpcNetwork) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
  245. err := self.RemoveAllVpc(ctx)
  246. if err != nil {
  247. return errors.Wrapf(err, "RemoveAllVpc")
  248. }
  249. return self.SEnabledStatusInfrasResourceBase.Delete(ctx, userCred)
  250. }
  251. func (self *SInterVpcNetwork) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.InterVpcNetworkSyncstatusInput) (jsonutils.JSONObject, error) {
  252. return nil, StartResourceSyncStatusTask(ctx, userCred, self, "InterVpcNetworkSyncstatusTask", "")
  253. }
  254. func (self *SInterVpcNetwork) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
  255. return self.RealDelete(ctx, userCred)
  256. }
  257. func (self *SInterVpcNetwork) StartInterVpcNetworkAddVpcTask(ctx context.Context, userCred mcclient.TokenCredential, vpc *SVpc) error {
  258. data := jsonutils.NewDict()
  259. data.Set("vpc_id", jsonutils.NewString(vpc.Id))
  260. task, err := taskman.TaskManager.NewTask(ctx, "InterVpcNetworkAddVpcTask", self, userCred, data, "", "", nil)
  261. if err != nil {
  262. return err
  263. }
  264. self.SetStatus(ctx, userCred, api.INTER_VPC_NETWORK_STATUS_ADDVPC, "")
  265. task.ScheduleRun(nil)
  266. return nil
  267. }
  268. func (self *SInterVpcNetwork) PerformAddvpc(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.InterVpcNetworkAddVpcInput) (jsonutils.JSONObject, error) {
  269. if len(input.VpcId) == 0 {
  270. return nil, httperrors.NewMissingParameterError("vpc_id")
  271. }
  272. _vpc, err := validators.ValidateModel(ctx, userCred, VpcManager, &input.VpcId)
  273. if err != nil {
  274. return nil, err
  275. }
  276. vpc := _vpc.(*SVpc)
  277. vpcCloudProvider := vpc.GetCloudprovider()
  278. cloudProvider := self.GetCloudprovider()
  279. if err != nil {
  280. return nil, httperrors.NewGeneralError(err)
  281. }
  282. if vpcCloudProvider.Provider != cloudProvider.Provider {
  283. return nil, httperrors.NewNotSupportedError("vpc joint interVpcNetwork on different cloudprovider is not supported")
  284. }
  285. if vpcCloudProvider.AccessUrl != cloudProvider.AccessUrl {
  286. return nil, httperrors.NewNotSupportedError("vpc joint interVpcNetwork on different cloudEnv is not supported")
  287. }
  288. q := InterVpcNetworkVpcManager.Query().Equals("vpc_id", vpc.Id)
  289. vpcNetworkjoints := []SInterVpcNetworkVpc{}
  290. err = db.FetchModelObjects(InterVpcNetworkVpcManager, q, &vpcNetworkjoints)
  291. if err != nil {
  292. return nil, httperrors.NewGeneralError(err)
  293. }
  294. if len(vpcNetworkjoints) > 0 {
  295. return nil, httperrors.NewInputParameterError("vpc %s already connected to a interVpcNetwork", vpc.Id)
  296. }
  297. err = self.StartInterVpcNetworkAddVpcTask(ctx, userCred, vpc)
  298. if err != nil {
  299. return nil, err
  300. }
  301. return nil, nil
  302. }
  303. func (self *SInterVpcNetwork) StartInterVpcNetworkRemoveVpcTask(ctx context.Context, userCred mcclient.TokenCredential, vpc *SVpc) error {
  304. data := jsonutils.NewDict()
  305. data.Set("vpc_id", jsonutils.NewString(vpc.Id))
  306. task, err := taskman.TaskManager.NewTask(ctx, "InterVpcNetworkRemoveVpcTask", self, userCred, data, "", "", nil)
  307. if err != nil {
  308. return err
  309. }
  310. self.SetStatus(ctx, userCred, api.INTER_VPC_NETWORK_STATUS_REMOVEVPC, "")
  311. task.ScheduleRun(nil)
  312. return nil
  313. }
  314. func (self *SInterVpcNetwork) PerformRemovevpc(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.InterVpcNetworkRemoveVpcInput) (jsonutils.JSONObject, error) {
  315. if len(input.VpcId) == 0 {
  316. return nil, httperrors.NewMissingParameterError("vpc_id")
  317. }
  318. // get vpc
  319. _vpc, err := VpcManager.FetchByIdOrName(ctx, userCred, input.VpcId)
  320. if err != nil {
  321. if errors.Cause(err) == sql.ErrNoRows {
  322. return nil, httperrors.NewResourceNotFoundError2("vpc", input.VpcId)
  323. }
  324. return nil, httperrors.NewGeneralError(err)
  325. }
  326. vpc := _vpc.(*SVpc)
  327. q := InterVpcNetworkVpcManager.Query().Equals("inter_vpc_network_id", self.Id).Equals("vpc_id", vpc.Id)
  328. vpcNetworkjoints := []SInterVpcNetworkVpc{}
  329. err = db.FetchModelObjects(InterVpcNetworkVpcManager, q, &vpcNetworkjoints)
  330. if err != nil {
  331. return nil, httperrors.NewGeneralError(err)
  332. }
  333. if len(vpcNetworkjoints) == 0 {
  334. return nil, httperrors.NewInputParameterError("vpc %s is not connected to this interVpcNetwork", vpc.Id)
  335. }
  336. err = self.StartInterVpcNetworkRemoveVpcTask(ctx, userCred, vpc)
  337. if err != nil {
  338. return nil, err
  339. }
  340. return nil, nil
  341. }
  342. func (self *SInterVpcNetwork) AddVpc(ctx context.Context, vpcId string) error {
  343. networkVpc := &SInterVpcNetworkVpc{}
  344. networkVpc.SetModelManager(InterVpcNetworkVpcManager, networkVpc)
  345. networkVpc.VpcId = vpcId
  346. networkVpc.InterVpcNetworkId = self.Id
  347. return InterVpcNetworkVpcManager.TableSpec().Insert(ctx, networkVpc)
  348. }
  349. func (self *SInterVpcNetwork) GetVpcs() ([]SVpc, error) {
  350. sq := InterVpcNetworkVpcManager.Query("vpc_id").Equals("inter_vpc_network_id", self.Id)
  351. q := VpcManager.Query().In("id", sq.SubQuery())
  352. vpcs := []SVpc{}
  353. err := db.FetchModelObjects(VpcManager, q, &vpcs)
  354. if err != nil {
  355. return nil, errors.Wrap(err, "db.FetchModelObjects")
  356. }
  357. return vpcs, nil
  358. }
  359. func (self *SInterVpcNetwork) RemoveVpc(ctx context.Context, vpcId string) error {
  360. q := InterVpcNetworkVpcManager.Query().Equals("inter_vpc_network_id", self.Id).Equals("vpc_id", vpcId)
  361. networkVpcs := []SInterVpcNetworkVpc{}
  362. err := db.FetchModelObjects(InterVpcNetworkVpcManager, q, &networkVpcs)
  363. if err != nil {
  364. return errors.Wrapf(err, "db.FetchModelObjects")
  365. }
  366. for i := range networkVpcs {
  367. err = networkVpcs[i].Delete(ctx, nil)
  368. if err != nil {
  369. return errors.Wrap(err, "Delete")
  370. }
  371. }
  372. return nil
  373. }
  374. func (self *SInterVpcNetwork) RemoveAllVpc(ctx context.Context) error {
  375. q := InterVpcNetworkVpcManager.Query().Equals("inter_vpc_network_id", self.Id)
  376. networkVpcs := []SInterVpcNetworkVpc{}
  377. err := db.FetchModelObjects(InterVpcNetworkVpcManager, q, &networkVpcs)
  378. if err != nil {
  379. return errors.Wrapf(err, "db.FetchModelObjects")
  380. }
  381. for i := range networkVpcs {
  382. err = networkVpcs[i].Delete(ctx, nil)
  383. if err != nil {
  384. return errors.Wrap(err, "Delete")
  385. }
  386. }
  387. return nil
  388. }
  389. func (self *SInterVpcNetwork) SyncWithCloudInterVpcNetwork(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudInterVpcNetwork) error {
  390. _, err := db.Update(self, func() error {
  391. self.ExternalId = ext.GetGlobalId()
  392. self.Status = ext.GetStatus()
  393. if options.Options.EnableSyncName {
  394. self.Name = ext.GetName()
  395. }
  396. return nil
  397. })
  398. if err != nil {
  399. return errors.Wrapf(err, "db.Update")
  400. }
  401. localVpcs, err := self.GetVpcs()
  402. if err != nil {
  403. return errors.Wrapf(err, "GetVpcs")
  404. }
  405. externalVpcIds, err := ext.GetICloudVpcIds()
  406. if err != nil {
  407. return errors.Wrapf(err, "GetICloudVpcIds")
  408. }
  409. remoteVpcIds := []string{}
  410. manager := self.GetCloudprovider()
  411. for i := range externalVpcIds {
  412. vpc, err := db.FetchByExternalIdAndManagerId(VpcManager, externalVpcIds[i], func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
  413. managerQ := CloudproviderManager.Query("id").Equals("provider", manager.Provider)
  414. return q.In("manager_id", managerQ.SubQuery())
  415. })
  416. if err != nil {
  417. if errors.Cause(err) != sql.ErrNoRows {
  418. return errors.Wrapf(err, "vpc.FetchByExternalIdAndManagerId(%s)", externalVpcIds[i])
  419. }
  420. } else {
  421. remoteVpcIds = append(remoteVpcIds, vpc.GetId())
  422. }
  423. }
  424. localVpcIdSet := set.New(set.ThreadSafe)
  425. for i := range localVpcs {
  426. localVpcIdSet.Add(localVpcs[i].Id)
  427. }
  428. remoteVpcIdSet := set.New(set.ThreadSafe)
  429. for i := range remoteVpcIds {
  430. remoteVpcIdSet.Add(remoteVpcIds[i])
  431. }
  432. for _, del := range set.Difference(localVpcIdSet, remoteVpcIdSet).List() {
  433. err := self.RemoveVpc(ctx, del.(string))
  434. if err != nil {
  435. return errors.Wrapf(err, "self.RemoveVpc %s", del.(string))
  436. }
  437. }
  438. for _, add := range set.Difference(remoteVpcIdSet, localVpcIdSet).List() {
  439. err := self.AddVpc(ctx, add.(string))
  440. if err != nil {
  441. return errors.Wrapf(err, "self.RemoveVpc %s", add.(string))
  442. }
  443. }
  444. return nil
  445. }
  446. /*
  447. func (self *SInterVpcNetwork) GetCloudaccount() (*SCloudaccount, error) {
  448. account, err := CloudaccountManager.FetchById(self.CloudaccountId)
  449. if err != nil {
  450. return nil, errors.Wrapf(err, "CloudaccountManager.FetchById(%s)", self.CloudaccountId)
  451. }
  452. return account.(*SCloudaccount), nil
  453. }
  454. */
  455. func (self *SInterVpcNetwork) GetInterVpcNetworkRouteSets() ([]SInterVpcNetworkRouteSet, error) {
  456. routes := []SInterVpcNetworkRouteSet{}
  457. q := InterVpcNetworkRouteSetManager.Query().Equals("inter_vpc_network_id", self.Id)
  458. err := db.FetchModelObjects(InterVpcNetworkRouteSetManager, q, &routes)
  459. if err != nil {
  460. return nil, errors.Wrapf(err, "db.FetchModelObjects")
  461. }
  462. return routes, nil
  463. }
  464. func (self *SInterVpcNetwork) SyncInterVpcNetworkRouteSets(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudInterVpcNetwork, xor bool) compare.SyncResult {
  465. lockman.LockRawObject(ctx, self.Keyword(), fmt.Sprintf("%s-records", self.Id))
  466. defer lockman.ReleaseRawObject(ctx, self.Keyword(), fmt.Sprintf("%s-records", self.Id))
  467. syncResult := compare.SyncResult{}
  468. iRoutes, err := ext.GetIRoutes()
  469. if err != nil {
  470. syncResult.Error(errors.Wrapf(err, "GetIRoutes"))
  471. return syncResult
  472. }
  473. dbRouteSets, err := self.GetInterVpcNetworkRouteSets()
  474. if err != nil {
  475. syncResult.Error(errors.Wrapf(err, "GetRouteTableRouteSets"))
  476. return syncResult
  477. }
  478. removed := make([]SInterVpcNetworkRouteSet, 0)
  479. commondb := make([]SInterVpcNetworkRouteSet, 0)
  480. commonext := make([]cloudprovider.ICloudInterVpcNetworkRoute, 0)
  481. added := make([]cloudprovider.ICloudInterVpcNetworkRoute, 0)
  482. if err := compare.CompareSets(dbRouteSets, iRoutes, &removed, &commondb, &commonext, &added); err != nil {
  483. syncResult.Error(err)
  484. return syncResult
  485. }
  486. for i := 0; i < len(removed); i++ {
  487. err := removed[i].syncRemoveRouteSet(ctx, userCred)
  488. if err != nil {
  489. syncResult.DeleteError(err)
  490. } else {
  491. syncResult.Delete()
  492. }
  493. }
  494. if !xor {
  495. for i := 0; i < len(commondb); i++ {
  496. err := commondb[i].syncWithCloudRouteSet(ctx, userCred, self, commonext[i])
  497. if err != nil {
  498. syncResult.UpdateError(err)
  499. continue
  500. }
  501. syncResult.Update()
  502. }
  503. }
  504. for i := 0; i < len(added); i++ {
  505. _, err := InterVpcNetworkRouteSetManager.newRouteSetFromCloud(ctx, userCred, self, added[i])
  506. if err != nil {
  507. syncResult.AddError(err)
  508. continue
  509. }
  510. syncResult.Add()
  511. }
  512. return syncResult
  513. }
  514. func (self *SInterVpcNetwork) GetProvider(ctx context.Context) (cloudprovider.ICloudProvider, error) {
  515. provider, err := self.GetCloudprovider().GetProvider(ctx)
  516. if err != nil {
  517. return nil, errors.Wrapf(err, "self.GetCloudprovider().GetProvider()")
  518. }
  519. return provider, nil
  520. }
  521. func (self *SInterVpcNetwork) GetICloudInterVpcNetwork(ctx context.Context) (cloudprovider.ICloudInterVpcNetwork, error) {
  522. provider, err := self.GetProvider(ctx)
  523. if err != nil {
  524. return nil, errors.Wrap(err, "snetwork.GetProvider()")
  525. }
  526. iVpcNetwork, err := provider.GetICloudInterVpcNetworkById(self.ExternalId)
  527. if err != nil {
  528. return nil, errors.Wrapf(err, "GetICloudInterVpcNetworkById(%s)", self.ExternalId)
  529. }
  530. return iVpcNetwork, nil
  531. }