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