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  }