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