ipv6_gateways.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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 SIPv6GatewayManager struct {
  35. db.SSharableVirtualResourceBaseManager
  36. db.SExternalizedResourceBaseManager
  37. SVpcResourceBaseManager
  38. }
  39. var IPv6GatewayManager *SIPv6GatewayManager
  40. func init() {
  41. IPv6GatewayManager = &SIPv6GatewayManager{
  42. SSharableVirtualResourceBaseManager: db.NewSharableVirtualResourceBaseManager(
  43. SIPv6Gateway{},
  44. "ipv6_gateways_tbl",
  45. "ipv6_gateway",
  46. "ipv6_gateways",
  47. ),
  48. }
  49. IPv6GatewayManager.SetVirtualObject(IPv6GatewayManager)
  50. }
  51. type SIPv6Gateway struct {
  52. db.SSharableVirtualResourceBase
  53. db.SExternalizedResourceBase
  54. SVpcResourceBase `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"`
  55. InstanceType string `width:"64" charset:"utf8" nullable:"true" list:"user" create:"optional"`
  56. }
  57. func (manager *SIPv6GatewayManager) GetContextManagers() [][]db.IModelManager {
  58. return [][]db.IModelManager{
  59. {VpcManager},
  60. }
  61. }
  62. func (self *SIPv6Gateway) ValidateDeleteCondition(ctx context.Context, data *api.IPv6GatewayDetails) error {
  63. return self.SSharableVirtualResourceBase.ValidateDeleteCondition(ctx, nil)
  64. }
  65. func (self *SVpc) GetIPv6Gateways() ([]SIPv6Gateway, error) {
  66. q := IPv6GatewayManager.Query().Equals("vpc_id", self.Id)
  67. ret := []SIPv6Gateway{}
  68. err := db.FetchModelObjects(IPv6GatewayManager, q, &ret)
  69. return ret, err
  70. }
  71. func (self *SVpc) SyncIPv6Gateways(
  72. ctx context.Context,
  73. userCred mcclient.TokenCredential,
  74. exts []cloudprovider.ICloudIPv6Gateway,
  75. provider *SCloudprovider,
  76. xor bool,
  77. ) compare.SyncResult {
  78. lockman.LockRawObject(ctx, IPv6GatewayManager.Keyword(), self.Id)
  79. defer lockman.ReleaseRawObject(ctx, IPv6GatewayManager.Keyword(), self.Id)
  80. result := compare.SyncResult{}
  81. dbRes, err := self.GetIPv6Gateways()
  82. if err != nil {
  83. result.Error(err)
  84. return result
  85. }
  86. removed := make([]SIPv6Gateway, 0)
  87. commondb := make([]SIPv6Gateway, 0)
  88. commonext := make([]cloudprovider.ICloudIPv6Gateway, 0)
  89. added := make([]cloudprovider.ICloudIPv6Gateway, 0)
  90. err = compare.CompareSets(dbRes, exts, &removed, &commondb, &commonext, &added)
  91. if err != nil {
  92. result.Error(err)
  93. return result
  94. }
  95. for i := 0; i < len(removed); i += 1 {
  96. err = removed[i].syncRemoveCloudIPv6Gateway(ctx, userCred)
  97. if err != nil {
  98. result.DeleteError(err)
  99. } else {
  100. result.Delete()
  101. }
  102. }
  103. if !xor {
  104. for i := 0; i < len(commondb); i += 1 {
  105. err = commondb[i].SyncWithCloudIPv6Gateway(ctx, userCred, commonext[i], provider)
  106. if err != nil {
  107. result.UpdateError(err)
  108. continue
  109. }
  110. result.Update()
  111. }
  112. }
  113. for i := 0; i < len(added); i += 1 {
  114. _, err := self.newFromCloudIPv6Gateway(ctx, userCred, added[i], provider)
  115. if err != nil {
  116. result.AddError(err)
  117. continue
  118. }
  119. result.Add()
  120. }
  121. return result
  122. }
  123. func (self *SIPv6Gateway) syncRemoveCloudIPv6Gateway(ctx context.Context, userCred mcclient.TokenCredential) error {
  124. lockman.LockObject(ctx, self)
  125. defer lockman.ReleaseObject(ctx, self)
  126. err := self.ValidateDeleteCondition(ctx, nil)
  127. if err != nil { // cannot delete
  128. self.SetStatus(ctx, userCred, api.NETWORK_STATUS_UNKNOWN, "Sync to remove")
  129. return err
  130. }
  131. return self.RealDelete(ctx, userCred)
  132. }
  133. func (self *SIPv6Gateway) SyncWithCloudIPv6Gateway(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudIPv6Gateway, provider *SCloudprovider) error {
  134. diff, err := db.Update(self, func() error {
  135. if options.Options.EnableSyncName {
  136. newName, _ := db.GenerateAlterName(self, ext.GetName())
  137. if len(newName) > 0 {
  138. self.Name = newName
  139. }
  140. }
  141. self.Status = ext.GetStatus()
  142. self.InstanceType = ext.GetInstanceType()
  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 *SVpc) newFromCloudIPv6Gateway(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudIPv6Gateway, provider *SCloudprovider) (*SIPv6Gateway, error) {
  162. ret := &SIPv6Gateway{}
  163. ret.SetModelManager(IPv6GatewayManager, ret)
  164. ret.Status = ext.GetStatus()
  165. ret.ExternalId = ext.GetGlobalId()
  166. ret.VpcId = self.Id
  167. ret.InstanceType = ext.GetInstanceType()
  168. if createdAt := ext.GetCreatedAt(); !createdAt.IsZero() {
  169. ret.CreatedAt = createdAt
  170. }
  171. var err = func() error {
  172. lockman.LockRawObject(ctx, IPv6GatewayManager.Keyword(), "name")
  173. defer lockman.ReleaseRawObject(ctx, IPv6GatewayManager.Keyword(), "name")
  174. newName, err := db.GenerateName(ctx, IPv6GatewayManager, provider.GetOwnerId(), ext.GetName())
  175. if err != nil {
  176. return err
  177. }
  178. ret.Name = newName
  179. return IPv6GatewayManager.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 *SIPv6GatewayManager) 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.IPv6GatewayDetails {
  201. rows := make([]api.IPv6GatewayDetails, len(objs))
  202. virtRows := manager.SSharableVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  203. vpcRows := manager.SVpcResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  204. for i := range rows {
  205. rows[i] = api.IPv6GatewayDetails{
  206. SharableVirtualResourceDetails: virtRows[i],
  207. VpcResourceInfo: vpcRows[i],
  208. }
  209. }
  210. return rows
  211. }
  212. func (manager *SIPv6GatewayManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.IPv6GatewayCreateInput) (api.IPv6GatewayCreateInput, error) {
  213. return input, httperrors.NewNotImplementedError("ValidateCreateData")
  214. }
  215. func (self *SIPv6Gateway) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.IPv6GatewayUpdateInput) (api.IPv6GatewayUpdateInput, error) {
  216. return input, httperrors.NewNotImplementedError("ValidateCreateData")
  217. }
  218. func (self *SIPv6Gateway) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
  219. self.SetStatus(ctx, userCred, apis.STATUS_DELETING, "")
  220. return nil
  221. }
  222. func (self *SIPv6Gateway) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
  223. db.OpsLog.LogEvent(self, db.ACT_DELOCATE, self.GetShortDesc(ctx), userCred)
  224. return self.SSharableVirtualResourceBase.Delete(ctx, userCred)
  225. }
  226. // IPv6网关列表
  227. func (manager *SIPv6GatewayManager) ListItemFilter(
  228. ctx context.Context,
  229. q *sqlchemy.SQuery,
  230. userCred mcclient.TokenCredential,
  231. input api.IPv6GatewayListInput,
  232. ) (*sqlchemy.SQuery, error) {
  233. var err error
  234. q, err = manager.SSharableVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, input.SharableVirtualResourceListInput)
  235. if err != nil {
  236. return nil, errors.Wrap(err, "SSharableVirtualResourceBaseManager.ListItemFilter")
  237. }
  238. q, err = manager.SVpcResourceBaseManager.ListItemFilter(ctx, q, userCred, input.VpcFilterListInput)
  239. if err != nil {
  240. return nil, errors.Wrap(err, "SVpcResourceBaseManager.ListItemFilter")
  241. }
  242. q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, input.ExternalizedResourceBaseListInput)
  243. if err != nil {
  244. return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
  245. }
  246. return q, nil
  247. }
  248. func (manager *SIPv6GatewayManager) OrderByExtraFields(
  249. ctx context.Context,
  250. q *sqlchemy.SQuery,
  251. userCred mcclient.TokenCredential,
  252. input api.IPv6GatewayListInput,
  253. ) (*sqlchemy.SQuery, error) {
  254. var err error
  255. q, err = manager.SSharableVirtualResourceBaseManager.OrderByExtraFields(ctx, q, userCred, input.SharableVirtualResourceListInput)
  256. if err != nil {
  257. return nil, errors.Wrap(err, "SSharableVirtualResourceBaseManager.OrderByExtraFields")
  258. }
  259. return q, nil
  260. }
  261. func (manager *SIPv6GatewayManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
  262. var err error
  263. q, err = manager.SSharableVirtualResourceBaseManager.QueryDistinctExtraField(q, field)
  264. if err == nil {
  265. return q, nil
  266. }
  267. return q, httperrors.ErrNotFound
  268. }
  269. func (self *SIPv6Gateway) ValidateUpdateCondition(ctx context.Context) error {
  270. return self.SSharableVirtualResourceBase.ValidateUpdateCondition(ctx)
  271. }
  272. func (self *SIPv6Gateway) GetChangeOwnerCandidateDomainIds() []string {
  273. candidates := [][]string{}
  274. vpc, _ := self.GetVpc()
  275. if vpc != nil {
  276. candidates = append(candidates, vpc.GetChangeOwnerCandidateDomainIds())
  277. }
  278. return db.ISharableMergeChangeOwnerCandidateDomainIds(self, candidates...)
  279. }
  280. func (manager *SIPv6GatewayManager) ListItemExportKeys(ctx context.Context,
  281. q *sqlchemy.SQuery,
  282. userCred mcclient.TokenCredential,
  283. keys stringutils2.SSortedStrings,
  284. ) (*sqlchemy.SQuery, error) {
  285. var err error
  286. q, err = manager.SSharableVirtualResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  287. if err != nil {
  288. return nil, errors.Wrap(err, "SSharableVirtualResourceBaseManager.ListItemExportKeys")
  289. }
  290. if keys.ContainsAny(manager.SVpcResourceBaseManager.GetExportKeys()...) {
  291. q, err = manager.SVpcResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  292. if err != nil {
  293. return nil, errors.Wrap(err, "SVpcResourceBaseManager.ListItemExportKeys")
  294. }
  295. }
  296. return q, nil
  297. }
  298. func (manager *SIPv6GatewayManager) AllowScope(userCred mcclient.TokenCredential) rbacscope.TRbacScope {
  299. scope, _ := policy.PolicyManager.AllowScope(userCred, api.SERVICE_TYPE, IPv6GatewayManager.KeywordPlural(), policy.PolicyActionGet)
  300. return scope
  301. }