yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/qcloud/snapshot_policy.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  
    21  	"yunion.io/x/jsonutils"
    22  	"yunion.io/x/pkg/errors"
    23  
    24  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    25  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    26  	"yunion.io/x/cloudmux/pkg/multicloud"
    27  )
    28  
    29  const (
    30  	NORMAL = "NORMAL"
    31  	UNKOWN = "ISOLATED"
    32  )
    33  
    34  type SSnapshotDatePolicy struct {
    35  	DayOfWeek []int
    36  	Hour      []int
    37  }
    38  
    39  type SSnapshotPolicy struct {
    40  	multicloud.SResourceBase
    41  	QcloudTags
    42  	region *SRegion
    43  
    44  	AutoSnapshotPolicyName  string
    45  	AutoSnapshotPolicyId    string
    46  	AutoSnapshotPolicyState string
    47  	RetentionDays           int
    48  	Policy                  []SSnapshotDatePolicy
    49  	Activated               bool `json:"IsActivated"`
    50  	IsPermanent             bool
    51  }
    52  
    53  func (self *SSnapshotPolicy) GetId() string {
    54  	return self.AutoSnapshotPolicyId
    55  }
    56  
    57  func (self *SSnapshotPolicy) GetName() string {
    58  	return self.AutoSnapshotPolicyName
    59  }
    60  
    61  func (self *SSnapshotPolicy) GetGlobalId() string {
    62  	return self.GetId()
    63  }
    64  
    65  func (self *SSnapshotPolicy) GetStatus() string {
    66  	if self.AutoSnapshotPolicyState == NORMAL {
    67  		return api.SNAPSHOT_POLICY_READY
    68  	}
    69  	return api.SNAPSHOT_POLICY_UNKNOWN
    70  }
    71  
    72  func (self *SSnapshotPolicy) Refresh() error {
    73  	if snapshotPolicies, total, err := self.region.GetSnapshotPolicies(self.AutoSnapshotPolicyId, 0, 1); err != nil {
    74  		return err
    75  	} else if total != 1 {
    76  		return cloudprovider.ErrNotFound
    77  	} else if err := jsonutils.Update(self, snapshotPolicies[0]); err != nil {
    78  		return err
    79  	}
    80  	return nil
    81  }
    82  
    83  func (self *SSnapshotPolicy) IsEmulated() bool {
    84  	return false
    85  }
    86  
    87  func (self *SSnapshotPolicy) GetProjectId() string {
    88  	return ""
    89  }
    90  
    91  func (self *SSnapshotPolicy) GetRetentionDays() int {
    92  	if self.IsPermanent {
    93  		return -1
    94  	}
    95  	return self.RetentionDays
    96  }
    97  
    98  func (self *SSnapshotPolicy) GetRepeatWeekdays() ([]int, error) {
    99  	if len(self.Policy) == 0 {
   100  		return nil, errors.Error("Policy Set Empty")
   101  	}
   102  	repeatWeekdays := self.Policy[0].DayOfWeek
   103  	if len(repeatWeekdays) > 0 {
   104  		if repeatWeekdays[0] == 0 {
   105  			repeatWeekdays = append(repeatWeekdays, 7)[1:]
   106  		}
   107  	}
   108  	return repeatWeekdays, nil
   109  }
   110  
   111  func (self *SSnapshotPolicy) GetTimePoints() ([]int, error) {
   112  	if len(self.Policy) == 0 {
   113  		return nil, errors.Error("Policy Set Empty")
   114  	}
   115  	return self.Policy[0].Hour, nil
   116  }
   117  
   118  func (self *SSnapshotPolicy) IsActivated() bool {
   119  	return self.Activated
   120  }
   121  
   122  func (self *SRegion) GetISnapshotPolicies() ([]cloudprovider.ICloudSnapshotPolicy, error) {
   123  	snapshotPolicies, total, err := self.GetSnapshotPolicies("", 0, 50)
   124  	if err != nil {
   125  		return nil, err
   126  	}
   127  	for len(snapshotPolicies) < total {
   128  		var parts []SSnapshotPolicy
   129  		parts, total, err = self.GetSnapshotPolicies("", len(snapshotPolicies), 50)
   130  		if err != nil {
   131  			return nil, err
   132  		}
   133  		snapshotPolicies = append(snapshotPolicies, parts...)
   134  	}
   135  	ret := make([]cloudprovider.ICloudSnapshotPolicy, len(snapshotPolicies))
   136  	for i := 0; i < len(snapshotPolicies); i += 1 {
   137  		ret[i] = &snapshotPolicies[i]
   138  	}
   139  	return ret, nil
   140  }
   141  
   142  func (self *SRegion) GetSnapshotPolicies(policyId string, offset int, limit int) ([]SSnapshotPolicy, int, error) {
   143  	params := make(map[string]string)
   144  	if len(policyId) > 0 {
   145  		params["AutoSnapshotPolicyIds.0"] = policyId
   146  	}
   147  	if limit != 0 {
   148  		params["Limit"] = strconv.Itoa(limit)
   149  		params["Offset"] = strconv.Itoa(offset)
   150  	}
   151  	body, err := self.cbsRequest("DescribeAutoSnapshotPolicies", params)
   152  	if err != nil {
   153  		return nil, 0, errors.Wrap(err, "Get Snapshot Policies failed")
   154  	}
   155  	snapshotPolicies := make([]SSnapshotPolicy, 0, 1)
   156  	if err := body.Unmarshal(&snapshotPolicies, "AutoSnapshotPolicySet"); err != nil {
   157  		return nil, 0, errors.Wrap(err, "Unmarshal snapshot policies detail failed")
   158  	}
   159  	for i := range snapshotPolicies {
   160  		snapshotPolicies[i].region = self
   161  	}
   162  	return snapshotPolicies, len(snapshotPolicies), nil
   163  }
   164  
   165  func (self *SSnapshotPolicy) Delete() error {
   166  	if self.region == nil {
   167  		return fmt.Errorf("Not init region for snapshotPolicy %s", self.GetId())
   168  	}
   169  	return self.region.DeleteSnapshotPolicy(self.GetId())
   170  }
   171  
   172  func (self *SRegion) DeleteSnapshotPolicy(snapshotPolicyId string) error {
   173  	params := make(map[string]string)
   174  	params["AutoSnapshotPolicyIds.0"] = snapshotPolicyId
   175  	_, err := self.cbsRequest("DeleteAutoSnapshotPolicies", params)
   176  	if err != nil {
   177  		return errors.Wrapf(err, "delete auto snapshot policy %s failed", snapshotPolicyId)
   178  	}
   179  	return nil
   180  }
   181  
   182  func (self *SRegion) GetISnapshotPolicyById(snapshotPolicyId string) (cloudprovider.ICloudSnapshotPolicy, error) {
   183  	policies, _, err := self.GetSnapshotPolicies(snapshotPolicyId, 0, 1)
   184  	if err != nil {
   185  		return nil, err
   186  	}
   187  	if len(policies) == 0 {
   188  		return nil, cloudprovider.ErrNotFound
   189  	}
   190  	return &policies[0], nil
   191  }
   192  
   193  func (self *SRegion) CreateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInput) (string, error) {
   194  	if input.RepeatWeekdays == nil {
   195  		return "", fmt.Errorf("Can't create snapshot policy with nil repeatWeekdays")
   196  	}
   197  	if input.TimePoints == nil {
   198  		return "", fmt.Errorf("Can't create snapshot policy with nil timePoints")
   199  	}
   200  	params := make(map[string]string)
   201  
   202  	// In Qcloud, that IsPermanent is true means that keep snapshot forever,
   203  	// In OneCloud, that RetentionDays is -1 means that keep snapshot forever.
   204  	if input.RetentionDays == -1 {
   205  		params["IsPermanent"] = strconv.FormatBool(true)
   206  	} else {
   207  		params["RetentionDays"] = strconv.Itoa(input.RetentionDays)
   208  	}
   209  	dayOfWeekPrefix, hourPrefix := "Policy.0.DayOfWeek.", "Policy.0.Hour."
   210  	for index, day := range input.RepeatWeekdays {
   211  		if day == 7 {
   212  			day = 0
   213  		}
   214  		params[dayOfWeekPrefix+strconv.Itoa(index)] = strconv.Itoa(day)
   215  	}
   216  	if len(input.PolicyName) > 0 {
   217  		params["AutoSnapshotPolicyName"] = input.PolicyName
   218  	}
   219  	for index, hour := range input.TimePoints {
   220  		params[hourPrefix+strconv.Itoa(index)] = strconv.Itoa(hour)
   221  	}
   222  	body, err := self.cbsRequest("CreateAutoSnapshotPolicy", params)
   223  	if err != nil {
   224  		return "", errors.Wrap(err, "create auto snapshot policy failed")
   225  	}
   226  	id, _ := body.GetString("AutoSnapshotPolicyId")
   227  	return id, nil
   228  }
   229  
   230  func (self *SRegion) UpdateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInput, snapshotPolicyId string) error {
   231  	// not implement
   232  	return nil
   233  }
   234  
   235  func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
   236  	params := make(map[string]string)
   237  	params["AutoSnapshotPolicyId"] = snapshotPolicyId
   238  	params["DiskIds.0"] = diskId
   239  	_, err := self.cbsRequest("BindAutoSnapshotPolicy", params)
   240  	if err != nil {
   241  		return errors.Wrapf(err, "Bind AutoSnapshotPolicy %s to Disk failed", snapshotPolicyId)
   242  	}
   243  	return nil
   244  }
   245  
   246  func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
   247  	params := make(map[string]string)
   248  	params["AutoSnapshotPolicyId"] = snapshotPolicyId
   249  	params["DiskIds.0"] = diskId
   250  	_, err := self.cbsRequest("UnbindAutoSnapshotPolicy", params)
   251  	if err != nil {
   252  		return errors.Wrapf(err, "Unbind AutoSnapshotPolicy %s of Disk failed", snapshotPolicyId)
   253  	}
   254  	return nil
   255  }
   256  
   257  func (self *SRegion) GetSnapshotIdByDiskId(diskID string) ([]string, error) {
   258  	params := make(map[string]string)
   259  	params["DiskId"] = diskID
   260  
   261  	rps, err := self.cbsRequest("DescribeDiskAssociatedAutoSnapshotPolicy", params)
   262  	if err != nil {
   263  		return nil, errors.Wrapf(err, "Get All SnapshotpolicyIDs of Disk %s failed", diskID)
   264  	}
   265  
   266  	snapshotpolicies := make([]SSnapshotPolicy, 0)
   267  	if err := rps.Unmarshal(&snapshotpolicies, "AutoSnapshotPolicySet"); err != nil {
   268  		return nil, errors.Wrapf(err, "Unmarshal snapshot policies details failed")
   269  	}
   270  	ret := make([]string, len(snapshotpolicies))
   271  	for i := range snapshotpolicies {
   272  		ret[i] = snapshotpolicies[i].GetId()
   273  	}
   274  	return ret, nil
   275  }