yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/aliyun/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 aliyun 16 17 import ( 18 "fmt" 19 "strconv" 20 "strings" 21 "time" 22 23 "github.com/aokoli/goutils" 24 "github.com/pkg/errors" 25 26 "yunion.io/x/jsonutils" 27 "yunion.io/x/log" 28 29 api "yunion.io/x/cloudmux/pkg/apis/compute" 30 "yunion.io/x/cloudmux/pkg/cloudprovider" 31 "yunion.io/x/cloudmux/pkg/multicloud" 32 "yunion.io/x/onecloud/pkg/util/billing" 33 ) 34 35 // https://help.aliyun.com/document_detail/60933.html?spm=a2c4g.11186623.6.726.38f82ca9U1Gtxw 36 type SElasticcache struct { 37 multicloud.SElasticcacheBase 38 AliyunTags 39 40 region *SRegion 41 attribute *SElasticcacheAttribute 42 netinfo []SNetInfo 43 44 Config string `json:"Config"` 45 HasRenewChangeOrder bool `json:"HasRenewChangeOrder"` 46 InstanceID string `json:"InstanceId"` 47 UserName string `json:"UserName"` 48 ArchitectureType string `json:"ArchitectureType"` 49 ZoneID string `json:"ZoneId"` 50 PrivateIP string `json:"PrivateIp"` 51 VSwitchID string `json:"VSwitchId"` 52 VpcID string `json:"VpcId"` 53 NetworkType string `json:"NetworkType"` 54 Qps int64 `json:"QPS"` 55 PackageType string `json:"PackageType"` 56 IsRDS bool `json:"IsRds"` 57 EngineVersion string `json:"EngineVersion"` 58 ConnectionDomain string `json:"ConnectionDomain"` 59 InstanceName string `json:"InstanceName"` 60 ReplacateID string `json:"ReplacateId"` 61 Bandwidth int64 `json:"Bandwidth"` 62 ChargeType TChargeType `json:"ChargeType"` 63 InstanceType string `json:"InstanceType"` 64 InstanceStatus string `json:"InstanceStatus"` 65 Port int `json:"Port"` 66 InstanceClass string `json:"InstanceClass"` 67 CreateTime time.Time `json:"CreateTime"` 68 EndTime time.Time `json:"EndTime"` 69 RegionID string `json:"RegionId"` 70 NodeType string `json:"NodeType"` 71 CapacityMB int `json:"Capacity"` 72 Connections int64 `json:"Connections"` 73 ResourceGroupId string `json:"ResourceGroupId"` 74 } 75 76 type SElasticcacheAttribute struct { 77 Config string `json:"Config"` 78 HasRenewChangeOrder string `json:"HasRenewChangeOrder"` 79 InstanceID string `json:"InstanceId"` 80 ZoneID string `json:"ZoneId"` 81 ArchitectureType string `json:"ArchitectureType"` 82 PrivateIP string `json:"PrivateIp"` 83 VSwitchID string `json:"VSwitchId"` 84 Engine string `json:"Engine"` 85 VpcID string `json:"VpcId"` 86 NetworkType string `json:"NetworkType"` 87 Qps int64 `json:"QPS"` 88 PackageType string `json:"PackageType"` 89 ReplicaID string `json:"ReplicaId"` 90 IsRDS bool `json:"IsRds"` 91 MaintainStartTime string `json:"MaintainStartTime"` 92 VpcAuthMode string `json:"VpcAuthMode"` 93 ConnectionDomain string `json:"ConnectionDomain"` 94 EngineVersion string `json:"EngineVersion"` 95 InstanceName string `json:"InstanceName"` 96 Bandwidth int64 `json:"Bandwidth"` 97 ChargeType TChargeType `json:"ChargeType"` 98 AuditLogRetention string `json:"AuditLogRetention"` 99 MaintainEndTime string `json:"MaintainEndTime"` 100 ReplicationMode string `json:"ReplicationMode"` 101 InstanceType string `json:"InstanceType"` 102 InstanceStatus string `json:"InstanceStatus"` 103 Port int64 `json:"Port"` 104 InstanceClass string `json:"InstanceClass"` 105 CreateTime time.Time `json:"CreateTime"` 106 NodeType string `json:"NodeType"` 107 RegionID string `json:"RegionId"` 108 AvailabilityValue string `json:"AvailabilityValue"` 109 CapacityMB int `json:"Capacity"` 110 Connections int64 `json:"Connections"` 111 SecurityIPList string `json:"SecurityIPList"` 112 } 113 114 type SNetInfo struct { 115 ConnectionString string `json:"ConnectionString"` 116 Port string `json:"Port"` 117 DBInstanceNetType string `json:"DBInstanceNetType"` 118 VPCID string `json:"VPCId"` 119 VPCInstanceID string `json:"VPCInstanceId"` 120 IPAddress string `json:"IPAddress"` 121 IPType string `json:"IPType"` 122 Upgradeable string `json:"Upgradeable"` 123 ExpiredTime *string `json:"ExpiredTime,omitempty"` 124 } 125 126 func (self *SElasticcache) GetId() string { 127 return self.InstanceID 128 } 129 130 func (self *SElasticcache) GetName() string { 131 if len(self.InstanceName) > 0 { 132 return self.InstanceName 133 } 134 135 return self.InstanceID 136 } 137 138 func (self *SElasticcache) GetGlobalId() string { 139 return self.GetId() 140 } 141 142 func (self *SElasticcache) GetStatus() string { 143 switch self.InstanceStatus { 144 case "Normal": 145 return api.ELASTIC_CACHE_STATUS_RUNNING 146 case "Creating": 147 return api.ELASTIC_CACHE_STATUS_DEPLOYING 148 case "Changing": 149 return api.ELASTIC_CACHE_STATUS_CHANGING 150 case "Inactive": 151 return api.ELASTIC_CACHE_STATUS_INACTIVE 152 case "Flushing": 153 return api.ELASTIC_CACHE_STATUS_FLUSHING 154 case "Released": 155 return api.ELASTIC_CACHE_STATUS_RELEASED 156 case "Transforming": 157 return api.ELASTIC_CACHE_STATUS_TRANSFORMING 158 case "Unavailable": 159 return api.ELASTIC_CACHE_STATUS_UNAVAILABLE 160 case "Error": 161 return api.ELASTIC_CACHE_STATUS_ERROR 162 case "Migrating": 163 return api.ELASTIC_CACHE_STATUS_MIGRATING 164 case "BackupRecovering": 165 return api.ELASTIC_CACHE_STATUS_BACKUPRECOVERING 166 case "MinorVersionUpgrading": 167 return api.ELASTIC_CACHE_STATUS_MINORVERSIONUPGRADING 168 case "NetworkModifying": 169 return api.ELASTIC_CACHE_STATUS_NETWORKMODIFYING 170 case "SSLModifying": 171 return api.ELASTIC_CACHE_STATUS_SSLMODIFYING 172 case "MajorVersionUpgrading": 173 return api.ELASTIC_CACHE_STATUS_MAJORVERSIONUPGRADING 174 default: 175 return api.ELASTIC_CACHE_STATUS_MAJORVERSIONUPGRADING 176 } 177 } 178 179 func (self *SElasticcache) Refresh() error { 180 cache, err := self.region.GetElasticCacheById(self.GetId()) 181 if err != nil { 182 return err 183 } 184 185 err = jsonutils.Update(self, cache) 186 if err != nil { 187 return err 188 } 189 190 return nil 191 } 192 193 func (self *SElasticcache) GetBillingType() string { 194 return convertChargeType(self.ChargeType) 195 } 196 197 func (self *SElasticcache) GetCreatedAt() time.Time { 198 return self.CreateTime 199 } 200 201 func (self *SElasticcache) GetExpiredAt() time.Time { 202 return convertExpiredAt(self.EndTime) 203 } 204 205 func (self *SElasticcache) GetInstanceType() string { 206 return self.InstanceClass 207 } 208 209 func (self *SElasticcache) GetCapacityMB() int { 210 return self.CapacityMB 211 } 212 213 func (self *SElasticcache) GetArchType() string { 214 switch self.ArchitectureType { 215 case "rwsplit": 216 return api.ELASTIC_CACHE_ARCH_TYPE_RWSPLIT 217 case "cluster": 218 return api.ELASTIC_CACHE_ARCH_TYPE_CLUSTER 219 case "standard": 220 if self.NodeType == "single" { 221 return api.ELASTIC_CACHE_ARCH_TYPE_SINGLE 222 } else if self.NodeType == "double" { 223 return api.ELASTIC_CACHE_ARCH_TYPE_MASTER 224 } 225 } 226 227 return "" 228 } 229 230 func (self *SElasticcache) GetNodeType() string { 231 return self.NodeType 232 } 233 234 func (self *SElasticcache) GetEngine() string { 235 return self.InstanceType 236 } 237 238 func (self *SElasticcache) GetEngineVersion() string { 239 return self.EngineVersion 240 } 241 242 func (self *SElasticcache) GetVpcId() string { 243 return self.VpcID 244 } 245 246 func (self *SElasticcache) GetZoneId() string { 247 zoneId := transZoneIdToEcsZoneId(self.region, "redis", self.ZoneID) 248 zone, err := self.region.getZoneById(fetchMasterZoneId(zoneId)) 249 if err != nil { 250 log.Errorf("failed to find zone for elasticcache %s error: %v", self.GetId(), err) 251 return "" 252 } 253 254 return zone.GetGlobalId() 255 } 256 257 func (self *SElasticcache) GetNetworkType() string { 258 switch self.NetworkType { 259 case "VPC": 260 return api.LB_NETWORK_TYPE_VPC 261 case "CLASSIC": 262 return api.LB_NETWORK_TYPE_CLASSIC 263 default: 264 return api.LB_NETWORK_TYPE_VPC 265 } 266 } 267 268 func (self *SElasticcache) GetNetworkId() string { 269 return self.VSwitchID 270 } 271 272 func (self *SElasticcache) GetPrivateDNS() string { 273 return self.ConnectionDomain 274 } 275 276 func (self *SElasticcache) GetPrivateIpAddr() string { 277 return self.PrivateIP 278 } 279 280 func (self *SElasticcache) GetPrivateConnectPort() int { 281 return self.Port 282 } 283 284 func (self *SElasticcache) GetPublicDNS() string { 285 pub, err := self.GetPublicNetInfo() 286 if err != nil { 287 log.Errorf("SElasticcache.GetPublicDNS %s", err) 288 return "" 289 } 290 291 if pub != nil { 292 return pub.ConnectionString 293 } 294 295 return "" 296 } 297 298 func (self *SElasticcache) GetPublicIpAddr() string { 299 pub, err := self.GetPublicNetInfo() 300 if err != nil { 301 log.Errorf("SElasticcache.GetPublicIpAddr %s", err) 302 } 303 304 if pub != nil { 305 return pub.IPAddress 306 } 307 308 return "" 309 } 310 311 func (self *SElasticcache) GetPublicConnectPort() int { 312 pub, err := self.GetPublicNetInfo() 313 if err != nil { 314 log.Errorf("SElasticcache.GetPublicConnectPort %s", err) 315 } 316 317 if pub != nil { 318 port, _ := strconv.Atoi(pub.Port) 319 return port 320 } 321 322 return 0 323 } 324 325 func (self *SElasticcache) GetMaintainStartTime() string { 326 attr, err := self.GetAttribute() 327 if err != nil { 328 log.Errorf("SElasticcache.GetMaintainStartTime %s", err) 329 } 330 331 if attr != nil { 332 return attr.MaintainStartTime 333 } 334 335 return "" 336 } 337 338 func (self *SElasticcache) GetBandwidth() int { 339 return int(self.Bandwidth) 340 } 341 342 func (self *SElasticcache) GetConnections() int { 343 attr, err := self.GetAttribute() 344 if err != nil { 345 log.Errorf("SElasticcache.GetMaintainEndTime %s", err) 346 } 347 348 if attr != nil { 349 return int(attr.Connections) 350 } 351 return 0 352 } 353 354 func (self *SElasticcache) GetMaintainEndTime() string { 355 attr, err := self.GetAttribute() 356 if err != nil { 357 log.Errorf("SElasticcache.GetMaintainEndTime %s", err) 358 } 359 360 if attr != nil { 361 return attr.MaintainEndTime 362 } 363 364 return "" 365 } 366 367 func (self *SElasticcache) GetICloudElasticcacheAccounts() ([]cloudprovider.ICloudElasticcacheAccount, error) { 368 accounts, err := self.region.GetElasticCacheAccounts(self.GetId()) 369 if err != nil { 370 return nil, err 371 } 372 373 iaccounts := make([]cloudprovider.ICloudElasticcacheAccount, len(accounts)) 374 for i := range accounts { 375 accounts[i].cacheDB = self 376 iaccounts[i] = &accounts[i] 377 } 378 379 return iaccounts, nil 380 } 381 382 func (self *SElasticcache) GetICloudElasticcacheAccountByName(accountName string) (cloudprovider.ICloudElasticcacheAccount, error) { 383 account, err := self.region.GetElasticCacheAccountByName(self.GetId(), accountName) 384 if err != nil { 385 return nil, err 386 } 387 388 account.cacheDB = self 389 return account, nil 390 } 391 392 func (self *SElasticcache) GetICloudElasticcacheAcls() ([]cloudprovider.ICloudElasticcacheAcl, error) { 393 acls, err := self.region.GetElasticCacheAcls(self.GetId()) 394 if err != nil { 395 return nil, err 396 } 397 398 iacls := make([]cloudprovider.ICloudElasticcacheAcl, len(acls)) 399 for i := range acls { 400 acls[i].cacheDB = self 401 iacls[i] = &acls[i] 402 } 403 404 return iacls, nil 405 } 406 407 func (self *SElasticcache) GetICloudElasticcacheBackups() ([]cloudprovider.ICloudElasticcacheBackup, error) { 408 start := self.CreateTime.Format("2006-01-02T15:04Z") 409 end := time.Now().Format("2006-01-02T15:04Z") 410 backups, err := self.region.GetElasticCacheBackups(self.GetId(), start, end) 411 if err != nil { 412 return nil, err 413 } 414 415 ibackups := make([]cloudprovider.ICloudElasticcacheBackup, len(backups)) 416 for i := range backups { 417 backups[i].cacheDB = self 418 ibackups[i] = &backups[i] 419 } 420 421 return ibackups, nil 422 } 423 424 func (self *SElasticcache) GetICloudElasticcacheParameters() ([]cloudprovider.ICloudElasticcacheParameter, error) { 425 parameters, err := self.region.GetElasticCacheParameters(self.GetId()) 426 if err != nil { 427 return nil, err 428 } 429 430 iparameters := make([]cloudprovider.ICloudElasticcacheParameter, len(parameters)) 431 for i := range parameters { 432 parameters[i].cacheDB = self 433 iparameters[i] = ¶meters[i] 434 } 435 436 return iparameters, nil 437 } 438 439 func (self *SElasticcache) GetAttribute() (*SElasticcacheAttribute, error) { 440 if self.attribute != nil { 441 return self.attribute, nil 442 } 443 444 params := make(map[string]string) 445 params["RegionId"] = self.region.RegionId 446 params["InstanceId"] = self.GetId() 447 448 rets := []SElasticcacheAttribute{} 449 err := DoListAll(self.region.kvsRequest, "DescribeInstanceAttribute", params, []string{"Instances", "DBInstanceAttribute"}, &rets) 450 if err != nil { 451 return nil, errors.Wrap(err, "elasticcache.GetAttribute") 452 } 453 454 count := len(rets) 455 if count >= 1 { 456 self.attribute = &rets[0] 457 return self.attribute, nil 458 } else { 459 return nil, errors.Wrapf(cloudprovider.ErrNotFound, "elasticcache.GetAttribute %s", self.GetId()) 460 } 461 } 462 463 func (self *SElasticcache) GetNetInfo() ([]SNetInfo, error) { 464 params := make(map[string]string) 465 params["RegionId"] = self.region.RegionId 466 params["InstanceId"] = self.GetId() 467 468 rets := []SNetInfo{} 469 err := DoListAll(self.region.kvsRequest, "DescribeDBInstanceNetInfo", params, []string{"NetInfoItems", "InstanceNetInfo"}, &rets) 470 if err != nil { 471 return nil, errors.Wrap(err, "elasticcache.GetNetInfo") 472 } 473 474 self.netinfo = rets 475 return self.netinfo, nil 476 } 477 478 // https://help.aliyun.com/document_detail/66742.html?spm=a2c4g.11186623.6.731.54c123d2P02qhk 479 func (self *SElasticcache) GetPublicNetInfo() (*SNetInfo, error) { 480 nets, err := self.GetNetInfo() 481 if err != nil { 482 return nil, err 483 } 484 485 for i := range nets { 486 if nets[i].IPType == "Public" { 487 return &nets[i], nil 488 } 489 } 490 491 return nil, nil 492 } 493 494 func (self *SRegion) GetElasticCaches(instanceIds []string) ([]SElasticcache, error) { 495 params := make(map[string]string) 496 params["RegionId"] = self.RegionId 497 if instanceIds != nil && len(instanceIds) > 0 { 498 params["InstanceIds"] = strings.Join(instanceIds, ",") 499 } 500 501 ret := []SElasticcache{} 502 err := DoListAll(self.kvsRequest, "DescribeInstances", params, []string{"Instances", "KVStoreInstance"}, &ret) 503 if err != nil { 504 return nil, errors.Wrap(err, "region.GetElasticCaches") 505 } 506 507 for i := range ret { 508 ret[i].region = self 509 } 510 511 return ret, nil 512 } 513 514 func (self *SRegion) GetElasticCacheById(instanceId string) (*SElasticcache, error) { 515 caches, err := self.GetElasticCaches([]string{instanceId}) 516 if err != nil { 517 return nil, errors.Wrapf(err, "region.GetElasticCacheById %s", instanceId) 518 } 519 520 if len(caches) == 1 { 521 return &caches[0], nil 522 } else if len(caches) == 0 { 523 return nil, cloudprovider.ErrNotFound 524 } else { 525 return nil, errors.Wrapf(cloudprovider.ErrDuplicateId, "region.GetElasticCacheById %s.expect 1 found %d ", instanceId, len(caches)) 526 } 527 } 528 529 func (self *SRegion) GetIElasticcacheById(id string) (cloudprovider.ICloudElasticcache, error) { 530 ec, err := self.GetElasticCacheById(id) 531 if err != nil { 532 return nil, err 533 } 534 535 return ec, nil 536 } 537 538 // https://help.aliyun.com/document_detail/95802.html?spm=a2c4g.11186623.6.746.143e782f3Pfkfg 539 func (self *SRegion) GetElasticCacheAccounts(instanceId string) ([]SElasticcacheAccount, error) { 540 params := make(map[string]string) 541 params["RegionId"] = self.RegionId 542 params["InstanceId"] = instanceId 543 544 ret := []SElasticcacheAccount{} 545 err := DoListAll(self.kvsRequest, "DescribeAccounts", params, []string{"Accounts", "Account"}, &ret) 546 if err != nil { 547 return nil, errors.Wrap(err, "region.GetElasticCacheAccounts") 548 } 549 550 return ret, nil 551 } 552 553 func (self *SRegion) GetElasticCacheAccountByName(instanceId string, accountName string) (*SElasticcacheAccount, error) { 554 params := make(map[string]string) 555 params["RegionId"] = self.RegionId 556 params["InstanceId"] = instanceId 557 params["AccountName"] = accountName 558 559 ret := []SElasticcacheAccount{} 560 err := DoListAll(self.kvsRequest, "DescribeAccounts", params, []string{"Accounts", "Account"}, &ret) 561 if err != nil { 562 return nil, errors.Wrap(err, "region.GetElasticCacheAccounts") 563 } 564 565 if len(ret) == 1 { 566 return &ret[0], nil 567 } else if len(ret) == 0 { 568 return nil, cloudprovider.ErrNotFound 569 } else { 570 return nil, errors.Wrap(fmt.Errorf("%d account with name %s found", len(ret), accountName), "region.GetElasticCacheAccountByName") 571 } 572 } 573 574 // https://help.aliyun.com/document_detail/63889.html?spm=a2c4g.11186623.6.764.3cb43852R7lnoS 575 func (self *SRegion) GetElasticCacheAcls(instanceId string) ([]SElasticcacheAcl, error) { 576 params := make(map[string]string) 577 params["RegionId"] = self.RegionId 578 params["InstanceId"] = instanceId 579 580 ret := []SElasticcacheAcl{} 581 err := DoListAll(self.kvsRequest, "DescribeSecurityIps", params, []string{"SecurityIpGroups", "SecurityIpGroup"}, &ret) 582 if err != nil { 583 return nil, errors.Wrap(err, "region.GetElasticCacheAcls") 584 } 585 586 return ret, nil 587 } 588 589 // https://help.aliyun.com/document_detail/61081.html?spm=a2c4g.11186623.6.754.10613852qAbEQV 590 func (self *SRegion) GetElasticCacheBackups(instanceId, startTime, endTime string) ([]SElasticcacheBackup, error) { 591 params := make(map[string]string) 592 params["RegionId"] = self.RegionId 593 params["InstanceId"] = instanceId 594 params["StartTime"] = startTime 595 params["EndTime"] = endTime 596 597 ret := []SElasticcacheBackup{} 598 err := DoListAll(self.kvsRequest, "DescribeBackups", params, []string{"Backups", "Backup"}, &ret) 599 if err != nil { 600 return nil, errors.Wrap(err, "region.GetElasticCacheBackups") 601 } 602 603 return ret, nil 604 } 605 606 // https://help.aliyun.com/document_detail/93078.html?spm=a2c4g.11186623.6.769.58011975YYL5Gl 607 func (self *SRegion) GetElasticCacheParameters(instanceId string) ([]SElasticcacheParameter, error) { 608 params := make(map[string]string) 609 params["RegionId"] = self.RegionId 610 params["DBInstanceId"] = instanceId 611 612 ret := []SElasticcacheParameter{} 613 err := DoListAll(self.kvsRequest, "DescribeParameters", params, []string{"RunningParameters", "Parameter"}, &ret) 614 if err != nil { 615 return nil, errors.Wrap(err, "region.GetElasticCacheParameters") 616 } 617 618 return ret, nil 619 } 620 621 // https://help.aliyun.com/document_detail/60873.html?spm=a2c4g.11174283.6.715.7412dce0qSYemb 622 func (self *SRegion) CreateIElasticcaches(ec *cloudprovider.SCloudElasticCacheInput) (cloudprovider.ICloudElasticcache, error) { 623 params := make(map[string]string) 624 params["RegionId"] = self.RegionId 625 params["InstanceClass"] = ec.InstanceType 626 params["InstanceName"] = ec.InstanceName 627 params["InstanceType"] = ec.Engine 628 params["EngineVersion"] = ec.EngineVersion 629 630 if len(ec.Password) > 0 { 631 params["UserName"] = ec.UserName 632 params["Password"] = ec.Password 633 } 634 635 if len(ec.ZoneIds) > 0 { 636 params["ZoneId"] = transZoneIdFromEcsZoneId(self, "redis", ec.ZoneIds[0]) 637 } 638 639 if len(ec.PrivateIpAddress) > 0 { 640 params["PrivateIpAddress"] = ec.PrivateIpAddress 641 } 642 643 if len(ec.NodeType) > 0 { 644 switch ec.NodeType { 645 case "single": 646 params["NodeType"] = "STAND_ALONE" 647 case "double": 648 params["NodeType"] = "MASTER_SLAVE" 649 } 650 } 651 652 if len(ec.ProjectId) > 0 { 653 params["ResourceGroupId"] = ec.ProjectId 654 } 655 656 params["NetworkType"] = ec.NetworkType 657 params["VpcId"] = ec.VpcId 658 params["VSwitchId"] = ec.NetworkId 659 params["ChargeType"] = "PostPaid" 660 if ec.BillingCycle != nil { 661 params["ChargeType"] = "PrePaid" 662 if ec.BillingCycle.GetMonths() >= 1 && ec.BillingCycle.GetMonths() <= 9 { 663 params["Period"] = strconv.Itoa(ec.BillingCycle.GetMonths()) 664 } else if ec.BillingCycle.GetMonths() == 12 || ec.BillingCycle.GetMonths() == 24 || ec.BillingCycle.GetMonths() == 36 { 665 params["Period"] = strconv.Itoa(ec.BillingCycle.GetMonths()) 666 } else { 667 return nil, fmt.Errorf("region.CreateIElasticcaches invalid billing cycle.reqired month (1~9) or year(1~3)") 668 } 669 } 670 671 ret := &SElasticcache{region: self} 672 err := DoAction(self.kvsRequest, "CreateInstance", params, []string{}, ret) 673 if err != nil { 674 return nil, errors.Wrap(err, "region.CreateIElasticcaches") 675 } 676 self.SetResourceTags(ALIYUN_SERVICE_KVS, "INSTANCE", ret.InstanceID, ec.Tags, true) 677 return ret, nil 678 } 679 680 // https://help.aliyun.com/document_detail/116215.html?spm=a2c4g.11174283.6.736.6b9ddce0c5nsw6 681 func (self *SElasticcache) Restart() error { 682 params := make(map[string]string) 683 params["InstanceId"] = self.GetId() 684 params["EffectiveTime"] = "0" // 立即重启 685 686 err := DoAction(self.region.kvsRequest, "RestartInstance", params, nil, nil) 687 if err != nil { 688 return errors.Wrap(err, "elasticcache.Restart") 689 } 690 691 return nil 692 } 693 694 // https://help.aliyun.com/document_detail/60898.html?spm=a2c4g.11186623.6.713.56ec1603KS0xA0 695 func (self *SElasticcache) Delete() error { 696 params := make(map[string]string) 697 params["InstanceId"] = self.GetId() 698 699 err := DoAction(self.region.kvsRequest, "DeleteInstance", params, nil, nil) 700 if err != nil { 701 return errors.Wrap(err, "elasticcache.Delete") 702 } 703 704 return nil 705 } 706 707 // https://help.aliyun.com/document_detail/60903.html?spm=a2c4g.11186623.6.711.3f062c92aRJNfw 708 func (self *SElasticcache) ChangeInstanceSpec(spec string) error { 709 params := make(map[string]string) 710 params["InstanceId"] = self.GetId() 711 params["InstanceClass"] = strings.Split(spec, ":")[0] 712 params["AutoPay"] = "true" // 自动付款 713 714 err := DoAction(self.region.kvsRequest, "ModifyInstanceSpec", params, nil, nil) 715 if err != nil { 716 return errors.Wrap(err, "elasticcache.ChangeInstanceSpec") 717 } 718 719 return nil 720 } 721 722 // https://help.aliyun.com/document_detail/61000.html?spm=a2c4g.11186623.6.730.57d66cb0QlQS86 723 func (self *SElasticcache) SetMaintainTime(maintainStartTime, maintainEndTime string) error { 724 params := make(map[string]string) 725 params["InstanceId"] = self.GetId() 726 params["MaintainStartTime"] = maintainStartTime 727 params["MaintainEndTime"] = maintainEndTime 728 729 err := DoAction(self.region.kvsRequest, "ModifyInstanceMaintainTime", params, nil, nil) 730 if err != nil { 731 return errors.Wrap(err, "elasticcache.SetMaintainTime") 732 } 733 734 return nil 735 } 736 737 // https://help.aliyun.com/document_detail/125795.html?spm=a2c4g.11186623.6.719.51542b3593cDKO 738 func (self *SElasticcache) AllocatePublicConnection(port int) (string, error) { 739 if port < 1024 { 740 port = 6379 741 } 742 743 suffix, _ := goutils.RandomAlphabetic(4) 744 conn := self.GetId() + strings.ToLower(suffix) 745 746 params := make(map[string]string) 747 params["InstanceId"] = self.GetId() 748 params["Port"] = strconv.Itoa(port) 749 params["ConnectionStringPrefix"] = conn 750 751 err := DoAction(self.region.kvsRequest, "AllocateInstancePublicConnection", params, nil, nil) 752 if err != nil { 753 return "", errors.Wrap(err, "elasticcache.AllocatePublicConnection") 754 } 755 756 return conn, nil 757 } 758 759 // https://help.aliyun.com/document_detail/125796.html?spm=a2c4g.11186623.6.720.702a3b23Qayopy 760 func (self *SElasticcache) ReleasePublicConnection() error { 761 publicConn := self.GetPublicDNS() 762 if len(publicConn) == 0 { 763 log.Debugf("elasticcache.ReleasePublicConnection public connect is empty") 764 return nil 765 } 766 767 params := make(map[string]string) 768 params["InstanceId"] = self.GetId() 769 params["CurrentConnectionString"] = publicConn 770 771 err := DoAction(self.region.kvsRequest, "ReleaseInstancePublicConnection", params, nil, nil) 772 if err != nil { 773 return errors.Wrap(err, "elasticcache.ReleasePublicConnection") 774 } 775 776 return nil 777 } 778 779 // https://help.aliyun.com/document_detail/93603.html?spm=a2c4g.11186623.6.732.10666cf9UVgNPb 修改链接地址 780 781 // https://help.aliyun.com/document_detail/95973.html?spm=a2c4g.11186623.6.742.4698126aH0s4Q5 782 func (self *SElasticcache) CreateAccount(input cloudprovider.SCloudElasticCacheAccountInput) (cloudprovider.ICloudElasticcacheAccount, error) { 783 params := make(map[string]string) 784 params["InstanceId"] = self.GetId() 785 params["AccountName"] = input.AccountName 786 params["AccountPassword"] = input.AccountPassword 787 if len(input.AccountPrivilege) > 0 { 788 params["AccountPrivilege"] = input.AccountPrivilege 789 } 790 791 if len(input.Description) > 0 { 792 params["AccountDescription"] = input.Description 793 } 794 795 err := DoAction(self.region.kvsRequest, "CreateAccount", params, nil, nil) 796 if err != nil { 797 return nil, errors.Wrap(err, "elasticcache.CreateAccount") 798 } 799 800 return self.GetICloudElasticcacheAccountByName(input.AccountName) 801 } 802 803 func (self *SElasticcache) CreateAcl(aclName, securityIps string) (cloudprovider.ICloudElasticcacheAcl, error) { 804 acl := &SElasticcacheAcl{} 805 acl.cacheDB = self 806 acl.SecurityIPGroupName = aclName 807 acl.SecurityIPList = securityIps 808 return acl, self.region.createAcl(self.GetId(), aclName, securityIps) 809 } 810 811 // https://help.aliyun.com/document_detail/61113.html?spm=a2c4g.11186623.6.770.16a61e7admr0xy 812 func (self *SElasticcache) UpdateInstanceParameters(config jsonutils.JSONObject) error { 813 params := make(map[string]string) 814 params["InstanceId"] = self.GetId() 815 params["Config"] = config.String() 816 817 err := DoAction(self.region.kvsRequest, "ModifyInstanceConfig", params, nil, nil) 818 if err != nil { 819 return errors.Wrap(err, "elasticcache.UpdateInstanceParameters") 820 } 821 822 return nil 823 } 824 825 // https://help.aliyun.com/document_detail/61075.html?spm=a2c4g.11186623.6.749.4cba126a2U9xNa 826 func (self *SElasticcache) CreateBackup(desc string) (cloudprovider.ICloudElasticcacheBackup, error) { 827 params := make(map[string]string) 828 params["InstanceId"] = self.GetId() 829 830 // 目前没有查询备份ID的接口,因此,备份ID没什么用 831 err := DoAction(self.region.kvsRequest, "CreateBackup", params, []string{"BackupJobID"}, nil) 832 if err != nil { 833 return nil, errors.Wrap(err, "elasticcache.CreateBackup") 834 } 835 836 return nil, nil 837 } 838 839 // https://help.aliyun.com/document_detail/61077.html?spm=a2c4g.11186623.6.750.3d7630be7ziUfg 840 func (self *SElasticcache) UpdateBackupPolicy(config cloudprovider.SCloudElasticCacheBackupPolicyUpdateInput) error { 841 params := make(map[string]string) 842 params["InstanceId"] = self.GetId() 843 params["PreferredBackupPeriod"] = config.PreferredBackupPeriod 844 params["PreferredBackupTime"] = config.PreferredBackupTime 845 846 err := DoAction(self.region.kvsRequest, "ModifyBackupPolicy", params, nil, nil) 847 if err != nil { 848 return errors.Wrap(err, "elasticcache.UpdateBackupPolicy") 849 } 850 851 return nil 852 } 853 854 // https://help.aliyun.com/document_detail/60931.html?spm=a2c4g.11186623.6.728.5c57292920UKx3 855 func (self *SElasticcache) FlushInstance(input cloudprovider.SCloudElasticCacheFlushInstanceInput) error { 856 params := make(map[string]string) 857 params["InstanceId"] = self.GetId() 858 859 err := DoAction(self.region.kvsRequest, "FlushInstance", params, nil, nil) 860 if err != nil { 861 return errors.Wrap(err, "elasticcache.FlushInstance") 862 } 863 864 return nil 865 } 866 867 // https://help.aliyun.com/document_detail/98531.html?spm=5176.11065259.1996646101.searchclickresult.4df474c38Sc2SO 868 func (self *SElasticcache) UpdateAuthMode(noPwdAccess bool, password string) error { 869 params := make(map[string]string) 870 params["InstanceId"] = self.GetId() 871 if noPwdAccess { 872 params["VpcAuthMode"] = "Close" 873 } else { 874 params["VpcAuthMode"] = "Open" 875 } 876 877 err := DoAction(self.region.kvsRequest, "ModifyInstanceVpcAuthMode", params, nil, nil) 878 if err != nil { 879 return errors.Wrap(err, "elasticcacheAccount.UpdateAuthMode") 880 } 881 882 return nil 883 } 884 885 func (self *SElasticcache) GetProjectId() string { 886 return self.ResourceGroupId 887 } 888 889 func (self *SElasticcache) GetAuthMode() string { 890 attribute, err := self.GetAttribute() 891 if err != nil { 892 log.Errorf("elasticcache.GetAuthMode %s", err) 893 } 894 switch attribute.VpcAuthMode { 895 case "Open": 896 return "on" 897 default: 898 return "off" 899 } 900 } 901 902 func (self *SElasticcache) GetSecurityGroupIds() ([]string, error) { 903 return nil, cloudprovider.ErrNotSupported 904 } 905 906 func (self *SElasticcache) GetICloudElasticcacheAccount(accountId string) (cloudprovider.ICloudElasticcacheAccount, error) { 907 segs := strings.Split(accountId, "/") 908 if len(segs) < 2 { 909 log.Debugf("elasticcache.GetICloudElasticcacheAccount invalid account id %s", accountId) 910 return nil, errors.Wrap(cloudprovider.ErrNotFound, "invalid account id") 911 } 912 913 return self.GetICloudElasticcacheAccountByName(segs[1]) 914 } 915 916 func (self *SElasticcache) GetICloudElasticcacheAcl(aclId string) (cloudprovider.ICloudElasticcacheAcl, error) { 917 acls, err := self.GetICloudElasticcacheAcls() 918 if err != nil { 919 return nil, err 920 } 921 922 for _, acl := range acls { 923 if acl.GetId() == aclId { 924 return acl, nil 925 } 926 } 927 928 return nil, cloudprovider.ErrNotFound 929 } 930 931 func (self *SElasticcache) GetICloudElasticcacheBackup(backupId string) (cloudprovider.ICloudElasticcacheBackup, error) { 932 backups, err := self.GetICloudElasticcacheBackups() 933 if err != nil { 934 return nil, err 935 } 936 937 for _, backup := range backups { 938 if backup.GetId() == backupId { 939 return backup, nil 940 } 941 } 942 943 return nil, cloudprovider.ErrNotFound 944 } 945 946 func (instance *SElasticcache) SetTags(tags map[string]string, replace bool) error { 947 return instance.region.SetResourceTags(ALIYUN_SERVICE_KVS, "INSTANCE", instance.GetId(), tags, replace) 948 } 949 950 func (self *SElasticcache) UpdateSecurityGroups(secgroupIds []string) error { 951 return errors.Wrap(cloudprovider.ErrNotSupported, "UpdateSecurityGroups") 952 } 953 954 // https://help.aliyun.com/document_detail/60903.html?spm=a2c4g.11174283.6.877.34653436jn6t4C 955 // https://help.aliyun.com/document_detail/95584.html?spm=a2c4g.11186623.6.907.60e3292bWsVIOE 956 // https://help.aliyun.com/document_detail/60909.html?spm=a2c4g.11186623.6.910.17664ce0jfir7F 957 func (self *SElasticcache) Renew(bc billing.SBillingCycle) error { 958 month := bc.GetMonths() 959 if month <= 0 { 960 return errors.Wrap(fmt.Errorf("month should great than 0"), "GetMonths") 961 } 962 963 if (month >= 1 && month <= 9) || month == 12 || month == 24 || month == 36 { 964 return errors.Wrap(fmt.Errorf("month %d is invalid, required: 1~9、12、24、36", month), "GetMonths") 965 } 966 967 params := map[string]string{} 968 params["InstanceId"] = self.GetId() 969 params["Period"] = fmt.Sprintf("%d", month) 970 params["AutoPay"] = "true" 971 _, err := self.region.kvsRequest("RenewInstance", params) 972 if err != nil { 973 return errors.Wrap(err, "RenewInstance") 974 } 975 976 return nil 977 } 978 979 func (self *SElasticcache) SetAutoRenew(bc billing.SBillingCycle) error { 980 params := map[string]string{} 981 params["DBInstanceId"] = self.GetId() 982 params["Duration"] = "1" 983 params["AutoRenew"] = fmt.Sprintf("%v", bc.AutoRenew) 984 _, err := self.region.kvsRequest("ModifyInstanceAutoRenewalAttribute", params) 985 if err != nil { 986 return errors.Wrap(err, "ModifyInstanceAutoRenewalAttribute") 987 } 988 989 return nil 990 }