Files
cloudpods/pkg/multicloud/huaweistack/elasticcache_instance.go
T
2021-08-12 14:33:44 +08:00

752 lines
23 KiB
Go

// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package huaweistack
import (
"fmt"
"strconv"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
"yunion.io/x/onecloud/pkg/util/billing"
)
// https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423020.html
type SElasticcache struct {
multicloud.SElasticcacheBase
multicloud.HuaweiTags
region *SRegion
Name string `json:"name"`
Engine string `json:"engine"`
CapacityGB int `json:"capacity"`
IP string `json:"ip"`
DomainName string `json:"domainName"`
Port int `json:"port"`
Status string `json:"status"`
Libos bool `json:"libos"`
Description string `json:"description"`
Task string `json:"task"`
MaxMemoryMB int `json:"max_memory"`
UsedMemoryMB int `json:"used_memory"`
InstanceID string `json:"instance_id"`
ResourceSpecCode string `json:"resource_spec_code"`
EngineVersion string `json:"engine_version"`
InternalVersion string `json:"internal_version"`
ChargingMode int `json:"charging_mode"`
CapacityMinor string `json:"capacity_minor"`
VpcID string `json:"vpc_id"`
VpcName string `json:"vpc_name"`
TaskStatus string `json:"task_status"`
CreatedAt string `json:"created_at"`
ErrorCode string `json:"error_code"`
UserID string `json:"user_id"`
UserName string `json:"user_name"`
MaintainBegin string `json:"maintain_begin"`
MaintainEnd string `json:"maintain_end"`
NoPasswordAccess string `json:"no_password_access"`
AccessUser string `json:"access_user"`
EnablePublicip bool `json:"enable_publicip"`
PublicipID string `json:"publicip_id"`
PublicipAddress string `json:"publicip_address"`
EnableSSL bool `json:"enable_ssl"`
ServiceUpgrade bool `json:"service_upgrade"`
ServiceTaskID string `json:"service_task_id"`
IsFree string `json:"is_free"`
EnterpriseProjectID string `json:"enterprise_project_id"`
AvailableZones []string `json:"available_zones"`
SubnetID string `json:"subnet_id"`
SecurityGroupID string `json:"security_group_id"`
BackendAddrs []string `json:"backend_addrs"`
ProductID string `json:"product_id"`
SecurityGroupName string `json:"security_group_name"`
SubnetName string `json:"subnet_name"`
OrderID string `json:"order_id"`
SubnetCIDR string `json:"subnet_cidr"`
InstanceBackupPolicy string `json:"instance_backup_policy"`
EnterpriseProjectName string `json:"enterprise_project_name"`
}
func (self *SElasticcache) GetId() string {
return self.InstanceID
}
func (self *SElasticcache) GetName() string {
return self.Name
}
func (self *SElasticcache) GetGlobalId() string {
return self.GetId()
}
func (self *SElasticcache) GetProjectId() string {
return self.EnterpriseProjectID
}
func (self *SElasticcache) Refresh() error {
cache, err := self.region.GetElasticCache(self.GetId())
if err != nil {
return errors.Wrap(err, "Elasticcache.Refresh.GetElasticCache")
}
err = jsonutils.Update(self, cache)
if err != nil {
return errors.Wrap(err, "Elasticcache.Refresh.Update")
}
return nil
}
func (self *SElasticcache) GetStatus() string {
switch self.Status {
case "RUNNING":
return api.ELASTIC_CACHE_STATUS_RUNNING
case "CREATING":
return api.ELASTIC_CACHE_STATUS_DEPLOYING
case "CREATEFAILED":
return api.ELASTIC_CACHE_STATUS_CREATE_FAILED
case "ERROR":
return api.ELASTIC_CACHE_STATUS_ERROR
case "RESTARTING":
return api.ELASTIC_CACHE_STATUS_RESTARTING
case "FROZEN":
return api.ELASTIC_CACHE_STATUS_UNAVAILABLE
case "EXTENDING":
return api.ELASTIC_CACHE_STATUS_CHANGING
case "RESTORING":
return api.ELASTIC_CACHE_STATUS_TRANSFORMING // ?
case "FLUSHING":
return api.ELASTIC_CACHE_STATUS_FLUSHING
}
return ""
}
func (self *SElasticcache) GetBillingType() string {
// charging_mode “0”:按需计费 “1”:按包年包月计费
if self.ChargingMode == 1 {
return billing_api.BILLING_TYPE_PREPAID
} else {
return billing_api.BILLING_TYPE_POSTPAID
}
}
func (self *SElasticcache) GetCreatedAt() time.Time {
var createtime time.Time
if len(self.CreatedAt) > 0 {
createtime, _ = time.Parse("2006-01-02T15:04:05.000Z", self.CreatedAt)
}
return createtime
}
func (self *SElasticcache) GetExpiredAt() time.Time {
var expiredTime time.Time
return expiredTime
}
func (self *SElasticcache) GetInstanceType() string {
// todo: ??
return self.ResourceSpecCode
}
func (self *SElasticcache) GetCapacityMB() int {
return self.CapacityGB * 1024
}
func (self *SElasticcache) GetArchType() string {
/*
资源规格标识。
dcs.single_node:表示实例类型为单机
dcs.master_standby:表示实例类型为主备
dcs.cluster:表示实例类型为集群
*/
if strings.Contains(self.ResourceSpecCode, "single") {
return api.ELASTIC_CACHE_ARCH_TYPE_SINGLE
} else if strings.Contains(self.ResourceSpecCode, "ha") {
return api.ELASTIC_CACHE_ARCH_TYPE_MASTER
} else if strings.Contains(self.ResourceSpecCode, "cluster") {
return api.ELASTIC_CACHE_ARCH_TYPE_CLUSTER
} else if strings.Contains(self.ResourceSpecCode, "proxy") {
return api.ELASTIC_CACHE_ARCH_TYPE_CLUSTER
}
return ""
}
func (self *SElasticcache) GetNodeType() string {
// single(单副本) | double(双副本)
if strings.Contains(self.ResourceSpecCode, "single") {
return "single"
} else {
return "double"
}
}
func (self *SElasticcache) GetEngine() string {
return self.Engine
}
func (self *SElasticcache) GetEngineVersion() string {
return self.EngineVersion
}
func (self *SElasticcache) GetVpcId() string {
return self.VpcID
}
func (self *SElasticcache) GetZoneId() string {
if len(self.AvailableZones) > 0 {
zone, err := self.region.getZoneById(self.AvailableZones[0])
if err != nil {
log.Errorf("elasticcache.GetZoneId %s", err)
return ""
}
return zone.GetGlobalId()
}
return ""
}
func (self *SElasticcache) GetNetworkType() string {
return api.LB_NETWORK_TYPE_VPC
}
func (self *SElasticcache) GetNetworkId() string {
return self.SubnetID
}
func (self *SElasticcache) GetPrivateDNS() string {
return self.DomainName
}
func (self *SElasticcache) GetPrivateIpAddr() string {
return self.IP
}
func (self *SElasticcache) GetPrivateConnectPort() int {
return self.Port
}
func (self *SElasticcache) GetPublicDNS() string {
return self.PublicipAddress
}
func (self *SElasticcache) GetPublicIpAddr() string {
return self.PublicipAddress
}
func (self *SElasticcache) GetPublicConnectPort() int {
return self.Port
}
func (self *SElasticcache) GetMaintainStartTime() string {
return self.MaintainBegin
}
func (self *SElasticcache) GetMaintainEndTime() string {
return self.MaintainEnd
}
func (self *SElasticcache) GetICloudElasticcacheAccounts() ([]cloudprovider.ICloudElasticcacheAccount, error) {
iaccounts := []cloudprovider.ICloudElasticcacheAccount{}
iaccount := &SElasticcacheAccount{cacheDB: self}
iaccounts = append(iaccounts, iaccount)
return iaccounts, nil
}
func (self *SElasticcache) GetICloudElasticcacheAcls() ([]cloudprovider.ICloudElasticcacheAcl, error) {
// 华为云使用安全组做访问控制。目前未支持
return []cloudprovider.ICloudElasticcacheAcl{}, nil
}
func (self *SElasticcache) GetICloudElasticcacheBackups() ([]cloudprovider.ICloudElasticcacheBackup, error) {
start := self.GetCreatedAt().Format("20060102150405")
end := time.Now().Format("20060102150405")
backups, err := self.region.GetElasticCacheBackups(self.GetId(), start, end)
if err != nil {
return nil, err
}
ibackups := make([]cloudprovider.ICloudElasticcacheBackup, len(backups))
for i := range backups {
backups[i].cacheDB = self
ibackups[i] = &backups[i]
}
return ibackups, nil
}
func (self *SElasticcache) GetICloudElasticcacheParameters() ([]cloudprovider.ICloudElasticcacheParameter, error) {
parameters, err := self.region.GetElasticCacheParameters(self.GetId())
if err != nil {
return nil, err
}
iparameters := make([]cloudprovider.ICloudElasticcacheParameter, len(parameters))
for i := range parameters {
parameters[i].cacheDB = self
iparameters[i] = &parameters[i]
}
return iparameters, nil
}
// https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423035.html
func (self *SRegion) GetElasticCacheBackups(instanceId, startTime, endTime string) ([]SElasticcacheBackup, error) {
params := make(map[string]string)
params["instance_id"] = instanceId
params["beginTime"] = startTime
params["endTime"] = endTime
backups := make([]SElasticcacheBackup, 0)
err := doListAll(self.ecsClient.Elasticcache.ListBackups, params, &backups)
if err != nil {
return nil, err
}
return backups, nil
}
// https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423027.html
func (self *SRegion) GetElasticCacheParameters(instanceId string) ([]SElasticcacheParameter, error) {
params := make(map[string]string)
params["instance_id"] = instanceId
parameters := make([]SElasticcacheParameter, 0)
err := doListAll(self.ecsClient.Elasticcache.ListParameters, params, &parameters)
if err != nil {
return nil, err
}
return parameters, nil
}
// https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423044.html
func (self *SRegion) GetElasticCaches() ([]SElasticcache, error) {
params := make(map[string]string)
caches := make([]SElasticcache, 0)
err := doListAll(self.ecsClient.Elasticcache.List, params, &caches)
if err != nil {
return nil, errors.Wrap(err, "region.GetElasticCaches")
}
for i := range caches {
cache, err := self.GetElasticCache(caches[i].GetId())
if err != nil {
return nil, err
} else {
caches[i] = *cache
}
caches[i].region = self
}
return caches, nil
}
// https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423020.html
func (self *SRegion) GetElasticCache(instanceId string) (*SElasticcache, error) {
cache := SElasticcache{}
err := DoGet(self.ecsClient.Elasticcache.Get, instanceId, nil, &cache)
if err != nil {
return nil, errors.Wrapf(err, "region.GetElasticCache %s", instanceId)
}
cache.region = self
return &cache, nil
}
func (self *SRegion) GetIElasticcacheById(id string) (cloudprovider.ICloudElasticcache, error) {
ec, err := self.GetElasticCache(id)
if err != nil {
return nil, errors.Wrap(err, "region.GetIElasticCacheById.GetElasticCache")
}
return ec, nil
}
// https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423047.html
func (self *SRegion) zoneNameToDcsZoneIds(zoneIds []string) ([]string, error) {
type Z struct {
ID string `json:"id"`
Code string `json:"code"`
Name string `json:"name"`
Port string `json:"port"`
ResourceAvailability string `json:"resource_availability"`
}
rs := []Z{}
err := doListAll(self.ecsClient.DcsAvailableZone.List, nil, &rs)
if err != nil {
return nil, errors.Wrap(err, "region.zoneNameToDcsZoneIds")
}
zoneMap := map[string]string{}
for i := range rs {
if rs[i].ResourceAvailability == "true" {
zoneMap[rs[i].Code] = rs[i].ID
}
}
ret := []string{}
for _, zone := range zoneIds {
if id, ok := zoneMap[zone]; ok {
ret = append(ret, id)
} else {
return nil, errors.Wrap(fmt.Errorf("zone %s not found or not available", zone), "region.zoneNameToDcsZoneIds")
}
}
return ret, nil
}
// https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423019.html
func (self *SRegion) CreateIElasticcaches(ec *cloudprovider.SCloudElasticCacheInput) (cloudprovider.ICloudElasticcache, error) {
params := jsonutils.NewDict()
params.Set("name", jsonutils.NewString(ec.InstanceName))
params.Set("engine", jsonutils.NewString(ec.Engine))
params.Set("engine_version", jsonutils.NewString(ec.EngineVersion))
params.Set("capacity", jsonutils.NewInt(ec.CapacityGB))
params.Set("vpc_id", jsonutils.NewString(ec.VpcId))
if len(ec.SecurityGroupIds) > 0 {
params.Set("security_group_id", jsonutils.NewString(ec.SecurityGroupIds[0]))
}
params.Set("subnet_id", jsonutils.NewString(ec.NetworkId))
params.Set("product_id", jsonutils.NewString(ec.InstanceType))
zones, err := self.zoneNameToDcsZoneIds(ec.ZoneIds)
if err != nil {
return nil, err
}
params.Set("available_zones", jsonutils.NewStringArray(zones))
if len(ec.ProjectId) > 0 {
params.Set("enterprise_project_id", jsonutils.NewString(ec.ProjectId))
}
if len(ec.Password) > 0 {
params.Set("no_password_access", jsonutils.NewString("false"))
params.Set("password", jsonutils.NewString(ec.Password))
// todo: 这里换成常量
if ec.Engine == "Memcache" {
params.Set("access_user", jsonutils.NewString(ec.UserName))
}
} else {
params.Set("no_password_access", jsonutils.NewString("true"))
}
if len(ec.EipId) > 0 {
params.Set("enable_publicip", jsonutils.NewString("true"))
params.Set("publicip_id", jsonutils.NewString(ec.EipId))
// enable_ssl
} else {
params.Set("enable_publicip", jsonutils.NewString("false"))
}
if len(ec.PrivateIpAddress) > 0 {
params.Set("private_ip", jsonutils.NewString(ec.PrivateIpAddress))
}
if len(ec.MaintainBegin) > 0 {
params.Set("maintain_begin", jsonutils.NewString(ec.MaintainBegin))
params.Set("maintain_end", jsonutils.NewString(ec.MaintainEnd))
}
if strings.ToLower(ec.ChargeType) == billing_api.BILLING_TYPE_PREPAID && ec.BC != nil {
bssParam := jsonutils.NewDict()
bssParam.Set("charging_mode", jsonutils.NewString("prePaid"))
bssParam.Set("is_auto_pay", jsonutils.NewString("true"))
bssParam.Set("is_auto_renew", jsonutils.NewString(fmt.Sprintf("%v", ec.BC.AutoRenew)))
if ec.BC.GetMonths() >= 1 && ec.BC.GetMonths() >= 9 {
bssParam.Set("period_type", jsonutils.NewString("month"))
bssParam.Set("period_num", jsonutils.NewInt(int64(ec.BC.GetMonths())))
} else if ec.BC.GetYears() >= 1 && ec.BC.GetYears() <= 3 {
bssParam.Set("period_type", jsonutils.NewString("year"))
bssParam.Set("period_num", jsonutils.NewInt(int64(ec.BC.GetYears())))
} else {
return nil, fmt.Errorf("region.CreateIElasticcaches invalid billing cycle.reqired month (1~9) or year(1~3)")
}
params.Set("bss_param", bssParam)
}
ret := &SElasticcache{}
err = DoCreate(self.ecsClient.Elasticcache.Create, params, ret)
if err != nil {
return nil, errors.Wrap(err, "region.CreateIElasticcaches")
}
ret.region = self
return ret, nil
}
// https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423030.html
func (self *SElasticcache) Restart() error {
resp, err := self.region.ecsClient.Elasticcache.Restart(self.GetId())
if err != nil {
return errors.Wrap(err, "elasticcache.Restart")
}
rets, err := resp.GetArray("results")
if err != nil {
return errors.Wrap(err, "elasticcache.results")
}
for _, r := range rets {
if ret, _ := r.GetString("result"); ret != "success" {
return fmt.Errorf("elasticcache.Restart failed")
}
}
return nil
}
// https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423022.html
func (self *SElasticcache) Delete() error {
err := DoDelete(self.region.ecsClient.Elasticcache.Delete, self.GetId(), nil, nil)
if err != nil {
return errors.Wrap(err, "elasticcache.Delete")
}
return nil
}
// https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423024.html
func (self *SElasticcache) ChangeInstanceSpec(spec string) error {
segs := strings.Split(spec, ":")
if len(segs) < 2 {
return fmt.Errorf("elasticcache.ChangeInstanceSpec invalid sku %s", spec)
}
if !strings.HasPrefix(segs[1], "m") || !strings.HasSuffix(segs[1], "g") {
return fmt.Errorf("elasticcache.ChangeInstanceSpec sku %s memeory size is invalid.", spec)
}
newCapacity := segs[1][1 : len(segs[1])-1]
capacity, err := strconv.Atoi(newCapacity)
if err != nil {
return errors.Wrap(fmt.Errorf("invalid sku capacity %s", spec), "Elasticcache.ChangeInstanceSpec")
}
_, err = self.region.ecsClient.Elasticcache.ChangeInstanceSpec(self.GetId(), segs[0], int64(capacity))
if err != nil {
return errors.Wrap(err, "elasticcache.ChangeInstanceSpec")
}
return nil
}
// https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423021.html
func (self *SElasticcache) SetMaintainTime(maintainStartTime, maintainEndTime string) error {
params := jsonutils.NewDict()
params.Set("maintain_begin", jsonutils.NewString(maintainStartTime))
params.Set("maintain_end", jsonutils.NewString(maintainEndTime))
err := DoUpdate(self.region.ecsClient.Elasticcache.Update, self.GetId(), params, nil)
if err != nil {
return errors.Wrap(err, "elasticcache.SetMaintainTime")
}
return nil
}
// https://support.huaweicloud.com/usermanual-dcs/dcs-zh-ug-180314001.html
// 目前只有Redis3.0版本密码模式的实例支持通过公网访问Redis实例,其他版本暂不支持公网访问。
// todo: 目前没找到api
func (self *SElasticcache) AllocatePublicConnection(port int) (string, error) {
return "", cloudprovider.ErrNotSupported
}
// todo: 目前没找到api
func (self *SElasticcache) ReleasePublicConnection() error {
return cloudprovider.ErrNotSupported
}
func (self *SElasticcache) CreateAccount(account cloudprovider.SCloudElasticCacheAccountInput) (cloudprovider.ICloudElasticcacheAccount, error) {
return nil, cloudprovider.ErrNotSupported
}
// https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423031.html
func (self *SElasticcache) CreateAcl(aclName, securityIps string) (cloudprovider.ICloudElasticcacheAcl, error) {
return nil, cloudprovider.ErrNotSupported
}
// https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423029.html
func (self *SElasticcache) UpdateInstanceParameters(config jsonutils.JSONObject) error {
params := jsonutils.NewDict()
params.Set("redis_config", config)
err := DoUpdateWithSpec(self.region.ecsClient.Elasticcache.UpdateInContextWithSpec, self.GetId(), "configs", params)
if err != nil {
return errors.Wrap(err, "elasticcache.UpdateInstanceParameters")
}
return nil
}
// https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423033.html
func (self *SElasticcache) CreateBackup(desc string) (cloudprovider.ICloudElasticcacheBackup, error) {
return nil, cloudprovider.ErrNotSupported
}
func backupPeriodTrans(config cloudprovider.SCloudElasticCacheBackupPolicyUpdateInput) *jsonutils.JSONArray {
segs := strings.Split(config.PreferredBackupPeriod, ",")
ret := jsonutils.NewArray()
for _, seg := range segs {
switch seg {
case "Monday":
ret.Add(jsonutils.NewString("1"))
case "Tuesday":
ret.Add(jsonutils.NewString("2"))
case "Wednesday":
ret.Add(jsonutils.NewString("3"))
case "Thursday":
ret.Add(jsonutils.NewString("4"))
case "Friday":
ret.Add(jsonutils.NewString("5"))
case "Saturday":
ret.Add(jsonutils.NewString("6"))
case "Sunday":
ret.Add(jsonutils.NewString("7"))
}
}
return ret
}
// https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423021.html
func (self *SElasticcache) UpdateBackupPolicy(config cloudprovider.SCloudElasticCacheBackupPolicyUpdateInput) error {
params := jsonutils.NewDict()
policy := jsonutils.NewDict()
policy.Set("save_days", jsonutils.NewInt(int64(config.BackupReservedDays)))
policy.Set("backup_type", jsonutils.NewString(config.BackupType))
plan := jsonutils.NewDict()
backTime := strings.ReplaceAll(config.PreferredBackupTime, "Z", "")
backupPeriod := backupPeriodTrans(config)
plan.Set("begin_at", jsonutils.NewString(backTime))
plan.Set("period_type", jsonutils.NewString("weekly"))
plan.Set("backup_at", backupPeriod)
policy.Set("periodical_backup_plan", plan)
params.Set("instance_backup_policy", policy)
err := DoUpdateWithSpec(self.region.ecsClient.Elasticcache.UpdateInContextWithSpec, self.GetId(), "configs", params)
if err != nil {
return errors.Wrap(err, "elasticcache.UpdateInstanceParameters")
}
return nil
}
// https://support.huaweicloud.com/api-dcs/dcs-zh-api-180423030.html
// 当前版本,只有DCS2.0实例支持清空数据功能,即flush操作。
func (self *SElasticcache) FlushInstance(input cloudprovider.SCloudElasticCacheFlushInstanceInput) error {
resp, err := self.region.ecsClient.Elasticcache.Flush(self.GetId())
if err != nil {
return errors.Wrap(err, "elasticcache.FlushInstance")
}
rets, err := resp.GetArray("results")
if err != nil {
return errors.Wrap(err, "elasticcache.FlushInstance")
}
for _, r := range rets {
if ret, _ := r.GetString("result"); ret != "success" {
return fmt.Errorf("elasticcache.FlushInstance failed")
}
}
return nil
}
// SElasticcacheAccount => ResetPassword
func (self *SElasticcache) UpdateAuthMode(noPwdAccess bool, password string) error {
return cloudprovider.ErrNotSupported
}
func (self *SElasticcache) GetAuthMode() string {
switch self.NoPasswordAccess {
case "true":
return "off"
default:
return "on"
}
}
func (self *SElasticcache) GetSecurityGroupIds() ([]string, error) {
return nil, cloudprovider.ErrNotSupported
}
func (self *SElasticcache) GetICloudElasticcacheAccount(accountId string) (cloudprovider.ICloudElasticcacheAccount, error) {
accounts, err := self.GetICloudElasticcacheAccounts()
if err != nil {
return nil, errors.Wrap(err, "Elasticcache.GetICloudElasticcacheAccount.Accounts")
}
for i := range accounts {
account := accounts[i]
if account.GetGlobalId() == accountId {
return account, nil
}
}
return nil, cloudprovider.ErrNotFound
}
func (self *SElasticcache) GetICloudElasticcacheAcl(aclId string) (cloudprovider.ICloudElasticcacheAcl, error) {
return nil, cloudprovider.ErrNotSupported
}
func (self *SElasticcache) GetICloudElasticcacheBackup(backupId string) (cloudprovider.ICloudElasticcacheBackup, error) {
backups, err := self.GetICloudElasticcacheBackups()
if err != nil {
return nil, err
}
for _, backup := range backups {
if backup.GetId() == backupId {
return backup, nil
}
}
return nil, cloudprovider.ErrNotFound
}
func (instance *SElasticcache) SetTags(tags map[string]string, replace bool) error {
return cloudprovider.ErrNotImplemented
}
func (self *SElasticcache) UpdateSecurityGroups(secgroupIds []string) error {
return errors.Wrap(cloudprovider.ErrNotSupported, "UpdateSecurityGroups")
}
func (self *SElasticcache) Renew(bc billing.SBillingCycle) error {
return cloudprovider.ErrNotSupported
}
func (self *SElasticcache) SetAutoRenew(autoRenew bool) error {
return cloudprovider.ErrNotSupported
}