disk.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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. "context"
  17. "strconv"
  18. "time"
  19. "yunion.io/x/jsonutils"
  20. "yunion.io/x/pkg/errors"
  21. "yunion.io/x/pkg/utils"
  22. billing_api "yunion.io/x/cloudmux/pkg/apis/billing"
  23. api "yunion.io/x/cloudmux/pkg/apis/compute"
  24. "yunion.io/x/cloudmux/pkg/cloudprovider"
  25. "yunion.io/x/cloudmux/pkg/multicloud"
  26. )
  27. type SDisk struct {
  28. storage *SStorage
  29. multicloud.SDisk
  30. CtyunTags
  31. multicloud.SBillingBase
  32. DiskName string
  33. DiskFreeze bool
  34. IsPackaged bool
  35. DiskMode string
  36. MultiAttach bool
  37. ProjectId string
  38. RegionId string
  39. DiskType string
  40. ExpireTime string
  41. IsEncrypt bool
  42. DiskSize int
  43. AzName string
  44. DiskStatus string
  45. CreateTime int64
  46. DiskId string
  47. InstanceId string
  48. IsSystemVolume bool
  49. }
  50. func (self *SDisk) GetBillingType() string {
  51. if len(self.ExpireTime) > 0 {
  52. return billing_api.BILLING_TYPE_PREPAID
  53. }
  54. return billing_api.BILLING_TYPE_POSTPAID
  55. }
  56. func (self *SDisk) GetCreatedAt() time.Time {
  57. return time.Unix(self.CreateTime/1000, 0)
  58. }
  59. func (self *SDisk) GetExpiredAt() time.Time {
  60. if len(self.ExpireTime) == 0 {
  61. return time.Time{}
  62. }
  63. at, _ := strconv.Atoi(self.ExpireTime)
  64. return time.Unix(int64(at/1000), 0)
  65. }
  66. func (self *SDisk) GetId() string {
  67. return self.DiskId
  68. }
  69. func (self *SDisk) GetName() string {
  70. return self.DiskName
  71. }
  72. func (self *SDisk) GetGlobalId() string {
  73. return self.GetId()
  74. }
  75. func (self *SDisk) GetStatus() string {
  76. switch self.DiskStatus {
  77. case "deleting":
  78. return api.DISK_DEALLOC
  79. case "creating":
  80. return api.DISK_ALLOCATING
  81. case "detaching":
  82. return api.DISK_DETACHING
  83. case "detached", "attached", "expired", "freezing", "available", "in-use":
  84. return api.DISK_READY
  85. case "attaching":
  86. return api.DISK_ATTACHING
  87. case "extending", "resizing":
  88. return api.DISK_RESIZING
  89. case "backup", "backupRestoring":
  90. return api.DISK_BACKUP_STARTALLOC
  91. default:
  92. return api.DISK_UNKNOWN
  93. }
  94. }
  95. func (self *SDisk) Refresh() error {
  96. disk, err := self.storage.zone.region.GetDisk(self.GetId())
  97. if err != nil {
  98. return err
  99. }
  100. return jsonutils.Update(self, disk)
  101. }
  102. func (self *SDisk) GetProjectId() string {
  103. return self.ProjectId
  104. }
  105. func (self *SDisk) GetIStorage() (cloudprovider.ICloudStorage, error) {
  106. return self.storage, nil
  107. }
  108. func (self *SDisk) GetIStorageId() string {
  109. return self.storage.GetId()
  110. }
  111. func (self *SDisk) GetDiskFormat() string {
  112. return "vhd"
  113. }
  114. func (self *SDisk) GetDiskSizeMB() int {
  115. return int(self.DiskSize * 1024)
  116. }
  117. func (self *SDisk) GetIsAutoDelete() bool {
  118. return self.IsSystemVolume
  119. }
  120. func (self *SDisk) GetTemplateId() string {
  121. if len(self.InstanceId) == 0 || !self.IsSystemVolume {
  122. return ""
  123. }
  124. vm, err := self.storage.zone.region.GetInstance(self.InstanceId)
  125. if err != nil {
  126. return ""
  127. }
  128. return vm.Image.ImageId
  129. }
  130. func (self *SDisk) GetDiskType() string {
  131. if self.IsSystemVolume {
  132. return api.DISK_TYPE_SYS
  133. }
  134. return api.DISK_TYPE_DATA
  135. }
  136. func (self *SDisk) GetFsFormat() string {
  137. return ""
  138. }
  139. func (self *SDisk) GetIsNonPersistent() bool {
  140. return false
  141. }
  142. func (self *SDisk) GetDriver() string {
  143. return self.DiskMode
  144. }
  145. func (self *SDisk) GetCacheMode() string {
  146. return "none"
  147. }
  148. func (self *SDisk) GetMountpoint() string {
  149. return ""
  150. }
  151. func (self *SDisk) GetAccessPath() string {
  152. return ""
  153. }
  154. func (self *SDisk) Delete(ctx context.Context) error {
  155. return self.storage.zone.region.DeleteDisk(self.GetId())
  156. }
  157. func (self *SDisk) CreateISnapshot(ctx context.Context, name string, desc string) (cloudprovider.ICloudSnapshot, error) {
  158. return nil, cloudprovider.ErrNotSupported
  159. }
  160. func (self *SDisk) GetISnapshot(idStr string) (cloudprovider.ICloudSnapshot, error) {
  161. return nil, cloudprovider.ErrNotFound
  162. }
  163. func (self *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
  164. return []cloudprovider.ICloudSnapshot{}, nil
  165. }
  166. func (self *SDisk) Resize(ctx context.Context, newSizeMB int64) error {
  167. return self.storage.zone.region.ResizeDisk(self.GetId(), newSizeMB/1024)
  168. }
  169. func (self *SDisk) Reset(ctx context.Context, snapshotId string) (string, error) {
  170. return "", cloudprovider.ErrNotSupported
  171. }
  172. func (self *SDisk) Rebuild(ctx context.Context) error {
  173. return cloudprovider.ErrNotSupported
  174. }
  175. func (self *SRegion) GetDisks() ([]SDisk, error) {
  176. pageNo := 1
  177. params := map[string]interface{}{
  178. "pageNo": pageNo,
  179. "pageSize": 50,
  180. }
  181. ret := []SDisk{}
  182. for {
  183. resp, err := self.list(SERVICE_EBS, "/v4/ebs/list-ebs", params)
  184. if err != nil {
  185. return nil, err
  186. }
  187. part := struct {
  188. ReturnObj struct {
  189. DiskList []SDisk
  190. }
  191. TotalCount int
  192. }{}
  193. err = resp.Unmarshal(&part)
  194. if err != nil {
  195. return nil, err
  196. }
  197. ret = append(ret, part.ReturnObj.DiskList...)
  198. if len(ret) >= part.TotalCount || len(part.ReturnObj.DiskList) == 0 {
  199. break
  200. }
  201. pageNo++
  202. params["pageNo"] = pageNo
  203. }
  204. return ret, nil
  205. }
  206. func (self *SRegion) GetDisk(diskId string) (*SDisk, error) {
  207. params := map[string]interface{}{
  208. "diskID": diskId,
  209. }
  210. resp, err := self.list(SERVICE_EBS, "/v4/ebs/info-ebs", params)
  211. if err != nil {
  212. return nil, err
  213. }
  214. ret := &SDisk{}
  215. return ret, resp.Unmarshal(ret, "returnObj")
  216. }
  217. func (self *SRegion) CreateDisk(zoneId, name, diskType string, size int) (*SDisk, error) {
  218. params := map[string]interface{}{
  219. "clientToken": utils.GenRequestId(20),
  220. "diskMode": "VBD",
  221. "diskType": diskType,
  222. "diskName": name,
  223. "diskSize": size,
  224. }
  225. if len(zoneId) > 0 && zoneId != "default" {
  226. params["azName"] = zoneId
  227. }
  228. resp, err := self.post(SERVICE_EBS, "/v4/ebs/new-ebs", params)
  229. if err != nil {
  230. return nil, err
  231. }
  232. orderId, err := resp.GetString("returnObj", "masterOrderID")
  233. if err != nil {
  234. return nil, errors.Wrapf(err, "get order id")
  235. }
  236. diskId, err := self.GetResourceId(orderId)
  237. if err != nil {
  238. return nil, errors.Wrapf(err, "GetResourceId")
  239. }
  240. return self.GetDisk(diskId)
  241. }
  242. func (self *SRegion) DeleteDisk(diskId string) error {
  243. params := map[string]interface{}{
  244. "clientToken": utils.GenRequestId(20),
  245. "diskID": diskId,
  246. }
  247. _, err := self.post(SERVICE_EBS, "/v4/ebs/refund-ebs", params)
  248. return err
  249. }
  250. func (self *SRegion) ResizeDisk(diskId string, newSizeGB int64) error {
  251. params := map[string]interface{}{
  252. "clientToken": utils.GenRequestId(20),
  253. "diskSize": newSizeGB,
  254. "diskID": diskId,
  255. }
  256. _, err := self.post(SERVICE_EBS, "/v4/ebs/resize-ebs", params)
  257. return err
  258. }