disk.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  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 baidu
  15. import (
  16. "context"
  17. "fmt"
  18. "net/url"
  19. "strings"
  20. "time"
  21. api "yunion.io/x/cloudmux/pkg/apis/compute"
  22. "yunion.io/x/cloudmux/pkg/cloudprovider"
  23. "yunion.io/x/cloudmux/pkg/multicloud"
  24. "yunion.io/x/jsonutils"
  25. "yunion.io/x/pkg/errors"
  26. "yunion.io/x/pkg/utils"
  27. )
  28. type Attachment struct {
  29. InstanceId string
  30. MountPoint string
  31. DeleteWithInstance bool
  32. }
  33. type Attachments struct {
  34. Id string
  35. InstanceId string
  36. Device string
  37. Serial string
  38. }
  39. type AutoSnapshotPolicy struct {
  40. Id string
  41. Name string
  42. TimePoints []int
  43. RepeatWeekdays []int
  44. RetentionDays int
  45. Status string
  46. }
  47. type SDisk struct {
  48. storage *SStorage
  49. multicloud.SDisk
  50. SBaiduTag
  51. Id string
  52. CreateTime time.Time
  53. ExpireTime string
  54. Name string
  55. DiskSizeInGB int
  56. Status string
  57. Type string
  58. StorageType string
  59. Desc string
  60. PaymentTiming string
  61. Attachments []Attachments
  62. RegionId string
  63. SourceSnapshotId string
  64. SnapshotNum string
  65. AutoSnapshotPolicy AutoSnapshotPolicy
  66. ZoneName string
  67. IsSystemVolume bool
  68. }
  69. func (region *SRegion) GetDisks(storageType, zoneName, instanceId string) ([]SDisk, error) {
  70. params := url.Values{}
  71. if len(zoneName) > 0 {
  72. params.Set("zoneName", zoneName)
  73. }
  74. if len(instanceId) > 0 {
  75. params.Set("instanceId", instanceId)
  76. }
  77. disks := []SDisk{}
  78. for {
  79. resp, err := region.bccList("v2/volume", params)
  80. if err != nil {
  81. return nil, errors.Wrap(err, "list disks")
  82. }
  83. part := struct {
  84. NextMarker string
  85. Volumes []SDisk
  86. }{}
  87. err = resp.Unmarshal(&part)
  88. if err != nil {
  89. return nil, err
  90. }
  91. for i := range part.Volumes {
  92. if len(storageType) == 0 || isMatchStorageType(storageType, part.Volumes[i].StorageType) {
  93. disks = append(disks, part.Volumes[i])
  94. }
  95. }
  96. if len(part.NextMarker) == 0 {
  97. break
  98. }
  99. params.Set("marker", part.NextMarker)
  100. }
  101. return disks, nil
  102. }
  103. func (region *SRegion) GetDisk(diskId string) (*SDisk, error) {
  104. resp, err := region.bccList(fmt.Sprintf("v2/volume/%s", diskId), nil)
  105. if err != nil {
  106. return nil, errors.Wrap(err, "list disks")
  107. }
  108. ret := &SDisk{}
  109. err = resp.Unmarshal(ret, "volume")
  110. if err != nil {
  111. return nil, errors.Wrap(err, "unmarshal disks")
  112. }
  113. return ret, nil
  114. }
  115. func (disk *SDisk) GetIStorage() (cloudprovider.ICloudStorage, error) {
  116. return disk.storage, nil
  117. }
  118. func (disk *SDisk) GetIStorageId() string {
  119. return disk.storage.GetGlobalId()
  120. }
  121. func (disk *SDisk) GetDiskFormat() string {
  122. return ""
  123. }
  124. func (disk *SDisk) GetId() string {
  125. return disk.Id
  126. }
  127. func (disk *SDisk) GetGlobalId() string {
  128. return disk.Id
  129. }
  130. func (disk *SDisk) GetName() string {
  131. return disk.Name
  132. }
  133. func (disk *SDisk) GetDeviceName() string {
  134. for _, attachment := range disk.Attachments {
  135. if len(attachment.Device) > 0 {
  136. return attachment.Device
  137. }
  138. }
  139. return ""
  140. }
  141. func (disk *SDisk) GetStatus() string {
  142. switch disk.Status {
  143. case "Available", "InUse", "Recharging":
  144. return api.DISK_READY
  145. case "Detaching":
  146. return api.DISK_DETACHING
  147. case "Error", "NotAvailable", "Expired":
  148. return api.DISK_UNKNOWN
  149. case "Creating":
  150. return api.DISK_ALLOCATING
  151. case "Attaching":
  152. return api.DISK_ATTACHING
  153. case "Deleting":
  154. return api.DISK_DETACHING
  155. case "Scaling":
  156. return api.DISK_RESIZING
  157. case "SnapshotProcessing", "ImageProcessing":
  158. return api.DISK_SAVING
  159. default:
  160. return strings.ToLower(disk.Status)
  161. }
  162. }
  163. func (disk *SDisk) GetDiskSizeMB() int {
  164. return disk.DiskSizeInGB * 1024
  165. }
  166. func (disk *SDisk) GetIsAutoDelete() bool {
  167. return false
  168. }
  169. func (disk *SDisk) GetTemplateId() string {
  170. return ""
  171. }
  172. func (disk *SDisk) GetDiskType() string {
  173. if disk.IsSystemVolume {
  174. return api.DISK_TYPE_SYS
  175. }
  176. return api.DISK_TYPE_DATA
  177. }
  178. func (disk *SDisk) GetFsFormat() string {
  179. return ""
  180. }
  181. func (disk *SDisk) GetIsNonPersistent() bool {
  182. return false
  183. }
  184. func (disk *SDisk) GetIops() int {
  185. return 0
  186. }
  187. func (disk *SDisk) GetDriver() string {
  188. return ""
  189. }
  190. func (disk *SDisk) GetCacheMode() string {
  191. return ""
  192. }
  193. func (disk *SDisk) GetMountpoint() string {
  194. return ""
  195. }
  196. func (disk *SDisk) GetAccessPath() string {
  197. return ""
  198. }
  199. func (disk *SDisk) Refresh() error {
  200. res, err := disk.storage.zone.region.GetDisk(disk.Id)
  201. if err != nil {
  202. return err
  203. }
  204. return jsonutils.Update(disk, res)
  205. }
  206. func (disk *SDisk) Delete(ctx context.Context) error {
  207. return disk.storage.zone.region.DeleteDisk(disk.Id)
  208. }
  209. func (disk *SDisk) CreateISnapshot(ctx context.Context, name string, desc string) (cloudprovider.ICloudSnapshot, error) {
  210. snapshot, err := disk.storage.zone.region.CreateSnapshot(name, desc, disk.Id)
  211. if err != nil {
  212. return nil, err
  213. }
  214. return snapshot, nil
  215. }
  216. func (disk *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
  217. snapshots, err := disk.storage.zone.region.GetSnapshots(disk.Id)
  218. if err != nil {
  219. return nil, err
  220. }
  221. ret := []cloudprovider.ICloudSnapshot{}
  222. for i := range snapshots {
  223. snapshots[i].region = disk.storage.zone.region
  224. ret = append(ret, &snapshots[i])
  225. }
  226. return ret, nil
  227. }
  228. func (disk *SDisk) GetExtSnapshotPolicyIds() ([]string, error) {
  229. ret := []string{}
  230. if len(disk.AutoSnapshotPolicy.Id) > 0 {
  231. ret = append(ret, disk.AutoSnapshotPolicy.Id)
  232. }
  233. return ret, nil
  234. }
  235. func (disk *SDisk) Resize(ctx context.Context, newSizeMB int64) error {
  236. return disk.storage.zone.region.ResizeDisk(disk.Id, newSizeMB/1024)
  237. }
  238. func (disk *SDisk) Reset(ctx context.Context, snapshotId string) (string, error) {
  239. return disk.Id, disk.storage.zone.region.ResetDisk(disk.Id, snapshotId)
  240. }
  241. func (self *SRegion) ResetDisk(diskId, snapshotId string) error {
  242. params := url.Values{}
  243. params.Set("rollback", "")
  244. body := map[string]interface{}{
  245. "snapshotId": snapshotId,
  246. }
  247. _, err := self.bccUpdate(fmt.Sprintf("v2/volume/%s", diskId), params, body)
  248. return err
  249. }
  250. func (disk *SDisk) Rebuild(ctx context.Context) error {
  251. return cloudprovider.ErrNotSupported
  252. }
  253. func (region *SRegion) DeleteDisk(id string) error {
  254. _, err := region.bccDelete(fmt.Sprintf("v2/volume/%s", id), nil)
  255. return err
  256. }
  257. func (region *SRegion) CreateDisk(storageType, zoneName string, opts *cloudprovider.DiskCreateConfig) (*SDisk, error) {
  258. params := url.Values{}
  259. params.Set("clientToken", utils.GenRequestId(20))
  260. body := map[string]interface{}{
  261. "name": opts.Name,
  262. "description": opts.Desc,
  263. "cdsSizeInGB": opts.SizeGb,
  264. "storageType": storageType,
  265. "zoneName": zoneName,
  266. }
  267. resp, err := region.bccPost("v2/volume", params, body)
  268. if err != nil {
  269. return nil, err
  270. }
  271. ret := struct {
  272. VolumeIds []string
  273. }{}
  274. err = resp.Unmarshal(&ret)
  275. if err != nil {
  276. return nil, err
  277. }
  278. for _, id := range ret.VolumeIds {
  279. return region.GetDisk(id)
  280. }
  281. return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", resp.String())
  282. }
  283. func (region *SRegion) ResizeDisk(diskId string, sizeGb int64) error {
  284. params := url.Values{}
  285. params.Set("clientToken", utils.GenRequestId(20))
  286. params.Set("resize", "")
  287. body := map[string]interface{}{
  288. "newCdsSizeInGB": sizeGb,
  289. }
  290. _, err := region.bccUpdate(fmt.Sprintf("v2/volume/%s", diskId), params, body)
  291. return err
  292. }