yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/apsara/dbinstance.go (about) 1 // Copyright 2019 Yunion 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package apsara 16 17 import ( 18 "context" 19 "fmt" 20 "strings" 21 "time" 22 23 "yunion.io/x/jsonutils" 24 "yunion.io/x/log" 25 "yunion.io/x/pkg/errors" 26 "yunion.io/x/pkg/utils" 27 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 "yunion.io/x/onecloud/pkg/util/rand" 33 ) 34 35 type SReadOnlyDBInstanceIds struct { 36 ReadOnlyDBInstanceId []string 37 } 38 39 type SDBInstanceId struct { 40 DBInstanceId []string 41 } 42 43 type SDBInstanceExtra struct { 44 DBInstanceId SDBInstanceId 45 } 46 47 type SDBInstance struct { 48 multicloud.SDBInstanceBase 49 ApsaraTags 50 51 netInfo []SDBInstanceNetwork 52 53 region *SRegion 54 55 AccountMaxQuantity int 56 AccountType string 57 CanTempUpgrade bool 58 Category string 59 AvailabilityValue string 60 DBInstanceDescription string 61 DBInstanceId string 62 ConnectionMode string 63 ConnectionString string 64 CurrentKernelVersion string 65 DBInstanceCPU int 66 CreateTime time.Time 67 DBInstanceClass string 68 DBInstanceClassType string 69 DBInstanceNetType string 70 DBInstanceStatus string 71 DBInstanceType string 72 DBInstanceDiskUsed int64 73 DBInstanceStorage int 74 DBInstanceStorageType string 75 MasterInstanceId string 76 DBInstanceMemory int 77 DBMaxQuantity int 78 IPType string 79 LatestKernelVersion string 80 DispenseMode string 81 Engine string 82 EngineVersion string 83 ExpireTime time.Time 84 InstanceNetworkType string 85 LockMode string 86 LockReason string 87 MutriORsignle bool 88 MaintainTime string 89 MaxConnections int 90 MaxIOPS int 91 Port int 92 PayType TChargeType 93 ReadOnlyDBInstanceIds SReadOnlyDBInstanceIds 94 RegionId string 95 VSwitchId string 96 VpcCloudInstanceId string 97 VpcId string 98 ZoneId string 99 Extra SDBInstanceExtra 100 SecurityIPList string 101 SecurityIPMode string 102 SupportCreateSuperAccount string 103 SupportUpgradeAccountType string 104 TempUpgradeTimeEnd time.Time 105 TempUpgradeTimeStart time.Time 106 DepartmentInfo 107 } 108 109 func (rds *SDBInstance) GetName() string { 110 if len(rds.DBInstanceDescription) > 0 { 111 return rds.DBInstanceDescription 112 } 113 return rds.DBInstanceId 114 } 115 116 func (rds *SDBInstance) GetId() string { 117 return rds.DBInstanceId 118 } 119 120 func (rds *SDBInstance) GetGlobalId() string { 121 return rds.GetId() 122 } 123 124 // Creating 创建中 125 // Running 使用中 126 // Deleting 删除中 127 // Rebooting 重启中 128 // DBInstanceClassChanging 升降级中 129 // TRANSING 迁移中 130 // EngineVersionUpgrading 迁移版本中 131 // TransingToOthers 迁移数据到其他RDS中 132 // GuardDBInstanceCreating 生产灾备实例中 133 // Restoring 备份恢复中 134 // Importing 数据导入中 135 // ImportingFromOthers 从其他RDS实例导入数据中 136 // DBInstanceNetTypeChanging 内外网切换中 137 // GuardSwitching 容灾切换中 138 // INS_CLONING 实例克隆中 139 func (rds *SDBInstance) GetStatus() string { 140 switch rds.DBInstanceStatus { 141 case "Creating", "GuardDBInstanceCreating", "DBInstanceNetTypeChanging", "GuardSwitching", "NET_CREATING", "NET_DELETING": 142 return api.DBINSTANCE_DEPLOYING 143 case "DBInstanceClassChanging": 144 return api.DBINSTANCE_CHANGE_CONFIG 145 case "Running": 146 return api.DBINSTANCE_RUNNING 147 case "Deleting": 148 return api.DBINSTANCE_DELETING 149 case "Rebooting": 150 return api.DBINSTANCE_REBOOTING 151 case "TRANSING", "EngineVersionUpgrading", "TransingToOthers": 152 return api.DBINSTANCE_MIGRATING 153 case "Restoring": 154 return api.DBINSTANCE_RESTORING 155 case "Importing", "ImportingFromOthers": 156 return api.DBINSTANCE_IMPORTING 157 case "INS_CLONING": 158 return api.DBINSTANCE_CLONING 159 default: 160 log.Errorf("Unknown dbinstance status %s", rds.DBInstanceStatus) 161 return api.DBINSTANCE_UNKNOWN 162 } 163 } 164 165 func (rds *SDBInstance) GetBillingType() string { 166 return convertChargeType(rds.PayType) 167 } 168 169 func (rds *SDBInstance) GetExpiredAt() time.Time { 170 return rds.ExpireTime 171 } 172 173 func (rds *SDBInstance) GetCreatedAt() time.Time { 174 return rds.CreateTime 175 } 176 177 func (rds *SDBInstance) GetStorageType() string { 178 return rds.DBInstanceStorageType 179 } 180 181 func (rds *SDBInstance) GetIops() int { 182 return rds.MaxIOPS 183 } 184 185 func (rds *SDBInstance) GetEngine() string { 186 switch rds.Engine { 187 case "MySQL": 188 return api.DBINSTANCE_TYPE_MYSQL 189 case "SQLServer": 190 return api.DBINSTANCE_TYPE_SQLSERVER 191 case "PostgreSQL": 192 return api.DBINSTANCE_TYPE_POSTGRESQL 193 case "PPAS": 194 return api.DBINSTANCE_TYPE_PPAS 195 case "MariaDB": 196 return api.DBINSTANCE_TYPE_MARIADB 197 } 198 return rds.Engine 199 } 200 201 func (rds *SDBInstance) GetEngineVersion() string { 202 return rds.EngineVersion 203 } 204 205 func (rds *SDBInstance) GetInstanceType() string { 206 return rds.DBInstanceClass 207 } 208 209 func (rds *SDBInstance) GetCategory() string { 210 switch rds.Category { 211 case "Basic": 212 return api.ALIYUN_DBINSTANCE_CATEGORY_BASIC 213 case "HighAvailability": 214 return api.ALIYUN_DBINSTANCE_CATEGORY_HA 215 case "AlwaysOn": 216 return api.ALIYUN_DBINSTANCE_CATEGORY_ALWAYSON 217 case "Finance": 218 return api.ALIYUN_DBINSTANCE_CATEGORY_FINANCE 219 } 220 return rds.Category 221 } 222 223 func (rds *SDBInstance) GetVcpuCount() int { 224 if rds.DBInstanceCPU == 0 { 225 rds.Refresh() 226 } 227 return rds.DBInstanceCPU 228 } 229 230 func (rds *SDBInstance) GetVmemSizeMB() int { 231 if rds.DBInstanceMemory == 0 { 232 rds.Refresh() 233 } 234 return rds.DBInstanceMemory 235 } 236 237 func (rds *SDBInstance) GetDiskSizeGB() int { 238 if rds.DBInstanceStorage == 0 { 239 rds.Refresh() 240 } 241 return rds.DBInstanceStorage 242 } 243 244 func (rds *SDBInstance) GetDiskSizeUsedMB() int { 245 if rds.DBInstanceDiskUsed == 0 { 246 rds.Refresh() 247 } 248 return int(rds.DBInstanceDiskUsed / 1024 / 1024) 249 } 250 251 func (rds *SDBInstance) GetPort() int { 252 if rds.Port == 0 { 253 rds.Refresh() 254 } 255 return rds.Port 256 } 257 258 func (rds *SDBInstance) GetMaintainTime() string { 259 return rds.MaintainTime 260 } 261 262 func (rds *SDBInstance) GetIVpcId() string { 263 return rds.VpcId 264 } 265 266 func (rds *SDBInstance) Refresh() error { 267 instance, err := rds.region.GetDBInstanceDetail(rds.DBInstanceId) 268 if err != nil { 269 return err 270 } 271 return jsonutils.Update(rds, instance) 272 } 273 274 func (rds *SDBInstance) getZoneId(index int) string { 275 zoneId := rds.getZone(index) 276 if len(zoneId) > 0 { 277 zone, err := rds.region.getZoneById(zoneId) 278 if err != nil { 279 log.Errorf("failed to found zone %s for rds %s", zoneId, rds.GetName()) 280 return "" 281 } 282 return zone.GetGlobalId() 283 } 284 return "" 285 } 286 287 func (rds *SDBInstance) GetZone1Id() string { 288 return rds.getZoneId(1) 289 } 290 291 func (rds *SDBInstance) GetZone2Id() string { 292 return rds.getZoneId(2) 293 } 294 295 func (rds *SDBInstance) GetZone3Id() string { 296 return rds.getZoneId(3) 297 } 298 299 func (rds *SDBInstance) getZone(index int) string { 300 zoneStr := strings.Replace(rds.ZoneId, ")", "", -1) 301 zoneInfo := strings.Split(zoneStr, ",") 302 if len(zoneInfo) < index { 303 return "" 304 } 305 zone := zoneInfo[index-1] 306 zoneCode := zone[len(zone)-1] 307 if strings.HasPrefix(rds.ZoneId, fmt.Sprintf("%s-", rds.RegionId)) { 308 return fmt.Sprintf("%s-%s", rds.RegionId, string(zoneCode)) 309 } 310 return fmt.Sprintf("%s%s", rds.RegionId, string(zoneCode)) 311 } 312 313 func (rds *SDBInstance) GetDBNetworks() ([]cloudprovider.SDBInstanceNetwork, error) { 314 netInfo, err := rds.region.GetDBInstanceNetInfo(rds.DBInstanceId) 315 if err != nil { 316 return nil, errors.Wrapf(err, "GetDBInstanceNetInfo") 317 } 318 networks := []cloudprovider.SDBInstanceNetwork{} 319 for _, net := range netInfo { 320 if net.IPType == "Private" { 321 network := cloudprovider.SDBInstanceNetwork{} 322 network.IP = net.IPAddress 323 network.NetworkId = net.VSwitchId 324 networks = append(networks, network) 325 } 326 } 327 return networks, nil 328 } 329 330 func (rds *SDBInstance) fetchNetInfo() error { 331 if len(rds.netInfo) > 0 { 332 return nil 333 } 334 netInfo, err := rds.region.GetDBInstanceNetInfo(rds.DBInstanceId) 335 if err != nil { 336 return errors.Wrap(err, "GetDBInstanceNetInfo") 337 } 338 rds.netInfo = netInfo 339 return nil 340 } 341 342 func (rds *SDBInstance) GetInternalConnectionStr() string { 343 err := rds.fetchNetInfo() 344 if err != nil { 345 log.Errorf("failed to fetch netInfo error: %v", err) 346 return "" 347 } 348 349 for _, net := range rds.netInfo { 350 if net.IPType != "Public" { 351 return net.ConnectionString 352 } 353 } 354 return "" 355 } 356 357 func (rds *SDBInstance) GetConnectionStr() string { 358 err := rds.fetchNetInfo() 359 if err != nil { 360 log.Errorf("failed to fetch netInfo error: %v", err) 361 return "" 362 } 363 364 for _, net := range rds.netInfo { 365 if net.IPType == "Public" { 366 return net.ConnectionString 367 } 368 } 369 return "" 370 } 371 372 func (region *SRegion) GetDBInstances(ids []string, offset int, limit int) ([]SDBInstance, int, error) { 373 if limit > 50 || limit <= 0 { 374 limit = 50 375 } 376 params := make(map[string]string) 377 params["RegionId"] = region.RegionId 378 params["PageSize"] = fmt.Sprintf("%d", limit) 379 params["PageNumber"] = fmt.Sprintf("%d", (offset/limit)+1) 380 381 body, err := region.rdsRequest("DescribeDBInstances", params) 382 if err != nil { 383 return nil, 0, errors.Wrapf(err, "GetDBInstances") 384 } 385 instances := []SDBInstance{} 386 err = body.Unmarshal(&instances, "Items", "DBInstance") 387 if err != nil { 388 return nil, 0, errors.Wrapf(err, "GetDBInstances.Unmarshal") 389 } 390 total, _ := body.Int("TotalRecordCount") 391 return instances, int(total), nil 392 } 393 394 func (region *SRegion) GetIDBInstanceById(instanceId string) (cloudprovider.ICloudDBInstance, error) { 395 rds, err := region.GetDBInstanceDetail(instanceId) 396 if err != nil { 397 return nil, err 398 } 399 rds.region = region 400 return rds, nil 401 } 402 403 func (region *SRegion) GetIDBInstances() ([]cloudprovider.ICloudDBInstance, error) { 404 instances := []SDBInstance{} 405 for { 406 part, total, err := region.GetDBInstances([]string{}, len(instances), 50) 407 if err != nil { 408 return nil, err 409 } 410 instances = append(instances, part...) 411 if len(instances) >= total { 412 break 413 } 414 } 415 idbinstances := []cloudprovider.ICloudDBInstance{} 416 for i := 0; i < len(instances); i++ { 417 instances[i].region = region 418 idbinstances = append(idbinstances, &instances[i]) 419 } 420 return idbinstances, nil 421 } 422 423 func (region *SRegion) GetDBInstanceDetail(instanceId string) (*SDBInstance, error) { 424 if len(instanceId) == 0 { 425 return nil, cloudprovider.ErrNotFound 426 } 427 params := map[string]string{} 428 params["RegionId"] = region.RegionId 429 params["DBInstanceId"] = instanceId 430 body, err := region.rdsRequest("DescribeDBInstanceAttribute", params) 431 if err != nil { 432 return nil, errors.Wrapf(err, "GetDBInstanceDetail") 433 } 434 instances := []SDBInstance{} 435 err = body.Unmarshal(&instances, "Items", "DBInstanceAttribute") 436 if err != nil { 437 return nil, errors.Wrapf(err, "GetDBInstanceDetail.Unmarshal") 438 } 439 if len(instances) == 1 { 440 instances[0].region = region 441 return &instances[0], nil 442 } 443 if len(instances) == 0 { 444 return nil, cloudprovider.ErrNotFound 445 } 446 return nil, cloudprovider.ErrDuplicateId 447 } 448 449 func (region *SRegion) DeleteDBInstance(instanceId string) error { 450 params := map[string]string{} 451 params["RegionId"] = region.RegionId 452 params["DBInstanceId"] = instanceId 453 _, err := region.rdsRequest("DeleteDBInstance", params) 454 return err 455 } 456 457 type SDBInstanceWeight struct { 458 } 459 460 type SDBInstanceWeights struct { 461 DBInstanceWeight []SDBInstanceWeight 462 } 463 464 type SsecurityIPGroup struct { 465 } 466 467 type SSecurityIPGroups struct { 468 securityIPGroup []SsecurityIPGroup 469 } 470 471 type SDBInstanceNetwork struct { 472 ConnectionString string 473 ConnectionStringType string 474 DBInstanceWeights SDBInstanceWeights 475 IPAddress string 476 IPType string 477 Port int 478 SecurityIPGroups SSecurityIPGroups 479 Upgradeable string 480 VPCId string 481 VSwitchId string 482 } 483 484 func (network *SDBInstanceNetwork) GetGlobalId() string { 485 return network.IPAddress 486 } 487 488 func (network *SDBInstanceNetwork) GetINetworkId() string { 489 return network.VSwitchId 490 } 491 492 func (network *SDBInstanceNetwork) GetIP() string { 493 return network.IPAddress 494 } 495 496 func (region *SRegion) GetDBInstanceNetInfo(instanceId string) ([]SDBInstanceNetwork, error) { 497 params := map[string]string{} 498 params["RegionId"] = region.RegionId 499 params["DBInstanceId"] = instanceId 500 body, err := region.rdsRequest("DescribeDBInstanceNetInfo", params) 501 if err != nil { 502 return nil, errors.Wrapf(err, "GetDBInstanceNetwork") 503 } 504 networks := []SDBInstanceNetwork{} 505 err = body.Unmarshal(&networks, "DBInstanceNetInfos", "DBInstanceNetInfo") 506 if err != nil { 507 return nil, err 508 } 509 return networks, nil 510 } 511 512 func (rds *SDBInstance) GetIDBInstanceParameters() ([]cloudprovider.ICloudDBInstanceParameter, error) { 513 parameters, err := rds.region.GetDBInstanceParameters(rds.DBInstanceId) 514 if err != nil { 515 return nil, err 516 } 517 iparameters := []cloudprovider.ICloudDBInstanceParameter{} 518 for i := 0; i < len(parameters); i++ { 519 iparameters = append(iparameters, ¶meters[i]) 520 } 521 return iparameters, nil 522 } 523 524 func (region *SRegion) GetIDBInstanceBackupById(backupId string) (cloudprovider.ICloudDBInstanceBackup, error) { 525 backups, err := region.GetIDBInstanceBackups() 526 if err != nil { 527 return nil, errors.Wrap(err, "region.GetIDBInstanceBackups") 528 } 529 for _, backup := range backups { 530 if backup.GetGlobalId() == backupId { 531 return backup, nil 532 } 533 } 534 return nil, cloudprovider.ErrNotFound 535 } 536 537 func (rds *SDBInstance) Reboot() error { 538 return rds.region.RebootDBInstance(rds.DBInstanceId) 539 } 540 541 func (rds *SDBInstance) Delete() error { 542 return rds.region.DeleteDBInstance(rds.DBInstanceId) 543 } 544 545 func (region *SRegion) RebootDBInstance(instanceId string) error { 546 params := map[string]string{} 547 params["RegionId"] = region.RegionId 548 params["DBInstanceId"] = instanceId 549 _, err := region.rdsRequest("RestartDBInstance", params) 550 return err 551 } 552 553 func (rds *SDBInstance) GetIDBInstanceDatabases() ([]cloudprovider.ICloudDBInstanceDatabase, error) { 554 databases := []SDBInstanceDatabase{} 555 for { 556 parts, total, err := rds.region.GetDBInstanceDatabases(rds.DBInstanceId, "", len(databases), 500) 557 if err != nil { 558 return nil, err 559 } 560 databases = append(databases, parts...) 561 if len(databases) >= total { 562 break 563 } 564 } 565 566 idatabase := []cloudprovider.ICloudDBInstanceDatabase{} 567 for i := 0; i < len(databases); i++ { 568 databases[i].instance = rds 569 idatabase = append(idatabase, &databases[i]) 570 } 571 return idatabase, nil 572 } 573 574 func (rds *SDBInstance) GetIDBInstanceAccounts() ([]cloudprovider.ICloudDBInstanceAccount, error) { 575 accounts := []SDBInstanceAccount{} 576 for { 577 parts, total, err := rds.region.GetDBInstanceAccounts(rds.DBInstanceId, len(accounts), 50) 578 if err != nil { 579 return nil, err 580 } 581 accounts = append(accounts, parts...) 582 if len(accounts) >= total { 583 break 584 } 585 } 586 587 iaccounts := []cloudprovider.ICloudDBInstanceAccount{} 588 for i := 0; i < len(accounts); i++ { 589 accounts[i].instance = rds 590 iaccounts = append(iaccounts, &accounts[i]) 591 } 592 return iaccounts, nil 593 } 594 595 func (rds *SDBInstance) ChangeConfig(cxt context.Context, desc *cloudprovider.SManagedDBInstanceChangeConfig) error { 596 return rds.region.ChangeDBInstanceConfig(rds.DBInstanceId, string(rds.PayType), desc) 597 } 598 599 func (region *SRegion) ChangeDBInstanceConfig(instanceId, payType string, desc *cloudprovider.SManagedDBInstanceChangeConfig) error { 600 params := map[string]string{ 601 "RegionId": region.RegionId, 602 "DBInstanceId": instanceId, 603 "PayType": payType, 604 "DBInstanceClass": desc.InstanceType, 605 "DBInstanceStorage": fmt.Sprintf("%d", desc.DiskSizeGB), 606 } 607 608 _, err := region.rdsRequest("ModifyDBInstanceSpec", params) 609 if err != nil { 610 return errors.Wrap(err, "region.rdsRequest.ModifyDBInstanceSpec") 611 } 612 return nil 613 } 614 615 func (region *SRegion) CreateIDBInstance(desc *cloudprovider.SManagedDBInstanceCreateConfig) (cloudprovider.ICloudDBInstance, error) { 616 params := map[string]string{ 617 "RegionId": region.RegionId, 618 "Engine": desc.Engine, 619 "EngineVersion": desc.EngineVersion, 620 "DBInstanceStorage": fmt.Sprintf("%d", desc.DiskSizeGB), 621 "DBInstanceNetType": "Intranet", 622 "PayType": "Postpaid", 623 "SecurityIPList": "0.0.0.0/0", 624 "DBInstanceDescription": desc.Name, 625 "InstanceNetworkType": "VPC", 626 "VPCId": desc.VpcId, 627 "VSwitchId": desc.NetworkId, 628 "DBInstanceStorageType": desc.StorageType, 629 "DBInstanceClass": desc.InstanceType, 630 "ZoneId": desc.ZoneId, 631 "ClientToken": utils.GenRequestId(20), 632 } 633 switch desc.Category { 634 case api.ALIYUN_DBINSTANCE_CATEGORY_HA: 635 params["Category"] = "HighAvailability" 636 case api.ALIYUN_DBINSTANCE_CATEGORY_BASIC: 637 params["Category"] = "Basic" 638 case api.ALIYUN_DBINSTANCE_CATEGORY_ALWAYSON: 639 params["Category"] = "AlwaysOn" 640 case api.ALIYUN_DBINSTANCE_CATEGORY_FINANCE: 641 params["Category"] = "Finance" 642 } 643 644 if len(desc.Address) > 0 { 645 params["PrivateIpAddress"] = desc.Address 646 } 647 if len(desc.ProjectId) > 0 { 648 params["ResourceGroupId"] = desc.ProjectId 649 } 650 if desc.BillingCycle != nil { 651 params["PayType"] = "Prepaid" 652 if desc.BillingCycle.GetMonths() > 0 { 653 params["Period"] = "Month" 654 params["UsedTime"] = fmt.Sprintf("%d", desc.BillingCycle.GetMonths()) 655 } else { 656 params["Period"] = "Year" 657 params["UsedTime"] = fmt.Sprintf("%d", desc.BillingCycle.GetYears()) 658 } 659 params["AutoRenew"] = "False" 660 } 661 662 action := "CreateDBInstance" 663 if len(desc.MasterInstanceId) > 0 { 664 action = "CreateReadOnlyDBInstance" 665 params["DBInstanceId"] = desc.MasterInstanceId 666 } 667 668 resp, err := region.rdsRequest(action, params) 669 if err != nil { 670 return nil, errors.Wrapf(err, "rdsRequest") 671 } 672 instanceId, err := resp.GetString("DBInstanceId") 673 if err != nil { 674 return nil, errors.Wrap(err, `resp.GetString("DBInstanceId")`) 675 } 676 region.SetResourceTags("rds", "INSTANCE", []string{instanceId}, desc.Tags, false) 677 return region.GetIDBInstanceById(instanceId) 678 } 679 680 func (rds *SDBInstance) GetMasterInstanceId() string { 681 if len(rds.MasterInstanceId) > 0 { 682 return rds.MasterInstanceId 683 } 684 rds.Refresh() 685 return rds.MasterInstanceId 686 } 687 688 func (region *SRegion) OpenPublicConnection(instanceId string) error { 689 rds, err := region.GetDBInstanceDetail(instanceId) 690 if err != nil { 691 return err 692 } 693 params := map[string]string{ 694 "RegionId": region.RegionId, 695 "ConnectionStringPrefix": rds.DBInstanceId + rand.String(3), 696 "DBInstanceId": rds.DBInstanceId, 697 "Port": fmt.Sprintf("%d", rds.Port), 698 } 699 _, err = rds.region.rdsRequest("AllocateInstancePublicConnection", params) 700 if err != nil { 701 return errors.Wrap(err, "rdsRequest(AllocateInstancePublicConnection)") 702 } 703 return nil 704 } 705 706 func (rds *SDBInstance) OpenPublicConnection() error { 707 if url := rds.GetConnectionStr(); len(url) == 0 { 708 err := rds.region.OpenPublicConnection(rds.DBInstanceId) 709 if err != nil { 710 return err 711 } 712 rds.netInfo = []SDBInstanceNetwork{} 713 } 714 return nil 715 } 716 717 func (region *SRegion) ClosePublicConnection(instanceId string) error { 718 netInfo, err := region.GetDBInstanceNetInfo(instanceId) 719 if err != nil { 720 return errors.Wrap(err, "GetDBInstanceNetInfo") 721 } 722 723 for _, net := range netInfo { 724 if net.IPType == "Public" { 725 params := map[string]string{ 726 "RegionId": region.RegionId, 727 "CurrentConnectionString": net.ConnectionString, 728 "DBInstanceId": instanceId, 729 } 730 _, err = region.rdsRequest("ReleaseInstancePublicConnection", params) 731 if err != nil { 732 return errors.Wrap(err, "rdsRequest(ReleaseInstancePublicConnection)") 733 } 734 735 } 736 } 737 return nil 738 739 } 740 741 func (rds *SDBInstance) ClosePublicConnection() error { 742 return rds.region.ClosePublicConnection(rds.DBInstanceId) 743 } 744 745 func (rds *SDBInstance) RecoveryFromBackup(conf *cloudprovider.SDBInstanceRecoveryConfig) error { 746 if len(conf.OriginDBInstanceExternalId) == 0 { 747 conf.OriginDBInstanceExternalId = rds.DBInstanceId 748 } 749 return rds.region.RecoveryDBInstanceFromBackup(conf.OriginDBInstanceExternalId, rds.DBInstanceId, conf.BackupId, conf.Databases) 750 } 751 752 func (region *SRegion) RecoveryDBInstanceFromBackup(srcId, destId string, backupId string, databases map[string]string) error { 753 params := map[string]string{ 754 "RegionId": region.RegionId, 755 "DBInstanceId": srcId, 756 "TargetDBInstanceId": destId, 757 "BackupId": backupId, 758 "DbNames": jsonutils.Marshal(databases).String(), 759 } 760 _, err := region.rdsRequest("RecoveryDBInstance", params) 761 if err != nil { 762 return errors.Wrap(err, "rdsRequest.RecoveryDBInstance") 763 } 764 return nil 765 } 766 767 func (rds *SDBInstance) CreateDatabase(conf *cloudprovider.SDBInstanceDatabaseCreateConfig) error { 768 return rds.region.CreateDBInstanceDatabae(rds.DBInstanceId, conf.CharacterSet, conf.Name, conf.Description) 769 } 770 771 func (rds *SDBInstance) CreateAccount(conf *cloudprovider.SDBInstanceAccountCreateConfig) error { 772 return rds.region.CreateDBInstanceAccount(rds.DBInstanceId, conf.Name, conf.Password, conf.Description) 773 } 774 775 func (rds *SDBInstance) Renew(bc billing.SBillingCycle) error { 776 return rds.region.RenewInstance(rds.DBInstanceId, bc) 777 } 778 779 func (region *SRegion) RenewDBInstance(instanceId string, bc billing.SBillingCycle) error { 780 params := map[string]string{ 781 "DBInstanceId": instanceId, 782 "Period": fmt.Sprintf("%d", bc.GetMonths()), 783 "ClientToken": utils.GenRequestId(20), 784 } 785 _, err := region.rdsRequest("RenewInstance", params) 786 return err 787 } 788 789 func (rds *SDBInstance) GetTags() (map[string]string, error) { 790 tags, err := rds.region.ListResourceTags("rds", "INSTANCE", []string{rds.GetId()}) 791 if err != nil { 792 return nil, errors.Wrap(err, "rds.region.ListResourceTags") 793 } 794 if _, ok := tags[rds.GetId()]; !ok { 795 return map[string]string{}, nil 796 } 797 return *tags[rds.GetId()], nil 798 } 799 800 func (rds *SDBInstance) SetTags(tags map[string]string, replace bool) error { 801 return rds.region.SetResourceTags("rds", "INSTANCE", []string{rds.GetId()}, tags, replace) 802 }