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