disk.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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 google
  15. import (
  16. "context"
  17. "fmt"
  18. "strings"
  19. "time"
  20. "yunion.io/x/jsonutils"
  21. "yunion.io/x/pkg/util/encode"
  22. billing "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. SResourceBase
  30. multicloud.SDisk
  31. GoogleTags
  32. ProvisionedIops int
  33. CreationTimestamp time.Time
  34. SizeGB int
  35. Zone string
  36. Status string
  37. Type string
  38. SourceImage string
  39. LastAttachTimestamp time.Time
  40. LastDetachTimestamp time.Time
  41. LabelFingerprint string
  42. PhysicalBlockSizeBytes string
  43. ResourcePolicies []string
  44. Users []string
  45. Kind string
  46. autoDelete bool
  47. boot bool
  48. index int
  49. }
  50. func (region *SRegion) GetDisks(zone string, storageType string, maxResults int, pageToken string) ([]SDisk, error) {
  51. disks := []SDisk{}
  52. if len(zone) == 0 {
  53. return nil, fmt.Errorf("zone params can not be empty")
  54. }
  55. params := map[string]string{}
  56. if len(storageType) > 0 {
  57. params["filter"] = fmt.Sprintf(`type="%s/%s/projects/%s/zones/%s/diskTypes/%s"`, GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, region.GetProjectId(), zone, storageType)
  58. }
  59. return disks, region.List(fmt.Sprintf("zones/%s/disks", zone), params, maxResults, pageToken, &disks)
  60. }
  61. func (region *SRegion) GetDisk(id string) (*SDisk, error) {
  62. disk := &SDisk{}
  63. return disk, region.Get("disks", id, disk)
  64. }
  65. func (disk *SDisk) GetStatus() string {
  66. switch disk.Status {
  67. case "READY":
  68. return api.DISK_READY
  69. case "CREATING":
  70. return api.DISK_ALLOCATING
  71. case "RESTORING":
  72. return api.DISK_RESET
  73. case "FAILED":
  74. return api.DISK_ALLOC_FAILED
  75. case "DELETING":
  76. return api.DISK_DEALLOC
  77. default:
  78. return api.DISK_UNKNOWN
  79. }
  80. }
  81. func (disk *SDisk) IsEmulated() bool {
  82. return false
  83. }
  84. func (disk *SDisk) Refresh() error {
  85. _disk, err := disk.storage.zone.region.GetDisk(disk.Id)
  86. if err != nil {
  87. return err
  88. }
  89. return jsonutils.Update(disk, _disk)
  90. }
  91. func (disk *SDisk) GetIStorage() (cloudprovider.ICloudStorage, error) {
  92. return disk.storage, nil
  93. }
  94. func (disk *SDisk) GetIStorageId() string {
  95. return disk.storage.GetGlobalId()
  96. }
  97. func (disk *SDisk) GetDiskFormat() string {
  98. return "raw"
  99. }
  100. func (disk *SDisk) GetDiskSizeMB() int {
  101. return disk.SizeGB * 1024
  102. }
  103. func (disk *SDisk) GetIsAutoDelete() bool {
  104. if len(disk.Users) == 0 {
  105. return false
  106. }
  107. return disk.autoDelete
  108. }
  109. func (disk *SDisk) GetTemplateId() string {
  110. return disk.SourceImage
  111. }
  112. func (disk *SDisk) GetDiskType() string {
  113. if disk.boot && len(disk.Users) > 0 {
  114. return api.DISK_TYPE_SYS
  115. }
  116. return api.DISK_TYPE_DATA
  117. }
  118. func (disk *SDisk) GetFsFormat() string {
  119. return ""
  120. }
  121. func (disk *SDisk) GetIsNonPersistent() bool {
  122. return false
  123. }
  124. func (disk *SDisk) GetDriver() string {
  125. return "scsi"
  126. }
  127. func (disk *SDisk) GetCacheMode() string {
  128. return "none"
  129. }
  130. func (disk *SDisk) GetMountpoint() string {
  131. return ""
  132. }
  133. func (disk *SDisk) GetAccessPath() string {
  134. return ""
  135. }
  136. func (disk *SDisk) GetIops() int {
  137. return disk.ProvisionedIops
  138. }
  139. func (disk *SDisk) Delete(ctx context.Context) error {
  140. return disk.storage.zone.region.Delete(disk.SelfLink)
  141. }
  142. func (disk *SDisk) CreateISnapshot(ctx context.Context, name string, desc string) (cloudprovider.ICloudSnapshot, error) {
  143. snapshot, err := disk.storage.zone.region.CreateSnapshot(disk.SelfLink, name, desc)
  144. if err != nil {
  145. return nil, err
  146. }
  147. snapshot.region = disk.storage.zone.region
  148. return snapshot, nil
  149. }
  150. func (disk *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
  151. snapshots, err := disk.storage.zone.region.GetSnapshots(disk.SelfLink, 0, "")
  152. if err != nil {
  153. return nil, err
  154. }
  155. isnapshots := []cloudprovider.ICloudSnapshot{}
  156. for i := range snapshots {
  157. snapshots[i].region = disk.storage.zone.region
  158. isnapshots = append(isnapshots, &snapshots[i])
  159. }
  160. return isnapshots, nil
  161. }
  162. func (disk *SDisk) GetISnapshot(id string) (cloudprovider.ICloudSnapshot, error) {
  163. return disk.storage.zone.region.GetSnapshot(id)
  164. }
  165. func (disk *SDisk) Resize(ctx context.Context, newSizeMB int64) error {
  166. return disk.storage.zone.region.ResizeDisk(disk.SelfLink, int(newSizeMB>>10))
  167. }
  168. func (disk *SDisk) Reset(ctx context.Context, snapshotId string) (string, error) {
  169. return "", cloudprovider.ErrNotSupported
  170. }
  171. func (disk *SDisk) Rebuild(ctx context.Context) error {
  172. return cloudprovider.ErrNotSupported
  173. }
  174. func (disk *SDisk) GetBillingType() string {
  175. return billing.BILLING_TYPE_POSTPAID
  176. }
  177. func (disk *SDisk) GetCreatedAt() time.Time {
  178. return disk.CreationTimestamp
  179. }
  180. func (disk *SDisk) GetExpiredAt() time.Time {
  181. return time.Time{}
  182. }
  183. func (disk *SDisk) GetProjectId() string {
  184. return disk.storage.zone.region.GetProjectId()
  185. }
  186. func (region *SRegion) CreateDisk(zone string, storageType string, opts *cloudprovider.DiskCreateConfig) (*SDisk, error) {
  187. if !strings.HasPrefix(storageType, GOOGLE_COMPUTE_DOMAIN) {
  188. storageType = fmt.Sprintf("projects/%s/zones/%s/diskTypes/%s", region.GetProjectId(), zone, storageType)
  189. }
  190. labels := map[string]string{}
  191. for k, v := range opts.Tags {
  192. labels[encode.EncodeGoogleLabel(k)] = encode.EncodeGoogleLabel(v)
  193. }
  194. body := map[string]interface{}{
  195. "name": normalizeString(opts.Name),
  196. "description": opts.Desc,
  197. // https://www.googleapis.com/compute/v1/projects/my-project-15390453537169/zones/us-west2-c/diskTypes/pd-standard
  198. // projects/my-project-15390453537169/zones/us-west2-c/diskTypes/pd-standard
  199. "type": storageType,
  200. "labels": labels,
  201. }
  202. body["sizeGb"] = opts.SizeGb
  203. if len(opts.ImageId) > 0 {
  204. body["sourceImage"] = opts.ImageId
  205. }
  206. disk := &SDisk{}
  207. resource := fmt.Sprintf("zones/%s/disks", zone)
  208. err := region.Insert(resource, jsonutils.Marshal(body), disk)
  209. if err != nil {
  210. return nil, err
  211. }
  212. return disk, nil
  213. }
  214. func (region *SRegion) ResizeDisk(id string, sizeGb int) error {
  215. body := map[string]int{
  216. "sizeGb": sizeGb,
  217. }
  218. return region.Do(id, "resize", nil, jsonutils.Marshal(body))
  219. }
  220. func (self *SRegion) CreateSnapshot(diskId string, name string, desc string) (*SSnapshot, error) {
  221. body := map[string]string{
  222. "name": normalizeString(name),
  223. "description": desc,
  224. }
  225. err := self.Do(diskId, "createSnapshot", nil, jsonutils.Marshal(body))
  226. if err != nil {
  227. return nil, err
  228. }
  229. snapshot := &SSnapshot{region: self}
  230. return snapshot, self.GetBySelfId(fmt.Sprintf("projects/%s/global/snapshots/%s", self.GetProjectId(), name), snapshot)
  231. }