diff --git a/docs/resources/rds_instance.md b/docs/resources/rds_instance.md index f7c8281b3f..15f5d3072d 100644 --- a/docs/resources/rds_instance.md +++ b/docs/resources/rds_instance.md @@ -2,9 +2,9 @@ subcategory: "Relational Database Service (RDS)" --- -# huaweicloud\_rds\_instance +# huaweicloud_rds_instance -Manage RDS instance resource +Manage RDS instance resource within HuaweiCloud. This is an alternative to `huaweicloud_rds_instance_v3` ## Example Usage @@ -18,22 +18,24 @@ resource "huaweicloud_networking_secgroup" "secgroup" { } resource "huaweicloud_rds_instance" "instance" { + name = "terraform_test_rds_instance" + flavor = "rds.pg.n1.large.2" + vpc_id = "{{ vpc_id }}" + subnet_id = "{{ subnet_id }}" + security_group_id = huaweicloud_networking_secgroup.secgroup.id availability_zone = ["{{ availability_zone }}"] + db { - password = "Huangwei!120521" type = "PostgreSQL" - version = "9.5" - port = "8635" + version = "12" + password = "Huangwei!120521" } - name = "terraform_test_rds_instance" - security_group_id = huaweicloud_networking_secgroup.secgroup.id - subnet_id = "{{ subnet_id }}" - vpc_id = "{{ vpc_id }}" + volume { type = "ULTRAHIGH" size = 100 } - flavor = "rds.pg.c2.large" + backup_strategy { start_time = "08:00-09:00" keep_days = 1 @@ -50,23 +52,23 @@ resource "huaweicloud_networking_secgroup" "secgroup" { } resource "huaweicloud_rds_instance" "instance" { - availability_zone = ["{{ availability_zone_1 }}", "{{ availability_zone_2 }}"] + name = "terraform_test_rds_instance" + flavor = "rds.pg.n1.large.2.ha" + ha_replication_mode = "async" + vpc_id = "{{ vpc_id }}" + subnet_id = "{{ subnet_id }}" + security_group_id = huaweicloud_networking_secgroup.secgroup.id + availability_zone = ["{{ availability_zone_1 }}", "{{ availability_zone_2 }}"] + db { - password = "Huangwei!120521" type = "PostgreSQL" - version = "9.5" - port = "8635" + version = "12" + password = "Huangwei!120521" } - name = "terraform_test_rds_instance" - security_group_id = huaweicloud_networking_secgroup.secgroup.id - subnet_id = "{{ subnet_id }}" - vpc_id = "{{ vpc_id }}" volume { type = "ULTRAHIGH" size = 100 } - flavor = "rds.pg.s1.large.ha" - ha_replication_mode = "async" backup_strategy { start_time = "08:00-09:00" keep_days = 1 @@ -89,23 +91,23 @@ resource "huaweicloud_networking_secgroup" "secgroup" { } resource "huaweicloud_rds_instance" "instance" { + name = "terraform_test_rds_instance" + flavor = "rds.pg.n1.large.2" + vpc_id = "{{ vpc_id }}" + subnet_id = "{{ subnet_id }}" + security_group_id = huaweicloud_networking_secgroup.secgroup.id availability_zone = ["{{ availability_zone }}"] + db { - password = "Huangwei!120521" type = "PostgreSQL" - version = "9.5" - port = "8635" + version = "12" + password = "Huangwei!120521" } - name = "terraform_test_rds_instance" - security_group_id = huaweicloud_networking_secgroup.secgroup.id - subnet_id = "{{ subnet_id }}" - vpc_id = "{{ vpc_id }}" volume { - disk_encryption_id = huaweicloud_kms_key.key.id type = "ULTRAHIGH" size = 100 + disk_encryption_id = huaweicloud_kms_key.key.id } - flavor = "rds.pg.c2.large" backup_strategy { start_time = "08:00-09:00" keep_days = 1 @@ -120,7 +122,7 @@ The following arguments are supported: * `region` - (Optional, String, ForceNew) The region in which to create the rds instance resource. If omitted, the provider-level region will be used. Changing this creates a new rds instance resource. -* `availability_zone` - (Required, String, ForceNew) Specifies the AZ name. +* `availability_zone` - (Required, List, ForceNew) Specifies the list of AZ name. Changing this parameter will create a new resource. * `name` - (Required, String) Specifies the DB instance name. The DB instance name of the same type @@ -129,6 +131,8 @@ The following arguments are supported: * `flavor` - (Required, String) Specifies the specification code. + -> **NOTE:** Services will be interrupted for 5 to 10 minutes when you change RDS instance flavor. + * `db` - (Required, String, ForceNew) Specifies the database information. Structure is documented below. Changing this parameter will create a new resource. @@ -148,10 +152,14 @@ The following arguments are supported: * `backup_strategy` - (Optional, List) Specifies the advanced backup policy. Structure is documented below. * `ha_replication_mode` - (Optional, String, ForceNew) Specifies the replication mode for the standby DB instance. - For MySQL, the value is *async* or *semisync*. For PostgreSQL, the value is *async* or *sync*. - For Microsoft SQL Server, the value is *sync*. NOTE: async indicates the asynchronous replication mode. - semisync indicates the semi-synchronous replication mode. sync indicates the synchronous replication mode. Changing this parameter will create a new resource. + - For MySQL, the value is *async* or *semisync*. + - For PostgreSQL, the value is *async* or *sync*. + - For Microsoft SQL Server, the value is *sync*. + + -> **NOTE:** async indicates the asynchronous replication mode. + semisync indicates the semi-synchronous replication mode. + sync indicates the synchronous replication mode. * `param_group_id` - (Optional, String, ForceNew) Specifies the parameter group ID. Changing this parameter will create a new resource. @@ -160,7 +168,8 @@ The following arguments are supported: For MySQL and PostgreSQL Chinese mainland site and international site use UTC by default. The value ranges from UTC-12:00 to UTC+12:00 at the full hour. For Microsoft SQL Server international site use UTC by default and Chinese mainland site use China Standard Time. - The time zone is expressed as a character string, refer to [HuaweiCloud Document](https://support.huaweicloud.com/intl/en-us/api-rds/rds_01_0002.html#rds_01_0002__table613473883617). + The time zone is expressed as a character string, refer to + [HuaweiCloud Document](https://support.huaweicloud.com/intl/en-us/api-rds/rds_01_0002.html#rds_01_0002__table613473883617). * `charging_mode` - (Optional, String, ForceNew) Specifies the charging mode of the RDS DB instance. Valid values are *prePaid* and *postPaid*, defaults to *postPaid*. @@ -186,59 +195,56 @@ The following arguments are supported: The `db` block supports: +* `type` - (Required, String, ForceNew) Specifies the DB engine. Available value are *MySQL*, *PostgreSQL* and *SQLServer*. + Changing this parameter will create a new resource. + +* `version` - (Required, String, ForceNew) Specifies the database version. + Changing this parameter will create a new resource. Available values detailed in + [DB Engines and Versions](https://support.huaweicloud.com/intl/en-us/productdesc-rds/en-us_topic_0043898356.html). + * `password` - (Required, String, ForceNew) Specifies the database password. The value cannot be empty and should contain 8 to 32 characters, including uppercase and lowercase letters, digits, and the following special characters: ~!@#%^*-_=+? You are advised to enter a strong password to improve security, preventing security risks such as - brute force cracking. Changing this parameter will create a new resource. - -* `port` - (Optional, Int, ForceNew) Specifies the database port information. The MySQL database port - ranges from 1024 to 65535 (excluding 12017 and 33071, which are - occupied by the RDS system and cannot be used). The PostgreSQL - database port ranges from 2100 to 9500. The Microsoft SQL Server - database port can be 1433 or ranges from 2100 to 9500, excluding - 5355 and 5985. If this parameter is not set, the default value is - as follows: For MySQL, the default value is 3306. For PostgreSQL, - the default value is 5432. For Microsoft SQL Server, the default - value is 1433. Changing this parameter will create a new resource. - -* `type` - (Required, String, ForceNew) Specifies the DB engine. Value: *MySQL*, *PostgreSQL*, *SQLServer*. - Changing this parameter will create a new resource. - -* `version` - (Required, String, ForceNew) Specifies the database version. Changing this parameter will create a new resource. - Available value for attributes: + brute force cracking. Changing this parameter will create a new resource. -type | version ----- | --- -MySQL| 5.6
5.7
8.0
*8.0 is available only for users with the required permission.*
*You can contact customer service to apply for the permission.* -PostgreSQL | 9.5
9.6
10
11 -SQLServer| 2008_R2_EE
2008_R2_WEB
2012_SE
2014_SE
2016_SE
2017_SE
2012_EE
2014_EE
2016_EE
2017_EE
2012_WEB
2014_WEB
2016_WEB
2017_WEB +* `port` - (Optional, Int, ForceNew) Specifies the database port. Changing this parameter will create a new resource. + - The MySQL database port ranges from 1024 to 65535 (excluding 12017 and 33071, which are + occupied by the RDS system and cannot be used). The default value is 3306. + - The PostgreSQL database port ranges from 2100 to 9500. The default value is 5432. + - The Microsoft SQL Server database port can be 1433 or ranges from 2100 to 9500, + excluding 5355 and 5985. The default value is 1433. The `volume` block supports: * `size` - (Required, Int) Specifies the volume size. Its value range is from 40 GB to 4000 - GB. The value must be a multiple of 10. Changing this resize the volume. + GB. The value must be a multiple of 10 and greater than the original size. * `type` - (Required, String, ForceNew) Specifies the volume type. Its value can be any of the following and is case-sensitive: - - ULTRAHIGH: indicates the SSD type. - - LOCALSSD: indicates the local SSD. + - *ULTRAHIGH*: SSD storage. + - *LOCALSSD*: local SSD storage. + - *CLOUDSSD*: cloud SSD storage. This storage type is supported only with general-purpose and dedicated DB instances. + - *ESSD*: extreme SSD storage. - Changing this parameter will create a new resource. + Changing this parameter will create a new resource. For details about volume types, see + [DB Instance Storage Types](https://support.huaweicloud.com/intl/en-us/productdesc-rds/rds_01_0020.html). -* `disk_encryption_id` - (Optional) Specifies the key ID for disk encryption. Changing this parameter will create a new resource. +* `disk_encryption_id` - (Optional) Specifies the key ID for disk encryption. + Changing this parameter will create a new resource. The `backup_strategy` block supports: -* `keep_days` - (Optional, Int) Specifies the retention days for specific backup files. The value - range is from 0 to 732. If this parameter is not specified or set - to 0, the automated backup policy is disabled. NOTICE: - Primary/standby DB instances of Microsoft SQL Server do not +* `keep_days` - (Optional, Int) Specifies the retention days for specific backup files. + The value range is from 0 to 732. If this parameter is not specified or set to 0, + the automated backup policy is disabled. + + -> **NOTE:** Primary/standby DB instances of Microsoft SQL Server do not support disabling the automated backup policy. * `start_time` - (Required, String) Specifies the backup time window. Automated backups will be - triggered during the backup time window. It must be a valid value in the "hh:mm-HH:MM" + triggered during the backup time window. It must be a valid value in the **hh:mm-HH:MM** format. The current time is in the UTC format. The HH value must be 1 greater than the hh value. The values of mm and MM must be the same and must be set to any of the following: 00, 15, 30, or 45. diff --git a/docs/resources/rds_read_replica_instance.md b/docs/resources/rds_read_replica_instance.md index 6e55d68a98..deb66b6c3d 100644 --- a/docs/resources/rds_read_replica_instance.md +++ b/docs/resources/rds_read_replica_instance.md @@ -2,7 +2,7 @@ subcategory: "Relational Database Service (RDS)" --- -# huaweicloud\_rds\_read\_replica\_instance +# huaweicloud_rds_read_replica_instance Manage RDS Read Replica Instance resource. @@ -17,17 +17,17 @@ resource "huaweicloud_networking_secgroup" "secgroup" { resource "huaweicloud_rds_instance" "instance" { name = "terraform_test_rds_instance" - flavor = "rds.pg.c2.medium" - availability_zone = ["{{ availability_zone }}"] - security_group_id = huaweicloud_networking_secgroup.secgroup.id + flavor = "rds.pg.n1.large.2" + availability_zone = ["{{ availability_zone }}"] vpc_id = "{{ vpc_id }}" subnet_id = "{{ subnet_id }}" + security_group_id = huaweicloud_networking_secgroup.secgroup.id enterprise_project_id = "{{ enterprise_project_id }}" db { - password = "Huangwei!120521" type = "PostgreSQL" - version = "10" + version = "12" + password = "Huangwei!120521" port = "8635" } volume { @@ -41,8 +41,8 @@ resource "huaweicloud_rds_instance" "instance" { } resource "huaweicloud_rds_read_replica_instance" "replica_instance" { - name = "terraform_test_rds_read_replica_instance" - flavor = "rds.pg.c2.medium.rr" + name = "test_rds_readonly_instance" + flavor = "rds.pg.n1.large.2.rr" primary_instance_id = huaweicloud_rds_instance.instance.id availability_zone = "{{ availability_zone }}" enterprise_project_id = "{{ enterprise_project_id }}" @@ -75,6 +75,7 @@ The following arguments are supported: Changing this parameter will create a new resource. * `volume` - (Required, List, ForceNew) Specifies the volume information. Structure is documented below. + Changing this parameter will create a new resource. * `enterprise_project_id` - (Optional, String, ForceNew) The enterprise project id of the read replica instance. Changing this parameter will create a new resource. @@ -84,8 +85,10 @@ The following arguments are supported: The `volume` block supports: * `type` - (Required, String, ForceNew) Specifies the volume type. Its value can be any of the following and is case-sensitive: - - ULTRAHIGH: indicates the SSD type. - - LOCALSSD: indicates the local SSD. + - *ULTRAHIGH*: SSD storage. + - *LOCALSSD*: local SSD storage. + - *CLOUDSSD*: cloud SSD storage. This storage type is supported only with general-purpose and dedicated DB instances. + - *ESSD*: extreme SSD storage. Changing this parameter will create a new resource. diff --git a/huaweicloud/resource_huaweicloud_rds_instance_v3.go b/huaweicloud/resource_huaweicloud_rds_instance_v3.go index d714f34159..2f05e2a57e 100644 --- a/huaweicloud/resource_huaweicloud_rds_instance_v3.go +++ b/huaweicloud/resource_huaweicloud_rds_instance_v3.go @@ -281,11 +281,11 @@ func resourceRdsInstanceV3Create(d *schema.ResourceData, meta interface{}) error Port: strconv.Itoa(d.Get("db.0.port").(int)), EnterpriseProjectId: GetEnterpriseProjectID(d, config), Region: region, - AvailabilityZone: resourceRdsInstanceAvailabilityZone(d), - Datastore: resourceRdsInstanceDatastore(d), - Volume: resourceRdsInstanceVolume(d), - BackupStrategy: resourceRdsInstanceBackupStrategy(d), - Ha: resourceRdsInstanceHaReplicationMode(d), + AvailabilityZone: buildRdsInstanceAvailabilityZone(d), + Datastore: buildRdsInstanceDatastore(d), + Volume: buildRdsInstanceVolume(d), + BackupStrategy: buildRdsInstanceBackupStrategy(d), + Ha: buildRdsInstanceHaReplicationMode(d), } // PrePaid @@ -490,7 +490,7 @@ func resourceRdsInstanceV3Update(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("[ERROR] %s", err) } - if err := updateRdsInstanceVolume(d, client, instanceID); err != nil { + if err := updateRdsInstanceVolumeSize(d, client, instanceID); err != nil { return fmt.Errorf("[ERROR] %s", err) } @@ -508,7 +508,80 @@ func resourceRdsInstanceV3Update(d *schema.ResourceData, meta interface{}) error return resourceRdsInstanceV3Read(d, meta) } -func resourceRdsInstanceAvailabilityZone(d *schema.ResourceData) string { +func resourceRdsInstanceDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*config.Config) + client, err := config.RdsV3Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating huaweicloud rds client: %s ", err) + } + + id := d.Id() + log.Printf("[DEBUG] Deleting Instance %s", id) + if v, ok := d.GetOk("charging_mode"); ok && v.(string) == "prePaid" { + if err := UnsubscribePrePaidResource(d, config, []string{id}); err != nil { + return fmt.Errorf("Error unsubscribe HuaweiCloud RDS instance: %s", err) + } + } else { + result := instances.Delete(client, id) + if result.Err != nil { + return result.Err + } + } + + stateConf := &resource.StateChangeConf{ + Pending: []string{"ACTIVE"}, + Target: []string{"DELETED"}, + Refresh: rdsInstanceStateRefreshFunc(client, id), + Timeout: d.Timeout(schema.TimeoutCreate), + Delay: 15 * time.Second, + MinTimeout: 5 * time.Second, + } + + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf( + "Error waiting for rds instance (%s) to be deleted: %s ", + id, err) + } + + log.Printf("[DEBUG] Successfully deleted rds instance %s", id) + return nil +} + +func getRdsInstanceByID(client *golangsdk.ServiceClient, instanceID string) (*instances.RdsInstanceResponse, error) { + listOpts := instances.ListOpts{ + Id: instanceID, + } + pages, err := instances.List(client, listOpts).AllPages() + if err != nil { + return nil, fmt.Errorf("An error occured while querying rds instance %s: %s", instanceID, err) + } + + resp, err := instances.ExtractRdsInstances(pages) + if err != nil { + return nil, err + } + + instanceList := resp.Instances + if len(instanceList) == 0 { + // return an empty rds instance + log.Printf("[WARN] can not find the specified rds instance %s", instanceID) + instance := new(instances.RdsInstanceResponse) + return instance, nil + } + + if len(instanceList) > 1 { + return nil, fmt.Errorf("retrieving more than one rds instance by %s", instanceID) + } + if instanceList[0].Id != instanceID { + return nil, fmt.Errorf("the id of rds instance was expected %s, but got %s", + instanceID, instanceList[0].Id) + } + + return &instanceList[0], nil +} + +func buildRdsInstanceAvailabilityZone(d *schema.ResourceData) string { azList := make([]string, len(d.Get("availability_zone").([]interface{}))) for i, az := range d.Get("availability_zone").([]interface{}) { azList[i] = az.(string) @@ -516,7 +589,7 @@ func resourceRdsInstanceAvailabilityZone(d *schema.ResourceData) string { return strings.Join(azList, ",") } -func resourceRdsInstanceDatastore(d *schema.ResourceData) *instances.Datastore { +func buildRdsInstanceDatastore(d *schema.ResourceData) *instances.Datastore { var database *instances.Datastore dbRaw := d.Get("db").([]interface{}) @@ -528,7 +601,7 @@ func resourceRdsInstanceDatastore(d *schema.ResourceData) *instances.Datastore { return database } -func resourceRdsInstanceVolume(d *schema.ResourceData) *instances.Volume { +func buildRdsInstanceVolume(d *schema.ResourceData) *instances.Volume { var volume *instances.Volume volumeRaw := d.Get("volume").([]interface{}) @@ -540,7 +613,7 @@ func resourceRdsInstanceVolume(d *schema.ResourceData) *instances.Volume { return volume } -func resourceRdsInstanceBackupStrategy(d *schema.ResourceData) *instances.BackupStrategy { +func buildRdsInstanceBackupStrategy(d *schema.ResourceData) *instances.BackupStrategy { var backupStrategy *instances.BackupStrategy backupRaw := d.Get("backup_strategy").([]interface{}) @@ -552,70 +625,132 @@ func resourceRdsInstanceBackupStrategy(d *schema.ResourceData) *instances.Backup return backupStrategy } -func resourceRdsInstanceHaReplicationMode(d *schema.ResourceData) *instances.Ha { +func buildRdsInstanceHaReplicationMode(d *schema.ResourceData) *instances.Ha { var ha *instances.Ha - if hasFilledOpt(d, "ha_replication_mode") { + if v, ok := d.GetOk("ha_replication_mode"); ok { ha = new(instances.Ha) ha.Mode = "ha" - ha.ReplicationMode = d.Get("ha_replication_mode").(string) + ha.ReplicationMode = v.(string) } return ha } -func updateRdsInstanceBackpStrategy(d *schema.ResourceData, client *golangsdk.ServiceClient, instanceID string) error { - if d.HasChange("backup_strategy") { - var updateOpts backups.UpdateOpts - - backupRaw := d.Get("backup_strategy").([]interface{}) - rawMap := backupRaw[0].(map[string]interface{}) - keep_days := rawMap["keep_days"].(int) - updateOpts.KeepDays = &keep_days - updateOpts.StartTime = rawMap["start_time"].(string) - // TODO(zhenguo): Make Period configured by users - updateOpts.Period = "1,2,3,4,5,6,7" - log.Printf("[DEBUG] updateOpts: %#v", updateOpts) - err := backups.Update(client, instanceID, updateOpts).ExtractErr() - if err != nil { - return fmt.Errorf("Error updating HuaweiCloud RDS instance (%s): %s", instanceID, err) - } +func updateRdsInstanceName(d *schema.ResourceData, client *golangsdk.ServiceClient, instanceID string) error { + if !d.HasChange("name") { + return nil + } - stateConf := &resource.StateChangeConf{ - Pending: []string{"BACKING UP"}, - Target: []string{"ACTIVE"}, - Refresh: rdsInstanceStateRefreshFunc(client, instanceID), - Timeout: d.Timeout(schema.TimeoutUpdate), - Delay: 15 * time.Second, - MinTimeout: 3 * time.Second, - } - if _, err = stateConf.WaitForState(); err != nil { - return fmt.Errorf("Error waiting for RDS instance (%s) backup to be updated: %s ", instanceID, err) - } + renameOpts := instances.RenameInstanceOpts{ + Name: d.Get("name").(string), + } + r := instances.Rename(client, renameOpts, instanceID) + if r.Result.Err != nil { + return fmt.Errorf("Error renaming HuaweiCloud RDS instance (%s): %s", instanceID, r.Err) + } + + stateConf := &resource.StateChangeConf{ + Pending: []string{"MODIFYING", "ACTIVE"}, + Target: []string{"ACTIVE"}, + Refresh: rdsInstanceStateRefreshFunc(client, instanceID), + Timeout: d.Timeout(schema.TimeoutUpdate), + Delay: 5 * time.Second, + MinTimeout: 3 * time.Second, + } + if _, err := stateConf.WaitForState(); err != nil { + return fmt.Errorf("Error waiting for RDS instance (%s) flavor to be updated: %s ", instanceID, err) } + return nil } -func updateRdsInstanceName(d *schema.ResourceData, client *golangsdk.ServiceClient, instanceID string) error { - if d.HasChange("name") { - var renameOpts instances.RenameInstanceOpts +func updateRdsInstanceFlavor(d *schema.ResourceData, client *golangsdk.ServiceClient, instanceID string) error { + if !d.HasChange("flavor") { + return nil + } - renameOpts.Name = d.Get("name").(string) - r := instances.Rename(client, renameOpts, instanceID) - if r.Result.Err != nil { - return fmt.Errorf("Error renaming HuaweiCloud RDS instance (%s): %s", instanceID, r.Err) - } + resizeFlavor := instances.SpecCode{ + Speccode: d.Get("flavor").(string), + } + var resizeFlavorOpts instances.ResizeFlavorOpts + resizeFlavorOpts.ResizeFlavor = &resizeFlavor - stateConf := &resource.StateChangeConf{ - Pending: []string{"MODIFYING", "ACTIVE"}, - Target: []string{"ACTIVE"}, - Refresh: rdsInstanceStateRefreshFunc(client, instanceID), - Timeout: d.Timeout(schema.TimeoutUpdate), - Delay: 5 * time.Second, - MinTimeout: 3 * time.Second, - } - if _, err := stateConf.WaitForState(); err != nil { - return fmt.Errorf("Error waiting for RDS instance (%s) flavor to be updated: %s ", instanceID, err) - } + _, err := instances.Resize(client, resizeFlavorOpts, instanceID).Extract() + if err != nil { + return fmt.Errorf("Error updating instance Flavor from result: %s ", err) + } + + stateConf := &resource.StateChangeConf{ + Pending: []string{"MODIFYING"}, + Target: []string{"ACTIVE"}, + Refresh: rdsInstanceStateRefreshFunc(client, instanceID), + Timeout: d.Timeout(schema.TimeoutCreate), + Delay: 15 * time.Second, + PollInterval: 15 * time.Second, + } + if _, err = stateConf.WaitForState(); err != nil { + return fmt.Errorf("Error waiting for instance (%s) flavor to be Updated: %s ", instanceID, err) + } + return nil +} + +func updateRdsInstanceVolumeSize(d *schema.ResourceData, client *golangsdk.ServiceClient, instanceID string) error { + if !d.HasChange("volume.0.size") { + return nil + } + + volumeRaw := d.Get("volume").([]interface{}) + volumeItem := volumeRaw[0].(map[string]interface{}) + enlargeOpts := instances.EnlargeVolumeOpts{ + EnlargeVolume: &instances.EnlargeVolumeSize{ + Size: volumeItem["size"].(int), + }, + } + + log.Printf("[DEBUG] Enlarge Volume opts: %+v", enlargeOpts) + instance, err := instances.EnlargeVolume(client, enlargeOpts, instanceID).Extract() + if err != nil { + return fmt.Errorf("Error updating instance volume from result: %s ", err) + } + if err := checkRDSInstanceJobFinish(client, instance.JobId, d.Timeout(schema.TimeoutUpdate)); err != nil { + return fmt.Errorf("Error updating instance (%s): %s", instanceID, err) + } + + return nil +} + +func updateRdsInstanceBackpStrategy(d *schema.ResourceData, client *golangsdk.ServiceClient, instanceID string) error { + if !d.HasChange("backup_strategy") { + return nil + } + + backupRaw := d.Get("backup_strategy").([]interface{}) + rawMap := backupRaw[0].(map[string]interface{}) + keepDays := rawMap["keep_days"].(int) + + updateOpts := backups.UpdateOpts{ + KeepDays: &keepDays, + StartTime: rawMap["start_time"].(string), + Period: "1,2,3,4,5,6,7", + } + + log.Printf("[DEBUG] updateOpts: %#v", updateOpts) + err := backups.Update(client, instanceID, updateOpts).ExtractErr() + if err != nil { + return fmt.Errorf("Error updating FlexibleEngine RDS instance (%s): %s", instanceID, err) + } + + stateConf := &resource.StateChangeConf{ + Pending: []string{"BACKING UP"}, + Target: []string{"ACTIVE"}, + Refresh: rdsInstanceStateRefreshFunc(client, instanceID), + Timeout: d.Timeout(schema.TimeoutUpdate), + Delay: 15 * time.Second, + MinTimeout: 3 * time.Second, + } + if _, err = stateConf.WaitForState(); err != nil { + return fmt.Errorf("Error waiting for RDS instance (%s) backup to be updated: %s ", instanceID, err) } + return nil } @@ -647,3 +782,17 @@ func rdsInstanceJobRefreshFunc(client *golangsdk.ServiceClient, jobID string) re return jobList.Job, jobList.Job.Status, nil } } + +func rdsInstanceStateRefreshFunc(client *golangsdk.ServiceClient, instanceID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + instance, err := getRdsInstanceByID(client, instanceID) + if err != nil { + return nil, "FOUND ERROR", err + } + if instance.Id == "" { + return instance, "DELETED", nil + } + + return instance, instance.Status, nil + } +} diff --git a/huaweicloud/resource_huaweicloud_rds_instance_v3_test.go b/huaweicloud/resource_huaweicloud_rds_instance_v3_test.go index 978489eacb..a654fe2f0c 100644 --- a/huaweicloud/resource_huaweicloud_rds_instance_v3_test.go +++ b/huaweicloud/resource_huaweicloud_rds_instance_v3_test.go @@ -14,13 +14,13 @@ import ( func TestAccRdsInstanceV3_basic(t *testing.T) { var instance instances.RdsInstanceResponse name := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5)) - resourceLabel := "huaweicloud_rds_instance" + resourceType := "huaweicloud_rds_instance" resourceName := "huaweicloud_rds_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckRdsInstanceV3Destroy(resourceLabel), + CheckDestroy: testAccCheckRdsInstanceV3Destroy(resourceType), Steps: []resource.TestStep{ { Config: testAccRdsInstanceV3_basic(name), @@ -28,11 +28,11 @@ func TestAccRdsInstanceV3_basic(t *testing.T) { testAccCheckRdsInstanceV3Exists(resourceName, &instance), resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, "backup_strategy.0.keep_days", "1"), - resource.TestCheckResourceAttr(resourceName, "flavor", "rds.pg.c6.large.2"), + resource.TestCheckResourceAttr(resourceName, "flavor", "rds.pg.n1.large.2"), resource.TestCheckResourceAttr(resourceName, "volume.0.size", "50"), resource.TestCheckResourceAttr(resourceName, "tags.key", "value"), resource.TestCheckResourceAttr(resourceName, "tags.foo", "bar"), - resource.TestCheckResourceAttr(resourceName, "time_zone", "UTC+10:00"), + resource.TestCheckResourceAttr(resourceName, "time_zone", "UTC+08:00"), resource.TestCheckResourceAttr(resourceName, "fixed_ip", "192.168.0.58"), resource.TestCheckResourceAttr(resourceName, "charging_mode", "postPaid"), ), @@ -43,7 +43,7 @@ func TestAccRdsInstanceV3_basic(t *testing.T) { testAccCheckRdsInstanceV3Exists(resourceName, &instance), resource.TestCheckResourceAttr(resourceName, "name", fmt.Sprintf("%s-update", name)), resource.TestCheckResourceAttr(resourceName, "backup_strategy.0.keep_days", "2"), - resource.TestCheckResourceAttr(resourceName, "flavor", "rds.pg.c6.xlarge.2"), + resource.TestCheckResourceAttr(resourceName, "flavor", "rds.pg.n1.xlarge.2"), resource.TestCheckResourceAttr(resourceName, "volume.0.size", "100"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value"), resource.TestCheckResourceAttr(resourceName, "tags.foo", "bar_updated"), @@ -66,13 +66,13 @@ func TestAccRdsInstanceV3_basic(t *testing.T) { func TestAccRdsInstanceV3_withEpsId(t *testing.T) { var instance instances.RdsInstanceResponse name := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5)) - resourceLabel := "huaweicloud_rds_instance" + resourceType := "huaweicloud_rds_instance" resourceName := "huaweicloud_rds_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheckEpsID(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckRdsInstanceV3Destroy(resourceLabel), + CheckDestroy: testAccCheckRdsInstanceV3Destroy(resourceType), Steps: []resource.TestStep{ { Config: testAccRdsInstanceV3_epsId(name), @@ -88,13 +88,13 @@ func TestAccRdsInstanceV3_withEpsId(t *testing.T) { func TestAccRdsInstanceV3_ha(t *testing.T) { var instance instances.RdsInstanceResponse name := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5)) - resourceLabel := "huaweicloud_rds_instance" + resourceType := "huaweicloud_rds_instance" resourceName := "huaweicloud_rds_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckRdsInstanceV3Destroy(resourceLabel), + CheckDestroy: testAccCheckRdsInstanceV3Destroy(resourceType), Steps: []resource.TestStep{ { Config: testAccRdsInstanceV3_ha(name), @@ -102,11 +102,11 @@ func TestAccRdsInstanceV3_ha(t *testing.T) { testAccCheckRdsInstanceV3Exists(resourceName, &instance), resource.TestCheckResourceAttr(resourceName, "name", name), resource.TestCheckResourceAttr(resourceName, "backup_strategy.0.keep_days", "1"), - resource.TestCheckResourceAttr(resourceName, "flavor", "rds.pg.c6.large.2.ha"), + resource.TestCheckResourceAttr(resourceName, "flavor", "rds.pg.n1.large.2.ha"), resource.TestCheckResourceAttr(resourceName, "volume.0.size", "50"), resource.TestCheckResourceAttr(resourceName, "tags.key", "value"), resource.TestCheckResourceAttr(resourceName, "tags.foo", "bar"), - resource.TestCheckResourceAttr(resourceName, "time_zone", "UTC+10:00"), + resource.TestCheckResourceAttr(resourceName, "time_zone", "UTC+08:00"), resource.TestCheckResourceAttr(resourceName, "fixed_ip", "192.168.0.58"), resource.TestCheckResourceAttr(resourceName, "ha_replication_mode", "async"), ), @@ -115,7 +115,7 @@ func TestAccRdsInstanceV3_ha(t *testing.T) { }) } -func testAccCheckRdsInstanceV3Destroy(providerRes string) resource.TestCheckFunc { +func testAccCheckRdsInstanceV3Destroy(rsType string) resource.TestCheckFunc { return func(s *terraform.State) error { config := testAccProvider.Meta().(*config.Config) client, err := config.RdsV3Client(HW_REGION_NAME) @@ -124,7 +124,7 @@ func testAccCheckRdsInstanceV3Destroy(providerRes string) resource.TestCheckFunc } for _, rs := range s.RootModule().Resources { - if rs.Type != providerRes { + if rs.Type != rsType { continue } @@ -134,7 +134,7 @@ func testAccCheckRdsInstanceV3Destroy(providerRes string) resource.TestCheckFunc return err } if instance.Id != "" { - return fmt.Errorf("%s (%s) still exists", providerRes, id) + return fmt.Errorf("%s (%s) still exists", rsType, id) } } return nil @@ -202,22 +202,22 @@ func testAccRdsInstanceV3_basic(name string) string { resource "huaweicloud_rds_instance" "test" { name = "%s" - flavor = "rds.pg.c6.large.2" + flavor = "rds.pg.n1.large.2" availability_zone = [data.huaweicloud_availability_zones.test.names[0]] security_group_id = huaweicloud_networking_secgroup.test.id subnet_id = huaweicloud_vpc_subnet.test.id vpc_id = huaweicloud_vpc.test.id - time_zone = "UTC+10:00" + time_zone = "UTC+08:00" fixed_ip = "192.168.0.58" db { password = "Huangwei!120521" type = "PostgreSQL" - version = "10" + version = "12" port = 8635 } volume { - type = "ULTRAHIGH" + type = "CLOUDSSD" size = 50 } backup_strategy { @@ -240,21 +240,21 @@ func testAccRdsInstanceV3_update(name string) string { resource "huaweicloud_rds_instance" "test" { name = "%s-update" - flavor = "rds.pg.c6.xlarge.2" + flavor = "rds.pg.n1.xlarge.2" availability_zone = [data.huaweicloud_availability_zones.test.names[0]] security_group_id = huaweicloud_networking_secgroup.test.id subnet_id = huaweicloud_vpc_subnet.test.id vpc_id = huaweicloud_vpc.test.id - time_zone = "UTC+10:00" + time_zone = "UTC+08:00" db { password = "Huangwei!120521" type = "PostgreSQL" - version = "10" + version = "12" port = 8635 } volume { - type = "ULTRAHIGH" + type = "CLOUDSSD" size = 100 } backup_strategy { @@ -276,7 +276,7 @@ func testAccRdsInstanceV3_epsId(name string) string { resource "huaweicloud_rds_instance" "test" { name = "%s" - flavor = "rds.pg.c6.large.2" + flavor = "rds.pg.n1.large.2" availability_zone = [data.huaweicloud_availability_zones.test.names[0]] security_group_id = huaweicloud_networking_secgroup.test.id subnet_id = huaweicloud_vpc_subnet.test.id @@ -286,11 +286,11 @@ resource "huaweicloud_rds_instance" "test" { db { password = "Huangwei!120521" type = "PostgreSQL" - version = "10" + version = "12" port = 8635 } volume { - type = "ULTRAHIGH" + type = "CLOUDSSD" size = 50 } backup_strategy { @@ -307,11 +307,11 @@ func testAccRdsInstanceV3_ha(name string) string { resource "huaweicloud_rds_instance" "test" { name = "%s" - flavor = "rds.pg.c6.large.2.ha" + flavor = "rds.pg.n1.large.2.ha" security_group_id = huaweicloud_networking_secgroup.test.id subnet_id = huaweicloud_vpc_subnet.test.id vpc_id = huaweicloud_vpc.test.id - time_zone = "UTC+10:00" + time_zone = "UTC+08:00" fixed_ip = "192.168.0.58" ha_replication_mode = "async" availability_zone = [ @@ -322,11 +322,11 @@ resource "huaweicloud_rds_instance" "test" { db { password = "Huangwei!120521" type = "PostgreSQL" - version = "10" + version = "12" port = 8635 } volume { - type = "ULTRAHIGH" + type = "CLOUDSSD" size = 50 } backup_strategy { diff --git a/huaweicloud/resource_huaweicloud_rds_read_replica_instance.go b/huaweicloud/resource_huaweicloud_rds_read_replica_instance.go index cb3a1bd1e1..686392fe2f 100644 --- a/huaweicloud/resource_huaweicloud_rds_read_replica_instance.go +++ b/huaweicloud/resource_huaweicloud_rds_read_replica_instance.go @@ -3,15 +3,10 @@ package huaweicloud import ( "fmt" "log" - "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/huaweicloud/golangsdk" "github.com/huaweicloud/golangsdk/openstack/common/tags" - "github.com/huaweicloud/golangsdk/openstack/rds/v3/datastores" - "github.com/huaweicloud/golangsdk/openstack/rds/v3/flavors" "github.com/huaweicloud/golangsdk/openstack/rds/v3/instances" "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils" @@ -171,7 +166,6 @@ func ResourceRdsReadReplicaInstance() *schema.Resource { } func resourceRdsReadReplicaInstanceCreate(d *schema.ResourceData, meta interface{}) error { - config := meta.(*config.Config) client, err := config.RdsV3Client(GetRegion(d, config)) if err != nil { @@ -184,7 +178,7 @@ func resourceRdsReadReplicaInstanceCreate(d *schema.ResourceData, meta interface FlavorRef: d.Get("flavor").(string), Region: GetRegion(d, config), AvailabilityZone: d.Get("availability_zone").(string), - Volume: resourceReplicaInstanceVolume(d), + Volume: buildRdsReplicaInstanceVolume(d), DiskEncryptionId: d.Get("volume.0.disk_encryption_id").(string), EnterpriseProjectId: GetEnterpriseProjectID(d, config), } @@ -215,7 +209,6 @@ func resourceRdsReadReplicaInstanceCreate(d *schema.ResourceData, meta interface } func resourceRdsReadReplicaInstanceRead(d *schema.ResourceData, meta interface{}) error { - config := meta.(*config.Config) client, err := config.RdsV3Client(GetRegion(d, config)) if err != nil { @@ -233,12 +226,9 @@ func resourceRdsReadReplicaInstanceRead(d *schema.ResourceData, meta interface{} } log.Printf("[DEBUG] Retrieved rds read replica instance %s: %#v", instanceID, instance) - - az := readAvailabilityZone(instance) d.Set("name", instance.Name) d.Set("flavor", instance.FlavorRef) d.Set("region", instance.Region) - d.Set("availability_zone", az) d.Set("private_ips", instance.PrivateIps) d.Set("public_ips", instance.PublicIps) d.Set("vpc_id", instance.VpcId) @@ -247,14 +237,16 @@ func resourceRdsReadReplicaInstanceRead(d *schema.ResourceData, meta interface{} d.Set("type", instance.Type) d.Set("status", instance.Status) d.Set("enterprise_project_id", instance.EnterpriseProjectId) + d.Set("tags", utils.TagsToMap(instance.Tags)) - primaryInstanceID, err := readPrimaryInstanceID(instance) - if err != nil { + az := expandAvailabilityZone(instance) + d.Set("availability_zone", az) + + if primaryInstanceID, err := expandPrimaryInstanceID(instance); err == nil { + d.Set("primary_instance_id", primaryInstanceID) + } else { return err } - d.Set("primary_instance_id", primaryInstanceID) - - d.Set("tags", utils.TagsToMap(instance.Tags)) volumeList := make([]map[string]interface{}, 0, 1) volume := map[string]interface{}{ @@ -283,22 +275,17 @@ func resourceRdsReadReplicaInstanceRead(d *schema.ResourceData, meta interface{} } func resourceRdsReadReplicaInstanceUpdate(d *schema.ResourceData, meta interface{}) error { - config := meta.(*config.Config) client, err := config.RdsV3Client(GetRegion(d, config)) if err != nil { return fmt.Errorf("Error creating huaweicloud rds v3 client: %s ", err) } - instanceID := d.Id() + instanceID := d.Id() if err := updateRdsInstanceFlavor(d, client, instanceID); err != nil { return fmt.Errorf("[ERROR] %s", err) } - if err := updateRdsInstanceVolume(d, client, instanceID); err != nil { - return fmt.Errorf("[ERROR] %s", err) - } - if d.HasChange("tags") { tagErr := utils.UpdateResourceTags(client, d, "instances", instanceID) if tagErr != nil { @@ -309,187 +296,12 @@ func resourceRdsReadReplicaInstanceUpdate(d *schema.ResourceData, meta interface return resourceRdsReadReplicaInstanceRead(d, meta) } -func resourceRdsInstanceDelete(d *schema.ResourceData, meta interface{}) error { - - config := meta.(*config.Config) - client, err := config.RdsV3Client(GetRegion(d, config)) - if err != nil { - return fmt.Errorf("Error creating huaweicloud rds client: %s ", err) - } - - log.Printf("[DEBUG] Deleting Instance %s", d.Id()) - - id := d.Id() - if v, ok := d.GetOk("charging_mode"); ok && v.(string) == "prePaid" { - if err := UnsubscribePrePaidResource(d, config, []string{id}); err != nil { - return fmt.Errorf("Error unsubscribe HuaweiCloud RDS instance: %s", err) - } - } else { - result := instances.Delete(client, id) - if result.Err != nil { - return result.Err - } - } - - stateConf := &resource.StateChangeConf{ - Pending: []string{"ACTIVE"}, - Target: []string{"DELETED"}, - Refresh: rdsInstanceStateRefreshFunc(client, id), - Timeout: d.Timeout(schema.TimeoutCreate), - Delay: 15 * time.Second, - MinTimeout: 5 * time.Second, - } - - _, err = stateConf.WaitForState() - if err != nil { - return fmt.Errorf( - "Error waiting for rds instance (%s) to be deleted: %s ", - id, err) - } - - log.Printf("[DEBUG] Successfully deleted rds instance %s", id) - return nil -} - -func updateRdsInstanceFlavor(d *schema.ResourceData, client *golangsdk.ServiceClient, instanceID string) error { - if d.HasChange("flavor") { - nflavor := d.Get("flavor") - datastoreName := d.Get("db.0.type").(string) - datastoreVersion := d.Get("db.0.version").(string) - - datastoreAllPages, err := datastores.List(client, datastoreName).AllPages() - if err != nil { - return fmt.Errorf("Unable to retrieve datastores pages: %s ", err) - } - dataStores, err := datastores.ExtractDataStores(datastoreAllPages) - if err != nil { - return fmt.Errorf("Unable to analyse datastores: %s ", err) - } - if len(dataStores.DataStores) < 1 { - return fmt.Errorf("Returned no datastore result. ") - } - for _, datastore := range dataStores.DataStores { - if strings.HasPrefix(datastore.Name, datastoreVersion) { - datastoreVersion = datastore.Name - break - } - } - if datastoreVersion == "" { - return fmt.Errorf("Returned no datastore Name. ") - } - log.Printf("[DEBUG] Received datastore Version: %s", datastoreVersion) - - var dbFlavorsOpts flavors.DbFlavorsOpts - dbFlavorsOpts.Versionname = datastoreVersion - - flavorAllPages, err := flavors.List(client, dbFlavorsOpts, datastoreName).AllPages() - if err != nil { - return fmt.Errorf("Unable to retrieve flavors pages: %s", err) - } - dbFlavorsResp, err := flavors.ExtractDbFlavors(flavorAllPages) - if err != nil { - return fmt.Errorf("Unable to analyse flavors Resp: %s", err) - } - if len(dbFlavorsResp.Flavorslist) < 1 { - return fmt.Errorf("Returned no datastore result. ") - } - var rdsFlavor flavors.Flavors - for _, flavor := range dbFlavorsResp.Flavorslist { - if flavor.Speccode == nflavor.(string) { - rdsFlavor = flavor - break - } - } - - var resizeFlavorOpts instances.ResizeFlavorOpts - var resizeFlavor instances.SpecCode - resizeFlavor.Speccode = rdsFlavor.Speccode - resizeFlavorOpts.ResizeFlavor = &resizeFlavor - - // instance, err := instances.Resize(client, resizeFlavorOpts, instanceID).Extract() - _, err = instances.Resize(client, resizeFlavorOpts, instanceID).Extract() - if err != nil { - return fmt.Errorf("Error updating instance Flavor from result: %s ", err) - } - - stateConf := &resource.StateChangeConf{ - Pending: []string{"MODIFYING"}, - Target: []string{"ACTIVE"}, - Refresh: rdsInstanceStateRefreshFunc(client, instanceID), - Timeout: d.Timeout(schema.TimeoutCreate), - Delay: 15 * time.Second, - PollInterval: 15 * time.Second, - } - if _, err = stateConf.WaitForState(); err != nil { - return fmt.Errorf("Error waiting for instance (%s) flavor to be Updated: %s ", instanceID, err) - } - return nil - } - return nil -} - -func updateRdsInstanceVolume(d *schema.ResourceData, client *golangsdk.ServiceClient, instanceID string) error { - var enlargeOpts instances.EnlargeVolumeOpts - - volumeRaw := d.Get("volume").([]interface{}) - log.Printf("[DEBUG] Enlarge Volume : %+v", volumeRaw) - if len(volumeRaw) == 1 { - if m, ok := volumeRaw[0].(map[string]interface{}); ok { - var enlargeVolumeSize instances.EnlargeVolumeSize - enlargeVolumeSize.Size = m["size"].(int) - enlargeOpts.EnlargeVolume = &enlargeVolumeSize - } - } - instance, err := instances.EnlargeVolume(client, enlargeOpts, instanceID).Extract() - if err != nil { - return fmt.Errorf("Error updating instance volume from result: %s ", err) - } - if err := checkRDSInstanceJobFinish(client, instance.JobId, d.Timeout(schema.TimeoutUpdate)); err != nil { - return fmt.Errorf("Error updating instance (%s): %s", instanceID, err) - } - - return nil -} - -func getRdsInstanceByID(client *golangsdk.ServiceClient, instanceID string) (*instances.RdsInstanceResponse, error) { - listOpts := instances.ListOpts{ - Id: instanceID, - } - pages, err := instances.List(client, listOpts).AllPages() - if err != nil { - return nil, fmt.Errorf("An error occured while querying rds instance %s: %s", instanceID, err) - } - - resp, err := instances.ExtractRdsInstances(pages) - if err != nil { - return nil, err - } - - instanceList := resp.Instances - if len(instanceList) == 0 { - // return an empty rds instance - log.Printf("[WARN] can not find the specified rds instance %s", instanceID) - instance := new(instances.RdsInstanceResponse) - return instance, nil - } - - if len(instanceList) > 1 { - return nil, fmt.Errorf("retrieving more than one rds instance by %s", instanceID) - } - if instanceList[0].Id != instanceID { - return nil, fmt.Errorf("the id of rds instance was expected %s, but got %s", - instanceID, instanceList[0].Id) - } - - return &instanceList[0], nil -} - -func readAvailabilityZone(resp *instances.RdsInstanceResponse) string { +func expandAvailabilityZone(resp *instances.RdsInstanceResponse) string { node := resp.Nodes[0] return node.AvailabilityZone } -func readPrimaryInstanceID(resp *instances.RdsInstanceResponse) (string, error) { +func expandPrimaryInstanceID(resp *instances.RdsInstanceResponse) (string, error) { relatedInst := resp.RelatedInstance for _, relate := range relatedInst { if relate.Type == "replica_of" { @@ -499,7 +311,7 @@ func readPrimaryInstanceID(resp *instances.RdsInstanceResponse) (string, error) return "", fmt.Errorf("Error when get primary instance id for replica %s", resp.Id) } -func resourceReplicaInstanceVolume(d *schema.ResourceData) *instances.Volume { +func buildRdsReplicaInstanceVolume(d *schema.ResourceData) *instances.Volume { var volume *instances.Volume volumeRaw := d.Get("volume").([]interface{}) @@ -516,17 +328,3 @@ func resourceReplicaInstanceVolume(d *schema.ResourceData) *instances.Volume { log.Printf("[DEBUG] volume: %+v", volume) return volume } - -func rdsInstanceStateRefreshFunc(client *golangsdk.ServiceClient, instanceID string) resource.StateRefreshFunc { - return func() (interface{}, string, error) { - instance, err := getRdsInstanceByID(client, instanceID) - if err != nil { - return nil, "FOUND ERROR", err - } - if instance.Id == "" { - return instance, "DELETED", nil - } - - return instance, instance.Status, nil - } -} diff --git a/huaweicloud/resource_huaweicloud_rds_read_replica_instance_test.go b/huaweicloud/resource_huaweicloud_rds_read_replica_instance_test.go index ee6feafcbb..029438b330 100644 --- a/huaweicloud/resource_huaweicloud_rds_read_replica_instance_test.go +++ b/huaweicloud/resource_huaweicloud_rds_read_replica_instance_test.go @@ -12,22 +12,22 @@ import ( func TestAccRdsReadReplicaInstance_basic(t *testing.T) { var replica instances.RdsInstanceResponse name := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5)) - resourceLabel := "huaweicloud_rds_read_replica_instance" + resourceType := "huaweicloud_rds_read_replica_instance" resourceName := "huaweicloud_rds_read_replica_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckRdsInstanceV3Destroy(resourceLabel), + CheckDestroy: testAccCheckRdsInstanceV3Destroy(resourceType), Steps: []resource.TestStep{ { Config: testAccReadRdsReplicaInstance_basic(name), Check: resource.ComposeTestCheckFunc( testAccCheckRdsInstanceV3Exists(resourceName, &replica), resource.TestCheckResourceAttr(resourceName, "name", name), - resource.TestCheckResourceAttr(resourceName, "flavor", "rds.pg.c6.large.2.rr"), + resource.TestCheckResourceAttr(resourceName, "flavor", "rds.pg.n1.large.2.rr"), resource.TestCheckResourceAttr(resourceName, "type", "Replica"), - resource.TestCheckResourceAttr(resourceName, "volume.0.type", "ULTRAHIGH"), + resource.TestCheckResourceAttr(resourceName, "volume.0.type", "CLOUDSSD"), resource.TestCheckResourceAttr(resourceName, "volume.0.size", "50"), resource.TestCheckResourceAttr(resourceName, "tags.key", "value"), resource.TestCheckResourceAttr(resourceName, "tags.foo", "bar"), @@ -37,9 +37,9 @@ func TestAccRdsReadReplicaInstance_basic(t *testing.T) { Config: testAccReadRdsReplicaInstance_update(name), Check: resource.ComposeTestCheckFunc( testAccCheckRdsInstanceV3Exists(resourceName, &replica), - resource.TestCheckResourceAttr(resourceName, "flavor", "rds.pg.c6.xlarge.2.rr"), - resource.TestCheckResourceAttr(resourceName, "volume.0.type", "ULTRAHIGH"), - resource.TestCheckResourceAttr(resourceName, "volume.0.size", "120"), + resource.TestCheckResourceAttr(resourceName, "flavor", "rds.pg.n1.xlarge.2.rr"), + resource.TestCheckResourceAttr(resourceName, "volume.0.type", "CLOUDSSD"), + resource.TestCheckResourceAttr(resourceName, "volume.0.size", "50"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value"), resource.TestCheckResourceAttr(resourceName, "tags.foo", "bar2"), ), @@ -59,13 +59,13 @@ func TestAccRdsReadReplicaInstance_basic(t *testing.T) { func TestAccRdsReadReplicaInstance_withEpsId(t *testing.T) { var replica instances.RdsInstanceResponse name := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5)) - resourceLabel := "huaweicloud_rds_read_replica_instance" + resourceType := "huaweicloud_rds_read_replica_instance" resourceName := "huaweicloud_rds_read_replica_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheckEpsID(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckRdsInstanceV3Destroy(resourceLabel), + CheckDestroy: testAccCheckRdsInstanceV3Destroy(resourceType), Steps: []resource.TestStep{ { Config: testAccReadRdsReplicaInstance_withEpsId(name), @@ -84,7 +84,7 @@ func testAccReadRdsReplicaInstanceV3_base(name string) string { resource "huaweicloud_rds_instance" "test" { name = "%s" - flavor = "rds.pg.c6.large.2" + flavor = "rds.pg.n1.large.2" availability_zone = [data.huaweicloud_availability_zones.test.names[0]] security_group_id = huaweicloud_networking_secgroup.test.id vpc_id = huaweicloud_vpc.test.id @@ -93,11 +93,11 @@ resource "huaweicloud_rds_instance" "test" { db { password = "Huangwei!120521" type = "PostgreSQL" - version = "10" + version = "12" port = 8635 } volume { - type = "ULTRAHIGH" + type = "CLOUDSSD" size = 50 } } @@ -110,12 +110,12 @@ func testAccReadRdsReplicaInstance_basic(name string) string { resource "huaweicloud_rds_read_replica_instance" "test" { name = "%s" - flavor = "rds.pg.c6.large.2.rr" + flavor = "rds.pg.n1.large.2.rr" primary_instance_id = huaweicloud_rds_instance.test.id availability_zone = data.huaweicloud_availability_zones.test.names[0] volume { - type = "ULTRAHIGH" + type = "CLOUDSSD" } tags = { @@ -132,13 +132,12 @@ func testAccReadRdsReplicaInstance_update(name string) string { resource "huaweicloud_rds_read_replica_instance" "test" { name = "%s" - flavor = "rds.pg.c6.xlarge.2.rr" + flavor = "rds.pg.n1.xlarge.2.rr" primary_instance_id = huaweicloud_rds_instance.test.id availability_zone = data.huaweicloud_availability_zones.test.names[0] volume { - type = "ULTRAHIGH" - size = 120 + type = "CLOUDSSD" } tags = { @@ -155,12 +154,13 @@ func testAccReadRdsReplicaInstance_withEpsId(name string) string { resource "huaweicloud_rds_read_replica_instance" "test" { name = "%s" - flavor = "rds.pg.c6.large.2.rr" + flavor = "rds.pg.n1.large.2.rr" primary_instance_id = huaweicloud_rds_instance.test.id availability_zone = data.huaweicloud_availability_zones.test.names[0] enterprise_project_id = "%s" + volume { - type = "ULTRAHIGH" + type = "CLOUDSSD" } } `, testAccReadRdsReplicaInstanceV3_base(name), name, HW_ENTERPRISE_PROJECT_ID_TEST) diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/datastores/requests.go b/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/datastores/requests.go deleted file mode 100644 index bb69935399..0000000000 --- a/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/datastores/requests.go +++ /dev/null @@ -1,18 +0,0 @@ -package datastores - -import ( - "github.com/huaweicloud/golangsdk" - "github.com/huaweicloud/golangsdk/pagination" -) - -func List(client *golangsdk.ServiceClient, databasesname string) pagination.Pager { - url := listURL(client, databasesname) - - pageRdsList := pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return DataStoresPage{pagination.SinglePageBase(r)} - }) - - rdsheader := map[string]string{"Content-Type": "application/json"} - pageRdsList.Headers = rdsheader - return pageRdsList -} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/datastores/results.go b/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/datastores/results.go deleted file mode 100644 index 1f903dd8b4..0000000000 --- a/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/datastores/results.go +++ /dev/null @@ -1,35 +0,0 @@ -package datastores - -import ( - "github.com/huaweicloud/golangsdk" - "github.com/huaweicloud/golangsdk/pagination" -) - -type DataStoresResult struct { - golangsdk.Result -} -type DataStores struct { - DataStores []dataStores `json:"dataStores" ` -} -type dataStores struct { - Id string `json:"id" ` - Name string `json:"name"` -} - -type DataStoresPage struct { - pagination.SinglePageBase -} - -func (r DataStoresPage) IsEmpty() (bool, error) { - data, err := ExtractDataStores(r) - if err != nil { - return false, err - } - return len(data.DataStores) == 0, err -} - -func ExtractDataStores(r pagination.Page) (DataStores, error) { - var s DataStores - err := (r.(DataStoresPage)).ExtractInto(&s) - return s, err -} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/datastores/urls.go b/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/datastores/urls.go deleted file mode 100644 index 41691d8f8b..0000000000 --- a/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/datastores/urls.go +++ /dev/null @@ -1,7 +0,0 @@ -package datastores - -import "github.com/huaweicloud/golangsdk" - -func listURL(sc *golangsdk.ServiceClient, databasename string) string { - return sc.ServiceURL("datastores", databasename) -} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/flavors/requests.go b/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/flavors/requests.go deleted file mode 100644 index a8e282e43d..0000000000 --- a/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/flavors/requests.go +++ /dev/null @@ -1,42 +0,0 @@ -package flavors - -import ( - "github.com/huaweicloud/golangsdk" - "github.com/huaweicloud/golangsdk/pagination" -) - -type DbFlavorsOpts struct { - Versionname string `q:"version_name"` -} - -type DbFlavorsBuilder interface { - ToDbFlavorsListQuery() (string, error) -} - -func (opts DbFlavorsOpts) ToDbFlavorsListQuery() (string, error) { - q, err := golangsdk.BuildQueryString(opts) - if err != nil { - return "", err - } - return q.String(), err -} - -func List(client *golangsdk.ServiceClient, opts DbFlavorsBuilder, databasename string) pagination.Pager { - url := listURL(client, databasename) - if opts != nil { - query, err := opts.ToDbFlavorsListQuery() - - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - - pageRdsList := pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { - return DbFlavorsPage{pagination.SinglePageBase(r)} - }) - - rdsheader := map[string]string{"Content-Type": "application/json"} - pageRdsList.Headers = rdsheader - return pageRdsList -} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/flavors/results.go b/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/flavors/results.go deleted file mode 100644 index 247e04cbc1..0000000000 --- a/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/flavors/results.go +++ /dev/null @@ -1,34 +0,0 @@ -package flavors - -import ( - "github.com/huaweicloud/golangsdk/pagination" -) - -type DbFlavorsResp struct { - Flavorslist []Flavors `json:"flavors"` -} -type Flavors struct { - Vcpus string `json:"vcpus" ` - Ram int `json:"ram" ` - Speccode string `json:"spec_code" ` - Instancemode string `json:"instance_mode" ` - Azstatus map[string]string `json:"az_status" ` -} - -type DbFlavorsPage struct { - pagination.SinglePageBase -} - -func (r DbFlavorsPage) IsEmpty() (bool, error) { - data, err := ExtractDbFlavors(r) - if err != nil { - return false, err - } - return len(data.Flavorslist) == 0, err -} - -func ExtractDbFlavors(r pagination.Page) (DbFlavorsResp, error) { - var s DbFlavorsResp - err := (r.(DbFlavorsPage)).ExtractInto(&s) - return s, err -} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/flavors/urls.go b/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/flavors/urls.go deleted file mode 100644 index 3b144920b2..0000000000 --- a/vendor/github.com/huaweicloud/golangsdk/openstack/rds/v3/flavors/urls.go +++ /dev/null @@ -1,7 +0,0 @@ -package flavors - -import "github.com/huaweicloud/golangsdk" - -func listURL(sc *golangsdk.ServiceClient, databasename string) string { - return sc.ServiceURL("flavors", databasename) -} diff --git a/vendor/modules.txt b/vendor/modules.txt index fe523b2399..57c4d5e17d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -435,8 +435,6 @@ github.com/huaweicloud/golangsdk/openstack/opengauss/v3/backups github.com/huaweicloud/golangsdk/openstack/opengauss/v3/instances github.com/huaweicloud/golangsdk/openstack/rds/v3/backups github.com/huaweicloud/golangsdk/openstack/rds/v3/configurations -github.com/huaweicloud/golangsdk/openstack/rds/v3/datastores -github.com/huaweicloud/golangsdk/openstack/rds/v3/flavors github.com/huaweicloud/golangsdk/openstack/rds/v3/instances github.com/huaweicloud/golangsdk/openstack/rts/v1/softwareconfig github.com/huaweicloud/golangsdk/openstack/rts/v1/stackresources