snapshot.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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 ksyun
  15. import (
  16. "fmt"
  17. "strings"
  18. "time"
  19. api "yunion.io/x/cloudmux/pkg/apis/compute"
  20. "yunion.io/x/cloudmux/pkg/cloudprovider"
  21. "yunion.io/x/cloudmux/pkg/multicloud"
  22. "yunion.io/x/jsonutils"
  23. )
  24. /*
  25. {
  26. "SnapshotId": "780618d7-05d0-4445-8905-94a5a1fe8a3d",
  27. "SnapshotName": "test-snap",
  28. "SnapshotDesc": "",
  29. "VolumeId": "d9329bb8-fa1d-4e13-ac36-64096fea1a3a",
  30. "Size": 20,
  31. "BillSize": "0",
  32. "ProjectAvailable": true,
  33. "ProjectId": 0,
  34. "CreateTime": "2025-09-25 16:53:41",
  35. "SnapshotStatus": "available",
  36. "VolumeCategory": "data",
  37. "VolumeName": "test-disk",
  38. "VolumeType": "SSD3.0",
  39. "Progress": "100%",
  40. "AvailabilityZone": "cn-beijing-6a",
  41. "VolumeStatus": "available",
  42. "SnapshotType": "CommonSnapShot",
  43. "AutoSnapshot": false,
  44. "ImageRelated": false,
  45. "CopyFrom": false,
  46. "EbsClusterType": "Public"
  47. }
  48. */
  49. type SSnapshot struct {
  50. multicloud.SVirtualResourceBase
  51. SKsyunTags
  52. region *SRegion
  53. SnapshotId string
  54. VolumeId string
  55. SnapshotName string
  56. SnapshotDesc string
  57. Size int
  58. BillSize string
  59. ProjectAvailable bool
  60. ProjectId int
  61. SnapshotStatus string
  62. VolumeCategory string
  63. VolumeName string
  64. VolumeType string
  65. Progress string
  66. AvailabilityZone string
  67. VolumeStatus string
  68. SnapshotType string
  69. AutoSnapshot bool
  70. ImageRelated bool
  71. CopyFrom bool
  72. EbsClusterType string
  73. CreateTime time.Time
  74. }
  75. func (snap *SSnapshot) GetId() string {
  76. return snap.SnapshotId
  77. }
  78. func (snap *SSnapshot) GetName() string {
  79. if len(snap.SnapshotName) > 0 {
  80. return snap.SnapshotName
  81. }
  82. return snap.SnapshotId
  83. }
  84. func (snap *SSnapshot) GetStatus() string {
  85. switch snap.SnapshotStatus {
  86. case "available":
  87. return api.SNAPSHOT_READY
  88. case "creating":
  89. return api.SNAPSHOT_CREATING
  90. case "failed":
  91. return api.SNAPSHOT_FAILED
  92. default:
  93. return strings.ToLower(snap.SnapshotStatus)
  94. }
  95. }
  96. func (snap *SSnapshot) GetSizeMb() int32 {
  97. return int32(snap.Size * 1024)
  98. }
  99. func (snap *SSnapshot) GetDiskId() string {
  100. return snap.VolumeId
  101. }
  102. func (snap *SSnapshot) GetDiskType() string {
  103. if snap.VolumeCategory == "data" {
  104. return api.DISK_TYPE_DATA
  105. } else if snap.VolumeCategory == "system" {
  106. return api.DISK_TYPE_SYS
  107. } else {
  108. return ""
  109. }
  110. }
  111. func (snap *SSnapshot) Refresh() error {
  112. ret, err := snap.region.GetSnapshot(snap.SnapshotId)
  113. if err != nil {
  114. return err
  115. }
  116. return jsonutils.Update(snap, ret)
  117. }
  118. func (snap *SSnapshot) GetGlobalId() string {
  119. return snap.SnapshotId
  120. }
  121. func (region *SRegion) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
  122. snapshots, err := region.GetSnapshots("", "")
  123. if err != nil {
  124. return nil, err
  125. }
  126. ret := []cloudprovider.ICloudSnapshot{}
  127. for i := 0; i < len(snapshots); i += 1 {
  128. snapshots[i].region = region
  129. ret = append(ret, &snapshots[i])
  130. }
  131. return ret, nil
  132. }
  133. func (snap *SSnapshot) Delete() error {
  134. return snap.region.DeleteSnapshot(snap.SnapshotId)
  135. }
  136. func (region *SRegion) CreateSnapshot(diskId, name, desc string) (*SSnapshot, error) {
  137. params := map[string]interface{}{
  138. "VolumeId": diskId,
  139. "SnapshotName": name,
  140. "SnapshotDesc": desc,
  141. }
  142. body, err := region.ebsRequest("CreateSnapshot", params)
  143. if err != nil {
  144. return nil, err
  145. }
  146. id, err := body.GetString("SnapshotId")
  147. if err != nil {
  148. return nil, err
  149. }
  150. return region.GetSnapshot(id)
  151. }
  152. func (region *SRegion) GetSnapshots(snapshotId, volumeId string) ([]SSnapshot, error) {
  153. params := map[string]interface{}{
  154. "PageSize": "1000",
  155. }
  156. if len(snapshotId) > 0 {
  157. params["SnapshotId"] = snapshotId
  158. }
  159. if len(volumeId) > 0 {
  160. params["VolumeId"] = volumeId
  161. }
  162. PageNumber := 1
  163. ret := []SSnapshot{}
  164. for {
  165. params["PageNumber"] = fmt.Sprintf("%d", PageNumber)
  166. body, err := region.ebsRequest("DescribeSnapshots", params)
  167. if err != nil {
  168. return nil, err
  169. }
  170. part := struct {
  171. Snapshots []SSnapshot
  172. Page struct {
  173. TotalCount int64
  174. }
  175. }{}
  176. err = body.Unmarshal(&part)
  177. if err != nil {
  178. return nil, err
  179. }
  180. ret = append(ret, part.Snapshots...)
  181. if len(part.Snapshots) == 0 || len(ret) > int(part.Page.TotalCount) {
  182. break
  183. }
  184. PageNumber++
  185. }
  186. return ret, nil
  187. }
  188. func (region *SRegion) GetSnapshot(id string) (*SSnapshot, error) {
  189. snapshots, err := region.GetSnapshots("", id)
  190. if err != nil {
  191. return nil, err
  192. }
  193. for i := range snapshots {
  194. snapshots[i].region = region
  195. if snapshots[i].SnapshotId == id {
  196. return &snapshots[i], nil
  197. }
  198. }
  199. return nil, cloudprovider.ErrNotFound
  200. }
  201. func (region *SRegion) DeleteSnapshot(snapshotId string) error {
  202. params := map[string]interface{}{
  203. "SnapshotId": snapshotId,
  204. }
  205. _, err := region.ebsRequest("DeleteSnapshot", params)
  206. return err
  207. }