yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/huawei/elasticcache_instance.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 huawei 16 17 import ( 18 "fmt" 19 "strconv" 20 "strings" 21 "time" 22 23 "yunion.io/x/jsonutils" 24 "yunion.io/x/log" 25 "yunion.io/x/pkg/errors" 26 27 billing_api "yunion.io/x/cloudmux/pkg/apis/billing" 28 api "yunion.io/x/cloudmux/pkg/apis/compute" 29 "yunion.io/x/cloudmux/pkg/cloudprovider" 30 "yunion.io/x/cloudmux/pkg/multicloud" 31 "yunion.io/x/onecloud/pkg/util/billing" 32 ) 33 34 // https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423020.html 35 type SElasticcache struct { 36 multicloud.SElasticcacheBase 37 HuaweiTags 38 39 region *SRegion 40 41 Name string `json:"name"` 42 Engine string `json:"engine"` 43 CapacityGB int `json:"capacity"` 44 IP string `json:"ip"` 45 DomainName string `json:"domainName"` 46 Port int `json:"port"` 47 Status string `json:"status"` 48 Libos bool `json:"libos"` 49 Description string `json:"description"` 50 Task string `json:"task"` 51 MaxMemoryMB int `json:"max_memory"` 52 UsedMemoryMB int `json:"used_memory"` 53 InstanceID string `json:"instance_id"` 54 ResourceSpecCode string `json:"resource_spec_code"` 55 EngineVersion string `json:"engine_version"` 56 InternalVersion string `json:"internal_version"` 57 ChargingMode int `json:"charging_mode"` 58 CapacityMinor string `json:"capacity_minor"` 59 VpcID string `json:"vpc_id"` 60 VpcName string `json:"vpc_name"` 61 TaskStatus string `json:"task_status"` 62 CreatedAt string `json:"created_at"` 63 ErrorCode string `json:"error_code"` 64 UserID string `json:"user_id"` 65 UserName string `json:"user_name"` 66 MaintainBegin string `json:"maintain_begin"` 67 MaintainEnd string `json:"maintain_end"` 68 NoPasswordAccess string `json:"no_password_access"` 69 AccessUser string `json:"access_user"` 70 EnablePublicip bool `json:"enable_publicip"` 71 PublicipID string `json:"publicip_id"` 72 PublicipAddress string `json:"publicip_address"` 73 EnableSSL bool `json:"enable_ssl"` 74 ServiceUpgrade bool `json:"service_upgrade"` 75 ServiceTaskID string `json:"service_task_id"` 76 IsFree string `json:"is_free"` 77 EnterpriseProjectID string `json:"enterprise_project_id"` 78 AvailableZones []string `json:"available_zones"` 79 SubnetID string `json:"subnet_id"` 80 SecurityGroupID string `json:"security_group_id"` 81 BackendAddrs []string `json:"backend_addrs"` 82 ProductID string `json:"product_id"` 83 SecurityGroupName string `json:"security_group_name"` 84 SubnetName string `json:"subnet_name"` 85 OrderID string `json:"order_id"` 86 SubnetCIDR string `json:"subnet_cidr"` 87 InstanceBackupPolicy string `json:"instance_backup_policy"` 88 EnterpriseProjectName string `json:"enterprise_project_name"` 89 } 90 91 func (self *SElasticcache) GetId() string { 92 return self.InstanceID 93 } 94 95 func (self *SElasticcache) GetName() string { 96 return self.Name 97 } 98 99 func (self *SElasticcache) GetGlobalId() string { 100 return self.GetId() 101 } 102 103 func (self *SElasticcache) GetProjectId() string { 104 return self.EnterpriseProjectID 105 } 106 107 func (self *SElasticcache) Refresh() error { 108 cache, err := self.region.GetElasticCache(self.GetId()) 109 if err != nil { 110 return errors.Wrap(err, "Elasticcache.Refresh.GetElasticCache") 111 } 112 113 err = jsonutils.Update(self, cache) 114 if err != nil { 115 return errors.Wrap(err, "Elasticcache.Refresh.Update") 116 } 117 118 return nil 119 } 120 121 func (self *SElasticcache) GetStatus() string { 122 switch self.Status { 123 case "RUNNING": 124 return api.ELASTIC_CACHE_STATUS_RUNNING 125 case "CREATING": 126 return api.ELASTIC_CACHE_STATUS_DEPLOYING 127 case "CREATEFAILED": 128 return api.ELASTIC_CACHE_STATUS_CREATE_FAILED 129 case "ERROR": 130 return api.ELASTIC_CACHE_STATUS_ERROR 131 case "RESTARTING": 132 return api.ELASTIC_CACHE_STATUS_RESTARTING 133 case "FROZEN": 134 return api.ELASTIC_CACHE_STATUS_UNAVAILABLE 135 case "EXTENDING": 136 return api.ELASTIC_CACHE_STATUS_CHANGING 137 case "RESTORING": 138 return api.ELASTIC_CACHE_STATUS_TRANSFORMING // ? 139 case "FLUSHING": 140 return api.ELASTIC_CACHE_STATUS_FLUSHING 141 } 142 143 return "" 144 } 145 146 func (self *SElasticcache) GetBillingType() string { 147 // charging_mode “0”:按需计费 “1”:按包年包月计费 148 if self.ChargingMode == 1 { 149 return billing_api.BILLING_TYPE_PREPAID 150 } else { 151 return billing_api.BILLING_TYPE_POSTPAID 152 } 153 } 154 155 func (self *SElasticcache) GetCreatedAt() time.Time { 156 var createtime time.Time 157 if len(self.CreatedAt) > 0 { 158 createtime, _ = time.Parse("2006-01-02T15:04:05.000Z", self.CreatedAt) 159 } 160 161 return createtime 162 } 163 164 func (self *SElasticcache) GetExpiredAt() time.Time { 165 var expiredTime time.Time 166 if self.ChargingMode == 1 { 167 res, err := self.region.GetOrderResourceDetail(self.GetId()) 168 if err != nil { 169 log.Debugln(err) 170 } 171 172 expiredTime = res.ExpireTime 173 } 174 175 return expiredTime 176 } 177 178 func (self *SElasticcache) GetInstanceType() string { 179 // todo: ?? 180 return self.ResourceSpecCode 181 } 182 183 func (self *SElasticcache) GetCapacityMB() int { 184 return self.CapacityGB * 1024 185 } 186 187 func (self *SElasticcache) GetArchType() string { 188 /* 189 资源规格标识。 190 191 dcs.single_node:表示实例类型为单机 192 dcs.master_standby:表示实例类型为主备 193 dcs.cluster:表示实例类型为集群 194 */ 195 if strings.Contains(self.ResourceSpecCode, "single") { 196 return api.ELASTIC_CACHE_ARCH_TYPE_SINGLE 197 } else if strings.Contains(self.ResourceSpecCode, "ha") { 198 return api.ELASTIC_CACHE_ARCH_TYPE_MASTER 199 } else if strings.Contains(self.ResourceSpecCode, "cluster") { 200 return api.ELASTIC_CACHE_ARCH_TYPE_CLUSTER 201 } else if strings.Contains(self.ResourceSpecCode, "proxy") { 202 return api.ELASTIC_CACHE_ARCH_TYPE_CLUSTER 203 } 204 205 return "" 206 } 207 208 func (self *SElasticcache) GetNodeType() string { 209 // single(单副本) | double(双副本) 210 if strings.Contains(self.ResourceSpecCode, "single") { 211 return "single" 212 } else { 213 return "double" 214 } 215 } 216 217 func (self *SElasticcache) GetEngine() string { 218 return self.Engine 219 } 220 221 func (self *SElasticcache) GetEngineVersion() string { 222 return self.EngineVersion 223 } 224 225 func (self *SElasticcache) GetVpcId() string { 226 return self.VpcID 227 } 228 229 func (self *SElasticcache) GetZoneId() string { 230 if len(self.AvailableZones) > 0 { 231 zone, err := self.region.getZoneById(self.AvailableZones[0]) 232 if err != nil { 233 log.Errorf("elasticcache.GetZoneId %s", err) 234 return "" 235 } 236 237 return zone.GetGlobalId() 238 } 239 240 return "" 241 } 242 243 func (self *SElasticcache) GetNetworkType() string { 244 return api.LB_NETWORK_TYPE_VPC 245 } 246 247 func (self *SElasticcache) GetNetworkId() string { 248 return self.SubnetID 249 } 250 251 func (self *SElasticcache) GetPrivateDNS() string { 252 return self.DomainName 253 } 254 255 func (self *SElasticcache) GetPrivateIpAddr() string { 256 return self.IP 257 } 258 259 func (self *SElasticcache) GetPrivateConnectPort() int { 260 return self.Port 261 } 262 263 func (self *SElasticcache) GetPublicDNS() string { 264 return self.PublicipAddress 265 } 266 267 func (self *SElasticcache) GetPublicIpAddr() string { 268 return self.PublicipAddress 269 } 270 271 func (self *SElasticcache) GetPublicConnectPort() int { 272 return self.Port 273 } 274 275 func (self *SElasticcache) GetMaintainStartTime() string { 276 return self.MaintainBegin 277 } 278 279 func (self *SElasticcache) GetMaintainEndTime() string { 280 return self.MaintainEnd 281 } 282 283 func (self *SElasticcache) GetICloudElasticcacheAccounts() ([]cloudprovider.ICloudElasticcacheAccount, error) { 284 iaccounts := []cloudprovider.ICloudElasticcacheAccount{} 285 iaccount := &SElasticcacheAccount{cacheDB: self} 286 iaccounts = append(iaccounts, iaccount) 287 return iaccounts, nil 288 } 289 290 func (self *SElasticcache) GetICloudElasticcacheAcls() ([]cloudprovider.ICloudElasticcacheAcl, error) { 291 // 华为云使用安全组做访问控制。目前未支持 292 return []cloudprovider.ICloudElasticcacheAcl{}, nil 293 } 294 295 func (self *SElasticcache) GetICloudElasticcacheBackups() ([]cloudprovider.ICloudElasticcacheBackup, error) { 296 start := self.GetCreatedAt().Format("20060102150405") 297 end := time.Now().Format("20060102150405") 298 backups, err := self.region.GetElasticCacheBackups(self.GetId(), start, end) 299 if err != nil { 300 return nil, err 301 } 302 303 ibackups := make([]cloudprovider.ICloudElasticcacheBackup, len(backups)) 304 for i := range backups { 305 backups[i].cacheDB = self 306 ibackups[i] = &backups[i] 307 } 308 309 return ibackups, nil 310 } 311 312 func (self *SElasticcache) GetICloudElasticcacheParameters() ([]cloudprovider.ICloudElasticcacheParameter, error) { 313 parameters, err := self.region.GetElasticCacheParameters(self.GetId()) 314 if err != nil { 315 return nil, err 316 } 317 318 iparameters := make([]cloudprovider.ICloudElasticcacheParameter, len(parameters)) 319 for i := range parameters { 320 parameters[i].cacheDB = self 321 iparameters[i] = ¶meters[i] 322 } 323 324 return iparameters, nil 325 } 326 327 // https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423035.html 328 func (self *SRegion) GetElasticCacheBackups(instanceId, startTime, endTime string) ([]SElasticcacheBackup, error) { 329 params := make(map[string]string) 330 params["instance_id"] = instanceId 331 params["beginTime"] = startTime 332 params["endTime"] = endTime 333 334 backups := make([]SElasticcacheBackup, 0) 335 err := doListAll(self.ecsClient.Elasticcache.ListBackups, params, &backups) 336 if err != nil { 337 return nil, err 338 } 339 340 return backups, nil 341 } 342 343 // https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423027.html 344 func (self *SRegion) GetElasticCacheParameters(instanceId string) ([]SElasticcacheParameter, error) { 345 params := make(map[string]string) 346 params["instance_id"] = instanceId 347 348 parameters := make([]SElasticcacheParameter, 0) 349 err := doListAll(self.ecsClient.Elasticcache.ListParameters, params, ¶meters) 350 if err != nil { 351 return nil, err 352 } 353 354 return parameters, nil 355 } 356 357 // https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423044.html 358 func (self *SRegion) GetElasticCaches() ([]SElasticcache, error) { 359 params := make(map[string]string) 360 caches := make([]SElasticcache, 0) 361 err := doListAll(self.ecsClient.Elasticcache.List, params, &caches) 362 if err != nil { 363 return nil, errors.Wrap(err, "region.GetElasticCaches") 364 } 365 366 for i := range caches { 367 cache, err := self.GetElasticCache(caches[i].GetId()) 368 if err != nil { 369 return nil, err 370 } else { 371 caches[i] = *cache 372 } 373 374 caches[i].region = self 375 } 376 377 return caches, nil 378 } 379 380 // https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423020.html 381 func (self *SRegion) GetElasticCache(instanceId string) (*SElasticcache, error) { 382 cache := SElasticcache{} 383 err := DoGet(self.ecsClient.Elasticcache.Get, instanceId, nil, &cache) 384 if err != nil { 385 return nil, errors.Wrapf(err, "region.GetElasticCache %s", instanceId) 386 } 387 388 cache.region = self 389 return &cache, nil 390 } 391 392 func (self *SRegion) GetIElasticcacheById(id string) (cloudprovider.ICloudElasticcache, error) { 393 ec, err := self.GetElasticCache(id) 394 if err != nil { 395 return nil, errors.Wrap(err, "region.GetIElasticCacheById.GetElasticCache") 396 } 397 398 return ec, nil 399 } 400 401 // https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423047.html 402 func (self *SRegion) zoneNameToDcsZoneIds(zoneIds []string) ([]string, error) { 403 type Z struct { 404 ID string `json:"id"` 405 Code string `json:"code"` 406 Name string `json:"name"` 407 Port string `json:"port"` 408 ResourceAvailability string `json:"resource_availability"` 409 } 410 411 rs := []Z{} 412 err := doListAll(self.ecsClient.DcsAvailableZone.List, nil, &rs) 413 if err != nil { 414 return nil, errors.Wrap(err, "region.zoneNameToDcsZoneIds") 415 } 416 417 zoneMap := map[string]string{} 418 for i := range rs { 419 if rs[i].ResourceAvailability == "true" { 420 zoneMap[rs[i].Code] = rs[i].ID 421 } 422 } 423 424 ret := []string{} 425 for _, zone := range zoneIds { 426 if id, ok := zoneMap[zone]; ok { 427 ret = append(ret, id) 428 } else { 429 return nil, errors.Wrap(fmt.Errorf("zone %s not found or not available", zone), "region.zoneNameToDcsZoneIds") 430 } 431 } 432 433 return ret, nil 434 } 435 436 // https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423019.html 437 func (self *SRegion) CreateIElasticcaches(ec *cloudprovider.SCloudElasticCacheInput) (cloudprovider.ICloudElasticcache, error) { 438 params := jsonutils.NewDict() 439 params.Set("name", jsonutils.NewString(ec.InstanceName)) 440 params.Set("engine", jsonutils.NewString(ec.Engine)) 441 params.Set("engine_version", jsonutils.NewString(ec.EngineVersion)) 442 params.Set("capacity", jsonutils.NewInt(ec.CapacityGB)) 443 params.Set("vpc_id", jsonutils.NewString(ec.VpcId)) 444 if len(ec.SecurityGroupIds) > 0 { 445 params.Set("security_group_id", jsonutils.NewString(ec.SecurityGroupIds[0])) 446 } 447 params.Set("subnet_id", jsonutils.NewString(ec.NetworkId)) 448 params.Set("product_id", jsonutils.NewString(ec.InstanceType)) 449 zones, err := self.zoneNameToDcsZoneIds(ec.ZoneIds) 450 if err != nil { 451 return nil, err 452 } 453 params.Set("available_zones", jsonutils.NewStringArray(zones)) 454 455 if len(ec.ProjectId) > 0 { 456 params.Set("enterprise_project_id", jsonutils.NewString(ec.ProjectId)) 457 } 458 459 if len(ec.Password) > 0 { 460 params.Set("no_password_access", jsonutils.NewString("false")) 461 params.Set("password", jsonutils.NewString(ec.Password)) 462 463 // todo: 这里换成常量 464 if ec.Engine == "Memcache" { 465 params.Set("access_user", jsonutils.NewString(ec.UserName)) 466 } 467 } else { 468 params.Set("no_password_access", jsonutils.NewString("true")) 469 } 470 471 if len(ec.EipId) > 0 { 472 params.Set("enable_publicip", jsonutils.NewString("true")) 473 params.Set("publicip_id", jsonutils.NewString(ec.EipId)) 474 // enable_ssl 475 } else { 476 params.Set("enable_publicip", jsonutils.NewString("false")) 477 } 478 479 if len(ec.PrivateIpAddress) > 0 { 480 params.Set("private_ip", jsonutils.NewString(ec.PrivateIpAddress)) 481 } 482 483 if len(ec.MaintainBegin) > 0 { 484 params.Set("maintain_begin", jsonutils.NewString(ec.MaintainBegin)) 485 params.Set("maintain_end", jsonutils.NewString(ec.MaintainEnd)) 486 } 487 488 if ec.BillingCycle != nil { 489 bssParam := jsonutils.NewDict() 490 bssParam.Set("charging_mode", jsonutils.NewString("prePaid")) 491 bssParam.Set("is_auto_pay", jsonutils.NewString("true")) 492 bssParam.Set("is_auto_renew", jsonutils.NewString(fmt.Sprintf("%v", ec.BillingCycle.AutoRenew))) 493 if ec.BillingCycle.GetMonths() >= 1 && ec.BillingCycle.GetMonths() >= 9 { 494 bssParam.Set("period_type", jsonutils.NewString("month")) 495 bssParam.Set("period_num", jsonutils.NewInt(int64(ec.BillingCycle.GetMonths()))) 496 } else if ec.BillingCycle.GetYears() >= 1 && ec.BillingCycle.GetYears() <= 3 { 497 bssParam.Set("period_type", jsonutils.NewString("year")) 498 bssParam.Set("period_num", jsonutils.NewInt(int64(ec.BillingCycle.GetYears()))) 499 } else { 500 return nil, fmt.Errorf("region.CreateIElasticcaches invalid billing cycle.reqired month (1~9) or year(1~3)") 501 } 502 503 params.Set("bss_param", bssParam) 504 } 505 506 ret := &SElasticcache{} 507 err = DoCreate(self.ecsClient.Elasticcache.Create, params, ret) 508 if err != nil { 509 return nil, errors.Wrap(err, "region.CreateIElasticcaches") 510 } 511 512 ret.region = self 513 return ret, nil 514 } 515 516 // https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423030.html 517 func (self *SElasticcache) Restart() error { 518 resp, err := self.region.ecsClient.Elasticcache.Restart(self.GetId()) 519 if err != nil { 520 return errors.Wrap(err, "elasticcache.Restart") 521 } 522 523 rets, err := resp.GetArray("results") 524 if err != nil { 525 return errors.Wrap(err, "elasticcache.results") 526 } 527 528 for _, r := range rets { 529 if ret, _ := r.GetString("result"); ret != "success" { 530 return fmt.Errorf("elasticcache.Restart failed") 531 } 532 } 533 534 return nil 535 } 536 537 // https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423022.html 538 func (self *SElasticcache) Delete() error { 539 err := DoDelete(self.region.ecsClient.Elasticcache.Delete, self.GetId(), nil, nil) 540 if err != nil { 541 return errors.Wrap(err, "elasticcache.Delete") 542 } 543 544 return nil 545 } 546 547 // https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423024.html 548 func (self *SElasticcache) ChangeInstanceSpec(spec string) error { 549 segs := strings.Split(spec, ":") 550 if len(segs) < 2 { 551 return fmt.Errorf("elasticcache.ChangeInstanceSpec invalid sku %s", spec) 552 } 553 554 if !strings.HasPrefix(segs[1], "m") || !strings.HasSuffix(segs[1], "g") { 555 return fmt.Errorf("elasticcache.ChangeInstanceSpec sku %s memeory size is invalid.", spec) 556 } 557 558 newCapacity := segs[1][1 : len(segs[1])-1] 559 capacity, err := strconv.Atoi(newCapacity) 560 if err != nil { 561 return errors.Wrap(fmt.Errorf("invalid sku capacity %s", spec), "Elasticcache.ChangeInstanceSpec") 562 } 563 564 _, err = self.region.ecsClient.Elasticcache.ChangeInstanceSpec(self.GetId(), segs[0], int64(capacity)) 565 if err != nil { 566 return errors.Wrap(err, "elasticcache.ChangeInstanceSpec") 567 } 568 569 return nil 570 } 571 572 // https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423021.html 573 func (self *SElasticcache) SetMaintainTime(maintainStartTime, maintainEndTime string) error { 574 params := jsonutils.NewDict() 575 params.Set("maintain_begin", jsonutils.NewString(maintainStartTime)) 576 params.Set("maintain_end", jsonutils.NewString(maintainEndTime)) 577 err := DoUpdate(self.region.ecsClient.Elasticcache.Update, self.GetId(), params, nil) 578 if err != nil { 579 return errors.Wrap(err, "elasticcache.SetMaintainTime") 580 } 581 582 return nil 583 } 584 585 // https://support.huaweicloud.com/usermanual-dcs/dcs-zh-ug-180314001.html 586 // 目前只有Redis3.0版本密码模式的实例支持通过公网访问Redis实例,其他版本暂不支持公网访问。 587 // todo: 目前没找到api 588 func (self *SElasticcache) AllocatePublicConnection(port int) (string, error) { 589 return "", cloudprovider.ErrNotSupported 590 } 591 592 // todo: 目前没找到api 593 func (self *SElasticcache) ReleasePublicConnection() error { 594 return cloudprovider.ErrNotSupported 595 } 596 597 func (self *SElasticcache) CreateAccount(account cloudprovider.SCloudElasticCacheAccountInput) (cloudprovider.ICloudElasticcacheAccount, error) { 598 return nil, cloudprovider.ErrNotSupported 599 } 600 601 // https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423031.html 602 603 func (self *SElasticcache) CreateAcl(aclName, securityIps string) (cloudprovider.ICloudElasticcacheAcl, error) { 604 return nil, cloudprovider.ErrNotSupported 605 } 606 607 // https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423029.html 608 func (self *SElasticcache) UpdateInstanceParameters(config jsonutils.JSONObject) error { 609 params := jsonutils.NewDict() 610 params.Set("redis_config", config) 611 err := DoUpdateWithSpec(self.region.ecsClient.Elasticcache.UpdateInContextWithSpec, self.GetId(), "configs", params) 612 if err != nil { 613 return errors.Wrap(err, "elasticcache.UpdateInstanceParameters") 614 } 615 616 return nil 617 } 618 619 // https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423033.html 620 func (self *SElasticcache) CreateBackup(desc string) (cloudprovider.ICloudElasticcacheBackup, error) { 621 return nil, cloudprovider.ErrNotSupported 622 } 623 624 func backupPeriodTrans(config cloudprovider.SCloudElasticCacheBackupPolicyUpdateInput) *jsonutils.JSONArray { 625 segs := strings.Split(config.PreferredBackupPeriod, ",") 626 ret := jsonutils.NewArray() 627 for _, seg := range segs { 628 switch seg { 629 case "Monday": 630 ret.Add(jsonutils.NewString("1")) 631 case "Tuesday": 632 ret.Add(jsonutils.NewString("2")) 633 case "Wednesday": 634 ret.Add(jsonutils.NewString("3")) 635 case "Thursday": 636 ret.Add(jsonutils.NewString("4")) 637 case "Friday": 638 ret.Add(jsonutils.NewString("5")) 639 case "Saturday": 640 ret.Add(jsonutils.NewString("6")) 641 case "Sunday": 642 ret.Add(jsonutils.NewString("7")) 643 } 644 } 645 646 return ret 647 } 648 649 // https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423021.html 650 func (self *SElasticcache) UpdateBackupPolicy(config cloudprovider.SCloudElasticCacheBackupPolicyUpdateInput) error { 651 params := jsonutils.NewDict() 652 policy := jsonutils.NewDict() 653 policy.Set("save_days", jsonutils.NewInt(int64(config.BackupReservedDays))) 654 policy.Set("backup_type", jsonutils.NewString(config.BackupType)) 655 plan := jsonutils.NewDict() 656 backTime := strings.ReplaceAll(config.PreferredBackupTime, "Z", "") 657 backupPeriod := backupPeriodTrans(config) 658 plan.Set("begin_at", jsonutils.NewString(backTime)) 659 plan.Set("period_type", jsonutils.NewString("weekly")) 660 plan.Set("backup_at", backupPeriod) 661 policy.Set("periodical_backup_plan", plan) 662 params.Set("instance_backup_policy", policy) 663 err := DoUpdateWithSpec(self.region.ecsClient.Elasticcache.UpdateInContextWithSpec, self.GetId(), "configs", params) 664 if err != nil { 665 return errors.Wrap(err, "elasticcache.UpdateInstanceParameters") 666 } 667 668 return nil 669 } 670 671 // https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423030.html 672 // 当前版本,只有DCS2.0实例支持清空数据功能,即flush操作。 673 func (self *SElasticcache) FlushInstance(input cloudprovider.SCloudElasticCacheFlushInstanceInput) error { 674 resp, err := self.region.ecsClient.Elasticcache.Flush(self.GetId()) 675 if err != nil { 676 return errors.Wrap(err, "elasticcache.FlushInstance") 677 } 678 679 rets, err := resp.GetArray("results") 680 if err != nil { 681 return errors.Wrap(err, "elasticcache.FlushInstance") 682 } 683 684 for _, r := range rets { 685 if ret, _ := r.GetString("result"); ret != "success" { 686 return fmt.Errorf("elasticcache.FlushInstance failed") 687 } 688 } 689 690 return nil 691 } 692 693 // SElasticcacheAccount => ResetPassword 694 func (self *SElasticcache) UpdateAuthMode(noPwdAccess bool, password string) error { 695 return cloudprovider.ErrNotSupported 696 } 697 698 func (self *SElasticcache) GetAuthMode() string { 699 switch self.NoPasswordAccess { 700 case "true": 701 return "off" 702 default: 703 return "on" 704 } 705 } 706 707 func (self *SElasticcache) GetSecurityGroupIds() ([]string, error) { 708 return nil, cloudprovider.ErrNotSupported 709 } 710 711 func (self *SElasticcache) GetICloudElasticcacheAccount(accountId string) (cloudprovider.ICloudElasticcacheAccount, error) { 712 accounts, err := self.GetICloudElasticcacheAccounts() 713 if err != nil { 714 return nil, errors.Wrap(err, "Elasticcache.GetICloudElasticcacheAccount.Accounts") 715 } 716 717 for i := range accounts { 718 account := accounts[i] 719 if account.GetGlobalId() == accountId { 720 return account, nil 721 } 722 } 723 724 return nil, cloudprovider.ErrNotFound 725 } 726 727 func (self *SElasticcache) GetICloudElasticcacheAcl(aclId string) (cloudprovider.ICloudElasticcacheAcl, error) { 728 return nil, cloudprovider.ErrNotSupported 729 } 730 731 func (self *SElasticcache) GetICloudElasticcacheBackup(backupId string) (cloudprovider.ICloudElasticcacheBackup, error) { 732 backups, err := self.GetICloudElasticcacheBackups() 733 if err != nil { 734 return nil, err 735 } 736 737 for _, backup := range backups { 738 if backup.GetId() == backupId { 739 return backup, nil 740 } 741 } 742 743 return nil, cloudprovider.ErrNotFound 744 } 745 746 func (instance *SElasticcache) SetTags(tags map[string]string, replace bool) error { 747 return cloudprovider.ErrNotImplemented 748 } 749 750 func (self *SElasticcache) UpdateSecurityGroups(secgroupIds []string) error { 751 return errors.Wrap(cloudprovider.ErrNotSupported, "UpdateSecurityGroups") 752 } 753 754 func (self *SElasticcache) Renew(bc billing.SBillingCycle) error { 755 return cloudprovider.ErrNotSupported 756 } 757 758 func (self *SElasticcache) SetAutoRenew(bc billing.SBillingCycle) error { 759 return cloudprovider.ErrNotSupported 760 }