yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/aliyun/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 aliyun
    16  
    17  import (
    18  	"fmt"
    19  	"sort"
    20  	"strconv"
    21  
    22  	"yunion.io/x/jsonutils"
    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  type SSnapshotPolicyType string
    30  
    31  const (
    32  	Creating  SSnapshotPolicyType = "Creating"
    33  	Available SSnapshotPolicyType = "Available"
    34  	Normal    SSnapshotPolicyType = "Normal"
    35  )
    36  
    37  type SSnapshotPolicy struct {
    38  	multicloud.SResourceBase
    39  	AliyunTags
    40  	region *SRegion
    41  
    42  	AutoSnapshotPolicyName string
    43  	AutoSnapshotPolicyId   string
    44  	RepeatWeekdays         string
    45  	TimePoints             string
    46  	RetentionDays          int
    47  	Status                 SSnapshotPolicyType
    48  }
    49  
    50  func (self *SSnapshotPolicy) GetId() string {
    51  	return self.AutoSnapshotPolicyId
    52  }
    53  
    54  func (self *SSnapshotPolicy) GetName() string {
    55  	return self.AutoSnapshotPolicyName
    56  }
    57  
    58  func (self *SSnapshotPolicy) GetStatus() string {
    59  	// XXX: aliyun文档与实际返回值不符
    60  	if self.Status == Normal || self.Status == Available {
    61  		return api.SNAPSHOT_POLICY_READY
    62  	} else if self.Status == Creating {
    63  		return api.SNAPSHOT_POLICY_CREATING
    64  	} else {
    65  		return api.SNAPSHOT_POLICY_UNKNOWN
    66  	}
    67  }
    68  
    69  func (self *SSnapshotPolicy) Refresh() error {
    70  	if snapshotPolicies, total, err := self.region.GetSnapshotPolicies(self.AutoSnapshotPolicyId, 0, 1); err != nil {
    71  		return err
    72  	} else if total != 1 {
    73  		return cloudprovider.ErrNotFound
    74  	} else if err := jsonutils.Update(self, snapshotPolicies[0]); err != nil {
    75  		return err
    76  	}
    77  	return nil
    78  }
    79  
    80  func (self *SSnapshotPolicy) IsEmulated() bool {
    81  	return false
    82  }
    83  
    84  func (self *SSnapshotPolicy) GetGlobalId() string {
    85  	return self.AutoSnapshotPolicyId
    86  }
    87  
    88  func (self *SSnapshotPolicy) GetProjectId() string {
    89  	return ""
    90  }
    91  
    92  func (self *SSnapshotPolicy) GetRetentionDays() int {
    93  	return self.RetentionDays
    94  }
    95  
    96  func sliceAtoi(sa []string) ([]int, error) {
    97  	si := make([]int, 0, len(sa))
    98  	for _, a := range sa {
    99  		i, err := strconv.Atoi(a)
   100  		if err != nil {
   101  			return si, err
   102  		}
   103  		si = append(si, i)
   104  	}
   105  	return si, nil
   106  }
   107  
   108  func stringToIntDays(days []string) ([]int, error) {
   109  	idays, err := sliceAtoi(days)
   110  	if err != nil {
   111  		return nil, err
   112  	}
   113  	sort.Ints(idays)
   114  	return idays, nil
   115  }
   116  
   117  func parsePolicy(policy string) ([]int, error) {
   118  	tp, err := jsonutils.ParseString(policy)
   119  	if err != nil {
   120  		return nil, fmt.Errorf("Parse policy %s error %s", policy, err)
   121  	}
   122  	atp, ok := tp.(*jsonutils.JSONArray)
   123  	if !ok {
   124  		return nil, fmt.Errorf("Policy %s Wrong format", tp)
   125  	}
   126  	return stringToIntDays(atp.GetStringArray())
   127  }
   128  
   129  func (self *SSnapshotPolicy) GetRepeatWeekdays() ([]int, error) {
   130  	return parsePolicy(self.RepeatWeekdays)
   131  }
   132  
   133  func (self *SSnapshotPolicy) GetTimePoints() ([]int, error) {
   134  	return parsePolicy(self.TimePoints)
   135  }
   136  
   137  func (self *SSnapshotPolicy) IsActivated() bool {
   138  	return true
   139  }
   140  
   141  func (self *SRegion) GetISnapshotPolicies() ([]cloudprovider.ICloudSnapshotPolicy, error) {
   142  	snapshotPolicies, total, err := self.GetSnapshotPolicies("", 0, 50)
   143  	if err != nil {
   144  		return nil, err
   145  	}
   146  	for len(snapshotPolicies) < total {
   147  		var parts []SSnapshotPolicy
   148  		parts, total, err = self.GetSnapshotPolicies("", len(snapshotPolicies), 50)
   149  		if err != nil {
   150  			return nil, err
   151  		}
   152  		snapshotPolicies = append(snapshotPolicies, parts...)
   153  	}
   154  	ret := make([]cloudprovider.ICloudSnapshotPolicy, len(snapshotPolicies))
   155  	for i := 0; i < len(snapshotPolicies); i += 1 {
   156  		ret[i] = &snapshotPolicies[i]
   157  	}
   158  	return ret, nil
   159  }
   160  
   161  func (self *SRegion) GetSnapshotPolicies(policyId string, offset int, limit int) ([]SSnapshotPolicy, int, error) {
   162  	params := make(map[string]string)
   163  
   164  	params["RegionId"] = self.RegionId
   165  	if limit != 0 {
   166  		params["PageSize"] = fmt.Sprintf("%d", limit)
   167  		params["PageNumber"] = fmt.Sprintf("%d", (offset/limit)+1)
   168  	}
   169  
   170  	if len(policyId) > 0 {
   171  		params["AutoSnapshotPolicyId"] = policyId
   172  	}
   173  
   174  	body, err := self.ecsRequest("DescribeAutoSnapshotPolicyEx", params)
   175  	if err != nil {
   176  		return nil, 0, fmt.Errorf("GetSnapshotPolicys fail %s", err)
   177  	}
   178  
   179  	snapshotPolicies := make([]SSnapshotPolicy, 0)
   180  	if err := body.Unmarshal(&snapshotPolicies, "AutoSnapshotPolicies", "AutoSnapshotPolicy"); err != nil {
   181  		return nil, 0, fmt.Errorf("Unmarshal snapshot policies details fail %s", err)
   182  	}
   183  	total, _ := body.Int("TotalCount")
   184  	for i := 0; i < len(snapshotPolicies); i += 1 {
   185  		snapshotPolicies[i].region = self
   186  	}
   187  	return snapshotPolicies, int(total), nil
   188  }
   189  
   190  func (self *SSnapshotPolicy) Delete() error {
   191  	if self.region == nil {
   192  		return fmt.Errorf("Not init region for snapshotPolicy %s", self.AutoSnapshotPolicyId)
   193  	}
   194  	return self.region.DeleteSnapshotPolicy(self.AutoSnapshotPolicyId)
   195  }
   196  
   197  func (self *SRegion) DeleteSnapshotPolicy(snapshotPolicyId string) error {
   198  	params := make(map[string]string)
   199  	params["autoSnapshotPolicyId"] = snapshotPolicyId
   200  	params["regionId"] = self.RegionId
   201  	_, err := self.ecsRequest("DeleteAutoSnapshotPolicy", params)
   202  	return err
   203  }
   204  
   205  func (self *SRegion) GetISnapshotPolicyById(snapshotPolicyId string) (cloudprovider.ICloudSnapshotPolicy, error) {
   206  	policies, _, err := self.GetSnapshotPolicies(snapshotPolicyId, 0, 1)
   207  	if err != nil {
   208  		return nil, err
   209  	}
   210  	if len(policies) == 0 {
   211  		return nil, cloudprovider.ErrNotFound
   212  	}
   213  	return &policies[0], nil
   214  }
   215  
   216  func (self *SRegion) CreateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInput) (string, error) {
   217  	if input.RepeatWeekdays == nil {
   218  		return "", fmt.Errorf("Can't create snapshot policy with nil repeatWeekdays")
   219  	}
   220  	if input.TimePoints == nil {
   221  		return "", fmt.Errorf("Can't create snapshot policy with nil timePoints")
   222  	}
   223  	params := make(map[string]string)
   224  	params["RegionId"] = self.RegionId
   225  	params["repeatWeekdays"] = jsonutils.Marshal(input.GetStringArrayRepeatWeekdays()).String()
   226  	params["timePoints"] = jsonutils.Marshal(input.GetStringArrayTimePoints()).String()
   227  	params["retentionDays"] = strconv.Itoa(input.RetentionDays)
   228  	params["autoSnapshotPolicyName"] = input.PolicyName
   229  	if body, err := self.ecsRequest("CreateAutoSnapshotPolicy", params); err != nil {
   230  		return "", fmt.Errorf("CreateAutoSnapshotPolicy fail %s", err)
   231  	} else {
   232  		return body.GetString("AutoSnapshotPolicyId")
   233  	}
   234  }
   235  
   236  func (self *SRegion) UpdateSnapshotPolicy(input *cloudprovider.SnapshotPolicyInput, snapshotPolicyId string) error {
   237  	params := make(map[string]string)
   238  	params["RegionId"] = self.RegionId
   239  	if input.RetentionDays != 0 {
   240  		params["retentionDays"] = strconv.Itoa(input.RetentionDays)
   241  	}
   242  	if input.RepeatWeekdays != nil && len(input.RepeatWeekdays) != 0 {
   243  		params["repeatWeekdays"] = jsonutils.Marshal(input.GetStringArrayRepeatWeekdays()).String()
   244  	}
   245  	if input.TimePoints != nil && len(input.TimePoints) != 0 {
   246  		params["timePoints"] = jsonutils.Marshal(input.GetStringArrayTimePoints()).String()
   247  	}
   248  	_, err := self.ecsRequest("ModifyAutoSnapshotPolicyEx", params)
   249  	if err != nil {
   250  		return fmt.Errorf("ModifyAutoSnapshotPolicyEx Fail %s", err)
   251  	}
   252  	return nil
   253  }
   254  
   255  //func (self *SRegion) UpdateSnapshotPolicy(
   256  //	snapshotPolicyId string, retentionDays *int,
   257  //	repeatWeekdays, timePoints *jsonutils.JSONArray, policyName string,
   258  //) error {
   259  //	params := make(map[string]string)
   260  //	params["RegionId"] = self.RegionId
   261  //	if len(policyName) > 0 {
   262  //		params["autoSnapshotPolicyName"] = policyName
   263  //	}
   264  //	if retentionDays != nil {
   265  //		params["retentionDays"] = strconv.Itoa(*retentionDays)
   266  //	}
   267  //	if repeatWeekdays != nil {
   268  //		params["repeatWeekdays"] = repeatWeekdays.String()
   269  //	}
   270  //	if timePoints != nil {
   271  //		params["timePoints"] = timePoints.String()
   272  //	}
   273  //	_, err := self.ecsRequest("ModifyAutoSnapshotPolicyEx", params)
   274  //	if err != nil {
   275  //		return fmt.Errorf("ModifyAutoSnapshotPolicyEx Fail %s", err)
   276  //	}
   277  //	return nil
   278  //}
   279  
   280  func (self *SRegion) ApplySnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
   281  	params := make(map[string]string)
   282  	params["RegionId"] = self.RegionId
   283  	params["autoSnapshotPolicyId"] = snapshotPolicyId
   284  	diskIds := []string{diskId}
   285  	params["diskIds"] = jsonutils.Marshal(diskIds).String()
   286  	_, err := self.ecsRequest("ApplyAutoSnapshotPolicy", params)
   287  	if err != nil {
   288  		return fmt.Errorf("ApplyAutoSnapshotPolicy Fail %s", err)
   289  	}
   290  	return nil
   291  }
   292  
   293  func (self *SRegion) CancelSnapshotPolicyToDisks(snapshotPolicyId string, diskId string) error {
   294  	params := make(map[string]string)
   295  	params["RegionId"] = self.RegionId
   296  	diskIds := []string{diskId}
   297  	params["diskIds"] = jsonutils.Marshal(diskIds).String()
   298  	_, err := self.ecsRequest("CancelAutoSnapshotPolicy", params)
   299  	if err != nil {
   300  		return fmt.Errorf("CancelAutoSnapshotPolicy Fail %s", err)
   301  	}
   302  	return nil
   303  }