eip.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  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 ctyun
  15. import (
  16. "strings"
  17. "time"
  18. "yunion.io/x/jsonutils"
  19. "yunion.io/x/pkg/errors"
  20. "yunion.io/x/pkg/utils"
  21. billing_api "yunion.io/x/cloudmux/pkg/apis/billing"
  22. api "yunion.io/x/cloudmux/pkg/apis/compute"
  23. "yunion.io/x/cloudmux/pkg/cloudprovider"
  24. "yunion.io/x/cloudmux/pkg/multicloud"
  25. )
  26. type SEip struct {
  27. region *SRegion
  28. multicloud.SEipBase
  29. CtyunTags
  30. Id string
  31. Name string
  32. EipAddress string
  33. AssociationId string
  34. AssociationType string
  35. PrivateIPAddress string
  36. Bandwidth int
  37. Status string
  38. Tags string
  39. CreatedAt time.Time
  40. UpdatedAt time.Time
  41. ExpiredAt time.Time
  42. ProjectId string
  43. }
  44. func (self *SEip) GetBillingType() string {
  45. if !self.ExpiredAt.IsZero() {
  46. return billing_api.BILLING_TYPE_PREPAID
  47. }
  48. return billing_api.BILLING_TYPE_POSTPAID
  49. }
  50. func (self *SEip) GetCreatedAt() time.Time {
  51. return self.CreatedAt
  52. }
  53. func (self *SEip) GetExpiredAt() time.Time {
  54. return self.ExpiredAt
  55. }
  56. func (self *SEip) GetId() string {
  57. return self.Id
  58. }
  59. func (self *SEip) GetName() string {
  60. return self.Name
  61. }
  62. func (self *SEip) GetGlobalId() string {
  63. return self.GetId()
  64. }
  65. func (self *SEip) GetStatus() string {
  66. switch self.Status {
  67. case "ACTIVE", "DOWN", "UPDATING", "BANDING_OR_UNBANGDING":
  68. return api.EIP_STATUS_READY
  69. case "ERROR":
  70. return api.EIP_STATUS_ALLOCATE_FAIL
  71. case "DELETING", "DELETED", "EXPIRED":
  72. return api.EIP_STATUS_DEALLOCATE
  73. default:
  74. return strings.ToLower(self.Status)
  75. }
  76. }
  77. func (self *SEip) Refresh() error {
  78. eip, err := self.region.GetEip(self.Id)
  79. if err != nil {
  80. return err
  81. }
  82. return jsonutils.Update(self, eip)
  83. }
  84. func (self *SEip) GetProjectId() string {
  85. return ""
  86. }
  87. func (self *SEip) GetIpAddr() string {
  88. return self.EipAddress
  89. }
  90. func (self *SEip) GetMode() string {
  91. return api.EIP_MODE_STANDALONE_EIP
  92. }
  93. func (self *SEip) GetAssociationType() string {
  94. switch self.AssociationType {
  95. case "LOADBALANCER":
  96. return api.EIP_ASSOCIATE_TYPE_LOADBALANCER
  97. case "INSTANCE":
  98. return api.EIP_ASSOCIATE_TYPE_SERVER
  99. default:
  100. return strings.ToLower(self.AssociationType)
  101. }
  102. }
  103. func (self *SEip) GetAssociationExternalId() string {
  104. return self.AssociationId
  105. }
  106. func (self *SEip) GetBandwidth() int {
  107. return self.Bandwidth
  108. }
  109. func (self *SEip) GetInternetChargeType() string {
  110. if self.GetBillingType() == billing_api.BILLING_TYPE_PREPAID {
  111. return api.EIP_CHARGE_TYPE_BY_BANDWIDTH
  112. }
  113. return api.EIP_CHARGE_TYPE_BY_TRAFFIC
  114. }
  115. func (self *SEip) Delete() error {
  116. return self.region.DeleteEip(self.GetId())
  117. }
  118. func (self *SEip) Associate(opts *cloudprovider.AssociateConfig) error {
  119. return self.region.AssociateEip(self.GetId(), opts.InstanceId)
  120. }
  121. func (self *SEip) Dissociate() error {
  122. return self.region.DissociateEip(self.GetId())
  123. }
  124. func (self *SEip) ChangeBandwidth(bw int) error {
  125. return self.region.ChangeBandwidthEip(self.GetId(), bw)
  126. }
  127. func (self *SRegion) GetEips(status string) ([]SEip, error) {
  128. pageNo := 1
  129. params := map[string]interface{}{
  130. "pageNo": pageNo,
  131. "pageSize": 50,
  132. }
  133. if len(status) > 0 {
  134. params["status"] = status
  135. }
  136. ret := []SEip{}
  137. for {
  138. params["clientToken"] = utils.GenRequestId(20)
  139. resp, err := self.post(SERVICE_VPC, "/v4/eip/list", params)
  140. if err != nil {
  141. return nil, err
  142. }
  143. part := struct {
  144. ReturnObj struct {
  145. Eips []SEip
  146. }
  147. TotalCount int
  148. }{}
  149. err = resp.Unmarshal(&part)
  150. if err != nil {
  151. return nil, err
  152. }
  153. ret = append(ret, part.ReturnObj.Eips...)
  154. if len(ret) >= part.TotalCount || len(part.ReturnObj.Eips) == 0 {
  155. break
  156. }
  157. pageNo++
  158. params["pageNo"] = pageNo
  159. }
  160. return ret, nil
  161. }
  162. func (self *SRegion) GetEip(eipId string) (*SEip, error) {
  163. params := map[string]interface{}{
  164. "eipID": eipId,
  165. }
  166. resp, err := self.list(SERVICE_VPC, "/v4/eip/show", params)
  167. if err != nil {
  168. return nil, err
  169. }
  170. ret := &SEip{region: self}
  171. err = resp.Unmarshal(ret, "returnObj")
  172. if err != nil {
  173. return nil, errors.Wrapf(err, "Unmarshal")
  174. }
  175. return ret, nil
  176. }
  177. func (self *SRegion) CreateEip(opts *cloudprovider.SEip) (*SEip, error) {
  178. params := map[string]interface{}{
  179. "clientToken": utils.GenRequestId(20),
  180. "name": opts.Name,
  181. "cycleType": "on_demand",
  182. "demandBillingType": "upflowc",
  183. }
  184. if opts.BandwidthMbps > 0 {
  185. params["bandwidth"] = opts.BandwidthMbps
  186. }
  187. if opts.ChargeType == "bandwidth" {
  188. params["demandBillingType"] = "bandwidth"
  189. }
  190. var err error
  191. var eipId string
  192. for i := 0; i < 10; i++ {
  193. resp, err := self.post(SERVICE_VPC, "/v4/eip/create", params)
  194. if err != nil {
  195. return nil, err
  196. }
  197. status, err := resp.GetString("returnObj", "masterResourceStatus")
  198. if err != nil {
  199. return nil, errors.Wrapf(err, "get resource status")
  200. }
  201. if status != "started" {
  202. time.Sleep(time.Second * 5)
  203. continue
  204. }
  205. eipId, err = resp.GetString("returnObj", "eipID")
  206. if len(eipId) > 0 {
  207. break
  208. }
  209. }
  210. if err != nil {
  211. return nil, errors.Wrapf(err, "get eipId")
  212. }
  213. return self.GetEip(eipId)
  214. }
  215. func (self *SRegion) DeleteEip(id string) error {
  216. params := map[string]interface{}{
  217. "clientToken": utils.GenRequestId(20),
  218. "eipID": id,
  219. }
  220. _, err := self.post(SERVICE_VPC, "/v4/eip/delete", params)
  221. return err
  222. }
  223. func (self *SRegion) AssociateEip(eipId, instanceId string) error {
  224. params := map[string]interface{}{
  225. "clientToken": utils.GenRequestId(20),
  226. "eipID": eipId,
  227. "associationID": instanceId,
  228. "associationType": 1,
  229. }
  230. _, err := self.post(SERVICE_VPC, "/v4/eip/associate", params)
  231. return err
  232. }
  233. func (self *SRegion) DissociateEip(eipId string) error {
  234. params := map[string]interface{}{
  235. "clientToken": utils.GenRequestId(20),
  236. "eipID": eipId,
  237. }
  238. _, err := self.post(SERVICE_VPC, "/v4/eip/disassociate", params)
  239. return err
  240. }
  241. func (self *SRegion) ChangeBandwidthEip(eipId string, bandwidth int) error {
  242. params := map[string]interface{}{
  243. "clientToken": utils.GenRequestId(20),
  244. "eipID": eipId,
  245. "bandwidth": bandwidth,
  246. }
  247. _, err := self.post(SERVICE_VPC, "/v4/eip/modify-spec", params)
  248. return err
  249. }