yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/qcloud/snapshot.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 qcloud
    16  
    17  import (
    18  	"fmt"
    19  	"strconv"
    20  	"time"
    21  
    22  	"yunion.io/x/jsonutils"
    23  	"yunion.io/x/log"
    24  
    25  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    26  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    27  	"yunion.io/x/cloudmux/pkg/multicloud"
    28  )
    29  
    30  type SnapshotStatusType string
    31  
    32  const (
    33  	SnapshotStatusAccomplished SnapshotStatusType = "NORMAL"
    34  	SnapshotStatusProgress     SnapshotStatusType = "CREATING"
    35  	SnapshotStatusFailed       SnapshotStatusType = "failed"
    36  )
    37  
    38  type SSnapshot struct {
    39  	multicloud.SResourceBase
    40  	QcloudTags
    41  	region *SRegion
    42  
    43  	SnapshotId       string             //	快照ID。
    44  	Placement        Placement          //	快照所在的位置。
    45  	DiskUsage        string             //	创建此快照的云硬盘类型。取值范围:SYSTEM_DISK:系统盘 DATA_DISK:数据盘。
    46  	DiskId           string             //	创建此快照的云硬盘ID。
    47  	DiskSize         int32              //	创建此快照的云硬盘大小,单位GB。
    48  	SnapshotState    SnapshotStatusType //	快照的状态。取值范围: NORMAL:正常 CREATING:创建中 ROLLBACKING:回滚中 COPYING_FROM_REMOTE:跨地域复制快照拷贝中。
    49  	SnapshotName     string             //	快照名称,用户自定义的快照别名。调用ModifySnapshotAttribute可修改此字段。
    50  	Percent          int                //	快照创建进度百分比,快照创建成功后此字段恒为100。
    51  	CreateTime       time.Time          //	快照的创建时间。
    52  	DeadlineTime     time.Time          //	快照到期时间。如果快照为永久保留,此字段为空。
    53  	Encrypt          bool               //	是否为加密盘创建的快照。取值范围:true:该快照为加密盘创建的 false:非加密盘创建的快照。
    54  	IsPermanent      bool               //	是否为永久快照。取值范围: true:永久快照 false:非永久快照。
    55  	CopyingToRegions []string           //	快照正在跨地域复制的目的地域,默认取值为[]。
    56  	CopyFromRemote   bool               //	是否为跨地域复制的快照。取值范围:true:表示为跨地域复制的快照。 false:本地域的快照。
    57  }
    58  
    59  func (self *SRegion) GetISnapshotById(snapshotId string) (cloudprovider.ICloudSnapshot, error) {
    60  	snapshots, total, err := self.GetSnapshots("", "", "", []string{snapshotId}, 0, 1)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  	if total > 1 {
    65  		return nil, cloudprovider.ErrDuplicateId
    66  	}
    67  	if total == 0 {
    68  		return nil, cloudprovider.ErrNotFound
    69  	}
    70  	return &snapshots[0], nil
    71  }
    72  
    73  func (self *SSnapshot) GetStatus() string {
    74  	// NORMAL:正常
    75  	// CREATING:创建中
    76  	// ROLLBACKING:回滚中
    77  	// COPYING_FROM_REMOTE:跨地域复制快照拷贝中。
    78  	switch self.SnapshotState {
    79  	case "NORMAL", "COPYING_FROM_REMOTE":
    80  		return api.SNAPSHOT_READY
    81  	case "CREATING":
    82  		return api.SNAPSHOT_CREATING
    83  	case "ROLLBACKING":
    84  		return api.SNAPSHOT_ROLLBACKING
    85  	}
    86  	return api.SNAPSHOT_UNKNOWN
    87  }
    88  
    89  func (self *SSnapshot) IsEmulated() bool {
    90  	return false
    91  }
    92  
    93  func (self *SSnapshot) Refresh() error {
    94  	snapshots, total, err := self.region.GetSnapshots("", "", "", []string{self.SnapshotId}, 0, 1)
    95  	if err != nil {
    96  		return err
    97  	}
    98  	if total > 1 {
    99  		return cloudprovider.ErrDuplicateId
   100  	}
   101  
   102  	if total == 0 {
   103  		return cloudprovider.ErrNotFound
   104  	}
   105  	return jsonutils.Update(self, snapshots[0])
   106  }
   107  
   108  func (self *SRegion) GetSnapshots(instanceId string, diskId string, snapshotName string, snapshotIds []string, offset int, limit int) ([]SSnapshot, int, error) {
   109  	if limit > 50 || limit <= 0 {
   110  		limit = 50
   111  	}
   112  	params := make(map[string]string)
   113  	params["Limit"] = fmt.Sprintf("%d", limit)
   114  	params["Offset"] = fmt.Sprintf("%d", offset)
   115  
   116  	filter := 0
   117  	if len(instanceId) > 0 {
   118  	}
   119  	if len(diskId) > 0 {
   120  		params[fmt.Sprintf("Filters.%d.Name", filter)] = "disk-id"
   121  		params[fmt.Sprintf("Filters.%d.Values.0", filter)] = diskId
   122  		filter++
   123  	}
   124  	if len(snapshotName) > 0 {
   125  		params[fmt.Sprintf("Filters.%d.Name", filter)] = "snapshot-name"
   126  		params[fmt.Sprintf("Filters.%d.Values", filter)] = snapshotName
   127  		filter++
   128  	}
   129  	if snapshotIds != nil && len(snapshotIds) > 0 {
   130  		for index, snapshotId := range snapshotIds {
   131  			params[fmt.Sprintf("SnapshotIds.%d", index)] = snapshotId
   132  		}
   133  	}
   134  	snapshots := []SSnapshot{}
   135  	body, err := self.cbsRequest("DescribeSnapshots", params)
   136  	if err != nil {
   137  		log.Errorf("GetSnapshots fail %s", err)
   138  		return nil, 0, err
   139  	}
   140  	body.Unmarshal(&snapshots, "SnapshotSet")
   141  	if err != nil {
   142  		return nil, 0, err
   143  	}
   144  	total, _ := body.Float("TotalCount")
   145  	for i := 0; i < len(snapshots); i++ {
   146  		snapshots[i].region = self
   147  	}
   148  	return snapshots, int(total), nil
   149  }
   150  
   151  func (self *SRegion) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
   152  	snapshots, total, err := self.GetSnapshots("", "", "", []string{}, 0, 50)
   153  	if err != nil {
   154  		return nil, err
   155  	}
   156  	for len(snapshots) < total {
   157  		var parts []SSnapshot
   158  		parts, total, err = self.GetSnapshots("", "", "", []string{}, len(snapshots), 50)
   159  		if err != nil {
   160  			return nil, err
   161  		}
   162  		snapshots = append(snapshots, parts...)
   163  	}
   164  	ret := make([]cloudprovider.ICloudSnapshot, len(snapshots))
   165  	for i := 0; i < len(snapshots); i++ {
   166  		ret[i] = &snapshots[i]
   167  	}
   168  	return ret, nil
   169  }
   170  
   171  func (self *SSnapshot) GetRegionId() string {
   172  	return self.region.GetId()
   173  }
   174  
   175  func (self *SSnapshot) GetSizeMb() int32 {
   176  	return self.DiskSize * 1024
   177  }
   178  
   179  func (self *SSnapshot) GetDiskId() string {
   180  	return self.DiskId
   181  }
   182  
   183  func (self *SSnapshot) GetId() string {
   184  	return self.SnapshotId
   185  }
   186  
   187  func (self *SSnapshot) GetGlobalId() string {
   188  	return fmt.Sprintf("%s", self.SnapshotId)
   189  }
   190  
   191  func (self *SSnapshot) GetName() string {
   192  	return self.SnapshotName
   193  }
   194  
   195  func (self *SSnapshot) Delete() error {
   196  	if self.region == nil {
   197  		return fmt.Errorf("not init region for snapshot %s", self.SnapshotId)
   198  	}
   199  	return self.region.DeleteSnapshot(self.SnapshotId)
   200  }
   201  
   202  func (self *SSnapshot) GetDiskType() string {
   203  	switch self.DiskUsage {
   204  	case "SYSTEM_DISK":
   205  		return api.DISK_TYPE_SYS
   206  	case "DATA_DISK":
   207  		return api.DISK_TYPE_DATA
   208  	}
   209  	return api.DISK_TYPE_DATA
   210  }
   211  
   212  func (self *SRegion) DeleteSnapshot(snapshotId string) error {
   213  	params := map[string]string{"SnapshotIds.0": snapshotId}
   214  	_, err := self.cbsRequest("DeleteSnapshots", params)
   215  	return err
   216  }
   217  
   218  func (self *SRegion) CreateSnapshot(diskId, name, desc string) (string, error) {
   219  	params := make(map[string]string)
   220  	params["DiskId"] = diskId
   221  	params["SnapshotName"] = name
   222  
   223  	body, err := self.cbsRequest("CreateSnapshot", params)
   224  	if err != nil {
   225  		log.Errorf("CreateSnapshot fail %s", err)
   226  		return "", err
   227  	}
   228  	return body.GetString("SnapshotId")
   229  }
   230  
   231  func (self *SSnapshot) GetProjectId() string {
   232  	return strconv.Itoa(self.Placement.ProjectId)
   233  }