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 }