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 }