diff --git a/.changelog/2618.txt b/.changelog/2618.txt new file mode 100644 index 0000000000..eca0c0ed29 --- /dev/null +++ b/.changelog/2618.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/tencentcloud_postgresql_instance: support params db_major_version create resource +``` diff --git a/.changelog/2669.txt b/.changelog/2669.txt new file mode 100644 index 0000000000..76c39445fc --- /dev/null +++ b/.changelog/2669.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/tencentcloud_cfs_file_system: fix null fs_id +``` diff --git a/.changelog/2671.txt b/.changelog/2671.txt new file mode 100644 index 0000000000..994feb8bde --- /dev/null +++ b/.changelog/2671.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/tencentcloud_user_info: Support retry +``` \ No newline at end of file diff --git a/.changelog/2672.txt b/.changelog/2672.txt new file mode 100644 index 0000000000..57952fe83f --- /dev/null +++ b/.changelog/2672.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/tencentcloud_teo_rule_engine: Change action to Optional +``` diff --git a/.changelog/2674.txt b/.changelog/2674.txt new file mode 100644 index 0000000000..ff4a27760c --- /dev/null +++ b/.changelog/2674.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/tencentcloud_cynosdb_cluster: modify tag. +``` \ No newline at end of file diff --git a/.changelog/2675.txt b/.changelog/2675.txt new file mode 100644 index 0000000000..349263f689 --- /dev/null +++ b/.changelog/2675.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/tencentcloud_clb_instance: Support ipv6 return value `ipv6_mode` and `address_ipv6` +``` diff --git a/CHANGELOG.md b/CHANGELOG.md index e02c50768d..4396b850d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +## 1.81.101 (June 5, 2024) + +ENHANCEMENTS: + +* resource/tencentcloud_postgresql_instance: support params db_major_version create resource ([#2618](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2618)) + +BUG FIXES: + +* resource/tencentcloud_cfs_file_system: fix null fs_id ([#2669](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2669)) + +## 1.81.100 (June 4, 2024) + +ENHANCEMENTS: + +* resource/tencentcloud_cls_index: optimize example ([#2667](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2667)) +* resource/tencentcloud_tdmq_rocketmq_vip_instance: support `ip_rules` params ([#2659](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2659)) + ## 1.81.99 (May 28, 2024) ENHANCEMENTS: diff --git a/tencentcloud/acctest/test_util.go b/tencentcloud/acctest/test_util.go index b0a75821d5..a844b5ebf2 100644 --- a/tencentcloud/acctest/test_util.go +++ b/tencentcloud/acctest/test_util.go @@ -5,6 +5,7 @@ import ( "log" "os" "testing" + "time" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -251,3 +252,10 @@ func SharedClientForRegion(region string) (interface{}, error) { return &tcClient, nil } + +func AccStepTimeSleepDuration(d time.Duration) resource.TestCheckFunc { + return func(s *terraform.State) error { + time.Sleep(d) + return nil + } +} diff --git a/tencentcloud/services/cam/data_source_tc_user_info.go b/tencentcloud/services/cam/data_source_tc_user_info.go index 1dc6b614ad..5767bdccf7 100644 --- a/tencentcloud/services/cam/data_source_tc_user_info.go +++ b/tencentcloud/services/cam/data_source_tc_user_info.go @@ -3,6 +3,7 @@ package cam import ( "context" "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "log" "math/rand" "strconv" @@ -67,9 +68,18 @@ func datasourceTencentCloudUserInfoRead(d *schema.ResourceData, meta interface{} logId = tccommon.GetLogId(ctx) request := cam.NewGetUserAppIdRequest() + response := cam.NewGetUserAppIdResponse() ratelimit.Check(request.GetAction()) - response, err := client.UseCamClient().GetUserAppId(request) + + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + result, e := client.UseCamClient().GetUserAppId(request) + if e != nil { + return tccommon.RetryError(e) + } + response = result + return nil + }) if err != nil { log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", @@ -80,25 +90,37 @@ func datasourceTencentCloudUserInfoRead(d *schema.ResourceData, meta interface{} log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) - if err != nil { - return err - } - - result := response.Response - - if result == nil { + if response == nil || response.Response == nil { return fmt.Errorf("get user appid error: empty response") } - - appId := strconv.FormatUint(*result.AppId, 10) - uin := *result.Uin - ownerUin := *result.OwnerUin + var appId, uin, ownerUin string accountInfoRequest := cam.NewDescribeSubAccountsRequest() + accountInfoResponse := cam.NewDescribeSubAccountsResponse() + + if response.Response.AppId != nil { + appId = strconv.FormatUint(*response.Response.AppId, 10) + } + if response.Response.Uin != nil { + uin = *response.Response.Uin + } + if response.Response.OwnerUin != nil { + ownerUin = *response.Response.Uin + } accountInfoRequest.FilterSubAccountUin = []*uint64{helper.Uint64(helper.StrToUInt64(uin))} - accountInfoResponse, err := client.UseCamClient().DescribeSubAccounts(accountInfoRequest) + + err = resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + accountInfoResult, e := client.UseCamClient().DescribeSubAccounts(accountInfoRequest) + if e != nil { + return tccommon.RetryError(e) + } + accountInfoResponse = accountInfoResult + return nil + }) if err != nil { + log.Printf("[CRITAL]%s read CAM users failed, reason:%s\n", logId, err.Error()) return err } + subAccounts := accountInfoResponse.Response.SubAccounts var name string if len(subAccounts) > 0 { diff --git a/tencentcloud/services/cam/data_source_tc_user_info_test.go b/tencentcloud/services/cam/data_source_tc_user_info_test.go index 3392348b4b..5efae2b07a 100644 --- a/tencentcloud/services/cam/data_source_tc_user_info_test.go +++ b/tencentcloud/services/cam/data_source_tc_user_info_test.go @@ -14,8 +14,7 @@ func TestAccTencentCloudDataSourceUserInfoBasic(t *testing.T) { Providers: tcacctest.AccProviders, Steps: []resource.TestStep{ { - PreConfig: func() { tcacctest.AccStepPreConfigSetTempAKSK(t, tcacctest.ACCOUNT_TYPE_COMMON) }, - Config: testAccDataUserInfoBasic, + Config: testAccDataUserInfoBasic, Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttrSet("data.tencentcloud_user_info.info", "app_id"), resource.TestCheckResourceAttrSet("data.tencentcloud_user_info.info", "uin"), @@ -33,8 +32,7 @@ func TestAccTencentCloudDataSourceUserInfoSubAccount(t *testing.T) { Steps: []resource.TestStep{ { // Need use subaccount aksk - PreConfig: func() { tcacctest.AccStepPreConfigSetTempAKSK(t, tcacctest.ACCOUNT_TYPE_SUB_ACCOUNT) }, - Config: testAccDataUserInfoSubAccount, + Config: testAccDataUserInfoSubAccount, Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttrSet("data.tencentcloud_user_info.info_sub_account", "app_id"), resource.TestCheckResourceAttrSet("data.tencentcloud_user_info.info_sub_account", "uin"), diff --git a/tencentcloud/services/cfs/resource_tc_cfs_file_system.go b/tencentcloud/services/cfs/resource_tc_cfs_file_system.go index 693dd04e2a..9a56b0c17e 100644 --- a/tencentcloud/services/cfs/resource_tc_cfs_file_system.go +++ b/tencentcloud/services/cfs/resource_tc_cfs_file_system.go @@ -289,6 +289,7 @@ func resourceTencentCloudCfsFileSystemRead(d *schema.ResourceData, meta interfac _ = d.Set("ccn_id", mountTarget.CcnID) _ = d.Set("cidr_block", mountTarget.CidrBlock) _ = d.Set("net_interface", mountTarget.NetworkInterface) + _ = d.Set("fs_id", mountTarget.FSID) } return nil diff --git a/tencentcloud/services/clb/resource_tc_clb_instance.go b/tencentcloud/services/clb/resource_tc_clb_instance.go index 86c0f229d3..1deed9f585 100644 --- a/tencentcloud/services/clb/resource_tc_clb_instance.go +++ b/tencentcloud/services/clb/resource_tc_clb_instance.go @@ -216,6 +216,16 @@ func ResourceTencentCloudClbInstance() *schema.Resource { Computed: true, Description: "Domain name of the CLB instance.", }, + "ipv6_mode": { + Type: schema.TypeString, + Computed: true, + Description: "This field is meaningful when the IP address version is ipv6, `IPv6Nat64` | `IPv6FullChain`.", + }, + "address_ipv6": { + Type: schema.TypeString, + Computed: true, + Description: "The IPv6 address of the load balancing instance.", + }, }, } } @@ -575,6 +585,8 @@ func resourceTencentCloudClbInstanceRead(d *schema.ResourceData, meta interface{ _ = d.Set("project_id", instance.ProjectId) _ = d.Set("security_groups", helper.StringsInterfaces(instance.SecureGroups)) _ = d.Set("domain", instance.LoadBalancerDomain) + _ = d.Set("ipv6_mode", instance.IPv6Mode) + _ = d.Set("address_ipv6", instance.AddressIPv6) if instance.SlaType != nil { _ = d.Set("sla_type", instance.SlaType) diff --git a/tencentcloud/services/clb/resource_tc_clb_instance.md b/tencentcloud/services/clb/resource_tc_clb_instance.md index d0bc227535..fcf7b4edb1 100644 --- a/tencentcloud/services/clb/resource_tc_clb_instance.md +++ b/tencentcloud/services/clb/resource_tc_clb_instance.md @@ -37,6 +37,22 @@ resource "tencentcloud_clb_instance" "internal_clb" { OPEN CLB +```hcl +resource "tencentcloud_clb_instance" "open_clb" { + network_type = "OPEN" + clb_name = "myclb" + project_id = 0 + vpc_id = "vpc-da7ffa61" + security_groups = ["sg-o0ek7r93"] + + tags = { + test = "tf" + } +} +``` + +SUPPORT CORS + ```hcl resource "tencentcloud_clb_instance" "open_clb" { network_type = "OPEN" diff --git a/tencentcloud/services/clb/resource_tc_clb_instance_test.go b/tencentcloud/services/clb/resource_tc_clb_instance_test.go index cdb252deb5..14eb1e7734 100644 --- a/tencentcloud/services/clb/resource_tc_clb_instance_test.go +++ b/tencentcloud/services/clb/resource_tc_clb_instance_test.go @@ -424,10 +424,6 @@ resource "tencentcloud_clb_instance" "clb_internal" { ` const testAccClbInstance_open = ` -resource "tencentcloud_security_group" "foo" { - name = "keep-ci-temp-test-sg" -} - resource "tencentcloud_vpc" "foo" { name = "clb-instance-open-vpc" cidr_block = "10.0.0.0/16" @@ -440,7 +436,7 @@ resource "tencentcloud_clb_instance" "clb_open" { vpc_id = tencentcloud_vpc.foo.id target_region_info_region = "ap-guangzhou" target_region_info_vpc_id = tencentcloud_vpc.foo.id - security_groups = [tencentcloud_security_group.foo.id] + security_groups = ["sg-if748odn"] tags = { test = "tf" @@ -509,9 +505,6 @@ resource "tencentcloud_clb_instance" "clb_internal" { } ` const testAccClbInstance_update_open = ` -resource "tencentcloud_security_group" "foo" { - name = "clb-instance-sg" -} resource "tencentcloud_vpc" "foo" { name = "clb-instance-open-vpc" @@ -525,7 +518,7 @@ resource "tencentcloud_clb_instance" "clb_open" { project_id = 0 target_region_info_region = "ap-guangzhou" target_region_info_vpc_id = tencentcloud_vpc.foo.id - security_groups = [tencentcloud_security_group.foo.id] + security_groups = ["sg-if748odn"] tags = { test = "test" @@ -546,12 +539,6 @@ resource "tencentcloud_subnet" "subnet" { is_multicast = false } -resource "tencentcloud_security_group" "sglab" { - name = "clb-instance-enable-sg" - description = "favourite sg" - project_id = 0 -} - resource "tencentcloud_vpc" "foo" { name = "clb-instance-default-vpc" cidr_block = "10.0.0.0/16" @@ -568,7 +555,7 @@ resource "tencentcloud_clb_instance" "default_enable" { vpc_id = tencentcloud_vpc.foo.id load_balancer_pass_to_target = true - security_groups = [tencentcloud_security_group.sglab.id] + security_groups = ["sg-if748odn"] target_region_info_region = "ap-guangzhou" target_region_info_vpc_id = tencentcloud_vpc.foo.id @@ -591,12 +578,6 @@ resource "tencentcloud_subnet" "subnet" { is_multicast = false } -resource "tencentcloud_security_group" "sglab" { - name = "clb-instance-enable-sg" - description = "favourite sg" - project_id = 0 -} - resource "tencentcloud_vpc" "foo" { name = "clb-instance-default-vpc" cidr_block = "10.0.0.0/16" @@ -613,7 +594,7 @@ resource "tencentcloud_clb_instance" "default_enable" { vpc_id = tencentcloud_vpc.foo.id load_balancer_pass_to_target = true - security_groups = [tencentcloud_security_group.sglab.id] + security_groups = ["sg-if748odn"] target_region_info_region = "ap-guangzhou" target_region_info_vpc_id = tencentcloud_vpc.foo.id diff --git a/tencentcloud/services/cvm/data_source_tc_eips.go b/tencentcloud/services/cvm/data_source_tc_eips.go index 58057f6c3d..5879d45ed7 100644 --- a/tencentcloud/services/cvm/data_source_tc_eips.go +++ b/tencentcloud/services/cvm/data_source_tc_eips.go @@ -2,49 +2,24 @@ package cvm import ( "context" - "log" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" - svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag" - svcvpc "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/vpc" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" ) func DataSourceTencentCloudEips() *schema.Resource { return &schema.Resource{ Read: dataSourceTencentCloudEipsRead, - Schema: map[string]*schema.Schema{ "eip_id": { Type: schema.TypeString, Optional: true, Description: "ID of the EIP to be queried.", }, - "eip_name": { - Type: schema.TypeString, - Optional: true, - Description: "Name of the EIP to be queried.", - }, - "public_ip": { - Type: schema.TypeString, - Optional: true, - Description: "The elastic ip address.", - }, - "tags": { - Type: schema.TypeMap, - Optional: true, - Description: "The tags of EIP.", - }, - "result_output_file": { - Type: schema.TypeString, - Optional: true, - Description: "Used to save results.", - }, "eip_list": { Type: schema.TypeList, @@ -52,6 +27,11 @@ func DataSourceTencentCloudEips() *schema.Resource { Description: "An information list of EIP. Each element contains the following attributes:", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "Creation time of the EIP.", + }, "eip_id": { Type: schema.TypeString, Computed: true, @@ -67,30 +47,25 @@ func DataSourceTencentCloudEips() *schema.Resource { Computed: true, Description: "Type of the EIP.", }, - "status": { - Type: schema.TypeString, - Computed: true, - Description: "The EIP current status.", - }, - "public_ip": { + "eni_id": { Type: schema.TypeString, Computed: true, - Description: "The elastic ip address.", + Description: "The eni id to bind with the EIP.", }, "instance_id": { Type: schema.TypeString, Computed: true, Description: "The instance id to bind with the EIP.", }, - "eni_id": { + "public_ip": { Type: schema.TypeString, Computed: true, - Description: "The eni id to bind with the EIP.", + Description: "The elastic ip address.", }, - "create_time": { + "status": { Type: schema.TypeString, Computed: true, - Description: "Creation time of the EIP.", + Description: "The EIP current status.", }, "tags": { Type: schema.TypeMap, @@ -100,91 +75,101 @@ func DataSourceTencentCloudEips() *schema.Resource { }, }, }, + + "eip_name": { + Type: schema.TypeString, + Optional: true, + Description: "Name of the EIP to be queried.", + }, + + "public_ip": { + Type: schema.TypeString, + Optional: true, + Description: "The elastic ip address.", + }, + + "tags": { + Type: schema.TypeMap, + Optional: true, + Description: "The tags of EIP.", + }, + + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, }, } } func dataSourceTencentCloudEipsRead(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("data_source.tencentcloud_eips.read")() - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() - vpcService := svcvpc.NewVpcService(client) - tagService := svctag.NewTagService(client) - region := client.Region + service := VpcService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - filter := make(map[string][]string) + paramMap := make(map[string]interface{}) + var filtersList []*vpc.Filter + filtersMap := map[string]*vpc.Filter{} + filter := vpc.Filter{} + name := "address-id" + filter.Name = &name if v, ok := d.GetOk("eip_id"); ok { - filter["address-id"] = []string{v.(string)} + filter.Values = []*string{helper.String(v.(string))} } + filtersMap["Temp0"] = &filter + if v, ok := filtersMap["Temp0"]; ok && len(v.Values) > 0 { + filtersList = append(filtersList, v) + } + filter2 := vpc.Filter{} + name2 := "address-name" + filter2.Name = &name2 if v, ok := d.GetOk("eip_name"); ok { - filter["address-name"] = []string{v.(string)} + filter2.Values = []*string{helper.String(v.(string))} + } + filtersMap["Temp1"] = &filter2 + if v, ok := filtersMap["Temp1"]; ok && len(v.Values) > 0 { + filtersList = append(filtersList, v) } + filter3 := vpc.Filter{} + name3 := "public-ip" + filter3.Name = &name3 if v, ok := d.GetOk("public_ip"); ok { - filter["public-ip"] = []string{v.(string)} + filter3.Values = []*string{helper.String(v.(string))} } + filtersMap["Temp2"] = &filter3 + if v, ok := filtersMap["Temp2"]; ok && len(v.Values) > 0 { + filtersList = append(filtersList, v) + } + paramMap["Filters"] = filtersList - tags := helper.GetTags(d, "tags") - - var eips []*vpc.Address - var errRet error + var respData *vpc.DescribeAddressesResponseParams err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - eips, errRet = vpcService.DescribeEipByFilter(ctx, filter) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) + result, e := service.DescribeEipsByFilter(ctx, paramMap) + if e != nil { + return tccommon.RetryError(e) } + respData = result return nil }) if err != nil { return err } - eipList := make([]map[string]interface{}, 0, len(eips)) - ids := make([]string, 0, len(eips)) - -EIP_LOOP: - for _, eip := range eips { - respTags, err := tagService.DescribeResourceTags(ctx, svcvpc.VPC_SERVICE_TYPE, svcvpc.EIP_RESOURCE_TYPE, region, *eip.AddressId) - if err != nil { - log.Printf("[CRITAL]%s describe eip tags failed: %+v", logId, err) - return err - } - - for k, v := range tags { - if respTags[k] != v { - continue EIP_LOOP - } - } - - mapping := map[string]interface{}{ - "eip_id": eip.AddressId, - "eip_name": eip.AddressName, - "eip_type": eip.AddressType, - "status": eip.AddressStatus, - "public_ip": eip.AddressIp, - "instance_id": eip.InstanceId, - "eni_id": eip.NetworkInterfaceId, - "create_time": eip.CreatedTime, - "tags": respTags, - } - - eipList = append(eipList, mapping) - ids = append(ids, *eip.AddressId) - } - - d.SetId(helper.DataResourceIdsHash(ids)) - err = d.Set("eip_list", eipList) - if err != nil { - log.Printf("[CRITAL]%s provider set eip list fail, reason:%s\n ", logId, err.Error()) + if err := dataSourceTencentCloudEipsReadPostHandleResponse0(ctx, paramMap, respData); err != nil { return err } output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if err := tccommon.WriteToFile(output.(string), eipList); err != nil { - return err + if e := tccommon.WriteToFile(output.(string), dataSourceTencentCloudEipsReadOutputContent(ctx)); e != nil { + return e } } + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_eips_extension.go b/tencentcloud/services/cvm/data_source_tc_eips_extension.go new file mode 100644 index 0000000000..522e73c259 --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_eips_extension.go @@ -0,0 +1,65 @@ +package cvm + +import ( + "context" + "log" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" + svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag" + svcvpc "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/vpc" + + vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" +) + +func dataSourceTencentCloudEipsReadOutputContent(ctx context.Context) interface{} { + eipList := ctx.Value("eipList") + return eipList +} + +func dataSourceTencentCloudEipsReadPostHandleResponse0(ctx context.Context, req map[string]interface{}, resp *vpc.DescribeAddressesResponseParams) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + logId := tccommon.GetLogId(tccommon.ContextNil) + client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + tagService := svctag.NewTagService(client) + region := client.Region + + tags := helper.GetTags(d, "tags") + eipList := make([]map[string]interface{}, 0, len(resp.AddressSet)) + ids := make([]string, 0, len(resp.AddressSet)) + +EIP_LOOP: + for _, eip := range resp.AddressSet { + respTags, err := tagService.DescribeResourceTags(ctx, svcvpc.VPC_SERVICE_TYPE, svcvpc.EIP_RESOURCE_TYPE, region, *eip.AddressId) + if err != nil { + log.Printf("[CRITAL]%s describe eip tags failed: %+v", logId, err) + return err + } + + for k, v := range tags { + if respTags[k] != v { + continue EIP_LOOP + } + } + + mapping := map[string]interface{}{ + "eip_id": eip.AddressId, + "eip_name": eip.AddressName, + "eip_type": eip.AddressType, + "status": eip.AddressStatus, + "public_ip": eip.AddressIp, + "instance_id": eip.InstanceId, + "eni_id": eip.NetworkInterfaceId, + "create_time": eip.CreatedTime, + "tags": respTags, + } + + eipList = append(eipList, mapping) + ids = append(ids, *eip.AddressId) + } + + context.WithValue(ctx, "eipList", eipList) + d.SetId(helper.DataResourceIdsHash(ids)) + return nil +} diff --git a/tencentcloud/services/cvm/data_source_tc_image.go b/tencentcloud/services/cvm/data_source_tc_image.go index 807b6ca342..00527b2729 100644 --- a/tencentcloud/services/cvm/data_source_tc_image.go +++ b/tencentcloud/services/cvm/data_source_tc_image.go @@ -2,24 +2,18 @@ package cvm import ( "context" - "errors" - "fmt" - "regexp" - "strings" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" ) func DataSourceTencentCloudImage() *schema.Resource { return &schema.Resource{ Read: dataSourceTencentCloudImageRead, - Schema: map[string]*schema.Schema{ "filter": { Type: schema.TypeSet, @@ -35,137 +29,100 @@ func DataSourceTencentCloudImage() *schema.Resource { "values": { Type: schema.TypeList, Required: true, - Elem: &schema.Schema{Type: schema.TypeString}, Description: "Values of the filter.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, }, }, }, - "image_name_regex": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: tccommon.ValidateNameRegex, - Description: "A regex string to apply to the image list returned by TencentCloud. **NOTE**: it is not wildcard, should look like `image_name_regex = \"^CentOS\\s+6\\.8\\s+64\\w*\"`.", - }, - "os_name": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: tccommon.ValidateNotEmpty, - Description: "A string to apply with fuzzy match to the os_name attribute on the image list returned by TencentCloud. **NOTE**: when os_name is provided, highest priority is applied in this field instead of `image_name_regex`.", - }, - "result_output_file": { - Type: schema.TypeString, - Optional: true, - Description: "Used to save results.", - }, + "image_id": { Type: schema.TypeString, Computed: true, Description: "An image id indicate the uniqueness of a certain image, which can be used for instance creation or resetting.", }, + "image_name": { Type: schema.TypeString, Computed: true, Description: "Name of this image.", }, + + "image_name_regex": { + Type: schema.TypeString, + Optional: true, + Description: "A regex string to apply to the image list returned by TencentCloud. **NOTE**: it is not wildcard, should look like `image_name_regex = \"^CentOS\\s+6\\.8\\s+64\\w*\"`.", + }, + + "os_name": { + Type: schema.TypeString, + Optional: true, + Description: "A string to apply with fuzzy match to the os_name attribute on the image list returned by TencentCloud. **NOTE**: when os_name is provided, highest priority is applied in this field instead of `image_name_regex`.", + }, + + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, }, } } func dataSourceTencentCloudImageRead(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("data_source.tencentcloud_image.read")() - - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } - - filter := make(map[string][]string) - filters, ok := d.GetOk("filter") - if ok { - for _, v := range filters.(*schema.Set).List() { - vv := v.(map[string]interface{}) - name := vv["name"].(string) - filter[name] = []string{} - for _, vvv := range vv["values"].([]interface{}) { - filter[name] = append(filter[name], vvv.(string)) + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + paramMap := make(map[string]interface{}) + if v, ok := d.GetOk("filters"); ok { + filtersSet := v.([]interface{}) + tmpSet := make([]*cvm.Filter, 0, len(filtersSet)) + for _, item := range filtersSet { + filtersMap := item.(map[string]interface{}) + filter := cvm.Filter{} + if v, ok := filtersMap["name"]; ok { + filter.Name = helper.String(v.(string)) + } + if v, ok := filtersMap["values"]; ok { + valuesSet := v.(*schema.Set).List() + for i := range valuesSet { + values := valuesSet[i].(string) + filter.Values = append(filter.Values, helper.String(values)) + } } + tmpSet = append(tmpSet, &filter) } + paramMap["Filters"] = tmpSet } - var images []*cvm.Image - var errRet error + var respData []*cvm.Image err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - images, errRet = cvmService.DescribeImagesByFilter(ctx, filter, "") - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) + result, e := service.DescribeImageByFilter(ctx, paramMap) + if e != nil { + return tccommon.RetryError(e) } + respData = result return nil }) if err != nil { return err } - if len(images) == 0 { - return errors.New("No image found") - } - - var osName string - if v, ok := d.GetOk("os_name"); ok { - osName = v.(string) - } - - var regImageName string - var imageNameRegex *regexp.Regexp - if v, ok := d.GetOk("image_name_regex"); ok { - regImageName = v.(string) - imageNameRegex, err = regexp.Compile(regImageName) - if err != nil { - return fmt.Errorf("image_name_regex format error,%s", err.Error()) - } - } - - var resultImageId string - images = sortImages(images) - for _, image := range images { - if osName != "" { - if strings.Contains(strings.ToLower(*image.OsName), strings.ToLower(osName)) { - resultImageId = *image.ImageId - _ = d.Set("image_name", *image.ImageName) - break - } - continue - } - - if imageNameRegex != nil { - if imageNameRegex.MatchString(*image.ImageName) { - resultImageId = *image.ImageId - _ = d.Set("image_name", *image.ImageName) - break - } - continue - } - - resultImageId = *image.ImageId - _ = d.Set("image_name", *image.ImageName) - break - } - - if resultImageId == "" { - return errors.New("No image found") - } - - d.SetId(helper.DataResourceIdHash(resultImageId)) - if err := d.Set("image_id", resultImageId); err != nil { + if err := dataSourceTencentCloudImageReadPostHandleResponse0(ctx, paramMap, &respData); err != nil { return err } output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if err = tccommon.WriteToFile(output.(string), resultImageId); err != nil { - return err + if e := tccommon.WriteToFile(output.(string), dataSourceTencentCloudImageReadOutputContent(ctx)); e != nil { + return e } } diff --git a/tencentcloud/services/cvm/data_source_tc_image_extension.go b/tencentcloud/services/cvm/data_source_tc_image_extension.go new file mode 100644 index 0000000000..97eca70db8 --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_image_extension.go @@ -0,0 +1,81 @@ +package cvm + +import ( + "context" + "errors" + "fmt" + "regexp" + "strings" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" + + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +func dataSourceTencentCloudImageReadPostHandleResponse0(ctx context.Context, req map[string]interface{}, resp *[]*cvm.Image) error { + d := tccommon.ResourceDataFromContext(ctx) + images := *resp + var err error + if len(images) == 0 { + return errors.New("No image found") + } + + var osName string + if v, ok := d.GetOk("os_name"); ok { + osName = v.(string) + } + + var regImageName string + var imageNameRegex *regexp.Regexp + if v, ok := d.GetOk("image_name_regex"); ok { + regImageName = v.(string) + imageNameRegex, err = regexp.Compile(regImageName) + if err != nil { + return fmt.Errorf("image_name_regex format error,%s", err.Error()) + } + } + + var resultImageId string + images = sortImages(images) + for _, image := range images { + if osName != "" { + if strings.Contains(strings.ToLower(*image.OsName), strings.ToLower(osName)) { + resultImageId = *image.ImageId + _ = d.Set("image_name", *image.ImageName) + break + } + continue + } + + if imageNameRegex != nil { + if imageNameRegex.MatchString(*image.ImageName) { + resultImageId = *image.ImageId + _ = d.Set("image_name", *image.ImageName) + break + } + continue + } + + resultImageId = *image.ImageId + _ = d.Set("image_name", *image.ImageName) + break + } + + if resultImageId == "" { + return errors.New("No image found") + } + + d.SetId(helper.DataResourceIdHash(resultImageId)) + if err := d.Set("image_id", resultImageId); err != nil { + return err + } + + context.WithValue(ctx, "resultImageId", resultImageId) + return nil +} + +func dataSourceTencentCloudImageReadOutputContent(ctx context.Context) interface{} { + resultImageId := ctx.Value("resultImageId") + return resultImageId +} diff --git a/tencentcloud/services/cvm/data_source_tc_images.go b/tencentcloud/services/cvm/data_source_tc_images.go index b105b0ac25..f966348370 100644 --- a/tencentcloud/services/cvm/data_source_tc_images.go +++ b/tencentcloud/services/cvm/data_source_tc_images.go @@ -2,137 +2,106 @@ package cvm import ( "context" - "fmt" - "log" - "regexp" - "strings" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" - - svccbs "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/cbs" ) func DataSourceTencentCloudImages() *schema.Resource { return &schema.Resource{ Read: dataSourceTencentCloudImagesRead, - Schema: map[string]*schema.Schema{ "image_id": { Type: schema.TypeString, Optional: true, Description: "ID of the image to be queried.", }, - "image_type": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - Description: "A list of the image type to be queried. Valid values: 'PUBLIC_IMAGE', 'PRIVATE_IMAGE', 'SHARED_IMAGE', 'MARKET_IMAGE'.", - }, + "image_name_regex": { Type: schema.TypeString, Optional: true, ConflictsWith: []string{"os_name"}, - ValidateFunc: tccommon.ValidateNameRegex, Description: "A regex string to apply to the image list returned by TencentCloud, conflict with 'os_name'. **NOTE**: it is not wildcard, should look like `image_name_regex = \"^CentOS\\s+6\\.8\\s+64\\w*\"`.", }, - "os_name": { - Type: schema.TypeString, - Optional: true, - ConflictsWith: []string{"image_name_regex"}, - ValidateFunc: tccommon.ValidateNotEmpty, - Description: "A string to apply with fuzzy match to the os_name attribute on the image list returned by TencentCloud, conflict with 'image_name_regex'.", - }, - "instance_type": { - Type: schema.TypeString, - Optional: true, - Description: "Instance type, such as `S1.SMALL1`.", - }, - "result_output_file": { - Type: schema.TypeString, + + "image_type": { + Type: schema.TypeList, Optional: true, - Description: "Used to save results.", + Description: "A list of the image type to be queried. Valid values: 'PUBLIC_IMAGE', 'PRIVATE_IMAGE', 'SHARED_IMAGE', 'MARKET_IMAGE'.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, + "images": { Type: schema.TypeList, Computed: true, Description: "An information list of image. Each element contains the following attributes:", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "image_id": { + "architecture": { Type: schema.TypeString, Computed: true, - Description: "ID of the image.", + Description: "Architecture of the image.", }, - "os_name": { + "created_time": { Type: schema.TypeString, Computed: true, - Description: "OS name of the image.", + Description: "Created time of the image.", }, - "image_type": { + "image_creator": { Type: schema.TypeString, Computed: true, - Description: "Type of the image.", + Description: "Image creator of the image.", }, - "created_time": { + "image_description": { Type: schema.TypeString, Computed: true, - Description: "Created time of the image.", + Description: "Description of the image.", }, - "image_name": { + "image_id": { Type: schema.TypeString, Computed: true, - Description: "Name of the image.", + Description: "ID of the image.", }, - "image_description": { + "image_name": { Type: schema.TypeString, Computed: true, - Description: "Description of the image.", + Description: "Name of the image.", }, "image_size": { Type: schema.TypeInt, Computed: true, Description: "Size of the image.", }, - "architecture": { + "image_source": { Type: schema.TypeString, Computed: true, - Description: "Architecture of the image.", + Description: "Image source of the image.", }, "image_state": { Type: schema.TypeString, Computed: true, Description: "State of the image.", }, - "platform": { + "image_type": { Type: schema.TypeString, Computed: true, - Description: "Platform of the image.", + Description: "Type of the image.", }, - "image_creator": { + "os_name": { Type: schema.TypeString, Computed: true, - Description: "Image creator of the image.", + Description: "OS name of the image.", }, - "image_source": { + "platform": { Type: schema.TypeString, Computed: true, - Description: "Image source of the image.", - }, - "sync_percent": { - Type: schema.TypeInt, - Computed: true, - Description: "Sync percent of the image.", - }, - "support_cloud_init": { - Type: schema.TypeBool, - Computed: true, - Description: "Whether support cloud-init.", + Description: "Platform of the image.", }, "snapshots": { Type: schema.TypeList, @@ -140,202 +109,116 @@ func DataSourceTencentCloudImages() *schema.Resource { Description: "List of snapshot details.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "snapshot_id": { - Type: schema.TypeString, + "disk_size": { + Type: schema.TypeInt, Computed: true, - Description: "Snapshot ID.", + Description: "Size of the cloud disk used to create the snapshot; unit: GB.", }, - "snapshot_name": { + "disk_usage": { Type: schema.TypeString, Computed: true, - Description: "Snapshot name, the user-defined snapshot alias.", + Description: "Type of the cloud disk used to create the snapshot.", }, - "disk_usage": { + "snapshot_id": { Type: schema.TypeString, Computed: true, - Description: "Type of the cloud disk used to create the snapshot.", + Description: "Snapshot ID.", }, - "disk_size": { - Type: schema.TypeInt, + "snapshot_name": { + Type: schema.TypeString, Computed: true, - Description: "Size of the cloud disk used to create the snapshot; unit: GB.", + Description: "Snapshot name, the user-defined snapshot alias.", }, }, }, }, + "support_cloud_init": { + Type: schema.TypeBool, + Computed: true, + Description: "Whether support cloud-init.", + }, + "sync_percent": { + Type: schema.TypeInt, + Computed: true, + Description: "Sync percent of the image.", + }, }, }, }, + + "instance_type": { + Type: schema.TypeString, + Optional: true, + Description: "Instance type, such as `S1.SMALL1`.", + }, + + "os_name": { + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"image_name_regex"}, + Description: "A string to apply with fuzzy match to the os_name attribute on the image list returned by TencentCloud, conflict with 'image_name_regex'.", + }, + + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, }, } } func dataSourceTencentCloudImagesRead(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("data_source.tencentcloud_images.read")() + defer tccommon.InconsistentCheck(d, meta)() - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } - - cbsService := svccbs.NewCbsService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) - - var ( - imageId string - imageType []string - imageName string - osName string - imageNameRegex *regexp.Regexp - err error - ) - - filter := make(map[string][]string) + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + paramMap := make(map[string]interface{}) + var filtersList []*cvm.Filter + filtersMap := map[string]*cvm.Filter{} + filter := cvm.Filter{} + name := "image-id" + filter.Name = &name if v, ok := d.GetOk("image_id"); ok { - imageId = v.(string) - if imageId != "" { - filter["image-id"] = []string{imageId} - } + filter.Values = []*string{helper.String(v.(string))} } - - if v, ok := d.GetOk("image_type"); ok { - for _, vv := range v.([]interface{}) { - if vv.(string) != "" { - imageType = append(imageType, vv.(string)) - } - } - if len(imageType) > 0 { - filter["image-type"] = imageType - } - } - - if v, ok := d.GetOk("image_name_regex"); ok { - imageName = v.(string) - if imageName != "" { - imageNameRegex, err = regexp.Compile(imageName) - if err != nil { - return fmt.Errorf("image_name_regex format error,%s", err.Error()) - } - } - } - - if v, ok := d.GetOk("os_name"); ok { - osName = v.(string) + filtersMap["Temp0"] = &filter + if v, ok := filtersMap["Temp0"]; ok && len(v.Values) > 0 { + filtersList = append(filtersList, v) } + paramMap["Filters"] = filtersList - var instanceType string - if v, ok := d.GetOk("instance_type"); ok { - instanceType = v.(string) + if err := dataSourceTencentCloudImagesReadPostFillRequest0(ctx, paramMap); err != nil { + return err } - var images []*cvm.Image - err = resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - var e error - images, e = cvmService.DescribeImagesByFilter(ctx, filter, instanceType) + var respData []*cvm.Image + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + result, e := service.DescribeImagesByFilter(ctx, paramMap) if e != nil { - return tccommon.RetryError(e, tccommon.InternalError) + return tccommon.RetryError(e) } + respData = result return nil }) if err != nil { return err } - var results []*cvm.Image - images = sortImages(images) - - if osName == "" && imageName == "" { - results = images - } else { - for _, image := range images { - if osName != "" { - if strings.Contains(strings.ToLower(*image.OsName), strings.ToLower(osName)) { - results = append(results, image) - continue - } - } - if imageNameRegex != nil { - if imageNameRegex.MatchString(*image.ImageName) { - results = append(results, image) - continue - } - } - } - } - - imageList := make([]map[string]interface{}, 0, len(results)) - ids := make([]string, 0, len(results)) - for _, image := range results { - snapshots, err := imagesReadSnapshotByIds(ctx, cbsService, image) - if err != nil { - return err - } - - mapping := map[string]interface{}{ - "image_id": image.ImageId, - "os_name": image.OsName, - "image_type": image.ImageType, - "created_time": image.CreatedTime, - "image_name": image.ImageName, - "image_description": image.ImageDescription, - "image_size": image.ImageSize, - "architecture": image.Architecture, - "image_state": image.ImageState, - "platform": image.Platform, - "image_creator": image.ImageCreator, - "image_source": image.ImageSource, - "sync_percent": image.SyncPercent, - "support_cloud_init": image.IsSupportCloudinit, - "snapshots": snapshots, - } - imageList = append(imageList, mapping) - ids = append(ids, *image.ImageId) - } - - d.SetId(helper.DataResourceIdsHash(ids)) - err = d.Set("images", imageList) - if err != nil { - log.Printf("[CRITAL]%s provider set image list fail, reason:%s\n ", logId, err.Error()) + if err := dataSourceTencentCloudImagesReadPostHandleResponse0(ctx, paramMap, &respData); err != nil { return err } output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if err := tccommon.WriteToFile(output.(string), imageList); err != nil { - return err + if e := tccommon.WriteToFile(output.(string), dataSourceTencentCloudImagesReadOutputContent(ctx)); e != nil { + return e } } return nil } - -func imagesReadSnapshotByIds(ctx context.Context, cbsService svccbs.CbsService, image *cvm.Image) (snapshotResults []map[string]interface{}, errRet error) { - if len(image.SnapshotSet) == 0 { - return - } - - snapshotByIds := make([]*string, 0, len(image.SnapshotSet)) - for _, snapshot := range image.SnapshotSet { - snapshotByIds = append(snapshotByIds, snapshot.SnapshotId) - } - - snapshots, errRet := cbsService.DescribeSnapshotByIds(ctx, snapshotByIds) - if errRet != nil { - return - } - - snapshotResults = make([]map[string]interface{}, 0, len(snapshots)) - for _, snapshot := range snapshots { - snapshotMap := make(map[string]interface{}, 4) - snapshotMap["snapshot_id"] = snapshot.SnapshotId - snapshotMap["disk_usage"] = snapshot.DiskUsage - snapshotMap["disk_size"] = snapshot.DiskSize - snapshotMap["snapshot_name"] = snapshot.SnapshotName - - snapshotResults = append(snapshotResults, snapshotMap) - } - - return -} diff --git a/tencentcloud/services/cvm/data_source_tc_images_extension.go b/tencentcloud/services/cvm/data_source_tc_images_extension.go new file mode 100644 index 0000000000..34c4db07c9 --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_images_extension.go @@ -0,0 +1,178 @@ +package cvm + +import ( + "context" + "fmt" + "log" + "regexp" + "strings" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" + svccbs "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/cbs" + + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +func dataSourceTencentCloudImagesReadOutputContent(ctx context.Context) interface{} { + imageList := ctx.Value("imageList") + return imageList +} + +func dataSourceTencentCloudImagesReadPreRequest0(ctx context.Context, req *cvm.DescribeImagesRequest) error { + d := tccommon.ResourceDataFromContext(ctx) + if v, ok := d.GetOk("instance_type"); ok { + req.InstanceType = helper.String(v.(string)) + } + + return nil +} + +func dataSourceTencentCloudImagesReadPostHandleResponse0(ctx context.Context, req map[string]interface{}, resp *[]*cvm.Image) error { + d := tccommon.ResourceDataFromContext(ctx) + images := *resp + var ( + imageName string + osName string + imageNameRegex *regexp.Regexp + err error + ) + + if v, ok := d.GetOk("os_name"); ok { + osName = v.(string) + } + + if v, ok := d.GetOk("image_name_regex"); ok { + imageName = v.(string) + if imageName != "" { + imageNameRegex, err = regexp.Compile(imageName) + if err != nil { + return fmt.Errorf("image_name_regex format error,%s", err.Error()) + } + } + } + + var results []*cvm.Image + images = sortImages(images) + if osName == "" && imageName == "" { + results = images + } else { + for _, image := range images { + if osName != "" { + if strings.Contains(strings.ToLower(*image.OsName), strings.ToLower(osName)) { + results = append(results, image) + continue + } + } + if imageNameRegex != nil { + if imageNameRegex.MatchString(*image.ImageName) { + results = append(results, image) + continue + } + } + } + } + + logId := tccommon.GetLogId(tccommon.ContextNil) + meta := tccommon.ProviderMetaFromContext(ctx) + cbsService := svccbs.NewCbsService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) + imageList := make([]map[string]interface{}, 0, len(results)) + ids := make([]string, 0, len(results)) + for _, image := range results { + snapshots, err := imagesReadSnapshotByIds(ctx, cbsService, image) + if err != nil { + return err + } + + mapping := map[string]interface{}{ + "image_id": image.ImageId, + "os_name": image.OsName, + "image_type": image.ImageType, + "created_time": image.CreatedTime, + "image_name": image.ImageName, + "image_description": image.ImageDescription, + "image_size": image.ImageSize, + "architecture": image.Architecture, + "image_state": image.ImageState, + "platform": image.Platform, + "image_creator": image.ImageCreator, + "image_source": image.ImageSource, + "sync_percent": image.SyncPercent, + "support_cloud_init": image.IsSupportCloudinit, + "snapshots": snapshots, + } + imageList = append(imageList, mapping) + ids = append(ids, *image.ImageId) + } + + d.SetId(helper.DataResourceIdsHash(ids)) + err = d.Set("images", imageList) + if err != nil { + log.Printf("[CRITAL]%s provider set image list fail, reason:%s\n ", logId, err.Error()) + return err + } + + context.WithValue(ctx, "imageList", imageList) + return nil +} + +func dataSourceTencentCloudImagesReadPostFillRequest0(ctx context.Context, req map[string]interface{}) error { + d := tccommon.ResourceDataFromContext(ctx) + var ( + imageName string + imageType []string + err error + ) + + if v, ok := d.GetOk("image_name_regex"); ok { + imageName = v.(string) + if imageName != "" { + _, err = regexp.Compile(imageName) + if err != nil { + return fmt.Errorf("image_name_regex format error,%s", err.Error()) + } + } + } + + if v, ok := d.GetOk("image_type"); ok { + for _, vv := range v.([]interface{}) { + if vv.(string) != "" { + imageType = append(imageType, vv.(string)) + } + } + if len(imageType) > 0 { + req["image-type"] = imageType + } + } + + return nil +} + +func imagesReadSnapshotByIds(ctx context.Context, cbsService svccbs.CbsService, image *cvm.Image) (snapshotResults []map[string]interface{}, errRet error) { + if len(image.SnapshotSet) == 0 { + return + } + + snapshotByIds := make([]*string, 0, len(image.SnapshotSet)) + for _, snapshot := range image.SnapshotSet { + snapshotByIds = append(snapshotByIds, snapshot.SnapshotId) + } + + snapshots, errRet := cbsService.DescribeSnapshotByIds(ctx, snapshotByIds) + if errRet != nil { + return + } + + snapshotResults = make([]map[string]interface{}, 0, len(snapshots)) + for _, snapshot := range snapshots { + snapshotMap := make(map[string]interface{}, 4) + snapshotMap["snapshot_id"] = snapshot.SnapshotId + snapshotMap["disk_usage"] = snapshot.DiskUsage + snapshotMap["disk_size"] = snapshot.DiskSize + snapshotMap["snapshot_name"] = snapshot.SnapshotName + + snapshotResults = append(snapshotResults, snapshotMap) + } + + return +} diff --git a/tencentcloud/services/cvm/data_source_tc_instance_types.go b/tencentcloud/services/cvm/data_source_tc_instance_types.go index 5b1fe66b7e..1a9eea539f 100644 --- a/tencentcloud/services/cvm/data_source_tc_instance_types.go +++ b/tencentcloud/services/cvm/data_source_tc_instance_types.go @@ -2,43 +2,39 @@ package cvm import ( "context" - "log" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" ) func DataSourceTencentCloudInstanceTypes() *schema.Resource { return &schema.Resource{ Read: dataSourceTencentCloudInstanceTypesRead, - Schema: map[string]*schema.Schema{ + "availability_zone": { + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"filter"}, + Description: "The available zone that the CVM instance locates at. This field is conflict with `filter`.", + }, + "cpu_core_count": { Type: schema.TypeInt, Optional: true, Description: "The number of CPU cores of the instance.", }, - "gpu_core_count": { - Type: schema.TypeInt, - Optional: true, - Description: "The number of GPU cores of the instance.", - }, - "memory_size": { - Type: schema.TypeInt, + + "exclude_sold_out": { + Type: schema.TypeBool, Optional: true, - Description: "Instance memory capacity, unit in GB.", - }, - "availability_zone": { - Type: schema.TypeString, - Optional: true, - ConflictsWith: []string{"filter"}, - Description: "The available zone that the CVM instance locates at. This field is conflict with `filter`.", + Default: false, + Description: "Indicate to filter instances types that is sold out or not, default is false.", }, + "filter": { Type: schema.TypeSet, Optional: true, @@ -55,25 +51,21 @@ func DataSourceTencentCloudInstanceTypes() *schema.Resource { "values": { Type: schema.TypeList, Required: true, - Elem: &schema.Schema{Type: schema.TypeString}, Description: "The filter values.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, }, }, }, - "exclude_sold_out": { - Type: schema.TypeBool, - Optional: true, - Default: false, - Description: "Indicate to filter instances types that is sold out or not, default is false.", - }, - "result_output_file": { - Type: schema.TypeString, + + "gpu_core_count": { + Type: schema.TypeInt, Optional: true, - Description: "Used to save results.", + Description: "The number of GPU cores of the instance.", }, - // Computed values. "instance_types": { Type: schema.TypeList, Computed: true, @@ -85,35 +77,35 @@ func DataSourceTencentCloudInstanceTypes() *schema.Resource { Computed: true, Description: "The available zone that the CVM instance locates at.", }, - "instance_type": { - Type: schema.TypeString, - Computed: true, - Description: "Type of the instance.", - }, "cpu_core_count": { Type: schema.TypeInt, Computed: true, Description: "The number of CPU cores of the instance.", }, + "family": { + Type: schema.TypeString, + Computed: true, + Description: "Type series of the instance.", + }, "gpu_core_count": { Type: schema.TypeInt, Computed: true, Description: "The number of GPU cores of the instance.", }, - "memory_size": { - Type: schema.TypeInt, + "instance_charge_type": { + Type: schema.TypeString, Computed: true, - Description: "Instance memory capacity, unit in GB.", + Description: "Charge type of the instance.", }, - "family": { + "instance_type": { Type: schema.TypeString, Computed: true, - Description: "Type series of the instance.", + Description: "Type of the instance.", }, - "instance_charge_type": { - Type: schema.TypeString, + "memory_size": { + Type: schema.TypeInt, Computed: true, - Description: "Charge type of the instance.", + Description: "Instance memory capacity, unit in GB.", }, "status": { Type: schema.TypeString, @@ -123,102 +115,80 @@ func DataSourceTencentCloudInstanceTypes() *schema.Resource { }, }, }, + + "memory_size": { + Type: schema.TypeInt, + Optional: true, + Description: "Instance memory capacity, unit in GB.", + }, + + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, }, } } func dataSourceTencentCloudInstanceTypesRead(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("data_source.tencentcloud_instance_types.read")() - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } + defer tccommon.InconsistentCheck(d, meta)() - isExcludeSoldOut := d.Get("exclude_sold_out").(bool) - cpu, cpuOk := d.GetOk("cpu_core_count") - gpu, gpuOk := d.GetOk("gpu_core_count") - memory, memoryOk := d.GetOk("memory_size") - var instanceSellTypes []*cvm.InstanceTypeQuotaItem - var errRet error - var err error - typeList := make([]map[string]interface{}, 0) - ids := make([]string, 0) - - var zone string - var zone_in = 0 - if v, ok := d.GetOk("availability_zone"); ok { - zone = v.(string) - zone_in = 1 - } - filters := d.Get("filter").(*schema.Set).List() - filterMap := make(map[string][]string, len(filters)+zone_in) - for _, v := range filters { - item := v.(map[string]interface{}) - name := item["name"].(string) - values := item["values"].([]interface{}) - filterValues := make([]string, 0, len(values)) - for _, value := range values { - filterValues = append(filterValues, value.(string)) + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + paramMap := make(map[string]interface{}) + if v, ok := d.GetOk("filters"); ok { + filtersSet := v.([]interface{}) + tmpSet := make([]*cvm.Filter, 0, len(filtersSet)) + for _, item := range filtersSet { + filtersMap := item.(map[string]interface{}) + filter := cvm.Filter{} + if v, ok := filtersMap["name"]; ok { + filter.Name = helper.String(v.(string)) + } + if v, ok := filtersMap["values"]; ok { + valuesSet := v.(*schema.Set).List() + for i := range valuesSet { + values := valuesSet[i].(string) + filter.Values = append(filter.Values, helper.String(values)) + } + } + tmpSet = append(tmpSet, &filter) } - filterMap[name] = filterValues + paramMap["Filters"] = tmpSet } - if zone != "" { - filterMap["zone"] = []string{zone} + + if err := dataSourceTencentCloudInstanceTypesReadPostFillRequest0(ctx, paramMap); err != nil { + return err } - err = resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - instanceSellTypes, errRet = cvmService.DescribeInstancesSellTypeByFilter(ctx, filterMap) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) + + var respData *cvm.DescribeZoneInstanceConfigInfosResponseParams + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + result, e := service.DescribeInstanceTypesByFilter(ctx, paramMap) + if e != nil { + return tccommon.RetryError(e) } + respData = result return nil }) if err != nil { return err } - for _, instanceType := range instanceSellTypes { - flag := true - if cpuOk && int64(cpu.(int)) != *instanceType.Cpu { - flag = false - } - if gpuOk && int64(gpu.(int)) != *instanceType.Gpu { - flag = false - } - if memoryOk && int64(memory.(int)) != *instanceType.Memory { - flag = false - } - if isExcludeSoldOut && CVM_SOLD_OUT_STATUS == *instanceType.Status { - flag = false - } - - if flag { - mapping := map[string]interface{}{ - "availability_zone": instanceType.Zone, - "cpu_core_count": instanceType.Cpu, - "gpu_core_count": instanceType.Gpu, - "memory_size": instanceType.Memory, - "family": instanceType.InstanceFamily, - "instance_type": instanceType.InstanceType, - "instance_charge_type": instanceType.InstanceChargeType, - "status": instanceType.Status, - } - typeList = append(typeList, mapping) - ids = append(ids, *instanceType.InstanceType) - } - } - d.SetId(helper.DataResourceIdsHash(ids)) - err = d.Set("instance_types", typeList) - if err != nil { - log.Printf("[CRITAL]%s provider set instance type list fail, reason:%s\n ", logId, err.Error()) + if err := dataSourceTencentCloudInstanceTypesReadPostHandleResponse0(ctx, paramMap, respData); err != nil { return err } output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if err := tccommon.WriteToFile(output.(string), typeList); err != nil { - return err + if e := tccommon.WriteToFile(output.(string), dataSourceTencentCloudInstanceTypesReadOutputContent(ctx)); e != nil { + return e } } + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_instance_types_extension.go b/tencentcloud/services/cvm/data_source_tc_instance_types_extension.go new file mode 100644 index 0000000000..79c109f98c --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_instance_types_extension.go @@ -0,0 +1,97 @@ +package cvm + +import ( + "context" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" + + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +func dataSourceTencentCloudInstanceTypesReadPostFillRequest0(ctx context.Context, req map[string]interface{}) error { + d := tccommon.ResourceDataFromContext(ctx) + var zone string + var zone_in = 0 + if v, ok := d.GetOk("availability_zone"); ok { + zone = v.(string) + zone_in = 1 + } + filters := d.Get("filter").(*schema.Set).List() + filterMap := make(map[string][]string, len(filters)+zone_in) + for _, v := range filters { + item := v.(map[string]interface{}) + name := item["name"].(string) + values := item["values"].([]interface{}) + filterValues := make([]string, 0, len(values)) + for _, value := range values { + filterValues = append(filterValues, value.(string)) + } + filterMap[name] = filterValues + } + if zone != "" { + filterMap["zone"] = []string{zone} + } + + return nil +} + +func dataSourceTencentCloudInstanceTypesReadPostHandleResponse0(ctx context.Context, req map[string]interface{}, resp *cvm.DescribeZoneInstanceConfigInfosResponseParams) error { + d := tccommon.ResourceDataFromContext(ctx) + logId := tccommon.GetLogId(tccommon.ContextNil) + isExcludeSoldOut := d.Get("exclude_sold_out").(bool) + cpu, cpuOk := d.GetOk("cpu_core_count") + gpu, gpuOk := d.GetOk("gpu_core_count") + memory, memoryOk := d.GetOk("memory_size") + var err error + typeList := make([]map[string]interface{}, 0) + ids := make([]string, 0) + + instanceSellTypes := resp.InstanceTypeQuotaSet + for _, instanceType := range instanceSellTypes { + flag := true + if cpuOk && int64(cpu.(int)) != *instanceType.Cpu { + flag = false + } + if gpuOk && int64(gpu.(int)) != *instanceType.Gpu { + flag = false + } + if memoryOk && int64(memory.(int)) != *instanceType.Memory { + flag = false + } + if isExcludeSoldOut && CVM_SOLD_OUT_STATUS == *instanceType.Status { + flag = false + } + + if flag { + mapping := map[string]interface{}{ + "availability_zone": instanceType.Zone, + "cpu_core_count": instanceType.Cpu, + "gpu_core_count": instanceType.Gpu, + "memory_size": instanceType.Memory, + "family": instanceType.InstanceFamily, + "instance_type": instanceType.InstanceType, + "instance_charge_type": instanceType.InstanceChargeType, + "status": instanceType.Status, + } + typeList = append(typeList, mapping) + ids = append(ids, *instanceType.InstanceType) + } + } + + d.SetId(helper.DataResourceIdsHash(ids)) + err = d.Set("instance_types", typeList) + if err != nil { + log.Printf("[CRITAL]%s provider set instance type list fail, reason:%s\n ", logId, err.Error()) + return err + } + context.WithValue(ctx, "typeList", typeList) + return nil +} + +func dataSourceTencentCloudInstanceTypesReadOutputContent(ctx context.Context) interface{} { + typeList := ctx.Value("typeList").([]interface{}) + return typeList +} diff --git a/tencentcloud/services/cvm/data_source_tc_instances.go b/tencentcloud/services/cvm/data_source_tc_instances.go index fb0a158882..f852e76029 100644 --- a/tencentcloud/services/cvm/data_source_tc_instances.go +++ b/tencentcloud/services/cvm/data_source_tc_instances.go @@ -2,146 +2,66 @@ package cvm import ( "context" - "fmt" - "log" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" ) func DataSourceTencentCloudInstances() *schema.Resource { return &schema.Resource{ Read: dataSourceTencentCloudInstancesRead, - Schema: map[string]*schema.Schema{ - "instance_id": { - Type: schema.TypeString, - Optional: true, - Description: "ID of the instances to be queried.", - }, - "instance_name": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: tccommon.ValidateStringLengthInRange(1, 30), - Description: "Name of the instances to be queried.", - }, "availability_zone": { Type: schema.TypeString, Optional: true, Description: "The available zone that the CVM instance locates at.", }, - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The project CVM belongs to.", - }, - "vpc_id": { - Type: schema.TypeString, - Optional: true, - Description: "ID of the vpc to be queried.", - }, - "subnet_id": { - Type: schema.TypeString, - Optional: true, - Description: "ID of a vpc subnetwork.", - }, - "instance_set_ids": { - Type: schema.TypeList, - Optional: true, - MaxItems: 100, - ConflictsWith: []string{"instance_id", "instance_name", "availability_zone", "project_id", "vpc_id", "subnet_id", "tags"}, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - Description: "Instance set ids, max length is 100, conflict with other field.", - }, - "tags": { - Type: schema.TypeMap, - Optional: true, - Description: "Tags of the instance.", - }, - "result_output_file": { + + "instance_id": { Type: schema.TypeString, Optional: true, - Description: "Used to save results.", + Description: "ID of the instances to be queried.", }, - // computed "instance_list": { Type: schema.TypeList, Computed: true, Description: "An information list of cvm instance. Each element contains the following attributes:", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "instance_id": { - Type: schema.TypeString, + "allocate_public_ip": { + Type: schema.TypeBool, Computed: true, - Description: "ID of the instances.", + Description: "Indicates whether public ip is assigned.", }, - "instance_name": { + "availability_zone": { Type: schema.TypeString, Computed: true, - Description: "Name of the instances.", + Description: "The available zone that the CVM instance locates at.", }, - "instance_type": { + "cam_role_name": { Type: schema.TypeString, Computed: true, - Description: "Type of the instance.", + Description: "CAM role name authorized to access.", }, "cpu": { Type: schema.TypeInt, Computed: true, Description: "The number of CPU cores of the instance.", }, - "memory": { - Type: schema.TypeInt, - Computed: true, - Description: "Instance memory capacity, unit in GB.", - }, "os_name": { Type: schema.TypeString, Computed: true, Description: "Instance os name.", }, - "availability_zone": { - Type: schema.TypeString, - Computed: true, - Description: "The available zone that the CVM instance locates at.", - }, - "project_id": { - Type: schema.TypeInt, - Computed: true, - Description: "The project CVM belongs to.", - }, - "image_id": { - Type: schema.TypeString, - Computed: true, - Description: "ID of the image.", - }, - "instance_charge_type": { - Type: schema.TypeString, - Computed: true, - Description: "The charge type of the instance.", - }, - "system_disk_type": { - Type: schema.TypeString, - Computed: true, - Description: "Type of the system disk.", - }, - "system_disk_size": { - Type: schema.TypeInt, - Computed: true, - Description: "Size of the system disk.", - }, - "system_disk_id": { + "create_time": { Type: schema.TypeString, Computed: true, - Description: "Image ID of the system disk.", + Description: "Creation time of the instance.", }, "data_disks": { Type: schema.TypeList, @@ -149,20 +69,20 @@ func DataSourceTencentCloudInstances() *schema.Resource { Description: "An information list of data disk. Each element contains the following attributes:", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "data_disk_type": { + "data_disk_id": { Type: schema.TypeString, Computed: true, - Description: "Type of the data disk.", + Description: "Image ID of the data disk.", }, "data_disk_size": { Type: schema.TypeInt, Computed: true, Description: "Size of the data disk.", }, - "data_disk_id": { + "data_disk_type": { Type: schema.TypeString, Computed: true, - Description: "Image ID of the data disk.", + Description: "Type of the data disk.", }, "delete_with_instance": { Type: schema.TypeBool, @@ -172,15 +92,40 @@ func DataSourceTencentCloudInstances() *schema.Resource { }, }, }, - "vpc_id": { + "expired_time": { Type: schema.TypeString, Computed: true, - Description: "ID of the vpc.", + Description: "Expired time of the instance.", }, - "subnet_id": { + "image_id": { Type: schema.TypeString, Computed: true, - Description: "ID of a vpc subnetwork.", + Description: "ID of the image.", + }, + "instance_charge_type": { + Type: schema.TypeString, + Computed: true, + Description: "The charge type of the instance.", + }, + "instance_charge_type_prepaid_renew_flag": { + Type: schema.TypeString, + Computed: true, + Description: "The way that CVM instance will be renew automatically or not when it reach the end of the prepaid tenancy.", + }, + "instance_id": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the instances.", + }, + "instance_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the instances.", + }, + "instance_type": { + Type: schema.TypeString, + Computed: true, + Description: "Type of the instance.", }, "internet_charge_type": { Type: schema.TypeString, @@ -192,180 +137,224 @@ func DataSourceTencentCloudInstances() *schema.Resource { Computed: true, Description: "Public network maximum output bandwidth of the instance.", }, - "allocate_public_ip": { - Type: schema.TypeBool, + "memory": { + Type: schema.TypeInt, Computed: true, - Description: "Indicates whether public ip is assigned.", + Description: "Instance memory capacity, unit in GB.", }, - "status": { + "private_ip": { Type: schema.TypeString, Computed: true, - Description: "Status of the instance.", + Description: "Private IP of the instance.", }, - "public_ip": { - Type: schema.TypeString, + "project_id": { + Type: schema.TypeInt, Computed: true, - Description: "Public IP of the instance.", + Description: "The project CVM belongs to.", }, - "private_ip": { + "public_ip": { Type: schema.TypeString, Computed: true, - Description: "Private IP of the instance.", + Description: "Public IP of the instance.", }, "security_groups": { Type: schema.TypeList, Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, Description: "Security groups of the instance.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, - "tags": { - Type: schema.TypeMap, + "status": { + Type: schema.TypeString, Computed: true, - Description: "Tags of the instance.", + Description: "Status of the instance.", }, - "create_time": { + "subnet_id": { Type: schema.TypeString, Computed: true, - Description: "Creation time of the instance.", + Description: "ID of a vpc subnetwork.", }, - "expired_time": { + "system_disk_id": { Type: schema.TypeString, Computed: true, - Description: "Expired time of the instance.", + Description: "Image ID of the system disk.", }, - "instance_charge_type_prepaid_renew_flag": { + "system_disk_size": { + Type: schema.TypeInt, + Computed: true, + Description: "Size of the system disk.", + }, + "system_disk_type": { Type: schema.TypeString, Computed: true, - Description: "The way that CVM instance will be renew automatically or not when it reach the end of the prepaid tenancy.", + Description: "Type of the system disk.", }, - "cam_role_name": { + "tags": { + Type: schema.TypeMap, + Computed: true, + Description: "Tags of the instance.", + }, + "vpc_id": { Type: schema.TypeString, Computed: true, - Description: "CAM role name authorized to access.", + Description: "ID of the vpc.", }, }, }, }, + + "instance_name": { + Type: schema.TypeString, + Optional: true, + Description: "Name of the instances to be queried.", + }, + + "instance_set_ids": { + Type: schema.TypeList, + Optional: true, + MaxItems: 100, + ConflictsWith: []string{"instance_id", "instance_name", "availability_zone", "project_id", "vpc_id", "subnet_id", "tags"}, + Description: "Instance set ids, max length is 100, conflict with other field.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "project_id": { + Type: schema.TypeInt, + Optional: true, + Description: "The project CVM belongs to.", + }, + + "subnet_id": { + Type: schema.TypeString, + Optional: true, + Description: "ID of a vpc subnetwork.", + }, + + "tags": { + Type: schema.TypeMap, + Optional: true, + Description: "Tags of the instance.", + }, + + "vpc_id": { + Type: schema.TypeString, + Optional: true, + Description: "ID of the vpc to be queried.", + }, + + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, }, } } func dataSourceTencentCloudInstancesRead(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("data_source.tencentcloud_instances.read")() - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } + defer tccommon.InconsistentCheck(d, meta)() - var instanceSetIds []*string + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - filter := make(map[string]string) + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + paramMap := make(map[string]interface{}) + var filtersList []*cvm.Filter + filtersMap := map[string]*cvm.Filter{} + filter := cvm.Filter{} + name := "instance-id" + filter.Name = &name if v, ok := d.GetOk("instance_id"); ok { - filter["instance-id"] = v.(string) + filter.Values = []*string{helper.String(v.(string))} + } + filtersMap["Temp0"] = &filter + if v, ok := filtersMap["Temp0"]; ok && len(v.Values) > 0 { + filtersList = append(filtersList, v) } + filter2 := cvm.Filter{} + name2 := "instance-name" + filter2.Name = &name2 if v, ok := d.GetOk("instance_name"); ok { - filter["instance-name"] = v.(string) + filter2.Values = []*string{helper.String(v.(string))} } + filtersMap["Temp1"] = &filter2 + if v, ok := filtersMap["Temp1"]; ok && len(v.Values) > 0 { + filtersList = append(filtersList, v) + } + filter3 := cvm.Filter{} + name3 := "zone" + filter3.Name = &name3 if v, ok := d.GetOk("availability_zone"); ok { - filter["zone"] = v.(string) + filter3.Values = []*string{helper.String(v.(string))} + } + filtersMap["Temp2"] = &filter3 + if v, ok := filtersMap["Temp2"]; ok && len(v.Values) > 0 { + filtersList = append(filtersList, v) } - if v, ok := d.GetOkExists("project_id"); ok { - filter["project-id"] = fmt.Sprintf("%d", v.(int)) + filter4 := cvm.Filter{} + name4 := "project-id" + filter4.Name = &name4 + if v, ok := d.GetOk("project_id"); ok { + filter4.Values = []*string{helper.String(v.(string))} } + filtersMap["Temp3"] = &filter4 + if v, ok := filtersMap["Temp3"]; ok && len(v.Values) > 0 { + filtersList = append(filtersList, v) + } + filter5 := cvm.Filter{} + name5 := "vpc-id" + filter5.Name = &name5 if v, ok := d.GetOk("vpc_id"); ok { - filter["vpc-id"] = v.(string) + filter5.Values = []*string{helper.String(v.(string))} + } + filtersMap["Temp4"] = &filter5 + if v, ok := filtersMap["Temp4"]; ok && len(v.Values) > 0 { + filtersList = append(filtersList, v) } + filter6 := cvm.Filter{} + name6 := "subnet-id" + filter6.Name = &name6 if v, ok := d.GetOk("subnet_id"); ok { - filter["subnet-id"] = v.(string) + filter6.Values = []*string{helper.String(v.(string))} } - if v, ok := d.GetOk("instance_set_ids"); ok { - instanceSetIds = helper.InterfacesStringsPoint(v.([]interface{})) + filtersMap["Temp5"] = &filter6 + if v, ok := filtersMap["Temp5"]; ok && len(v.Values) > 0 { + filtersList = append(filtersList, v) } + paramMap["Filters"] = filtersList - if v, ok := d.GetOk("tags"); ok { - for key, value := range v.(map[string]interface{}) { - filter["tag:"+key] = value.(string) - } + if err := dataSourceTencentCloudInstancesReadPostFillRequest0(ctx, paramMap); err != nil { + return err } - var instances []*cvm.Instance - var errRet error + var respData []*cvm.Instance err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - instances, errRet = cvmService.DescribeInstanceByFilter(ctx, instanceSetIds, filter) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) + result, e := service.DescribeInstancesByFilter(ctx, paramMap) + if e != nil { + return tccommon.RetryError(e) } + respData = result return nil }) if err != nil { return err } - instanceList := make([]map[string]interface{}, 0, len(instances)) - ids := make([]string, 0, len(instances)) - for _, instance := range instances { - mapping := map[string]interface{}{ - "instance_id": instance.InstanceId, - "instance_name": instance.InstanceName, - "instance_type": instance.InstanceType, - "cpu": instance.CPU, - "memory": instance.Memory, - "os_name": instance.OsName, - "availability_zone": instance.Placement.Zone, - "project_id": instance.Placement.ProjectId, - "image_id": instance.ImageId, - "instance_charge_type": instance.InstanceChargeType, - "system_disk_type": instance.SystemDisk.DiskType, - "system_disk_size": instance.SystemDisk.DiskSize, - "system_disk_id": instance.SystemDisk.DiskId, - "vpc_id": instance.VirtualPrivateCloud.VpcId, - "subnet_id": instance.VirtualPrivateCloud.SubnetId, - "internet_charge_type": instance.InternetAccessible.InternetChargeType, - "internet_max_bandwidth_out": instance.InternetAccessible.InternetMaxBandwidthOut, - "allocate_public_ip": instance.InternetAccessible.PublicIpAssigned, - "status": instance.InstanceState, - "security_groups": helper.StringsInterfaces(instance.SecurityGroupIds), - "tags": flattenCvmTagsMapping(instance.Tags), - "create_time": instance.CreatedTime, - "expired_time": instance.ExpiredTime, - "instance_charge_type_prepaid_renew_flag": instance.RenewFlag, - "cam_role_name": instance.CamRoleName, - } - if len(instance.PublicIpAddresses) > 0 { - mapping["public_ip"] = *instance.PublicIpAddresses[0] - } - if len(instance.PrivateIpAddresses) > 0 { - mapping["private_ip"] = *instance.PrivateIpAddresses[0] - } - dataDisks := make([]map[string]interface{}, 0, len(instance.DataDisks)) - for _, v := range instance.DataDisks { - dataDisk := map[string]interface{}{ - "data_disk_type": v.DiskType, - "data_disk_size": v.DiskSize, - "data_disk_id": v.DiskId, - "delete_with_instance": v.DeleteWithInstance, - } - dataDisks = append(dataDisks, dataDisk) - } - mapping["data_disks"] = dataDisks - instanceList = append(instanceList, mapping) - ids = append(ids, *instance.InstanceId) - } - - d.SetId(helper.DataResourceIdsHash(ids)) - err = d.Set("instance_list", instanceList) - if err != nil { - log.Printf("[CRITAL]%s provider set instance list fail, reason:%s\n ", logId, err.Error()) + if err := dataSourceTencentCloudInstancesReadPostHandleResponse0(ctx, paramMap, &respData); err != nil { return err } output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if err := tccommon.WriteToFile(output.(string), instanceList); err != nil { - return err + if e := tccommon.WriteToFile(output.(string), dataSourceTencentCloudInstancesReadOutputContent(ctx)); e != nil { + return e } } - return nil + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_instances_extension.go b/tencentcloud/services/cvm/data_source_tc_instances_extension.go new file mode 100644 index 0000000000..a2cf6be7b3 --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_instances_extension.go @@ -0,0 +1,103 @@ +package cvm + +import ( + "context" + "log" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" + + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +func dataSourceTencentCloudInstancesReadPostFillRequest0(ctx context.Context, req map[string]interface{}) error { + d := tccommon.ResourceDataFromContext(ctx) + if v, ok := d.GetOk("tags"); ok { + for key, value := range v.(map[string]interface{}) { + req["tag:"+key] = value.(string) + } + } + + return nil +} + +func dataSourceTencentCloudInstancesReadPreRequest0(ctx context.Context, req *cvm.DescribeInstancesRequest) error { + d := tccommon.ResourceDataFromContext(ctx) + if v, ok := d.GetOk("instance_set_ids"); ok { + req.InstanceIds = helper.InterfacesStringsPoint(v.([]interface{})) + } + + return nil +} + +func dataSourceTencentCloudInstancesReadPostHandleResponse0(ctx context.Context, req map[string]interface{}, resp *[]*cvm.Instance) error { + d := tccommon.ResourceDataFromContext(ctx) + logId := tccommon.GetLogId(tccommon.ContextNil) + var err error + instances := *resp + instanceList := make([]map[string]interface{}, 0, len(instances)) + ids := make([]string, 0, len(instances)) + for _, instance := range instances { + mapping := map[string]interface{}{ + "instance_id": instance.InstanceId, + "instance_name": instance.InstanceName, + "instance_type": instance.InstanceType, + "cpu": instance.CPU, + "memory": instance.Memory, + "os_name": instance.OsName, + "availability_zone": instance.Placement.Zone, + "project_id": instance.Placement.ProjectId, + "image_id": instance.ImageId, + "instance_charge_type": instance.InstanceChargeType, + "system_disk_type": instance.SystemDisk.DiskType, + "system_disk_size": instance.SystemDisk.DiskSize, + "system_disk_id": instance.SystemDisk.DiskId, + "vpc_id": instance.VirtualPrivateCloud.VpcId, + "subnet_id": instance.VirtualPrivateCloud.SubnetId, + "internet_charge_type": instance.InternetAccessible.InternetChargeType, + "internet_max_bandwidth_out": instance.InternetAccessible.InternetMaxBandwidthOut, + "allocate_public_ip": instance.InternetAccessible.PublicIpAssigned, + "status": instance.InstanceState, + "security_groups": helper.StringsInterfaces(instance.SecurityGroupIds), + "tags": flattenCvmTagsMapping(instance.Tags), + "create_time": instance.CreatedTime, + "expired_time": instance.ExpiredTime, + "instance_charge_type_prepaid_renew_flag": instance.RenewFlag, + "cam_role_name": instance.CamRoleName, + } + if len(instance.PublicIpAddresses) > 0 { + mapping["public_ip"] = *instance.PublicIpAddresses[0] + } + if len(instance.PrivateIpAddresses) > 0 { + mapping["private_ip"] = *instance.PrivateIpAddresses[0] + } + dataDisks := make([]map[string]interface{}, 0, len(instance.DataDisks)) + for _, v := range instance.DataDisks { + dataDisk := map[string]interface{}{ + "data_disk_type": v.DiskType, + "data_disk_size": v.DiskSize, + "data_disk_id": v.DiskId, + "delete_with_instance": v.DeleteWithInstance, + } + dataDisks = append(dataDisks, dataDisk) + } + mapping["data_disks"] = dataDisks + instanceList = append(instanceList, mapping) + ids = append(ids, *instance.InstanceId) + } + + d.SetId(helper.DataResourceIdsHash(ids)) + err = d.Set("instance_list", instanceList) + if err != nil { + log.Printf("[CRITAL]%s provider set instance list fail, reason:%s\n ", logId, err.Error()) + return err + } + + context.WithValue(ctx, "instanceList", instanceList) + return nil +} + +func dataSourceTencentCloudInstancesReadOutputContent(ctx context.Context) interface{} { + instanceList := ctx.Value("instanceList") + return instanceList +} diff --git a/tencentcloud/services/cvm/data_source_tc_instances_set.go b/tencentcloud/services/cvm/data_source_tc_instances_set.go index 4f964a74bf..32f4a1ad54 100644 --- a/tencentcloud/services/cvm/data_source_tc_instances_set.go +++ b/tencentcloud/services/cvm/data_source_tc_instances_set.go @@ -2,130 +2,61 @@ package cvm import ( "context" - "fmt" - "log" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" ) func DataSourceTencentCloudInstancesSet() *schema.Resource { return &schema.Resource{ Read: dataSourceTencentCloudInstancesSetRead, - Schema: map[string]*schema.Schema{ - "instance_id": { - Type: schema.TypeString, - Optional: true, - Description: "ID of the instances to be queried.", - }, - "instance_name": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: tccommon.ValidateStringLengthInRange(1, 30), - Description: "Name of the instances to be queried.", - }, "availability_zone": { Type: schema.TypeString, Optional: true, Description: "The available zone that the CVM instance locates at.", }, - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The project CVM belongs to.", - }, - "vpc_id": { - Type: schema.TypeString, - Optional: true, - Description: "ID of the vpc to be queried.", - }, - "subnet_id": { - Type: schema.TypeString, - Optional: true, - Description: "ID of a vpc subnetwork.", - }, - "tags": { - Type: schema.TypeMap, - Optional: true, - Description: "Tags of the instance.", - }, - "result_output_file": { + + "instance_id": { Type: schema.TypeString, Optional: true, - Description: "Used to save results.", + Description: "ID of the instances to be queried.", }, - // computed "instance_list": { Type: schema.TypeList, Computed: true, Description: "An information list of cvm instance. Each element contains the following attributes:", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "instance_id": { - Type: schema.TypeString, - Computed: true, - Description: "ID of the instances.", - }, - "instance_name": { - Type: schema.TypeString, - Computed: true, - Description: "Name of the instances.", - }, - "instance_type": { - Type: schema.TypeString, - Computed: true, - Description: "Type of the instance.", - }, - "cpu": { - Type: schema.TypeInt, - Computed: true, - Description: "The number of CPU cores of the instance.", - }, - "memory": { - Type: schema.TypeInt, + "allocate_public_ip": { + Type: schema.TypeBool, Computed: true, - Description: "Instance memory capacity, unit in GB.", + Description: "Indicates whether public ip is assigned.", }, "availability_zone": { Type: schema.TypeString, Computed: true, Description: "The available zone that the CVM instance locates at.", }, - "project_id": { - Type: schema.TypeInt, - Computed: true, - Description: "The project CVM belongs to.", - }, - "image_id": { - Type: schema.TypeString, - Computed: true, - Description: "ID of the image.", - }, - "instance_charge_type": { - Type: schema.TypeString, - Computed: true, - Description: "The charge type of the instance.", - }, - "system_disk_type": { + "cam_role_name": { Type: schema.TypeString, Computed: true, - Description: "Type of the system disk.", + Description: "CAM role name authorized to access.", }, - "system_disk_size": { + "cpu": { Type: schema.TypeInt, Computed: true, - Description: "Size of the system disk.", + Description: "The number of CPU cores of the instance.", }, - "system_disk_id": { + "create_time": { Type: schema.TypeString, Computed: true, - Description: "Image ID of the system disk.", + Description: "Creation time of the instance.", }, "data_disks": { Type: schema.TypeList, @@ -133,20 +64,20 @@ func DataSourceTencentCloudInstancesSet() *schema.Resource { Description: "An information list of data disk. Each element contains the following attributes:", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "data_disk_type": { + "data_disk_id": { Type: schema.TypeString, Computed: true, - Description: "Type of the data disk.", + Description: "Image ID of the data disk.", }, "data_disk_size": { Type: schema.TypeInt, Computed: true, Description: "Size of the data disk.", }, - "data_disk_id": { + "data_disk_type": { Type: schema.TypeString, Computed: true, - Description: "Image ID of the data disk.", + Description: "Type of the data disk.", }, "delete_with_instance": { Type: schema.TypeBool, @@ -156,15 +87,40 @@ func DataSourceTencentCloudInstancesSet() *schema.Resource { }, }, }, - "vpc_id": { + "expired_time": { Type: schema.TypeString, Computed: true, - Description: "ID of the vpc.", + Description: "Expired time of the instance.", }, - "subnet_id": { + "image_id": { Type: schema.TypeString, Computed: true, - Description: "ID of a vpc subnetwork.", + Description: "ID of the image.", + }, + "instance_charge_type": { + Type: schema.TypeString, + Computed: true, + Description: "The charge type of the instance.", + }, + "instance_charge_type_prepaid_renew_flag": { + Type: schema.TypeString, + Computed: true, + Description: "The way that CVM instance will be renew automatically or not when it reach the end of the prepaid tenancy.", + }, + "instance_id": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the instances.", + }, + "instance_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the instances.", + }, + "instance_type": { + Type: schema.TypeString, + Computed: true, + Description: "Type of the instance.", }, "internet_charge_type": { Type: schema.TypeString, @@ -176,172 +132,213 @@ func DataSourceTencentCloudInstancesSet() *schema.Resource { Computed: true, Description: "Public network maximum output bandwidth of the instance.", }, - "allocate_public_ip": { - Type: schema.TypeBool, + "memory": { + Type: schema.TypeInt, Computed: true, - Description: "Indicates whether public ip is assigned.", + Description: "Instance memory capacity, unit in GB.", }, - "status": { + "private_ip": { Type: schema.TypeString, Computed: true, - Description: "Status of the instance.", + Description: "Private IP of the instance.", }, - "public_ip": { - Type: schema.TypeString, + "project_id": { + Type: schema.TypeInt, Computed: true, - Description: "Public IP of the instance.", + Description: "The project CVM belongs to.", }, - "private_ip": { + "public_ip": { Type: schema.TypeString, Computed: true, - Description: "Private IP of the instance.", + Description: "Public IP of the instance.", }, "security_groups": { Type: schema.TypeList, Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, Description: "Security groups of the instance.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, - "tags": { - Type: schema.TypeMap, + "status": { + Type: schema.TypeString, Computed: true, - Description: "Tags of the instance.", + Description: "Status of the instance.", }, - "create_time": { + "subnet_id": { Type: schema.TypeString, Computed: true, - Description: "Creation time of the instance.", + Description: "ID of a vpc subnetwork.", }, - "expired_time": { + "system_disk_id": { Type: schema.TypeString, Computed: true, - Description: "Expired time of the instance.", + Description: "Image ID of the system disk.", }, - "instance_charge_type_prepaid_renew_flag": { + "system_disk_size": { + Type: schema.TypeInt, + Computed: true, + Description: "Size of the system disk.", + }, + "system_disk_type": { Type: schema.TypeString, Computed: true, - Description: "The way that CVM instance will be renew automatically or not when it reach the end of the prepaid tenancy.", + Description: "Type of the system disk.", }, - "cam_role_name": { + "tags": { + Type: schema.TypeMap, + Computed: true, + Description: "Tags of the instance.", + }, + "vpc_id": { Type: schema.TypeString, Computed: true, - Description: "CAM role name authorized to access.", + Description: "ID of the vpc.", }, }, }, }, + + "instance_name": { + Type: schema.TypeString, + Optional: true, + Description: "Name of the instances to be queried.", + }, + + "project_id": { + Type: schema.TypeInt, + Optional: true, + Description: "The project CVM belongs to.", + }, + + "subnet_id": { + Type: schema.TypeString, + Optional: true, + Description: "ID of a vpc subnetwork.", + }, + + "tags": { + Type: schema.TypeMap, + Optional: true, + Description: "Tags of the instance.", + }, + + "vpc_id": { + Type: schema.TypeString, + Optional: true, + Description: "ID of the vpc to be queried.", + }, + + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, }, } } func dataSourceTencentCloudInstancesSetRead(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("data_source.tencentcloud_instances_set.read")() - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - filter := make(map[string]string) + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + paramMap := make(map[string]interface{}) + var filtersList []*cvm.Filter + filtersMap := map[string]*cvm.Filter{} + filter := cvm.Filter{} + name := "instance-id" + filter.Name = &name if v, ok := d.GetOk("instance_id"); ok { - filter["instance-id"] = v.(string) + filter.Values = []*string{helper.String(v.(string))} + } + filtersMap["Temp0"] = &filter + if v, ok := filtersMap["Temp0"]; ok && len(v.Values) > 0 { + filtersList = append(filtersList, v) } + filter2 := cvm.Filter{} + name2 := "instance-name" + filter2.Name = &name2 if v, ok := d.GetOk("instance_name"); ok { - filter["instance-name"] = v.(string) + filter2.Values = []*string{helper.String(v.(string))} } + filtersMap["Temp1"] = &filter2 + if v, ok := filtersMap["Temp1"]; ok && len(v.Values) > 0 { + filtersList = append(filtersList, v) + } + filter3 := cvm.Filter{} + name3 := "zone" + filter3.Name = &name3 if v, ok := d.GetOk("availability_zone"); ok { - filter["zone"] = v.(string) + filter3.Values = []*string{helper.String(v.(string))} + } + filtersMap["Temp2"] = &filter3 + if v, ok := filtersMap["Temp2"]; ok && len(v.Values) > 0 { + filtersList = append(filtersList, v) + } + filter4 := cvm.Filter{} + name4 := "project-id" + filter4.Name = &name4 + if v, ok := d.GetOk("project_id"); ok { + filter4.Values = []*string{helper.String(v.(string))} } - if v, ok := d.GetOkExists("project_id"); ok { - filter["project-id"] = fmt.Sprintf("%d", v.(int)) + filtersMap["Temp3"] = &filter4 + if v, ok := filtersMap["Temp3"]; ok && len(v.Values) > 0 { + filtersList = append(filtersList, v) } + filter5 := cvm.Filter{} + name5 := "vpc-id" + filter5.Name = &name5 if v, ok := d.GetOk("vpc_id"); ok { - filter["vpc-id"] = v.(string) + filter5.Values = []*string{helper.String(v.(string))} } + filtersMap["Temp4"] = &filter5 + if v, ok := filtersMap["Temp4"]; ok && len(v.Values) > 0 { + filtersList = append(filtersList, v) + } + filter6 := cvm.Filter{} + name6 := "subnet-id" + filter6.Name = &name6 if v, ok := d.GetOk("subnet_id"); ok { - filter["subnet-id"] = v.(string) + filter6.Values = []*string{helper.String(v.(string))} } - - if v, ok := d.GetOk("tags"); ok { - for key, value := range v.(map[string]interface{}) { - filter["tag:"+key] = value.(string) - } + filtersMap["Temp5"] = &filter6 + if v, ok := filtersMap["Temp5"]; ok && len(v.Values) > 0 { + filtersList = append(filtersList, v) } + paramMap["Filters"] = filtersList - var instances []*cvm.Instance - var errRet error - - instances, errRet = cvmService.DescribeInstanceInParallelByFilter(ctx, filter) - - if errRet != nil { - return errRet + if err := dataSourceTencentCloudInstancesSetReadPostFillRequest0(ctx, paramMap); err != nil { + return err } - instanceList := make([]map[string]interface{}, 0, len(instances)) - ids := make([]string, 0, len(instances)) - for _, instance := range instances { - mapping := map[string]interface{}{ - "instance_id": instance.InstanceId, - "instance_name": instance.InstanceName, - "instance_type": instance.InstanceType, - "cpu": instance.CPU, - "memory": instance.Memory, - "availability_zone": instance.Placement.Zone, - "project_id": instance.Placement.ProjectId, - "image_id": instance.ImageId, - "instance_charge_type": instance.InstanceChargeType, - "system_disk_type": instance.SystemDisk.DiskType, - "system_disk_size": instance.SystemDisk.DiskSize, - "system_disk_id": instance.SystemDisk.DiskId, - "vpc_id": instance.VirtualPrivateCloud.VpcId, - "subnet_id": instance.VirtualPrivateCloud.SubnetId, - "internet_charge_type": instance.InternetAccessible.InternetChargeType, - "internet_max_bandwidth_out": instance.InternetAccessible.InternetMaxBandwidthOut, - "allocate_public_ip": instance.InternetAccessible.PublicIpAssigned, - "status": instance.InstanceState, - "security_groups": helper.StringsInterfaces(instance.SecurityGroupIds), - "tags": flattenCvmTagsMapping(instance.Tags), - "create_time": instance.CreatedTime, - "expired_time": instance.ExpiredTime, - "instance_charge_type_prepaid_renew_flag": instance.RenewFlag, - "cam_role_name": instance.CamRoleName, - } - if len(instance.PublicIpAddresses) > 0 { - mapping["public_ip"] = *instance.PublicIpAddresses[0] + var respData []*cvm.Instance + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + result, e := service.DescribeInstancesSetByFilter(ctx, paramMap) + if e != nil { + return tccommon.RetryError(e) } - if len(instance.PrivateIpAddresses) > 0 { - mapping["private_ip"] = *instance.PrivateIpAddresses[0] - } - dataDisks := make([]map[string]interface{}, 0, len(instance.DataDisks)) - for _, v := range instance.DataDisks { - dataDisk := map[string]interface{}{ - "data_disk_type": v.DiskType, - "data_disk_size": v.DiskSize, - "data_disk_id": v.DiskId, - "delete_with_instance": v.DeleteWithInstance, - } - dataDisks = append(dataDisks, dataDisk) - } - mapping["data_disks"] = dataDisks - instanceList = append(instanceList, mapping) - ids = append(ids, *instance.InstanceId) - } - log.Printf("[DEBUG]%s set instance attribute finished", logId) - d.SetId(helper.DataResourceIdsHash(ids)) - err := d.Set("instance_list", instanceList) + respData = result + return nil + }) if err != nil { - log.Printf("[CRITAL]%s provider set instance list fail, reason:%s\n ", logId, err.Error()) + return err + } + + if err := dataSourceTencentCloudInstancesSetReadPostHandleResponse0(ctx, paramMap, &respData); err != nil { return err } output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if err := tccommon.WriteToFile(output.(string), instanceList); err != nil { - return err + if e := tccommon.WriteToFile(output.(string), dataSourceTencentCloudInstancesSetReadOutputContent(ctx)); e != nil { + return e } } - log.Printf("[DEBUG]%s all operate finished", logId) return nil - } diff --git a/tencentcloud/services/cvm/data_source_tc_instances_set_extension.go b/tencentcloud/services/cvm/data_source_tc_instances_set_extension.go new file mode 100644 index 0000000000..e99cf86092 --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_instances_set_extension.go @@ -0,0 +1,91 @@ +package cvm + +import ( + "context" + "log" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" + + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +func dataSourceTencentCloudInstancesSetReadPostFillRequest0(ctx context.Context, req map[string]interface{}) error { + d := tccommon.ResourceDataFromContext(ctx) + if v, ok := d.GetOk("tags"); ok { + for key, value := range v.(map[string]interface{}) { + req["tag:"+key] = value.(string) + } + } + + return nil +} + +func dataSourceTencentCloudInstancesSetReadPostHandleResponse0(ctx context.Context, req map[string]interface{}, resp *[]*cvm.Instance) error { + logId := tccommon.GetLogId(tccommon.ContextNil) + d := tccommon.ResourceDataFromContext(ctx) + instances := *resp + instanceList := make([]map[string]interface{}, 0, len(instances)) + ids := make([]string, 0, len(instances)) + for _, instance := range instances { + mapping := map[string]interface{}{ + "instance_id": instance.InstanceId, + "instance_name": instance.InstanceName, + "instance_type": instance.InstanceType, + "cpu": instance.CPU, + "memory": instance.Memory, + "availability_zone": instance.Placement.Zone, + "project_id": instance.Placement.ProjectId, + "image_id": instance.ImageId, + "instance_charge_type": instance.InstanceChargeType, + "system_disk_type": instance.SystemDisk.DiskType, + "system_disk_size": instance.SystemDisk.DiskSize, + "system_disk_id": instance.SystemDisk.DiskId, + "vpc_id": instance.VirtualPrivateCloud.VpcId, + "subnet_id": instance.VirtualPrivateCloud.SubnetId, + "internet_charge_type": instance.InternetAccessible.InternetChargeType, + "internet_max_bandwidth_out": instance.InternetAccessible.InternetMaxBandwidthOut, + "allocate_public_ip": instance.InternetAccessible.PublicIpAssigned, + "status": instance.InstanceState, + "security_groups": helper.StringsInterfaces(instance.SecurityGroupIds), + "tags": flattenCvmTagsMapping(instance.Tags), + "create_time": instance.CreatedTime, + "expired_time": instance.ExpiredTime, + "instance_charge_type_prepaid_renew_flag": instance.RenewFlag, + "cam_role_name": instance.CamRoleName, + } + if len(instance.PublicIpAddresses) > 0 { + mapping["public_ip"] = *instance.PublicIpAddresses[0] + } + if len(instance.PrivateIpAddresses) > 0 { + mapping["private_ip"] = *instance.PrivateIpAddresses[0] + } + dataDisks := make([]map[string]interface{}, 0, len(instance.DataDisks)) + for _, v := range instance.DataDisks { + dataDisk := map[string]interface{}{ + "data_disk_type": v.DiskType, + "data_disk_size": v.DiskSize, + "data_disk_id": v.DiskId, + "delete_with_instance": v.DeleteWithInstance, + } + dataDisks = append(dataDisks, dataDisk) + } + mapping["data_disks"] = dataDisks + instanceList = append(instanceList, mapping) + ids = append(ids, *instance.InstanceId) + } + log.Printf("[DEBUG]%s set instance attribute finished", logId) + d.SetId(helper.DataResourceIdsHash(ids)) + err := d.Set("instance_list", instanceList) + if err != nil { + log.Printf("[CRITAL]%s provider set instance list fail, reason:%s\n ", logId, err.Error()) + return err + } + context.WithValue(ctx, "instanceList", instanceList) + return nil +} + +func dataSourceTencentCloudInstancesSetReadOutputContent(ctx context.Context) interface{} { + instanceList := ctx.Value("instanceList") + return instanceList +} diff --git a/tencentcloud/services/cvm/data_source_tc_key_pairs.go b/tencentcloud/services/cvm/data_source_tc_key_pairs.go index 6dbbf49d5f..e541d2a6d6 100644 --- a/tencentcloud/services/cvm/data_source_tc_key_pairs.go +++ b/tencentcloud/services/cvm/data_source_tc_key_pairs.go @@ -2,24 +2,17 @@ package cvm import ( "context" - "fmt" - "log" - "regexp" - "strings" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" - "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" ) func DataSourceTencentCloudKeyPairs() *schema.Resource { return &schema.Resource{ Read: dataSourceTencentCloudKeyPairsRead, - Schema: map[string]*schema.Schema{ "key_id": { Type: schema.TypeString, @@ -27,31 +20,25 @@ func DataSourceTencentCloudKeyPairs() *schema.Resource { ConflictsWith: []string{"key_name", "project_id"}, Description: "ID of the key pair to be queried.", }, + "key_name": { Type: schema.TypeString, Optional: true, ConflictsWith: []string{"key_id"}, Description: "Name of the key pair to be queried. Support regular expression search, only `^` and `$` are supported.", }, - "project_id": { - Type: schema.TypeInt, - Optional: true, - ConflictsWith: []string{"key_id"}, - Description: "Project ID of the key pair to be queried.", - }, - "result_output_file": { - Type: schema.TypeString, - Optional: true, - Description: "Used to save results.", - }, - // computed "key_pair_list": { Type: schema.TypeList, Computed: true, Description: "An information list of key pair. Each element contains the following attributes:", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "Creation time of the key pair.", + }, "key_id": { Type: schema.TypeString, Computed: true, @@ -72,98 +59,59 @@ func DataSourceTencentCloudKeyPairs() *schema.Resource { Computed: true, Description: "public key of the key pair.", }, - "create_time": { - Type: schema.TypeString, - Computed: true, - Description: "Creation time of the key pair.", - }, }, }, }, + + "project_id": { + Type: schema.TypeInt, + Optional: true, + ConflictsWith: []string{"key_id"}, + Description: "Project ID of the key pair to be queried.", + }, + + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, }, } } func dataSourceTencentCloudKeyPairsRead(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("data_source.tencentcloud_key_pairs.read")() - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } + defer tccommon.InconsistentCheck(d, meta)() - keyId := d.Get("key_id").(string) - keyName := d.Get("key_name").(string) - name := keyName - if keyName != "" { - if name[0] == '^' { - name = name[1:] - } - length := len(name) - if length > 0 && name[length-1] == '$' { - name = name[:length-1] - } + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - pattern := `^[a-zA-Z0-9_]+$` - if match, _ := regexp.MatchString(pattern, name); !match { - return fmt.Errorf("key_name only support letters, numbers, and _ : %s", keyName) - } - } + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - var projectId *int - if v, ok := d.GetOkExists("project_id"); ok { - vv := v.(int) - projectId = &vv - } - - var keyPairs []*cvm.KeyPair - var errRet error + paramMap := make(map[string]interface{}) + var respData []*cvm.KeyPair err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - keyPairs, errRet = cvmService.DescribeKeyPairByFilter(ctx, keyId, name, projectId) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) + result, e := service.DescribeKeyPairsByFilter(ctx, paramMap) + if e != nil { + return tccommon.RetryError(e) } + respData = result return nil }) if err != nil { return err } - keyPairList := make([]map[string]interface{}, 0, len(keyPairs)) - ids := make([]string, 0, len(keyPairs)) - namePattern, _ := regexp.Compile(keyName) - for _, keyPair := range keyPairs { - if match := namePattern.MatchString(*keyPair.KeyName); !match { - continue - } - mapping := map[string]interface{}{ - "key_id": keyPair.KeyId, - "key_name": keyPair.KeyName, - "project_id": keyPair.ProjectId, - "create_time": keyPair.CreatedTime, - } - if keyPair.PublicKey != nil { - publicKey := *keyPair.PublicKey - split := strings.Split(publicKey, " ") - publicKey = strings.Join(split[0:len(split)-1], " ") - mapping["public_key"] = publicKey - } - keyPairList = append(keyPairList, mapping) - ids = append(ids, *keyPair.KeyId) - } - - d.SetId(helper.DataResourceIdsHash(ids)) - err = d.Set("key_pair_list", keyPairList) - if err != nil { - log.Printf("[CRITAL]%s provider set key pair list fail, reason:%s\n ", logId, err.Error()) + if err := dataSourceTencentCloudKeyPairsReadPostHandleResponse0(ctx, paramMap, &respData); err != nil { return err } output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if err := tccommon.WriteToFile(output.(string), keyPairList); err != nil { - return err + if e := tccommon.WriteToFile(output.(string), dataSourceTencentCloudKeyPairsReadOutputContent(ctx)); e != nil { + return e } } + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_key_pairs_extension.go b/tencentcloud/services/cvm/data_source_tc_key_pairs_extension.go new file mode 100644 index 0000000000..5c7e95ebf9 --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_key_pairs_extension.go @@ -0,0 +1,109 @@ +package cvm + +import ( + "context" + "fmt" + "log" + "regexp" + "strings" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" + + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +func dataSourceTencentCloudKeyPairsReadPostHandleResponse0(ctx context.Context, req map[string]interface{}, resp *[]*cvm.KeyPair) error { + d := tccommon.ResourceDataFromContext(ctx) + logId := tccommon.GetLogId(tccommon.ContextNil) + var err error + keyPairs := *resp + keyPairList := make([]map[string]interface{}, 0, len(keyPairs)) + ids := make([]string, 0, len(keyPairs)) + keyName := d.Get("key_name").(string) + namePattern, _ := regexp.Compile(keyName) + for _, keyPair := range keyPairs { + if match := namePattern.MatchString(*keyPair.KeyName); !match { + continue + } + mapping := map[string]interface{}{ + "key_id": keyPair.KeyId, + "key_name": keyPair.KeyName, + "project_id": keyPair.ProjectId, + "create_time": keyPair.CreatedTime, + } + if keyPair.PublicKey != nil { + publicKey := *keyPair.PublicKey + split := strings.Split(publicKey, " ") + publicKey = strings.Join(split[0:len(split)-1], " ") + mapping["public_key"] = publicKey + } + keyPairList = append(keyPairList, mapping) + ids = append(ids, *keyPair.KeyId) + } + + d.SetId(helper.DataResourceIdsHash(ids)) + err = d.Set("key_pair_list", keyPairList) + if err != nil { + log.Printf("[CRITAL]%s provider set key pair list fail, reason:%s\n ", logId, err.Error()) + return err + } + + context.WithValue(ctx, "keyPairList", keyPairList) + return nil +} + +func dataSourceTencentCloudKeyPairsReadOutputContent(ctx context.Context) interface{} { + eipList := ctx.Value("keyPairList") + return eipList +} + +func dataSourceTencentCloudKeyPairsReadPreRequest0(ctx context.Context, req *cvm.DescribeKeyPairsRequest) error { + d := tccommon.ResourceDataFromContext(ctx) + keyId := d.Get("key_id").(string) + keyName := d.Get("key_name").(string) + name := keyName + if keyName != "" { + if name[0] == '^' { + name = name[1:] + } + length := len(name) + if length > 0 && name[length-1] == '$' { + name = name[:length-1] + } + + pattern := `^[a-zA-Z0-9_]+$` + if match, _ := regexp.MatchString(pattern, name); !match { + return fmt.Errorf("key_name only support letters, numbers, and _ : %s", keyName) + } + } + + var projectId *int + if v, ok := d.GetOkExists("project_id"); ok { + vv := v.(int) + projectId = &vv + } + + if keyId != "" { + req.KeyIds = []*string{&keyId} + } + + req.Filters = make([]*cvm.Filter, 0) + if name != "" { + filter := &cvm.Filter{ + Name: helper.String("key-name"), + Values: []*string{&name}, + } + req.Filters = append(req.Filters, filter) + } + + if projectId != nil { + filter := &cvm.Filter{ + Name: helper.String("project-id"), + Values: []*string{helper.String(fmt.Sprintf("%d", *projectId))}, + } + req.Filters = append(req.Filters, filter) + } + + return nil +} diff --git a/tencentcloud/services/cvm/data_source_tc_placement_groups.go b/tencentcloud/services/cvm/data_source_tc_placement_groups.go index 4820d818d8..b798881eba 100644 --- a/tencentcloud/services/cvm/data_source_tc_placement_groups.go +++ b/tencentcloud/services/cvm/data_source_tc_placement_groups.go @@ -2,36 +2,29 @@ package cvm import ( "context" - "log" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" ) func DataSourceTencentCloudPlacementGroups() *schema.Resource { return &schema.Resource{ Read: dataSourceTencentCloudPlacementGroupsRead, - Schema: map[string]*schema.Schema{ - "placement_group_id": { - Type: schema.TypeString, - Optional: true, - Description: "ID of the placement group to be queried.", - }, "name": { Type: schema.TypeString, Optional: true, Description: "Name of the placement group to be queried.", }, - "result_output_file": { + + "placement_group_id": { Type: schema.TypeString, Optional: true, - Description: "Used to save results.", + Description: "ID of the placement group to be queried.", }, "placement_group_list": { @@ -40,107 +33,98 @@ func DataSourceTencentCloudPlacementGroups() *schema.Resource { Description: "An information list of placement group. Each element contains the following attributes:", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "placement_group_id": { - Type: schema.TypeString, - Computed: true, - Description: "ID of the placement group.", - }, - "name": { + "create_time": { Type: schema.TypeString, Computed: true, - Description: "Name of the placement group.", + Description: "Creation time of the placement group.", }, - "type": { - Type: schema.TypeString, + "current_num": { + Type: schema.TypeInt, Computed: true, - Description: "Type of the placement group.", + Description: "Number of hosts in the placement group.", }, "cvm_quota_total": { Type: schema.TypeInt, Computed: true, Description: "Maximum number of hosts in the placement group.", }, - "current_num": { - Type: schema.TypeInt, - Computed: true, - Description: "Number of hosts in the placement group.", - }, "instance_ids": { Type: schema.TypeList, Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, Description: "Host IDs in the placement group.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, - "create_time": { + "name": { Type: schema.TypeString, Computed: true, - Description: "Creation time of the placement group.", + Description: "Name of the placement group.", + }, + "placement_group_id": { + Type: schema.TypeString, + Computed: true, + Description: "ID of the placement group.", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "Type of the placement group.", }, }, }, }, + + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, }, } } func dataSourceTencentCloudPlacementGroupsRead(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("data_source.tencentcloud_placement_groups.read")() - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - var placementGroupId string - var name string + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + paramMap := make(map[string]interface{}) if v, ok := d.GetOk("placement_group_id"); ok { - placementGroupId = v.(string) + paramMap["DisasterRecoverGroupIds"] = []*string{helper.String(v.(string))} } + if v, ok := d.GetOk("name"); ok { - name = v.(string) + paramMap["Name"] = helper.String(v.(string)) } - var placementGroups []*cvm.DisasterRecoverGroup - var errRet error + var respData []*cvm.DisasterRecoverGroup err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - placementGroups, errRet = cvmService.DescribePlacementGroupByFilter(ctx, placementGroupId, name) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) + result, e := service.DescribePlacementGroupsByFilter(ctx, paramMap) + if e != nil { + return tccommon.RetryError(e) } + respData = result return nil }) if err != nil { return err } - placementGroupList := make([]map[string]interface{}, 0, len(placementGroups)) - ids := make([]string, 0, len(placementGroups)) - for _, placement := range placementGroups { - mapping := map[string]interface{}{ - "placement_group_id": placement.DisasterRecoverGroupId, - "name": placement.Name, - "type": placement.Type, - "cvm_quota_total": placement.CvmQuotaTotal, - "current_num": placement.CurrentNum, - "instance_ids": helper.StringsInterfaces(placement.InstanceIds), - "create_time": placement.CreateTime, - } - placementGroupList = append(placementGroupList, mapping) - ids = append(ids, *placement.DisasterRecoverGroupId) - } - - d.SetId(helper.DataResourceIdsHash(ids)) - err = d.Set("placement_group_list", placementGroupList) - if err != nil { - log.Printf("[CRITAL]%s provider set placement group list fail, reason:%s\n ", logId, err.Error()) + if err := dataSourceTencentCloudPlacementGroupsReadPostHandleResponse0(ctx, paramMap, &respData); err != nil { return err } output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if err := tccommon.WriteToFile(output.(string), placementGroupList); err != nil { - return err + if e := tccommon.WriteToFile(output.(string), dataSourceTencentCloudPlacementGroupsReadOutputContent(ctx)); e != nil { + return e } } + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_placement_groups_extension.go b/tencentcloud/services/cvm/data_source_tc_placement_groups_extension.go new file mode 100644 index 0000000000..63d2f7b420 --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_placement_groups_extension.go @@ -0,0 +1,48 @@ +package cvm + +import ( + "context" + "log" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" + + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +func dataSourceTencentCloudPlacementGroupsReadPostHandleResponse0(ctx context.Context, req map[string]interface{}, resp *[]*cvm.DisasterRecoverGroup) error { + d := tccommon.ResourceDataFromContext(ctx) + logId := tccommon.GetLogId(tccommon.ContextNil) + placementGroups := *resp + var err error + placementGroupList := make([]map[string]interface{}, 0, len(placementGroups)) + ids := make([]string, 0, len(placementGroups)) + for _, placement := range placementGroups { + mapping := map[string]interface{}{ + "placement_group_id": placement.DisasterRecoverGroupId, + "name": placement.Name, + "type": placement.Type, + "cvm_quota_total": placement.CvmQuotaTotal, + "current_num": placement.CurrentNum, + "instance_ids": helper.StringsInterfaces(placement.InstanceIds), + "create_time": placement.CreateTime, + } + placementGroupList = append(placementGroupList, mapping) + ids = append(ids, *placement.DisasterRecoverGroupId) + } + + d.SetId(helper.DataResourceIdsHash(ids)) + err = d.Set("placement_group_list", placementGroupList) + if err != nil { + log.Printf("[CRITAL]%s provider set placement group list fail, reason:%s\n ", logId, err.Error()) + return err + } + + context.WithValue(ctx, "placementGroupList", placementGroupList) + return nil +} + +func dataSourceTencentCloudPlacementGroupsReadOutputContent(ctx context.Context) interface{} { + eipList := ctx.Value("placementGroupList") + return eipList +} diff --git a/tencentcloud/services/cvm/resource_tc_cvm_renew_instance.go b/tencentcloud/services/cvm/resource_tc_cvm_renew_instance.go index 37758c7f76..ac982d00d7 100644 --- a/tencentcloud/services/cvm/resource_tc_cvm_renew_instance.go +++ b/tencentcloud/services/cvm/resource_tc_cvm_renew_instance.go @@ -1,14 +1,14 @@ package cvm import ( + "context" "log" - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" ) @@ -17,19 +17,18 @@ func ResourceTencentCloudCvmRenewInstance() *schema.Resource { Create: resourceTencentCloudCvmRenewInstanceCreate, Read: resourceTencentCloudCvmRenewInstanceRead, Delete: resourceTencentCloudCvmRenewInstanceDelete, - Schema: map[string]*schema.Schema{ "instance_id": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, - Description: "Instance ID.", + Description: "Instance ID. To obtain the instance IDs, you can call DescribeInstances and look for InstanceId in the response.", }, "instance_charge_prepaid": { + Type: schema.TypeList, Optional: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "Prepaid mode, that is, yearly and monthly subscription related parameter settings. Through this parameter, you can specify the renewal duration of the Subscription instance, whether to set automatic renewal, and other attributes. For yearly and monthly subscription instances, this parameter is required.", Elem: &schema.Resource{ @@ -40,26 +39,19 @@ func ResourceTencentCloudCvmRenewInstance() *schema.Resource { Description: "Subscription period; unit: month; valid values: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 24, 36, 48, 60. Note: This field may return null, indicating that no valid value is found.", }, "renew_flag": { - Type: schema.TypeString, - Optional: true, - Description: "Auto renewal flag. Valid values:\n" + - "- `NOTIFY_AND_AUTO_RENEW`: notify upon expiration and renew automatically;\n" + - "- `NOTIFY_AND_MANUAL_RENEW`: notify upon expiration but do not renew automatically;\n" + - "- `DISABLE_NOTIFY_AND_MANUAL_RENEW`: neither notify upon expiration nor renew automatically;\n" + - "Default value: NOTIFY_AND_MANUAL_RENEW. If this parameter is specified as NOTIFY_AND_AUTO_RENEW, the instance will be automatically renewed on a monthly basis if the account balance is sufficient. Note: This field may return null, indicating that no valid value is found.", + Type: schema.TypeString, + Optional: true, + Description: "Auto renewal flag. Valid values:
  • NOTIFY_AND_AUTO_RENEW: notify upon expiration and renew automatically
  • NOTIFY_AND_MANUAL_RENEW: notify upon expiration but do not renew automatically
  • DISABLE_NOTIFY_AND_MANUAL_RENEW: neither notify upon expiration nor renew automatically

    Default value: NOTIFY_AND_MANUAL_RENEW. If this parameter is specified as NOTIFY_AND_AUTO_RENEW, the instance will be automatically renewed on a monthly basis if the account balance is sufficient. Note: This field may return null, indicating that no valid value is found.", }, }, }, }, "renew_portable_data_disk": { - Optional: true, - ForceNew: true, - Type: schema.TypeBool, - Description: "Whether to renew the elastic data disk. Valid values:\n" + - "- `TRUE`: Indicates to renew the subscription instance and renew the attached elastic data disk at the same time\n" + - "- `FALSE`: Indicates that the subscription instance will be renewed and the elastic data disk attached to it will not be renewed\n" + - "Default value: TRUE.", + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Description: "Whether to renew the elastic data disk. Valid values:
  • TRUE: Indicates to renew the subscription instance and renew the attached elastic data disk at the same time
  • FALSE: Indicates that the subscription instance will be renewed and the elastic data disk attached to it will not be renewed

    Default value: TRUE.", }, }, } @@ -71,39 +63,54 @@ func resourceTencentCloudCvmRenewInstanceCreate(d *schema.ResourceData, meta int logId := tccommon.GetLogId(tccommon.ContextNil) - request := cvm.NewRenewInstancesRequest() - instanceId := d.Get("instance_id").(string) - request.InstanceIds = []*string{&instanceId} + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - if dMap, ok := helper.InterfacesHeadMap(d, "instance_charge_prepaid"); ok { + var ( + instanceId string + ) + var ( + request = cvm.NewRenewInstancesRequest() + response = cvm.NewRenewInstancesResponse() + ) + + if v, ok := d.GetOk("instance_id"); ok { + instanceId = v.(string) + } + + request.InstanceIds = []*string{helper.String(instanceId)} + + if instanceChargePrepaidMap, ok := helper.InterfacesHeadMap(d, "instance_charge_prepaid"); ok { instanceChargePrepaid := cvm.InstanceChargePrepaid{} - if v, ok := dMap["period"]; ok { + if v, ok := instanceChargePrepaidMap["period"]; ok { instanceChargePrepaid.Period = helper.IntInt64(v.(int)) } - if v, ok := dMap["renew_flag"]; ok && v.(string) != "" { + if v, ok := instanceChargePrepaidMap["renew_flag"]; ok { instanceChargePrepaid.RenewFlag = helper.String(v.(string)) } request.InstanceChargePrepaid = &instanceChargePrepaid } - if v, _ := d.GetOk("renew_portable_data_disk"); v != nil { + if v, ok := d.GetOkExists("renew_portable_data_disk"); ok { request.RenewPortableDataDisk = helper.Bool(v.(bool)) } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().RenewInstances(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().RenewInstancesWithContext(ctx, request) if e != nil { return tccommon.RetryError(e) } else { log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) } + response = result return nil }) if err != nil { - log.Printf("[CRITAL]%s operate cvm renewInstance failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s create cvm renew instance failed, reason:%+v", logId, err) return err } + _ = response + d.SetId(instanceId) return resourceTencentCloudCvmRenewInstanceRead(d, meta) diff --git a/tencentcloud/services/cvm/resource_tc_cvm_security_group_attachment.go b/tencentcloud/services/cvm/resource_tc_cvm_security_group_attachment.go index 03029e0940..e15871d3f4 100644 --- a/tencentcloud/services/cvm/resource_tc_cvm_security_group_attachment.go +++ b/tencentcloud/services/cvm/resource_tc_cvm_security_group_attachment.go @@ -6,11 +6,12 @@ import ( "log" "strings" - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" ) func ResourceTencentCloudCvmSecurityGroupAttachment() *schema.Resource { @@ -23,17 +24,17 @@ func ResourceTencentCloudCvmSecurityGroupAttachment() *schema.Resource { }, Schema: map[string]*schema.Schema{ "security_group_id": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, - Description: "Security group id.", + Description: "ID of the security group to be associated, such as sg-efil73jd. Only one security group can be associated.", }, "instance_id": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, - Description: "Instance id.", + Description: "Instance ID. To obtain the instance IDs, you can call DescribeInstances and look for InstanceId in the response.", }, }, } @@ -45,28 +46,46 @@ func resourceTencentCloudCvmSecurityGroupAttachmentCreate(d *schema.ResourceData logId := tccommon.GetLogId(tccommon.ContextNil) - request := cvm.NewAssociateSecurityGroupsRequest() - securityGroupId := d.Get("security_group_id").(string) - instanceId := d.Get("instance_id").(string) - request.SecurityGroupIds = []*string{} + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + var ( + instanceId string + securityGroupId string + ) + var ( + request = cvm.NewAssociateSecurityGroupsRequest() + response = cvm.NewAssociateSecurityGroupsResponse() + ) + + if v, ok := d.GetOk("instance_id"); ok { + instanceId = v.(string) + } + if v, ok := d.GetOk("security_group_id"); ok { + securityGroupId = v.(string) + } + + request.SecurityGroupIds = []*string{helper.String(securityGroupId)} - request.SecurityGroupIds = []*string{&securityGroupId} - request.InstanceIds = []*string{&instanceId} + request.InstanceIds = []*string{helper.String(instanceId)} err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().AssociateSecurityGroups(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().AssociateSecurityGroupsWithContext(ctx, request) if e != nil { return tccommon.RetryError(e) } else { log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) } + response = result return nil }) if err != nil { - log.Printf("[CRITAL]%s create cvm securityGroupAttachment failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s create cvm security group attachment failed, reason:%+v", logId, err) return err } - d.SetId(instanceId + tccommon.FILED_SP + securityGroupId) + + _ = response + + d.SetId(strings.Join([]string{instanceId, securityGroupId}, tccommon.FILED_SP)) return resourceTencentCloudCvmSecurityGroupAttachmentRead(d, meta) } @@ -77,7 +96,7 @@ func resourceTencentCloudCvmSecurityGroupAttachmentRead(d *schema.ResourceData, logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} @@ -88,26 +107,26 @@ func resourceTencentCloudCvmSecurityGroupAttachmentRead(d *schema.ResourceData, instanceId := idSplit[0] securityGroupId := idSplit[1] - instanceInfo, err := service.DescribeInstanceById(ctx, instanceId) + _ = d.Set("instance_id", instanceId) + + _ = d.Set("security_group_id", securityGroupId) + + respData, err := service.DescribeCvmSecurityGroupAttachmentById(ctx, instanceId) if err != nil { return err } - if instanceInfo == nil { + if respData == nil { d.SetId("") - log.Printf("[WARN]%s resource `CvmSecurityGroupAttachment` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + log.Printf("[WARN]%s resource `cvm_security_group_attachment` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) return nil } - - for _, sgId := range instanceInfo.SecurityGroupIds { - if *sgId == securityGroupId { - _ = d.Set("instance_id", instanceId) - _ = d.Set("security_group_id", securityGroupId) - return nil - - } + if err := resourceTencentCloudCvmSecurityGroupAttachmentReadPostHandleResponse0(ctx, respData); err != nil { + return err } - return fmt.Errorf("The security group get from api does not match with current instance %v", d.Id()) + + _ = securityGroupId + return nil } func resourceTencentCloudCvmSecurityGroupAttachmentDelete(d *schema.ResourceData, meta interface{}) error { @@ -115,6 +134,7 @@ func resourceTencentCloudCvmSecurityGroupAttachmentDelete(d *schema.ResourceData defer tccommon.InconsistentCheck(d, meta)() logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) idSplit := strings.Split(d.Id(), tccommon.FILED_SP) if len(idSplit) != 2 { @@ -123,22 +143,31 @@ func resourceTencentCloudCvmSecurityGroupAttachmentDelete(d *schema.ResourceData instanceId := idSplit[0] securityGroupId := idSplit[1] - request := cvm.NewDisassociateSecurityGroupsRequest() - request.SecurityGroupIds = []*string{&securityGroupId} - request.InstanceIds = []*string{&instanceId} + var ( + request = cvm.NewDisassociateSecurityGroupsRequest() + response = cvm.NewDisassociateSecurityGroupsResponse() + ) + + request.SecurityGroupIds = []*string{helper.String(securityGroupId)} + + request.InstanceIds = []*string{helper.String(instanceId)} + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().DisassociateSecurityGroups(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().DisassociateSecurityGroupsWithContext(ctx, request) if e != nil { return tccommon.RetryError(e) } else { log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) } + response = result return nil }) if err != nil { - log.Printf("[CRITAL]%s delete cvm securityGroupAttachment failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s delete cvm security group attachment failed, reason:%+v", logId, err) return err } + _ = response + _ = securityGroupId return nil } diff --git a/tencentcloud/services/cvm/resource_tc_cvm_security_group_attachment_extension.go b/tencentcloud/services/cvm/resource_tc_cvm_security_group_attachment_extension.go new file mode 100644 index 0000000000..0b94ae9897 --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_cvm_security_group_attachment_extension.go @@ -0,0 +1,41 @@ +package cvm + +import ( + "context" + "fmt" + "log" + "strings" + + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" +) + +func resourceTencentCloudCvmSecurityGroupAttachmentReadPostHandleResponse0(ctx context.Context, resp *cvm.DescribeInstancesResponseParams) error { + d := tccommon.ResourceDataFromContext(ctx) + logId := tccommon.GetLogId(tccommon.ContextNil) + if len(resp.InstanceSet) < 1 { + d.SetId("") + log.Printf("[WARN]%s resource `CvmSecurityGroupAttachment` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + return nil + } + + idSplit := strings.Split(d.Id(), tccommon.FILED_SP) + if len(idSplit) != 2 { + return fmt.Errorf("id is broken,%s", d.Id()) + } + instanceId := idSplit[0] + securityGroupId := idSplit[1] + + instanceInfo := resp.InstanceSet[0] + for _, sgId := range instanceInfo.SecurityGroupIds { + if *sgId == securityGroupId { + _ = d.Set("instance_id", instanceId) + _ = d.Set("security_group_id", securityGroupId) + return nil + } + } + + _ = d.Set("instance_id", nil) + _ = d.Set("security_group_id", nil) + return nil +} diff --git a/tencentcloud/services/cvm/resource_tc_cvm_sync_image.go b/tencentcloud/services/cvm/resource_tc_cvm_sync_image.go index 7ae8f57767..0947e7fed2 100644 --- a/tencentcloud/services/cvm/resource_tc_cvm_sync_image.go +++ b/tencentcloud/services/cvm/resource_tc_cvm_sync_image.go @@ -1,15 +1,14 @@ package cvm import ( + "context" "log" - "time" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" ) @@ -18,43 +17,42 @@ func ResourceTencentCloudCvmSyncImage() *schema.Resource { Create: resourceTencentCloudCvmSyncImageCreate, Read: resourceTencentCloudCvmSyncImageRead, Delete: resourceTencentCloudCvmSyncImageDelete, - Schema: map[string]*schema.Schema{ - "image_id": { + "destination_regions": { + Type: schema.TypeSet, Required: true, ForceNew: true, - Type: schema.TypeString, - Description: "Image ID. The specified image must meet the following requirement: the images must be in the `NORMAL` state.", - }, - - "destination_regions": { - Required: true, - ForceNew: true, - Type: schema.TypeSet, + Description: "List of destination regions for synchronization. Limits: It must be a valid region. For a custom image, the destination region cannot be the source region. For a shared image, the destination region must be the source region, which indicates to create a copy of the image as a custom image in the same region.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Description: "List of destination regions for synchronization. Limits: It must be a valid region. For a custom image, the destination region cannot be the source region. For a shared image, the destination region must be the source region, which indicates to create a copy of the image as a custom image in the same region.", }, "dry_run": { + Type: schema.TypeBool, Optional: true, ForceNew: true, - Type: schema.TypeBool, Description: "Checks whether image synchronization can be initiated.", }, + "image_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Image ID. The specified image must meet the following requirement: the images must be in the `NORMAL` state.", + }, + "image_name": { + Type: schema.TypeString, Optional: true, ForceNew: true, - Type: schema.TypeString, Description: "Destination image name.", }, "image_set_required": { + Type: schema.TypeBool, Optional: true, ForceNew: true, - Type: schema.TypeBool, Description: "Whether to return the ID of image created in the destination region.", }, }, @@ -66,19 +64,32 @@ func resourceTencentCloudCvmSyncImageCreate(d *schema.ResourceData, meta interfa defer tccommon.InconsistentCheck(d, meta)() logId := tccommon.GetLogId(tccommon.ContextNil) - request := cvm.NewSyncImagesRequest() - imageId := d.Get("image_id").(string) - request.ImageIds = []*string{&imageId} + + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + var ( + imageId string + ) + var ( + request = cvm.NewSyncImagesRequest() + response = cvm.NewSyncImagesResponse() + ) + + if v, ok := d.GetOk("image_id"); ok { + imageId = v.(string) + } + + request.ImageIds = []*string{helper.String(imageId)} if v, ok := d.GetOk("destination_regions"); ok { destinationRegionsSet := v.(*schema.Set).List() for i := range destinationRegionsSet { destinationRegions := destinationRegionsSet[i].(string) - request.DestinationRegions = append(request.DestinationRegions, &destinationRegions) + request.DestinationRegions = append(request.DestinationRegions, helper.String(destinationRegions)) } } - if v, _ := d.GetOk("dry_run"); v != nil { + if v, ok := d.GetOkExists("dry_run"); ok { request.DryRun = helper.Bool(v.(bool)) } @@ -86,34 +97,33 @@ func resourceTencentCloudCvmSyncImageCreate(d *schema.ResourceData, meta interfa request.ImageName = helper.String(v.(string)) } - if v, _ := d.GetOk("image_set_required"); v != nil { + if v, ok := d.GetOkExists("image_set_required"); ok { request.ImageSetRequired = helper.Bool(v.(bool)) } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().SyncImages(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().SyncImagesWithContext(ctx, request) if e != nil { return tccommon.RetryError(e) } else { log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) } + response = result return nil }) if err != nil { - log.Printf("[CRITAL]%s operate cvm syncImages failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s create cvm sync image failed, reason:%+v", logId, err) return err } - d.SetId(imageId) - - service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + _ = response - conf := tccommon.BuildStateChangeConf([]string{}, []string{"NORMAL"}, 20*tccommon.ReadRetryTimeout, time.Second, service.CvmSyncImagesStateRefreshFunc(d.Id(), []string{})) - - if _, e := conf.WaitForState(); e != nil { - return e + if err := resourceTencentCloudCvmSyncImageCreatePostHandleResponse0(ctx, response); err != nil { + return err } + d.SetId(imageId) + return resourceTencentCloudCvmSyncImageRead(d, meta) } diff --git a/tencentcloud/services/cvm/resource_tc_cvm_sync_image_extension.go b/tencentcloud/services/cvm/resource_tc_cvm_sync_image_extension.go new file mode 100644 index 0000000000..cf3acb7892 --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_cvm_sync_image_extension.go @@ -0,0 +1,23 @@ +package cvm + +import ( + "context" + "time" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +func resourceTencentCloudCvmSyncImageCreatePostHandleResponse0(ctx context.Context, resp *cvm.SyncImagesResponse) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + conf := tccommon.BuildStateChangeConf([]string{}, []string{"NORMAL"}, 20*tccommon.ReadRetryTimeout, time.Second, service.CvmSyncImagesStateRefreshFunc(d.Id(), []string{})) + + if _, e := conf.WaitForState(); e != nil { + return e + } + + return nil +} diff --git a/tencentcloud/services/cvm/resource_tc_eip.go b/tencentcloud/services/cvm/resource_tc_eip.go index e7ba5bbee4..fb32d1c9c2 100644 --- a/tencentcloud/services/cvm/resource_tc_eip.go +++ b/tencentcloud/services/cvm/resource_tc_eip.go @@ -5,16 +5,12 @@ import ( "fmt" "log" - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" - svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag" - svcvpc "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/vpc" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" - "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/ratelimit" ) func ResourceTencentCloudEip() *schema.Resource { @@ -26,57 +22,53 @@ func ResourceTencentCloudEip() *schema.Resource { Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, - Schema: map[string]*schema.Schema{ - "name": { + "anti_ddos_package_id": { Type: schema.TypeString, Optional: true, Computed: true, - Description: "The name of eip.", - }, - "type": { - Type: schema.TypeString, - Optional: true, - Default: svcvpc.EIP_TYPE_EIP, - ForceNew: true, - Description: "The type of eip. Valid value: `EIP` and `AnycastEIP` and `HighQualityEIP` and `AntiDDoSEIP`. Default is `EIP`.", + Description: "ID of anti DDos package, it must set when `type` is `AntiDDoSEIP`.", }, + "anycast_zone": { Type: schema.TypeString, Optional: true, ForceNew: true, Description: "The zone of anycast. Valid value: `ANYCAST_ZONE_GLOBAL` and `ANYCAST_ZONE_OVERSEAS`.", }, + "applicable_for_clb": { Type: schema.TypeBool, Optional: true, Description: "Indicates whether the anycast eip can be associated to a CLB.", Deprecated: "It has been deprecated from version 1.27.0.", }, - "internet_service_provider": { - Type: schema.TypeString, + + "auto_renew_flag": { + Type: schema.TypeInt, Optional: true, - ForceNew: true, - Description: "Internet service provider of eip. Valid value: `BGP`, `CMCC`, `CTCC` and `CUCC`.", + Description: "Auto renew flag. 0 - default state (manual renew); 1 - automatic renew; 2 - explicit no automatic renew. NOTES: Only supported prepaid EIP.", }, - "internet_charge_type": { + + "bandwidth_package_id": { Type: schema.TypeString, Optional: true, Computed: true, - Description: "The charge type of eip. Valid values: `BANDWIDTH_PACKAGE`, `BANDWIDTH_POSTPAID_BY_HOUR`, `BANDWIDTH_PREPAID_BY_MONTH` and `TRAFFIC_POSTPAID_BY_HOUR`.", + Description: "ID of bandwidth package, it will set when `internet_charge_type` is `BANDWIDTH_PACKAGE`.", }, - "prepaid_period": { - Type: schema.TypeInt, - Optional: true, - ValidateFunc: tccommon.ValidateAllowedIntValue(svcvpc.EIP_AVAILABLE_PERIOD), - Description: "Period of instance. Default value: `1`. Valid value: `1`, `2`, `3`, `4`, `6`, `7`, `8`, `9`, `12`, `24`, `36`. NOTES: must set when `internet_charge_type` is `BANDWIDTH_PREPAID_BY_MONTH`.", + + "egress": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Network egress. It defaults to `center_egress1`. If you want to try the egress feature, please [submit a ticket](https://console.cloud.tencent.com/workorder/category).", }, - "auto_renew_flag": { - Type: schema.TypeInt, - Optional: true, - ValidateFunc: tccommon.ValidateAllowedIntValue([]int{0, 1, 2}), - Description: "Auto renew flag. 0 - default state (manual renew); 1 - automatic renew; 2 - explicit no automatic renew. NOTES: Only supported prepaid EIP.", + "internet_charge_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The charge type of eip. Valid values: `BANDWIDTH_PACKAGE`, `BANDWIDTH_POSTPAID_BY_HOUR`, `BANDWIDTH_PREPAID_BY_MONTH` and `TRAFFIC_POSTPAID_BY_HOUR`.", }, "internet_max_bandwidth_out": { @@ -85,152 +77,139 @@ func ResourceTencentCloudEip() *schema.Resource { Computed: true, Description: "The bandwidth limit of EIP, unit is Mbps.", }, - "tags": { - Type: schema.TypeMap, - Optional: true, - Description: "The tags of eip.", - }, - "bandwidth_package_id": { + + "internet_service_provider": { Type: schema.TypeString, Optional: true, - Computed: true, - Description: "ID of bandwidth package, it will set when `internet_charge_type` is `BANDWIDTH_PACKAGE`.", + ForceNew: true, + Description: "Internet service provider of eip. Valid value: `BGP`, `CMCC`, `CTCC` and `CUCC`.", }, - "egress": { + + "name": { Type: schema.TypeString, Optional: true, Computed: true, - Description: "Network egress. It defaults to `center_egress1`. If you want to try the egress feature, please [submit a ticket](https://console.cloud.tencent.com/workorder/category).", + Description: "The name of eip.", }, - "anti_ddos_package_id": { - Type: schema.TypeString, + + "prepaid_period": { + Type: schema.TypeInt, Optional: true, - Computed: true, - Description: "ID of anti DDos package, it must set when `type` is `AntiDDoSEIP`.", + Description: "Period of instance. Default value: `1`. Valid value: `1`, `2`, `3`, `4`, `6`, `7`, `8`, `9`, `12`, `24`, `36`. NOTES: must set when `internet_charge_type` is `BANDWIDTH_PREPAID_BY_MONTH`.", }, - // computed + "public_ip": { Type: schema.TypeString, Computed: true, Description: "The elastic IP address.", }, + "status": { Type: schema.TypeString, Computed: true, Description: "The EIP current status.", }, + + "tags": { + Type: schema.TypeMap, + Optional: true, + Description: "The tags of eip.", + }, + + "type": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Default: "EIP", + Description: "The type of eip. Valid value: `EIP` and `AnycastEIP` and `HighQualityEIP` and `AntiDDoSEIP`. Default is `EIP`.", + }, }, } } func resourceTencentCloudEipCreate(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_eip.create")() + defer tccommon.InconsistentCheck(d, meta)() logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() - vpcService := svcvpc.NewVpcService(client) - tagService := svctag.NewTagService(client) - region := client.Region + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - var internetChargeType string + var ( + eipId string + ) + var ( + request = vpc.NewAllocateAddressesRequest() + response = vpc.NewAllocateAddressesResponse() + ) - request := vpc.NewAllocateAddressesRequest() - if v, ok := d.GetOk("type"); ok { - request.AddressType = helper.String(v.(string)) - } - if v, ok := d.GetOk("anycast_zone"); ok { - request.AnycastZone = helper.String(v.(string)) - } if v, ok := d.GetOk("internet_service_provider"); ok { request.InternetServiceProvider = helper.String(v.(string)) } + if v, ok := d.GetOk("internet_charge_type"); ok { - internetChargeType = v.(string) request.InternetChargeType = helper.String(v.(string)) } - if v, ok := d.GetOk("internet_max_bandwidth_out"); ok { + + if v, ok := d.GetOkExists("internet_max_bandwidth_out"); ok { request.InternetMaxBandwidthOut = helper.IntInt64(v.(int)) } - if internetChargeType == "BANDWIDTH_PREPAID_BY_MONTH" { - addressChargePrepaid := vpc.AddressChargePrepaid{} - period := d.Get("prepaid_period") - renewFlag := d.Get("auto_renew_flag") - addressChargePrepaid.Period = helper.IntInt64(period.(int)) - addressChargePrepaid.AutoRenewFlag = helper.IntInt64(renewFlag.(int)) - request.AddressChargePrepaid = &addressChargePrepaid + if v, ok := d.GetOk("type"); ok { + request.AddressType = helper.String(v.(string)) } - if v := helper.GetTags(d, "tags"); len(v) > 0 { - for tagKey, tagValue := range v { - tag := vpc.Tag{ - Key: helper.String(tagKey), - Value: helper.String(tagValue), - } - request.Tags = append(request.Tags, &tag) - } + if v, ok := d.GetOk("anycast_zone"); ok { + request.AnycastZone = helper.String(v.(string)) } + if v, ok := d.GetOk("bandwidth_package_id"); ok { request.BandwidthPackageId = helper.String(v.(string)) } + if v, ok := d.GetOk("name"); ok { request.AddressName = helper.String(v.(string)) } + if v, ok := d.GetOk("egress"); ok { request.Egress = helper.String(v.(string)) } + if v, ok := d.GetOk("anti_ddos_package_id"); ok { request.AntiDDoSPackageId = helper.String(v.(string)) } - eipId := "" - err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - ratelimit.Check(request.GetAction()) - response, err := client.UseVpcClient().AllocateAddresses(request) - if err != nil { - log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", - logId, request.GetAction(), request.ToJsonString(), err.Error()) - return tccommon.RetryError(err) - } - log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", - logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + if err := resourceTencentCloudEipCreatePostFillRequest0(ctx, request); err != nil { + return err + } - if len(response.Response.AddressSet) < 1 { - return resource.RetryableError(fmt.Errorf("eip id is nil")) + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().AllocateAddressesWithContext(ctx, request) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) } - eipId = *response.Response.AddressSet[0] + response = result return nil }) if err != nil { + log.Printf("[CRITAL]%s create eip failed, reason:%+v", logId, err) return err } - d.SetId(eipId) - if tags := helper.GetTags(d, "tags"); len(tags) > 0 { - resourceName := tccommon.BuildTagResourceName(svcvpc.VPC_SERVICE_TYPE, svcvpc.EIP_RESOURCE_TYPE, region, eipId) - if err := tagService.ModifyTags(ctx, resourceName, tags, nil); err != nil { - log.Printf("[CRITAL]%s set eip tags failed: %+v", logId, err) - return err - } + if len(response.Response.AddressSet) < 1 { + return fmt.Errorf("resource `tencentcloud_eip` create failed.") } - // wait for status - err = resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - eip, errRet := vpcService.DescribeEipById(ctx, eipId) - if errRet != nil { - return tccommon.RetryError(errRet) - } - if eip != nil && *eip.AddressStatus == svcvpc.EIP_STATUS_CREATING { - return resource.RetryableError(fmt.Errorf("eip is still creating")) - } - return nil - }) - if err != nil { + eipId = *response.Response.AddressSet[0] + + if err := resourceTencentCloudEipCreatePostHandleResponse0(ctx, response); err != nil { return err } + d.SetId(eipId) + return resourceTencentCloudEipRead(d, meta) } @@ -239,237 +218,231 @@ func resourceTencentCloudEipRead(d *schema.ResourceData, meta interface{}) error defer tccommon.InconsistentCheck(d, meta)() logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() - vpcService := svcvpc.NewVpcService(client) - tagService := svctag.NewTagService(client) - region := client.Region + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + service := VpcService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} eipId := d.Id() - var eip *vpc.Address - err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - instance, errRet := vpcService.DescribeEipById(ctx, eipId) - if errRet != nil { - return tccommon.RetryError(errRet) - } - eip = instance - return nil - }) + + respData, err := service.DescribeEipById(ctx, eipId) if err != nil { return err } - if eip == nil { + + if respData == nil { d.SetId("") + log.Printf("[WARN]%s resource `eip` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) return nil } + if respData.AddressName != nil { + _ = d.Set("name", respData.AddressName) + } - tags, err := tagService.DescribeResourceTags(ctx, svcvpc.VPC_SERVICE_TYPE, svcvpc.EIP_RESOURCE_TYPE, region, eipId) - if err != nil { - log.Printf("[CRITAL]%s describe eip tags failed: %+v", logId, err) - return err + if respData.AddressStatus != nil { + _ = d.Set("status", respData.AddressStatus) } - bgp, err := vpcService.DescribeVpcBandwidthPackageByEip(ctx, eipId) - if err != nil { - log.Printf("[CRITAL]%s describe eip tags failed: %+v", logId, err) - return err + if respData.AddressIp != nil { + _ = d.Set("public_ip", respData.AddressIp) + } + + if respData.AddressType != nil { + _ = d.Set("type", respData.AddressType) + } + + if respData.Bandwidth != nil { + _ = d.Set("internet_max_bandwidth_out", respData.Bandwidth) } - _ = d.Set("name", eip.AddressName) - _ = d.Set("type", eip.AddressType) - _ = d.Set("public_ip", eip.AddressIp) - _ = d.Set("status", eip.AddressStatus) - _ = d.Set("internet_charge_type", eip.InternetChargeType) - _ = d.Set("tags", tags) - if eip.Bandwidth != nil { - _ = d.Set("internet_max_bandwidth_out", eip.Bandwidth) + if respData.InternetChargeType != nil { + _ = d.Set("internet_charge_type", respData.InternetChargeType) } - if eip.Egress != nil { - _ = d.Set("egress", eip.Egress) + if respData.Egress != nil { + _ = d.Set("egress", respData.Egress) } - if eip.AntiDDoSPackageId != nil { - _ = d.Set("anti_ddos_package_id", eip.AntiDDoSPackageId) + if respData.AntiDDoSPackageId != nil { + _ = d.Set("anti_ddos_package_id", respData.AntiDDoSPackageId) } - if bgp != nil { - _ = d.Set("bandwidth_package_id", bgp.BandwidthPackageId) + if err := resourceTencentCloudEipReadPostHandleResponse0(ctx, respData); err != nil { + return err } + return nil } func resourceTencentCloudEipUpdate(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_eip.update")() + defer tccommon.InconsistentCheck(d, meta)() logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() - vpcService := svcvpc.NewVpcService(client) - tagService := svctag.NewTagService(client) - region := client.Region + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + immutableArgs := []string{"anti_ddos_package_id", "applicable_for_clb", "auto_renew_flag", "bandwidth_package_id", "egress", "prepaid_period", "tags"} + for _, v := range immutableArgs { + if d.HasChange(v) { + return fmt.Errorf("argument `%s` cannot be changed", v) + } + } eipId := d.Id() - d.Partial(true) - - unsupportedUpdateFields := []string{ - "bandwidth_package_id", - "anti_ddos_package_id", - "egress", + if err := resourceTencentCloudEipUpdateOnStart(ctx); err != nil { + return err } - for _, field := range unsupportedUpdateFields { - if d.HasChange(field) { - return fmt.Errorf("tencentcloud_eip update on %s is not support yet", field) + + needChange := false + mutableArgs := []string{"name"} + for _, v := range mutableArgs { + if d.HasChange(v) { + needChange = true + break } } - if d.HasChange("name") { - name := d.Get("name").(string) - err := vpcService.ModifyEipName(ctx, eipId, name) + if needChange { + request := vpc.NewModifyAddressAttributeRequest() + + request.AddressId = helper.String(eipId) + + if v, ok := d.GetOk("name"); ok { + request.AddressName = helper.String(v.(string)) + } + + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().ModifyAddressAttributeWithContext(ctx, request) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + return nil + }) if err != nil { + log.Printf("[CRITAL]%s update eip failed, reason:%+v", logId, err) return err } } - if d.HasChange("internet_charge_type") { - var ( - chargeType string - bandWidthOut int - ) + needChange1 := false + mutableArgs1 := []string{"internet_charge_type", "internet_max_bandwidth_out"} + for _, v := range mutableArgs1 { + if d.HasChange(v) { + needChange1 = true + break + } + } + + if needChange1 { + request1 := vpc.NewModifyAddressInternetChargeTypeRequest() + + request1.AddressId = helper.String(eipId) if v, ok := d.GetOk("internet_charge_type"); ok { - chargeType = v.(string) - } - if v, ok := d.GetOk("internet_max_bandwidth_out"); ok { - bandWidthOut = v.(int) + request1.InternetChargeType = helper.String(v.(string)) } - period := d.Get("prepaid_period").(int) - renewFlag := d.Get("auto_renew_flag").(int) + if v, ok := d.GetOkExists("internet_max_bandwidth_out"); ok { + request1.InternetMaxBandwidthOut = helper.IntUint64(v.(int)) + } - if chargeType != "" && bandWidthOut != 0 { - err := vpcService.ModifyEipInternetChargeType(ctx, eipId, chargeType, bandWidthOut, period, renewFlag) - if err != nil { - return err - } + if err := resourceTencentCloudEipUpdatePostFillRequest1(ctx, request1); err != nil { + return err } - } - if d.HasChange("internet_max_bandwidth_out") { - if v, ok := d.GetOk("internet_max_bandwidth_out"); ok { - bandwidthOut := v.(int) - err := vpcService.ModifyEipBandwidthOut(ctx, eipId, bandwidthOut) - if err != nil { - return err + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().ModifyAddressInternetChargeTypeWithContext(ctx, request1) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request1.GetAction(), request1.ToJsonString(), result.ToJsonString()) } - + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s update eip failed, reason:%+v", logId, err) + return err } } - if d.HasChange("prepaid_period") || d.HasChange("auto_renew_flag") { - period := d.Get("prepaid_period").(int) - renewFlag := d.Get("auto_renew_flag").(int) - err := vpcService.RenewAddress(ctx, eipId, period, renewFlag) - if err != nil { - return err + needChange2 := false + mutableArgs2 := []string{"internet_max_bandwidth_out"} + for _, v := range mutableArgs2 { + if d.HasChange(v) { + needChange2 = true + break } } - if d.HasChange("tags") { - oldTags, newTags := d.GetChange("tags") - replaceTags, deleteTags := svctag.DiffTags(oldTags.(map[string]interface{}), newTags.(map[string]interface{})) - resourceName := tccommon.BuildTagResourceName(svcvpc.VPC_SERVICE_TYPE, svcvpc.EIP_RESOURCE_TYPE, region, eipId) + if needChange2 { + request2 := vpc.NewModifyAddressesBandwidthRequest() - if err := tagService.ModifyTags(ctx, resourceName, replaceTags, deleteTags); err != nil { - log.Printf("[CRITAL]%s update eip tags failed: %+v", logId, err) - return err + request2.AddressIds = []*string{helper.String(eipId)} + + if v, ok := d.GetOkExists("internet_max_bandwidth_out"); ok { + request2.InternetMaxBandwidthOut = helper.IntInt64(v.(int)) } + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().ModifyAddressesBandwidthWithContext(ctx, request2) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request2.GetAction(), request2.ToJsonString(), result.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s update eip failed, reason:%+v", logId, err) + return err + } } - d.Partial(false) - return resourceTencentCloudEipRead(d, meta) } func resourceTencentCloudEipDelete(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_eip.delete")() + defer tccommon.InconsistentCheck(d, meta)() logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - vpcService := svcvpc.NewVpcService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + eipId := d.Id() - err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - errRet := vpcService.UnattachEip(ctx, eipId) - if errRet != nil { - return tccommon.RetryError(errRet, "DesOperation.MutexTaskRunning") - } - return nil - }) - if err != nil { + + var ( + request = vpc.NewReleaseAddressesRequest() + response = vpc.NewReleaseAddressesResponse() + ) + + request.AddressIds = []*string{helper.String(eipId)} + + if err := resourceTencentCloudEipDeletePostFillRequest0(ctx, request); err != nil { return err } - err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - errRet := vpcService.DeleteEip(ctx, eipId) - if errRet != nil { - return tccommon.RetryError(errRet, "DesOperation.MutexTaskRunning", "OperationDenied.MutexTaskRunning") + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().ReleaseAddressesWithContext(ctx, request) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) } + response = result return nil }) if err != nil { + log.Printf("[CRITAL]%s delete eip failed, reason:%+v", logId, err) return err } - var internetChargeType string - if v, ok := d.GetOk("internet_charge_type"); ok { - internetChargeType = v.(string) - } - - if internetChargeType == "BANDWIDTH_PREPAID_BY_MONTH" { - // isolated - err = resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - eip, errRet := vpcService.DescribeEipById(ctx, eipId) - if errRet != nil { - return tccommon.RetryError(errRet) - } - if !*eip.IsArrears { - return resource.RetryableError(fmt.Errorf("eip is still isolate")) - } - return nil - }) - if err != nil { - return err - } - - // release - err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - errRet := vpcService.DeleteEip(ctx, eipId) - if errRet != nil { - return tccommon.RetryError(errRet, "DesOperation.MutexTaskRunning", "OperationDenied.MutexTaskRunning") - } - return nil - }) - if err != nil { - return err - } - } - - err = resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - eip, errRet := vpcService.DescribeEipById(ctx, eipId) - if errRet != nil { - return tccommon.RetryError(errRet) - } - if eip != nil { - return resource.RetryableError(fmt.Errorf("eip is still deleting")) - } - return nil - }) - if err != nil { + _ = response + if err := resourceTencentCloudEipDeletePostHandleResponse0(ctx, response); err != nil { return err } + return nil } diff --git a/tencentcloud/services/cvm/resource_tc_eip_address_transform.go b/tencentcloud/services/cvm/resource_tc_eip_address_transform.go index a8f93a98d9..441febeb8f 100644 --- a/tencentcloud/services/cvm/resource_tc_eip_address_transform.go +++ b/tencentcloud/services/cvm/resource_tc_eip_address_transform.go @@ -1,16 +1,14 @@ package cvm import ( + "context" "log" - "time" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" - svcvpc "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/vpc" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - eip "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" + vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" ) @@ -19,12 +17,11 @@ func ResourceTencentCloudEipAddressTransform() *schema.Resource { Create: resourceTencentCloudEipAddressTransformCreate, Read: resourceTencentCloudEipAddressTransformRead, Delete: resourceTencentCloudEipAddressTransformDelete, - Schema: map[string]*schema.Schema{ "instance_id": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "the instance ID of a normal public network IP to be operated. eg:ins-23mk45jn.", }, }, @@ -37,18 +34,26 @@ func resourceTencentCloudEipAddressTransformCreate(d *schema.ResourceData, meta logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + var ( - request = eip.NewTransformAddressRequest() - response = eip.NewTransformAddressResponse() instanceId string ) + var ( + request = vpc.NewTransformAddressRequest() + response = vpc.NewTransformAddressResponse() + ) + if v, ok := d.GetOk("instance_id"); ok { instanceId = v.(string) + } + + if v, ok := d.GetOk("instance_id"); ok { request.InstanceId = helper.String(v.(string)) } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().TransformAddress(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().TransformAddressWithContext(ctx, request) if e != nil { return tccommon.RetryError(e) } else { @@ -58,21 +63,18 @@ func resourceTencentCloudEipAddressTransformCreate(d *schema.ResourceData, meta return nil }) if err != nil { - log.Printf("[CRITAL]%s operate eip addressTransform failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s create eip address transform failed, reason:%+v", logId, err) return err } - taskId := *response.Response.TaskId - d.SetId(instanceId) - - service := svcvpc.NewVpcService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) + _ = response - conf := tccommon.BuildStateChangeConf([]string{}, []string{"SUCCESS"}, 1*tccommon.ReadRetryTimeout, time.Second, service.VpcIpv6AddressStateRefreshFunc(helper.UInt64ToStr(taskId), []string{})) - - if _, e := conf.WaitForState(); e != nil { - return e + if err := resourceTencentCloudEipAddressTransformCreatePostHandleResponse0(ctx, response); err != nil { + return err } + d.SetId(instanceId) + return resourceTencentCloudEipAddressTransformRead(d, meta) } diff --git a/tencentcloud/services/cvm/resource_tc_eip_address_transform_extension.go b/tencentcloud/services/cvm/resource_tc_eip_address_transform_extension.go new file mode 100644 index 0000000000..9b69530b61 --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_eip_address_transform_extension.go @@ -0,0 +1,26 @@ +package cvm + +import ( + "context" + "time" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" + svcvpc "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/vpc" + + vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" +) + +func resourceTencentCloudEipAddressTransformCreatePostHandleResponse0(ctx context.Context, resp *vpc.TransformAddressResponse) error { + meta := tccommon.ProviderMetaFromContext(ctx) + service := svcvpc.NewVpcService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) + + taskId := *resp.Response.TaskId + conf := tccommon.BuildStateChangeConf([]string{}, []string{"SUCCESS"}, 1*tccommon.ReadRetryTimeout, time.Second, service.VpcIpv6AddressStateRefreshFunc(helper.UInt64ToStr(taskId), []string{})) + + if _, e := conf.WaitForState(); e != nil { + return e + } + + return nil +} diff --git a/tencentcloud/services/cvm/resource_tc_eip_association.go b/tencentcloud/services/cvm/resource_tc_eip_association.go index 0cee54ffbf..713cb480ab 100644 --- a/tencentcloud/services/cvm/resource_tc_eip_association.go +++ b/tencentcloud/services/cvm/resource_tc_eip_association.go @@ -2,18 +2,11 @@ package cvm import ( "context" - "fmt" "log" - "strings" - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" - svcvpc "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/vpc" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" - "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/ratelimit" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" ) func ResourceTencentCloudEipAssociation() *schema.Resource { @@ -26,45 +19,37 @@ func ResourceTencentCloudEipAssociation() *schema.Resource { }, Schema: map[string]*schema.Schema{ "eip_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: tccommon.ValidateStringLengthInRange(1, 25), - Description: "The ID of EIP.", + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The ID of EIP.", }, + "instance_id": { - Type: schema.TypeString, - ForceNew: true, - Optional: true, - Computed: true, - ConflictsWith: []string{ - "network_interface_id", - "private_ip", - }, - ValidateFunc: tccommon.ValidateStringLengthInRange(1, 25), - Description: "The CVM or CLB instance id going to bind with the EIP. This field is conflict with `network_interface_id` and `private_ip fields`.", + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"network_interface_id", "private_ip"}, + Description: "The CVM or CLB instance id going to bind with the EIP. This field is conflict with `network_interface_id` and `private_ip fields`.", }, + "network_interface_id": { - Type: schema.TypeString, - ForceNew: true, - Optional: true, - Computed: true, - ValidateFunc: tccommon.ValidateStringLengthInRange(1, 25), - ConflictsWith: []string{ - "instance_id", - }, - Description: "Indicates the network interface id like `eni-xxxxxx`. This field is conflict with `instance_id`.", + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"instance_id"}, + Description: "Indicates the network interface id like `eni-xxxxxx`. This field is conflict with `instance_id`.", }, + "private_ip": { - Type: schema.TypeString, - ForceNew: true, - Optional: true, - Computed: true, - ValidateFunc: tccommon.ValidateStringLengthInRange(7, 25), - ConflictsWith: []string{ - "instance_id", - }, - Description: "Indicates an IP belongs to the `network_interface_id`. This field is conflict with `instance_id`.", + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"instance_id"}, + Description: "Indicates an IP belongs to the `network_interface_id`. This field is conflict with `instance_id`.", }, }, } @@ -72,243 +57,67 @@ func ResourceTencentCloudEipAssociation() *schema.Resource { func resourceTencentCloudEipAssociationCreate(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_eip_association.create")() + defer tccommon.InconsistentCheck(d, meta)() - var ( - logId = tccommon.GetLogId(tccommon.ContextNil) - ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - vpcService = svcvpc.NewVpcService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) - eip *vpc.Address - errRet error - ) - - eipId := d.Get("eip_id").(string) - err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - eip, errRet = vpcService.DescribeEipById(ctx, eipId) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) - } + logId := tccommon.GetLogId(tccommon.ContextNil) - if eip == nil { - return resource.NonRetryableError(fmt.Errorf("eip is not found")) - } + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - return nil - }) + var ( + eipId string + ) + d.SetId(eipId) - if err != nil { + if err := resourceTencentCloudEipAssociationCreateOnExit(ctx); err != nil { return err } - if *eip.AddressStatus != svcvpc.EIP_STATUS_UNBIND { - return fmt.Errorf("eip status is illegal %s", *eip.AddressStatus) - } - - if v, ok := d.GetOk("instance_id"); ok { - instanceId := v.(string) - err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - e := vpcService.AttachEip(ctx, eipId, instanceId) - if e != nil { - return tccommon.RetryError(e) - } - - return nil - }) - - if err != nil { - return err - } - - associationId := fmt.Sprintf("%v::%v", eipId, instanceId) - err = resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - eip, errRet = vpcService.DescribeEipById(ctx, eipId) - if errRet != nil { - return tccommon.RetryError(errRet) - } - - if eip == nil { - return resource.NonRetryableError(fmt.Errorf("eip is not found")) - } - - if *eip.AddressStatus == svcvpc.EIP_STATUS_BIND { - return nil - } - - return resource.RetryableError(fmt.Errorf("wait for binding success: %s", *eip.AddressStatus)) - }) - - if err != nil { - return err - } - - d.SetId(associationId) - return resourceTencentCloudEipAssociationRead(d, meta) - } - - needRequest := false - request := vpc.NewAssociateAddressRequest() - request.AddressId = &eipId - var networkId string - var privateIp string - if v, ok := d.GetOk("network_interface_id"); ok { - needRequest = true - networkId = v.(string) - request.NetworkInterfaceId = &networkId - } - - if v, ok := d.GetOk("private_ip"); ok { - needRequest = true - privateIp = v.(string) - request.PrivateIpAddress = &privateIp - } - - if needRequest { - err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - ratelimit.Check(request.GetAction()) - response, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().AssociateAddress(request) - if e != nil { - log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", - logId, request.GetAction(), request.ToJsonString(), e.Error()) - return tccommon.RetryError(e) - } - - log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", - logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) - return nil - }) - - if err != nil { - return err - } - - id := fmt.Sprintf("%v::%v::%v", eipId, networkId, privateIp) - - err = resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - eip, errRet = vpcService.DescribeEipById(ctx, eipId) - if errRet != nil { - return tccommon.RetryError(errRet) - } - - if eip == nil { - return resource.NonRetryableError(fmt.Errorf("eip is not found")) - } - - if *eip.AddressStatus == svcvpc.EIP_STATUS_BIND_ENI || *eip.AddressStatus == svcvpc.EIP_STATUS_BIND { - return nil - } - - return resource.RetryableError(fmt.Errorf("wait for binding success: %s", *eip.AddressStatus)) - }) - - if err != nil { - return err - } - - d.SetId(id) - return resourceTencentCloudEipAssociationRead(d, meta) - } - - return nil + _ = ctx + return resourceTencentCloudEipAssociationRead(d, meta) } func resourceTencentCloudEipAssociationRead(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_eip_association.read")() defer tccommon.InconsistentCheck(d, meta)() - var ( - logId = tccommon.GetLogId(tccommon.ContextNil) - ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - vpcService = svcvpc.NewVpcService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) - id = d.Id() - ) + logId := tccommon.GetLogId(tccommon.ContextNil) - association, err := ParseEipAssociationId(id) - if err != nil { - return err - } + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - err = resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - eip, errRet := vpcService.DescribeEipById(ctx, association.EipId) - if errRet != nil { - return tccommon.RetryError(errRet) - } + service := VpcService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - if eip == nil { - d.SetId("") - } + eipId := d.Id() - return nil - }) + _ = d.Set("eip_id", eipId) + respData, err := service.DescribeEipAssociationById(ctx, eipId) if err != nil { return err } - _ = d.Set("eip_id", association.EipId) - // associate with instance - if len(association.InstanceId) > 0 { - _ = d.Set("instance_id", association.InstanceId) + if respData == nil { + d.SetId("") + log.Printf("[WARN]%s resource `eip_association` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) return nil } - _ = d.Set("network_interface_id", association.NetworkInterfaceId) - _ = d.Set("private_ip", association.PrivateIp) return nil } func resourceTencentCloudEipAssociationDelete(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_eip_association.delete")() + defer tccommon.InconsistentCheck(d, meta)() - var ( - logId = tccommon.GetLogId(tccommon.ContextNil) - ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - vpcService = svcvpc.NewVpcService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) - id = d.Id() - ) - - association, err := ParseEipAssociationId(id) - if err != nil { - return err - } - - err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - e := vpcService.UnattachEip(ctx, association.EipId) - if e != nil { - return tccommon.RetryError(e, "DesOperation.MutexTaskRunning") - } + logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - return nil - }) + eipId := d.Id() - if err != nil { + if err := resourceTencentCloudEipAssociationDeleteOnExit(ctx); err != nil { return err } + _ = eipId + _ = ctx return nil } - -type EipAssociationId struct { - EipId string - InstanceId string - NetworkInterfaceId string - PrivateIp string -} - -func ParseEipAssociationId(associationId string) (association EipAssociationId, errRet error) { - ids := strings.Split(associationId, "::") - if len(ids) < 2 || len(ids) > 3 { - errRet = fmt.Errorf("Invalid eip association ID: %v", associationId) - return - } - association.EipId = ids[0] - - // associate with instance - if len(ids) == 2 { - association.InstanceId = ids[1] - return - } - - // associate with network interface - association.NetworkInterfaceId = ids[1] - association.PrivateIp = ids[2] - return -} diff --git a/tencentcloud/services/cvm/resource_tc_eip_association_extension.go b/tencentcloud/services/cvm/resource_tc_eip_association_extension.go new file mode 100644 index 0000000000..1229c298f0 --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_eip_association_extension.go @@ -0,0 +1,228 @@ +package cvm + +import ( + "context" + "fmt" + "log" + "strings" + + vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/ratelimit" + svcvpc "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/vpc" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +type EipAssociationId struct { + EipId string + InstanceId string + NetworkInterfaceId string + PrivateIp string +} + +func resourceTencentCloudEipAssociationCreateOnExit(ctx context.Context) error { + var ( + logId = tccommon.GetLogId(tccommon.ContextNil) + meta = tccommon.ProviderMetaFromContext(ctx) + vpcService = svcvpc.NewVpcService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) + d = tccommon.ResourceDataFromContext(ctx) + eip *vpc.Address + errRet error + ) + + eipId := d.Get("eip_id").(string) + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + eip, errRet = vpcService.DescribeEipById(ctx, eipId) + if errRet != nil { + return tccommon.RetryError(errRet, tccommon.InternalError) + } + + if eip == nil { + return resource.NonRetryableError(fmt.Errorf("eip is not found")) + } + + return nil + }) + + if err != nil { + return err + } + + if *eip.AddressStatus != svcvpc.EIP_STATUS_UNBIND { + return fmt.Errorf("eip status is illegal %s", *eip.AddressStatus) + } + + if v, ok := d.GetOk("instance_id"); ok { + instanceId := v.(string) + err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + e := vpcService.AttachEip(ctx, eipId, instanceId) + if e != nil { + return tccommon.RetryError(e) + } + + return nil + }) + + if err != nil { + return err + } + + associationId := fmt.Sprintf("%v::%v", eipId, instanceId) + err = resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + eip, errRet = vpcService.DescribeEipById(ctx, eipId) + if errRet != nil { + return tccommon.RetryError(errRet) + } + + if eip == nil { + return resource.NonRetryableError(fmt.Errorf("eip is not found")) + } + + if *eip.AddressStatus == svcvpc.EIP_STATUS_BIND { + return nil + } + + return resource.RetryableError(fmt.Errorf("wait for binding success: %s", *eip.AddressStatus)) + }) + + if err != nil { + return err + } + + d.SetId(associationId) + return resourceTencentCloudEipAssociationRead(d, meta) + } + + needRequest := false + request := vpc.NewAssociateAddressRequest() + request.AddressId = &eipId + var networkId string + var privateIp string + if v, ok := d.GetOk("network_interface_id"); ok { + needRequest = true + networkId = v.(string) + request.NetworkInterfaceId = &networkId + } + + if v, ok := d.GetOk("private_ip"); ok { + needRequest = true + privateIp = v.(string) + request.PrivateIpAddress = &privateIp + } + + if needRequest { + err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + ratelimit.Check(request.GetAction()) + response, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().AssociateAddress(request) + if e != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), e.Error()) + return tccommon.RetryError(e) + } + + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + return nil + }) + + if err != nil { + return err + } + + id := fmt.Sprintf("%v::%v::%v", eipId, networkId, privateIp) + + err = resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + eip, errRet = vpcService.DescribeEipById(ctx, eipId) + if errRet != nil { + return tccommon.RetryError(errRet) + } + + if eip == nil { + return resource.NonRetryableError(fmt.Errorf("eip is not found")) + } + + if *eip.AddressStatus == svcvpc.EIP_STATUS_BIND_ENI || *eip.AddressStatus == svcvpc.EIP_STATUS_BIND { + return nil + } + + return resource.RetryableError(fmt.Errorf("wait for binding success: %s", *eip.AddressStatus)) + }) + + if err != nil { + return err + } + + d.SetId(id) + return resourceTencentCloudEipAssociationRead(d, meta) + } + + return nil +} + +func resourceTencentCloudEipAssociationReadPreRequest0(ctx context.Context, req *vpc.DescribeAddressesRequest) error { + d := tccommon.ResourceDataFromContext(ctx) + id := d.Id() + association, err := ParseEipAssociationId(id) + if err != nil { + return err + } + + _ = d.Set("eip_id", association.EipId) + if len(association.InstanceId) > 0 { + _ = d.Set("instance_id", association.InstanceId) + return nil + } + + _ = d.Set("network_interface_id", association.NetworkInterfaceId) + _ = d.Set("private_ip", association.PrivateIp) + + req.AddressIds = []*string{&association.EipId} + return nil +} + +func resourceTencentCloudEipAssociationDeleteOnExit(ctx context.Context) error { + d := tccommon.ResourceDataFromContext(ctx) + id := d.Id() + meta := tccommon.ProviderMetaFromContext(ctx) + vpcService := svcvpc.NewVpcService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) + association, err := ParseEipAssociationId(id) + if err != nil { + return err + } + + err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + e := vpcService.UnattachEip(ctx, association.EipId) + if e != nil { + return tccommon.RetryError(e, "DesOperation.MutexTaskRunning") + } + + return nil + }) + + if err != nil { + return err + } + + return nil +} + +func ParseEipAssociationId(associationId string) (association EipAssociationId, errRet error) { + ids := strings.Split(associationId, "::") + if len(ids) < 2 || len(ids) > 3 { + errRet = fmt.Errorf("Invalid eip association ID: %v", associationId) + return + } + association.EipId = ids[0] + + // associate with instance + if len(ids) == 2 { + association.InstanceId = ids[1] + return + } + + // associate with network interface + association.NetworkInterfaceId = ids[1] + association.PrivateIp = ids[2] + return +} diff --git a/tencentcloud/services/cvm/resource_tc_eip_extension.go b/tencentcloud/services/cvm/resource_tc_eip_extension.go new file mode 100644 index 0000000000..b5dc5a0158 --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_eip_extension.go @@ -0,0 +1,218 @@ +package cvm + +import ( + "context" + "fmt" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" + svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag" + svcvpc "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/vpc" +) + +func resourceTencentCloudEipCreatePostFillRequest0(ctx context.Context, req *vpc.AllocateAddressesRequest) error { + d := tccommon.ResourceDataFromContext(ctx) + if v := helper.GetTags(d, "tags"); len(v) > 0 { + for tagKey, tagValue := range v { + tag := vpc.Tag{ + Key: helper.String(tagKey), + Value: helper.String(tagValue), + } + req.Tags = append(req.Tags, &tag) + } + } + + var internetChargeType string + if v, ok := d.GetOk("internet_charge_type"); ok { + internetChargeType = v.(string) + } + + if internetChargeType == "BANDWIDTH_PREPAID_BY_MONTH" { + addressChargePrepaid := vpc.AddressChargePrepaid{} + period := d.Get("prepaid_period") + renewFlag := d.Get("auto_renew_flag") + addressChargePrepaid.Period = helper.IntInt64(period.(int)) + addressChargePrepaid.AutoRenewFlag = helper.IntInt64(renewFlag.(int)) + req.AddressChargePrepaid = &addressChargePrepaid + } + + return nil +} + +func resourceTencentCloudEipCreatePostHandleResponse0(ctx context.Context, resp *vpc.AllocateAddressesResponse) error { + d := tccommon.ResourceDataFromContext(ctx) + logId := tccommon.GetLogId(tccommon.ContextNil) + meta := tccommon.ProviderMetaFromContext(ctx) + client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + vpcService := svcvpc.NewVpcService(client) + tagService := svctag.NewTagService(client) + region := client.Region + eipId := *resp.Response.AddressSet[0] + if tags := helper.GetTags(d, "tags"); len(tags) > 0 { + resourceName := tccommon.BuildTagResourceName(svcvpc.VPC_SERVICE_TYPE, svcvpc.EIP_RESOURCE_TYPE, region, eipId) + if err := tagService.ModifyTags(ctx, resourceName, tags, nil); err != nil { + log.Printf("[CRITAL]%s set eip tags failed: %+v", logId, err) + return err + } + } + + // wait for status + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + eip, errRet := vpcService.DescribeEipById(ctx, eipId) + if errRet != nil { + return tccommon.RetryError(errRet) + } + if eip != nil && *eip.AddressStatus == svcvpc.EIP_STATUS_CREATING { + return resource.RetryableError(fmt.Errorf("eip is still creating")) + } + return nil + }) + if err != nil { + return err + } + + return nil +} + +func resourceTencentCloudEipReadPostHandleResponse0(ctx context.Context, resp *vpc.Address) error { + d := tccommon.ResourceDataFromContext(ctx) + logId := tccommon.GetLogId(tccommon.ContextNil) + meta := tccommon.ProviderMetaFromContext(ctx) + client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + vpcService := svcvpc.NewVpcService(client) + tagService := svctag.NewTagService(client) + region := client.Region + eipId := d.Id() + + tags, err := tagService.DescribeResourceTags(ctx, svcvpc.VPC_SERVICE_TYPE, svcvpc.EIP_RESOURCE_TYPE, region, eipId) + if err != nil { + log.Printf("[CRITAL]%s describe eip tags failed: %+v", logId, err) + return err + } + + bgp, err := vpcService.DescribeVpcBandwidthPackageByEip(ctx, eipId) + if err != nil { + log.Printf("[CRITAL]%s describe eip tags failed: %+v", logId, err) + return err + } + + _ = d.Set("tags", tags) + if bgp != nil { + _ = d.Set("bandwidth_package_id", bgp.BandwidthPackageId) + } + + return nil +} + +func resourceTencentCloudEipUpdatePostFillRequest1(ctx context.Context, req *vpc.ModifyAddressInternetChargeTypeRequest) error { + d := tccommon.ResourceDataFromContext(ctx) + period := d.Get("prepaid_period").(int) + renewFlag := d.Get("auto_renew_flag").(int) + + if *req.InternetChargeType != "" && *req.InternetMaxBandwidthOut != 0 { + if *req.InternetChargeType == "BANDWIDTH_PREPAID_BY_MONTH" { + addressChargePrepaid := vpc.AddressChargePrepaid{} + addressChargePrepaid.AutoRenewFlag = helper.IntInt64(renewFlag) + addressChargePrepaid.Period = helper.IntInt64(period) + req.AddressChargePrepaid = &addressChargePrepaid + } + } + + return nil +} + +func resourceTencentCloudEipDeletePostFillRequest0(ctx context.Context, req *vpc.ReleaseAddressesRequest) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + vpcService := svcvpc.NewVpcService(client) + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + errRet := vpcService.UnattachEip(ctx, d.Id()) + if errRet != nil { + return tccommon.RetryError(errRet, "DesOperation.MutexTaskRunning") + } + return nil + }) + if err != nil { + return err + } + + return nil +} + +func resourceTencentCloudEipDeletePostHandleResponse0(ctx context.Context, resp *vpc.ReleaseAddressesResponse) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + vpcService := svcvpc.NewVpcService(client) + eipId := d.Id() + var internetChargeType string + if v, ok := d.GetOk("internet_charge_type"); ok { + internetChargeType = v.(string) + } + + if internetChargeType == "BANDWIDTH_PREPAID_BY_MONTH" { + // isolated + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + eip, errRet := vpcService.DescribeEipById(ctx, eipId) + if errRet != nil { + return tccommon.RetryError(errRet) + } + if !*eip.IsArrears { + return resource.RetryableError(fmt.Errorf("eip is still isolate")) + } + return nil + }) + if err != nil { + return err + } + + // release + err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + errRet := vpcService.DeleteEip(ctx, eipId) + if errRet != nil { + return tccommon.RetryError(errRet, "DesOperation.MutexTaskRunning", "OperationDenied.MutexTaskRunning") + } + return nil + }) + if err != nil { + return err + } + } + + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + eip, errRet := vpcService.DescribeEipById(ctx, eipId) + if errRet != nil { + return tccommon.RetryError(errRet) + } + if eip != nil { + return resource.RetryableError(fmt.Errorf("eip is still deleting")) + } + return nil + }) + if err != nil { + return err + } + + return nil +} + +func resourceTencentCloudEipUpdateOnStart(ctx context.Context) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + vpcService := svcvpc.NewVpcService(client) + eipId := d.Id() + if d.HasChange("prepaid_period") || d.HasChange("auto_renew_flag") { + period := d.Get("prepaid_period").(int) + renewFlag := d.Get("auto_renew_flag").(int) + err := vpcService.RenewAddress(ctx, eipId, period, renewFlag) + if err != nil { + return err + } + } + return nil +} diff --git a/tencentcloud/services/cvm/resource_tc_eip_normal_address_return.go b/tencentcloud/services/cvm/resource_tc_eip_normal_address_return.go index 1800e802f1..d65cfd7f31 100644 --- a/tencentcloud/services/cvm/resource_tc_eip_normal_address_return.go +++ b/tencentcloud/services/cvm/resource_tc_eip_normal_address_return.go @@ -1,13 +1,14 @@ package cvm import ( + "context" "log" - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" ) func ResourceTencentCloudEipNormalAddressReturn() *schema.Resource { @@ -17,13 +18,13 @@ func ResourceTencentCloudEipNormalAddressReturn() *schema.Resource { Delete: resourceTencentCloudEipNormalAddressReturnDelete, Schema: map[string]*schema.Schema{ "address_ips": { - Optional: true, - ForceNew: true, - Type: schema.TypeSet, + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + Description: "The IP address of the EIP, example: 101.35.139.183.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Description: "The IP address of the EIP, example: 101.35.139.183.", }, }, } @@ -35,35 +36,43 @@ func resourceTencentCloudEipNormalAddressReturnCreate(d *schema.ResourceData, me logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + var ( - request = vpc.NewReturnNormalAddressesRequest() addressIps string ) - if v, ok := d.GetOk("address_ips"); ok { - addressIpsSet := v.(*schema.Set).List() - for i := range addressIpsSet { - addressIp := addressIpsSet[i].(string) - request.AddressIps = append(request.AddressIps, &addressIp) - addressIps = addressIp + tccommon.FILED_SP - } + var ( + request = vpc.NewReturnNormalAddressesRequest() + response = vpc.NewReturnNormalAddressesResponse() + ) + + if err := resourceTencentCloudEipNormalAddressReturnCreatePostFillRequest0(ctx, request); err != nil { + return err } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().ReturnNormalAddresses(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().ReturnNormalAddressesWithContext(ctx, request) if e != nil { return tccommon.RetryError(e) } else { log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) } + response = result return nil }) if err != nil { - log.Printf("[CRITAL]%s operate vpc normalAddressReturn failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s create eip normal address return failed, reason:%+v", logId, err) return err } + _ = response + d.SetId(addressIps) + if err := resourceTencentCloudEipNormalAddressReturnCreateOnExit(ctx); err != nil { + return err + } + return resourceTencentCloudEipNormalAddressReturnRead(d, meta) } diff --git a/tencentcloud/services/cvm/resource_tc_eip_normal_address_return_extension.go b/tencentcloud/services/cvm/resource_tc_eip_normal_address_return_extension.go new file mode 100644 index 0000000000..1a14e010c7 --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_eip_normal_address_return_extension.go @@ -0,0 +1,47 @@ +package cvm + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + + vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" +) + +func resourceTencentCloudEipNormalAddressReturnCreatePostFillRequest0(ctx context.Context, req *vpc.ReturnNormalAddressesRequest) error { + d := tccommon.ResourceDataFromContext(ctx) + var ( + addressIps string + ) + + if v, ok := d.GetOk("address_ips"); ok { + addressIpsSet := v.(*schema.Set).List() + for i := range addressIpsSet { + addressIp := addressIpsSet[i].(string) + req.AddressIps = append(req.AddressIps, &addressIp) + addressIps = addressIp + tccommon.FILED_SP + } + } + + _ = addressIps + return nil +} + +func resourceTencentCloudEipNormalAddressReturnCreateOnExit(ctx context.Context) error { + d := tccommon.ResourceDataFromContext(ctx) + var ( + addressIps string + ) + + if v, ok := d.GetOk("address_ips"); ok { + addressIpsSet := v.(*schema.Set).List() + for i := range addressIpsSet { + addressIp := addressIpsSet[i].(string) + addressIps = addressIp + tccommon.FILED_SP + } + } + + d.SetId(addressIps) + return nil +} diff --git a/tencentcloud/services/cvm/resource_tc_eip_public_address_adjust.go b/tencentcloud/services/cvm/resource_tc_eip_public_address_adjust.go index 7820d230a1..4310e762f2 100644 --- a/tencentcloud/services/cvm/resource_tc_eip_public_address_adjust.go +++ b/tencentcloud/services/cvm/resource_tc_eip_public_address_adjust.go @@ -1,16 +1,15 @@ package cvm import ( + "context" "log" - "time" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" - svcvpc "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/vpc" + "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" ) @@ -20,69 +19,78 @@ func ResourceTencentCloudEipPublicAddressAdjust() *schema.Resource { Read: resourceTencentCloudEipPublicAddressAdjustRead, Delete: resourceTencentCloudEipPublicAddressAdjustDelete, Schema: map[string]*schema.Schema{ - "instance_id": { + "address_id": { + Type: schema.TypeString, Optional: true, ForceNew: true, - Type: schema.TypeString, - Description: "A unique ID that identifies the CVM instance. The unique ID of CVM is in the form:`ins-osckfnm7`.", + Description: "A unique ID that identifies an EIP instance. The unique ID of EIP is in the form:`eip-erft45fu`.", }, - "address_id": { + + "instance_id": { + Type: schema.TypeString, Optional: true, ForceNew: true, - Type: schema.TypeString, - Description: "A unique ID that identifies an EIP instance. The unique ID of EIP is in the form:`eip-erft45fu`.", + Description: "A unique ID that identifies the CVM instance. The unique ID of CVM is in the form:`ins-osckfnm7`.", }, }, } } func resourceTencentCloudEipPublicAddressAdjustCreate(d *schema.ResourceData, meta interface{}) error { - defer tccommon.LogElapsed("resource.tencentcloud_vpc_public_address_adjust.create")() + defer tccommon.LogElapsed("resource.tencentcloud_eip_public_address_adjust.create")() defer tccommon.InconsistentCheck(d, meta)() + logId := tccommon.GetLogId(tccommon.ContextNil) + + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + var ( - logId = tccommon.GetLogId(tccommon.ContextNil) - service = svcvpc.NewVpcService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) - request = vpc.NewAdjustPublicAddressRequest() instanceId string addressId string - taskId uint64 + ) + var ( + request = vpc.NewAdjustPublicAddressRequest() + response = vpc.NewAdjustPublicAddressResponse() ) if v, ok := d.GetOk("instance_id"); ok { instanceId = v.(string) + } + if v, ok := d.GetOk("address_id"); ok { + addressId = v.(string) + } + + if v, ok := d.GetOk("instance_id"); ok { request.InstanceId = helper.String(v.(string)) } if v, ok := d.GetOk("address_id"); ok { - addressId = v.(string) request.AddressId = helper.String(v.(string)) } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().AdjustPublicAddress(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().AdjustPublicAddressWithContext(ctx, request) if e != nil { return tccommon.RetryError(e) } else { log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) } - - taskId = *result.Response.TaskId + response = result return nil }) - if err != nil { - log.Printf("[CRITAL]%s operate vpc publicAddressAdjust failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s create eip public address adjust failed, reason:%+v", logId, err) return err } - conf := tccommon.BuildStateChangeConf([]string{}, []string{"SUCCESS"}, 1*tccommon.ReadRetryTimeout, time.Second, service.VpcIpv6AddressStateRefreshFunc(helper.UInt64ToStr(taskId), []string{})) + _ = response - if _, e := conf.WaitForState(); e != nil { - return e + if err := resourceTencentCloudEipPublicAddressAdjustCreatePostHandleResponse0(ctx, response); err != nil { + return err } - d.SetId(instanceId + tccommon.FILED_SP + addressId) + d.SetId(strings.Join([]string{instanceId, addressId}, tccommon.FILED_SP)) + return resourceTencentCloudEipPublicAddressAdjustRead(d, meta) } diff --git a/tencentcloud/services/cvm/resource_tc_eip_public_address_adjust_extension.go b/tencentcloud/services/cvm/resource_tc_eip_public_address_adjust_extension.go new file mode 100644 index 0000000000..01d32135cd --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_eip_public_address_adjust_extension.go @@ -0,0 +1,25 @@ +package cvm + +import ( + "context" + "time" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" + svcvpc "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/vpc" + + vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" +) + +func resourceTencentCloudEipPublicAddressAdjustCreatePostHandleResponse0(ctx context.Context, resp *vpc.AdjustPublicAddressResponse) error { + meta := tccommon.ProviderMetaFromContext(ctx) + client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + vpcService := svcvpc.NewVpcService(client) + taskId := *resp.Response.TaskId + conf := tccommon.BuildStateChangeConf([]string{}, []string{"SUCCESS"}, 1*tccommon.ReadRetryTimeout, time.Second, vpcService.VpcIpv6AddressStateRefreshFunc(helper.UInt64ToStr(taskId), []string{})) + + if _, e := conf.WaitForState(); e != nil { + return e + } + return nil +} diff --git a/tencentcloud/services/cvm/service_tencentcloud_cvm.go b/tencentcloud/services/cvm/service_tencentcloud_cvm.go index 071d5d8f1f..5186a6189c 100644 --- a/tencentcloud/services/cvm/service_tencentcloud_cvm.go +++ b/tencentcloud/services/cvm/service_tencentcloud_cvm.go @@ -9,6 +9,8 @@ import ( "sync" "time" + vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -507,34 +509,38 @@ func (me *CvmService) DescribeInstanceTypes(ctx context.Context, zone string) (i return } -func (me *CvmService) DescribeInstanceTypesByFilter(ctx context.Context, filters map[string][]string) (instanceTypes []*cvm.InstanceTypeConfig, errRet error) { - logId := tccommon.GetLogId(ctx) - request := cvm.NewDescribeInstanceTypeConfigsRequest() - request.Filters = make([]*cvm.Filter, 0, len(filters)) - for k, v := range filters { - values := make([]*string, 0, len(v)) - for _, value := range v { - values = append(values, helper.String(value)) +func (me *CvmService) DescribeInstanceTypesByFilter(ctx context.Context, param map[string]interface{}) (ret *cvm.DescribeZoneInstanceConfigInfosResponseParams, errRet error) { + var ( + logId = tccommon.GetLogId(ctx) + request = cvm.NewDescribeZoneInstanceConfigInfosRequest() + ) + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) } - filter := &cvm.Filter{ - Name: helper.String(k), - Values: values, + }() + + for k, v := range param { + if k == "Filters" { + request.Filters = v.([]*cvm.Filter) } - request.Filters = append(request.Filters, filter) } ratelimit.Check(request.GetAction()) - response, err := me.client.UseCvmClient().DescribeInstanceTypeConfigs(request) + + response, err := me.client.UseCvmClient().DescribeZoneInstanceConfigInfos(request) if err != nil { - log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", - logId, request.GetAction(), request.ToJsonString(), err.Error()) errRet = err return } - log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", - logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) - instanceTypes = response.Response.InstanceTypeConfigSet + if response == nil || response.Response == nil { + return + } + + ret = response.Response return } @@ -1122,53 +1128,53 @@ func (me *CvmService) DescribeImageById(ctx context.Context, keyId string, isDel return } -func (me *CvmService) DescribeImagesByFilter(ctx context.Context, filters map[string][]string, instanceType string) (images []*cvm.Image, errRet error) { - logId := tccommon.GetLogId(ctx) - - request := cvm.NewDescribeImagesRequest() - request.Filters = make([]*cvm.Filter, 0, len(filters)) - for k, v := range filters { - filter := cvm.Filter{ - Name: helper.String(k), - Values: []*string{}, - } - for _, vv := range v { - filter.Values = append(filter.Values, helper.String(vv)) - } - request.Filters = append(request.Filters, &filter) - } - if instanceType != "" { - request.InstanceType = helper.String(instanceType) - } - var offset uint64 = 0 - var pageSize uint64 = 100 - images = make([]*cvm.Image, 0) - for { - request.Offset = &offset - request.Limit = &pageSize - ratelimit.Check(request.GetAction()) - response, err := me.client.UseCvmClient().DescribeImages(request) - if err != nil { - log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", - logId, request.GetAction(), request.ToJsonString(), err.Error()) - errRet = err - return - } - log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", - logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) - - if response == nil || len(response.Response.ImageSet) < 1 { - break - } - images = append(images, response.Response.ImageSet...) - if len(response.Response.ImageSet) < int(pageSize) { - break - } - offset += pageSize - } - - return -} +//func (me *CvmService) DescribeImagesByFilter(ctx context.Context, filters map[string][]string, instanceType string) (images []*cvm.Image, errRet error) { +// logId := tccommon.GetLogId(ctx) +// +// request := cvm.NewDescribeImagesRequest() +// request.Filters = make([]*cvm.Filter, 0, len(filters)) +// for k, v := range filters { +// filter := cvm.Filter{ +// Name: helper.String(k), +// Values: []*string{}, +// } +// for _, vv := range v { +// filter.Values = append(filter.Values, helper.String(vv)) +// } +// request.Filters = append(request.Filters, &filter) +// } +// if instanceType != "" { +// request.InstanceType = helper.String(instanceType) +// } +// var offset uint64 = 0 +// var pageSize uint64 = 100 +// images = make([]*cvm.Image, 0) +// for { +// request.Offset = &offset +// request.Limit = &pageSize +// ratelimit.Check(request.GetAction()) +// response, err := me.client.UseCvmClient().DescribeImages(request) +// if err != nil { +// log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", +// logId, request.GetAction(), request.ToJsonString(), err.Error()) +// errRet = err +// return +// } +// log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", +// logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) +// +// if response == nil || len(response.Response.ImageSet) < 1 { +// break +// } +// images = append(images, response.Response.ImageSet...) +// if len(response.Response.ImageSet) < int(pageSize) { +// break +// } +// offset += pageSize +// } +// +// return +//} func (me *CvmService) ModifyRenewParam(ctx context.Context, instanceId string, renewFlag string) error { logId := tccommon.GetLogId(ctx) @@ -1776,3 +1782,430 @@ func (me *CvmService) ModifyImageSharePermission(ctx context.Context, imageId, p } return } + +func NewVpcService(client *connectivity.TencentCloudClient) VpcService { + return VpcService{client: client} +} + +type VpcService struct { + client *connectivity.TencentCloudClient +} + +func (me *VpcService) DescribeEipById(ctx context.Context, eipId string) (ret *vpc.Address, errRet error) { + logId := tccommon.GetLogId(ctx) + + request := vpc.NewDescribeAddressesRequest() + request.AddressIds = []*string{helper.String(eipId)} + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + ratelimit.Check(request.GetAction()) + + response, err := me.client.UseVpcClient().DescribeAddresses(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if len(response.Response.AddressSet) < 1 { + return + } + + ret = response.Response.AddressSet[0] + return +} + +func (me *VpcService) DescribeEipsByFilter(ctx context.Context, param map[string]interface{}) (ret *vpc.DescribeAddressesResponseParams, errRet error) { + var ( + logId = tccommon.GetLogId(ctx) + request = vpc.NewDescribeAddressesRequest() + ) + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + for k, v := range param { + if k == "Filters" { + request.Filters = v.([]*vpc.Filter) + } + } + + ratelimit.Check(request.GetAction()) + + response, err := me.client.UseVpcClient().DescribeAddresses(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || response.Response == nil { + return + } + + ret = response.Response + return +} + +func (me *CvmService) DescribeImageByFilter(ctx context.Context, param map[string]interface{}) (ret []*cvm.Image, errRet error) { + var ( + logId = tccommon.GetLogId(ctx) + request = cvm.NewDescribeImagesRequest() + ) + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + for k, v := range param { + if k == "Filters" { + request.Filters = v.([]*cvm.Filter) + } + } + + ratelimit.Check(request.GetAction()) + + var ( + offset uint64 = 0 + limit uint64 = 100 + ) + for { + request.Offset = &offset + request.Limit = &limit + response, err := me.client.UseCvmClient().DescribeImages(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.ImageSet) < 1 { + break + } + ret = append(ret, response.Response.ImageSet...) + if len(response.Response.ImageSet) < int(limit) { + break + } + + offset += limit + } + + return +} + +func (me *CvmService) DescribeImagesByFilter(ctx context.Context, param map[string]interface{}) (ret []*cvm.Image, errRet error) { + var ( + logId = tccommon.GetLogId(ctx) + request = cvm.NewDescribeImagesRequest() + ) + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + for k, v := range param { + if k == "Filters" { + request.Filters = v.([]*cvm.Filter) + } + } + + ratelimit.Check(request.GetAction()) + + var ( + offset uint64 = 0 + limit uint64 = 100 + ) + for { + request.Offset = &offset + request.Limit = &limit + if err := dataSourceTencentCloudImagesReadPreRequest0(ctx, request); err != nil { + return nil, err + } + + response, err := me.client.UseCvmClient().DescribeImages(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.ImageSet) < 1 { + break + } + ret = append(ret, response.Response.ImageSet...) + if len(response.Response.ImageSet) < int(limit) { + break + } + + offset += limit + } + + return +} + +func (me *CvmService) DescribeInstancesSetByFilter(ctx context.Context, param map[string]interface{}) (ret []*cvm.Instance, errRet error) { + var ( + logId = tccommon.GetLogId(ctx) + request = cvm.NewDescribeInstancesRequest() + ) + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + for k, v := range param { + if k == "Filters" { + request.Filters = v.([]*cvm.Filter) + } + } + + ratelimit.Check(request.GetAction()) + + var ( + offset int64 = 0 + limit int64 = 100 + ) + for { + request.Offset = &offset + request.Limit = &limit + response, err := me.client.UseCvmClient().DescribeInstances(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.InstanceSet) < 1 { + break + } + ret = append(ret, response.Response.InstanceSet...) + if len(response.Response.InstanceSet) < int(limit) { + break + } + + offset += limit + } + + return +} + +func (me *CvmService) DescribeKeyPairsByFilter(ctx context.Context, param map[string]interface{}) (ret []*cvm.KeyPair, errRet error) { + var ( + logId = tccommon.GetLogId(ctx) + request = cvm.NewDescribeKeyPairsRequest() + ) + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + ratelimit.Check(request.GetAction()) + + var ( + offset int64 = 0 + limit int64 = 100 + ) + for { + request.Offset = &offset + request.Limit = &limit + if err := dataSourceTencentCloudKeyPairsReadPreRequest0(ctx, request); err != nil { + return nil, err + } + + response, err := me.client.UseCvmClient().DescribeKeyPairs(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.KeyPairSet) < 1 { + break + } + ret = append(ret, response.Response.KeyPairSet...) + if len(response.Response.KeyPairSet) < int(limit) { + break + } + + offset += limit + } + + return +} + +func (me *CvmService) DescribePlacementGroupsByFilter(ctx context.Context, param map[string]interface{}) (ret []*cvm.DisasterRecoverGroup, errRet error) { + var ( + logId = tccommon.GetLogId(ctx) + request = cvm.NewDescribeDisasterRecoverGroupsRequest() + ) + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + for k, v := range param { + if k == "DisasterRecoverGroupIds" { + request.DisasterRecoverGroupIds = v.([]*string) + } + if k == "Name" { + request.Name = v.(*string) + } + } + + ratelimit.Check(request.GetAction()) + + var ( + offset int64 = 0 + limit int64 = 100 + ) + for { + request.Offset = &offset + request.Limit = &limit + response, err := me.client.UseCvmClient().DescribeDisasterRecoverGroups(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.DisasterRecoverGroupSet) < 1 { + break + } + ret = append(ret, response.Response.DisasterRecoverGroupSet...) + if len(response.Response.DisasterRecoverGroupSet) < int(limit) { + break + } + + offset += limit + } + + return +} + +func (me *CvmService) DescribeInstancesByFilter(ctx context.Context, param map[string]interface{}) (ret []*cvm.Instance, errRet error) { + var ( + logId = tccommon.GetLogId(ctx) + request = cvm.NewDescribeInstancesRequest() + ) + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + for k, v := range param { + if k == "Filters" { + request.Filters = v.([]*cvm.Filter) + } + } + + ratelimit.Check(request.GetAction()) + + var ( + offset int64 = 0 + limit int64 = 100 + ) + for { + request.Offset = &offset + request.Limit = &limit + if err := dataSourceTencentCloudInstancesReadPreRequest0(ctx, request); err != nil { + return nil, err + } + + response, err := me.client.UseCvmClient().DescribeInstances(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.InstanceSet) < 1 { + break + } + ret = append(ret, response.Response.InstanceSet...) + if len(response.Response.InstanceSet) < int(limit) { + break + } + + offset += limit + } + + return +} + +func (me *CvmService) DescribeCvmSecurityGroupAttachmentById(ctx context.Context, instanceId string) (ret *cvm.DescribeInstancesResponseParams, errRet error) { + logId := tccommon.GetLogId(ctx) + + request := cvm.NewDescribeInstancesRequest() + request.InstanceIds = []*string{helper.String(instanceId)} + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + ratelimit.Check(request.GetAction()) + + response, err := me.client.UseCvmClient().DescribeInstances(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + ret = response.Response + return +} + +func (me *VpcService) DescribeEipAssociationById(ctx context.Context, eipId string) (ret *vpc.Address, errRet error) { + logId := tccommon.GetLogId(ctx) + + request := vpc.NewDescribeAddressesRequest() + request.AddressIds = []*string{helper.String(eipId)} + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + ratelimit.Check(request.GetAction()) + + if err := resourceTencentCloudEipAssociationReadPreRequest0(ctx, request); err != nil { + return nil, err + } + + response, err := me.client.UseVpcClient().DescribeAddresses(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if len(response.Response.AddressSet) < 1 { + return + } + + ret = response.Response.AddressSet[0] + return +} diff --git a/tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster.go b/tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster.go index f53625eb0e..1399a79f88 100644 --- a/tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster.go +++ b/tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster.go @@ -212,7 +212,7 @@ func resourceTencentCloudCynosdbClusterCreate(d *schema.ResourceData, meta inter // set tags if tags := helper.GetTags(d, "tags"); len(tags) > 0 { - resourceName := tccommon.BuildTagResourceName("cynosdb", "cluster", region, id) + resourceName := tccommon.BuildTagResourceName("cynosdb", "instance", region, id) if err := tagService.ModifyTags(ctx, resourceName, tags, nil); err != nil { return err } @@ -352,7 +352,7 @@ func resourceTencentCloudCynosdbClusterRead(d *schema.ResourceData, meta interfa //tag tagService := svctag.NewTagService(client) - tags, err := tagService.DescribeResourceTags(ctx, "cynosdb", "cluster", client.Region, id) + tags, err := tagService.DescribeResourceTags(ctx, "cynosdb", "instance", client.Region, id) if err != nil { return err } @@ -652,7 +652,7 @@ func resourceTencentCloudCynosdbClusterUpdate(d *schema.ResourceData, meta inter oldTags, newTags := d.GetChange("tags") replaceTags, deleteTags := svctag.DiffTags(oldTags.(map[string]interface{}), newTags.(map[string]interface{})) - resourceName := tccommon.BuildTagResourceName("cynosdb", "cluster", region, clusterId) + resourceName := tccommon.BuildTagResourceName("cynosdb", "instance", region, clusterId) if err := tagService.ModifyTags(ctx, resourceName, replaceTags, deleteTags); err != nil { return err } diff --git a/tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster_test.go b/tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster_test.go index d0042d2f07..e57c378538 100644 --- a/tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster_test.go +++ b/tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster_test.go @@ -68,8 +68,8 @@ func TestAccTencentCloudCynosdbClusterResourceBasic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckCynosdbClusterExists("tencentcloud_cynosdb_cluster.foo"), resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "available_zone", "ap-guangzhou-4"), - resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "vpc_id", "vpc-4owdpnwr"), - resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "subnet_id", "subnet-qpxez62e"), + resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "vpc_id", "vpc-m0d2dbnn"), + resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "subnet_id", "subnet-j10lsueq"), resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "db_type", "MYSQL"), resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "db_version", "5.7"), // resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "storage_limit", "1000"), @@ -79,7 +79,7 @@ func TestAccTencentCloudCynosdbClusterResourceBasic(t *testing.T) { resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "instance_maintain_weekdays.#", "7"), resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "instance_cpu_core", "1"), resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "instance_memory_size", "2"), - //resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "tags.test", "test"), + resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "tags.test", "test"), resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "force_delete", "true"), resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "rw_group_sg.#", "1"), resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "ro_group_sg.#", "1"), @@ -116,11 +116,11 @@ func TestAccTencentCloudCynosdbClusterResourceBasic(t *testing.T) { { Config: testAccCynosdbCluster_update, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "vpc_id", "vpc-k1t8ickr"), - resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "subnet_id", "subnet-jdi5xn22"), - resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "instance_maintain_duration", "7200"), - resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "instance_maintain_start_time", "21600"), - resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "instance_maintain_weekdays.#", "6"), + resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "vpc_id", "vpc-m0d2dbnn"), + resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "subnet_id", "subnet-j10lsueq"), + resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "instance_maintain_duration", "3600"), + resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "instance_maintain_start_time", "10800"), + resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "instance_maintain_weekdays.#", "7"), resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "instance_cpu_core", "2"), resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "instance_memory_size", "4"), resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "rw_group_sg.#", "1"), @@ -128,10 +128,10 @@ func TestAccTencentCloudCynosdbClusterResourceBasic(t *testing.T) { resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "param_items.#", "2"), resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "param_items.0.name", "character_set_server"), resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "param_items.0.old_value", "utf8"), - resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "param_items.0.current_value", "utf8mb4"), + resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "param_items.0.current_value", "utf8"), resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "param_items.1.name", "time_zone"), resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "param_items.1.old_value", "+09:00"), - resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "param_items.1.current_value", "+08:00"), + resource.TestCheckResourceAttr("tencentcloud_cynosdb_cluster.foo", "param_items.1.current_value", "+09:00"), ), }, }, @@ -238,22 +238,26 @@ func testAccCheckCynosdbClusterExists(n string) resource.TestCheckFunc { } } -const testAccCynosdbBasic = tcacctest.DefaultSecurityGroupData + ` +const testAccCynosdbBasic = ` variable "availability_zone" { default = "ap-guangzhou-4" } variable "my_vpc" { - default = "vpc-4owdpnwr" + default = "vpc-m0d2dbnn" } variable "my_subnet" { - default = "subnet-qpxez62e" + default = "subnet-j10lsueq" } variable "my_param_template" { default = "15765" } + +variable "rw_group_sg" { + default = "sg-05f7wnhn" +} ` const testAccCynosdbCluster = testAccCynosdbBasic + ` @@ -289,70 +293,68 @@ resource "tencentcloud_cynosdb_cluster" "foo" { current_value = "+09:00" } -# tags = { -# test = "test" -# } + tags = { + test = "test" + } force_delete = true rw_group_sg = [ - local.sg_id + var.rw_group_sg ] ro_group_sg = [ - local.sg_id + var.rw_group_sg ] - prarm_template_id = var.my_param_template +# prarm_template_id = var.my_param_template } ` const testAccCynosdbCluster_update = testAccCynosdbBasic + ` resource "tencentcloud_cynosdb_cluster" "foo" { available_zone = var.availability_zone - vpc_id = "vpc-k1t8ickr" - subnet_id = "subnet-jdi5xn22" - old_ip_reserve_hours = 1 + vpc_id = var.my_vpc + subnet_id = var.my_subnet db_type = "MYSQL" db_version = "5.7" storage_limit = 1000 cluster_name = "tf-cynosdb-update" password = "cynos@123" - instance_maintain_duration = 7200 - instance_maintain_start_time = 21600 + instance_maintain_duration = 3600 + instance_maintain_start_time = 10800 instance_maintain_weekdays = [ "Fri", "Mon", "Sat", "Sun", "Thu", + "Wed", "Tue", ] instance_cpu_core = 2 instance_memory_size = 4 - param_items { name = "character_set_server" - old_value = "utf8" - current_value = "utf8mb4" + old_value = "utf8" + current_value = "utf8" } - param_items { name = "time_zone" - old_value = "+09:00" - current_value = "+08:00" + old_value = "+09:00" + current_value = "+09:00" } -# tags = { -# test = "test-update" -# } + tags = { + test = "test" + } force_delete = true rw_group_sg = [ - local.sg_id2 + var.rw_group_sg ] ro_group_sg = [ - local.sg_id2 + var.rw_group_sg ] } ` diff --git a/tencentcloud/services/postgresql/resource_tc_postgresql_instance.go b/tencentcloud/services/postgresql/resource_tc_postgresql_instance.go index fa3ba7fd39..729857ac4d 100644 --- a/tencentcloud/services/postgresql/resource_tc_postgresql_instance.go +++ b/tencentcloud/services/postgresql/resource_tc_postgresql_instance.go @@ -72,10 +72,9 @@ func ResourceTencentCloudPostgresqlInstance() *schema.Resource { }, "engine_version": { Type: schema.TypeString, - ForceNew: true, Optional: true, - Default: "10.4", - Description: "Version of the postgresql database engine. Valid values: `10.4`, `11.8`, `12.4`.", + Computed: true, + Description: "Version of the postgresql database engine. Valid values: `10.4`, `10.17`, `10.23`, `11.8`, `11.12`, `11.22`, `12.4`, `12.7`, `12.18`, `13.3`, `14.2`, `14.11`, `15.1`, `16.0`.", }, "db_major_vesion": { Type: schema.TypeString, @@ -83,7 +82,7 @@ func ResourceTencentCloudPostgresqlInstance() *schema.Resource { Computed: true, Deprecated: "`db_major_vesion` will be deprecated, use `db_major_version` instead.", ConflictsWith: []string{"db_major_version"}, - Description: "PostgreSQL major version number. Valid values: 10, 11, 12, 13. " + + Description: "PostgreSQL major version number. Valid values: 10, 11, 12, 13, 14, 15, 16. " + "If it is specified, an instance running the latest kernel of PostgreSQL DBMajorVersion will be created.", }, "db_major_version": { @@ -91,7 +90,7 @@ func ResourceTencentCloudPostgresqlInstance() *schema.Resource { Optional: true, Computed: true, ConflictsWith: []string{"db_major_vesion"}, - Description: "PostgreSQL major version number. Valid values: 10, 11, 12, 13. " + + Description: "PostgreSQL major version number. Valid values: 10, 11, 12, 13, 14, 15, 16. " + "If it is specified, an instance running the latest kernel of PostgreSQL DBMajorVersion will be created.", }, "db_kernel_version": { @@ -101,7 +100,6 @@ func ResourceTencentCloudPostgresqlInstance() *schema.Resource { Description: "PostgreSQL kernel version number. " + "If it is specified, an instance running kernel DBKernelVersion will be created. It supports updating the minor kernel version immediately.", }, - "vpc_id": { Type: schema.TypeString, Required: true, @@ -344,9 +342,9 @@ func resourceTencentCloudPostgresqlInstanceCreate(d *schema.ResourceData, meta i // the sdk asks to set value with 1 when paytype is postpaid - var instanceId, specVersion, specCode string + var instanceId, majorVersion, specVersion, specCode string var outErr, inErr error - var allowVersion, allowSpec []string + var allowMajorVersion, allowSpecVersion, allowSpec []string var ( dbMajorVersion = "" @@ -404,6 +402,10 @@ func resourceTencentCloudPostgresqlInstanceCreate(d *schema.ResourceData, meta i requestSecurityGroup = append(requestSecurityGroup, v.(string)) } + if dbVersion == "" && dbMajorVersion == "" && dbKernelVersion == "" { + dbVersion = "10.4" + } + // get specCode with engine_version and memory outErr = resource.Retry(tccommon.ReadRetryTimeout*5, func() *resource.RetryError { speccodes, inErr := postgresqlService.DescribeSpecinfos(ctx, zone) @@ -411,10 +413,16 @@ func resourceTencentCloudPostgresqlInstanceCreate(d *schema.ResourceData, meta i return tccommon.RetryError(inErr) } for _, info := range speccodes { - if !tccommon.IsContains(allowVersion, *info.Version) { - allowVersion = append(allowVersion, *info.Version) + if !tccommon.IsContains(allowSpecVersion, *info.Version) { + allowSpecVersion = append(allowSpecVersion, *info.Version) + } + + if !tccommon.IsContains(allowMajorVersion, *info.MajorVersion) { + allowMajorVersion = append(allowMajorVersion, *info.MajorVersion) } - if *info.Version == dbVersion { + + if *info.MajorVersion == dbMajorVersion || *info.Version == dbVersion { + majorVersion = *info.MajorVersion specVersion = *info.Version specString := fmt.Sprintf("(%d, %d)", int(*info.Memory)/1024, int(*info.Cpu)) if !tccommon.IsContains(allowSpec, specString) { @@ -438,8 +446,8 @@ func resourceTencentCloudPostgresqlInstanceCreate(d *schema.ResourceData, meta i return outErr } - if specVersion == "" { - return fmt.Errorf(`The "engine_version" value: "%s" is invalid, Valid values are one of: "%s"`, dbVersion, strings.Join(allowVersion, `", "`)) + if majorVersion == "" && specVersion == "" { + return fmt.Errorf(`The "db_major_version" value: "%s" is invalid, Valid values are one of: "%s", The "engine_version" value: "%s" is invalid, Valid values are one of: "%s"`, dbMajorVersion, strings.Join(allowMajorVersion, `", "`), dbVersion, strings.Join(allowSpecVersion, `", "`)) } if specCode == "" { @@ -1126,13 +1134,19 @@ func resourceTencentCloudPostgresqlInstanceUpdate(d *schema.ResourceData, meta i paramEntrys["max_standby_streaming_delay"] = strconv.Itoa(v.(int)) } } + if d.HasChange("db_major_vesion") || d.HasChange("db_major_version") { return fmt.Errorf("Not support change db major version.") } + if d.HasChange("engine_version") { + return fmt.Errorf("Not support change engine_version.") + } + if d.HasChange("need_support_tde") || d.HasChange("kms_key_id") || d.HasChange("kms_region") { return fmt.Errorf("Not support change params contact with data transparent encryption.") } + if len(paramEntrys) != 0 { outErr = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { inErr := postgresqlService.ModifyPgParams(ctx, instanceId, paramEntrys) diff --git a/tencentcloud/services/postgresql/resource_tc_postgresql_instance.md b/tencentcloud/services/postgresql/resource_tc_postgresql_instance.md index 3bae843ab4..726faef795 100644 --- a/tencentcloud/services/postgresql/resource_tc_postgresql_instance.md +++ b/tencentcloud/services/postgresql/resource_tc_postgresql_instance.md @@ -1,41 +1,44 @@ Use this resource to create postgresql instance. -> **Note:** To update the charge type, please update the `charge_type` and specify the `period` for the charging period. It only supports updating from `POSTPAID_BY_HOUR` to `PREPAID`, and the `period` field only valid in that upgrading case. +-> **Note:** If no values are set for the two parameters: `db_major_version` and `engine_version`, then `engine_version` is set to `10.4` by default. Suggest using parameter `db_major_version` to create an instance Example Usage ```hcl variable "availability_zone" { - default = "ap-guangzhou-1" + default = "ap-guangzhou-3" } # create vpc resource "tencentcloud_vpc" "vpc" { - name = "guagua_vpc_instance_test" + name = "vpc" cidr_block = "10.0.0.0/16" } # create vpc subnet resource "tencentcloud_subnet" "subnet" { availability_zone = var.availability_zone - name = "guagua_vpc_subnet_test" + name = "subnet" vpc_id = tencentcloud_vpc.vpc.id cidr_block = "10.0.20.0/28" is_multicast = false } # create postgresql -resource "tencentcloud_postgresql_instance" "foo" { +resource "tencentcloud_postgresql_instance" "example" { name = "example" availability_zone = var.availability_zone charge_type = "POSTPAID_BY_HOUR" vpc_id = tencentcloud_vpc.vpc.id subnet_id = tencentcloud_subnet.subnet.id - engine_version = "10.4" + db_major_version = "10" + engine_version = "10.23" root_user = "root123" root_password = "Root123$" charset = "UTF8" project_id = 0 + cpu = 1 memory = 2 storage = 10 @@ -58,27 +61,27 @@ variable "standby_availability_zone" { # create vpc resource "tencentcloud_vpc" "vpc" { - name = "guagua_vpc_instance_test" + name = "vpc" cidr_block = "10.0.0.0/16" } # create vpc subnet resource "tencentcloud_subnet" "subnet" { availability_zone = var.availability_zone - name = "guagua_vpc_subnet_test" + name = "subnet" vpc_id = tencentcloud_vpc.vpc.id cidr_block = "10.0.20.0/28" is_multicast = false } # create postgresql -resource "tencentcloud_postgresql_instance" "foo" { +resource "tencentcloud_postgresql_instance" "example" { name = "example" availability_zone = var.availability_zone charge_type = "POSTPAID_BY_HOUR" vpc_id = tencentcloud_vpc.vpc.id subnet_id = tencentcloud_subnet.subnet.id - engine_version = "10.4" + db_major_version = "10" root_user = "root123" root_password = "Root123$" charset = "UTF8" @@ -91,6 +94,7 @@ resource "tencentcloud_postgresql_instance" "foo" { role = "Primary" zone = var.availability_zone } + db_node_set { zone = var.standby_availability_zone } @@ -102,20 +106,24 @@ resource "tencentcloud_postgresql_instance" "foo" { ``` create pgsql with kms key -``` -resource "tencentcloud_postgresql_instance" "pg" { +```hcl +variable "availability_zone" { + default = "ap-guangzhou-6" +} + +resource "tencentcloud_postgresql_instance" "example" { name = "tf_postsql_instance" - availability_zone = "ap-guangzhou-6" + availability_zone = var.availability_zone charge_type = "POSTPAID_BY_HOUR" vpc_id = "vpc-86v957zb" subnet_id = "subnet-enm92y0m" + db_major_version = "11" engine_version = "11.12" - # db_major_vesion = "11" db_kernel_version = "v11.12_r1.3" need_support_tde = 1 kms_key_id = "788c606a-c7b7-11ec-82d1-5254001e5c4e" kms_region = "ap-guangzhou" - root_password = "xxxxxxxxxx" + root_password = "Root123$" charset = "LATIN1" project_id = 0 memory = 4 @@ -135,32 +143,37 @@ resource "tencentcloud_postgresql_instance" "pg" { ``` upgrade kernel version -``` -resource "tencentcloud_postgresql_instance" "test" { - name = "tf_postsql_instance_update" - availability_zone = data.tencentcloud_availability_zones_by_product.zone.zones[5].name - charge_type = "POSTPAID_BY_HOUR" - vpc_id = local.vpc_id - subnet_id = local.subnet_id - engine_version = "13.3" - root_password = "*" - charset = "LATIN1" - project_id = 0 +```hcl +variable "availability_zone" { + default = "ap-guangzhou-6" +} + +resource "tencentcloud_postgresql_instance" "example" { + name = "tf_postsql_instance_update_kernel" + availability_zone = var.availability_zone + charge_type = "POSTPAID_BY_HOUR" + vpc_id = "vpc-86v957zb" + subnet_id = "subnet-enm92y0m" + engine_version = "13.3" + root_password = "Root123$" + charset = "LATIN1" + project_id = 0 public_access_switch = false - security_groups = [local.sg_id] - memory = 4 - storage = 250 + security_groups = ["sg-cm7fbbf3"] + memory = 4 + storage = 250 + backup_plan { - min_backup_start_time = "01:10:11" - max_backup_start_time = "02:10:11" - base_backup_retention_period = 5 - backup_period = ["monday", "thursday", "sunday"] + min_backup_start_time = "01:10:11" + max_backup_start_time = "02:10:11" + base_backup_retention_period = 5 + backup_period = ["monday", "thursday", "sunday"] } db_kernel_version = "v13.3_r1.4" # eg:from v13.3_r1.1 to v13.3_r1.4 tags = { - tf = "teest" + tf = "test" } } ``` @@ -170,5 +183,5 @@ Import postgresql instance can be imported using the id, e.g. ``` -$ terraform import tencentcloud_postgresql_instance.foo postgres-cda1iex1 +$ terraform import tencentcloud_postgresql_instance.example postgres-cda1iex1 ``` \ No newline at end of file diff --git a/tencentcloud/services/postgresql/resource_tc_postgresql_instance_test.go b/tencentcloud/services/postgresql/resource_tc_postgresql_instance_test.go index 50791f5332..b1a481ec33 100644 --- a/tencentcloud/services/postgresql/resource_tc_postgresql_instance_test.go +++ b/tencentcloud/services/postgresql/resource_tc_postgresql_instance_test.go @@ -425,7 +425,7 @@ func testAccCheckPostgresqlInstanceExists(n string) resource.TestCheckFunc { } } -const testAccPostgresqlInstanceBasic = tcacctest.DefaultSecurityGroupData + ` +const testAccPostgresqlInstanceBasic = ` data "tencentcloud_availability_zones_by_product" "zone" { product = "postgres" } @@ -440,7 +440,7 @@ resource "tencentcloud_postgresql_instance" "test" { subnet_id = local.subnet_id engine_version = "13.3" root_password = "t1qaA2k1wgvfa3?ZZZ" - security_groups = [local.sg_id] + security_groups = ["sg-5275dorp"] charset = "LATIN1" project_id = 0 memory = 4 @@ -465,14 +465,6 @@ data "tencentcloud_availability_zones_by_product" "zone" { product = "postgres" } -data "tencentcloud_security_groups" "internal" { - name = "default" -} - -locals { - sg_id = data.tencentcloud_security_groups.internal.security_groups.0.security_group_id -} - resource "tencentcloud_postgresql_instance" "test" { name = "tf_postsql_postpaid" availability_zone = var.default_az @@ -482,7 +474,7 @@ resource "tencentcloud_postgresql_instance" "test" { subnet_id = local.subnet_id engine_version = "13.3" root_password = "t1qaA2k1wgvfa3?ZZZ" - security_groups = [local.sg_id] + security_groups = ["sg-5275dorp"] charset = "LATIN1" project_id = 0 memory = 2 @@ -494,14 +486,6 @@ data "tencentcloud_availability_zones_by_product" "zone" { product = "postgres" } -data "tencentcloud_security_groups" "internal" { - name = "default" -} - -locals { - sg_id = data.tencentcloud_security_groups.internal.security_groups.0.security_group_id -} - resource "tencentcloud_postgresql_instance" "test" { name = "tf_postsql_postpaid_updated_to_prepaid" availability_zone = var.default_az @@ -511,7 +495,7 @@ resource "tencentcloud_postgresql_instance" "test" { subnet_id = local.subnet_id engine_version = "13.3" root_password = "t1qaA2k1wgvfa3?ZZZ" - security_groups = [local.sg_id] + security_groups = ["sg-5275dorp"] charset = "LATIN1" project_id = 0 memory = 2 @@ -523,14 +507,6 @@ data "tencentcloud_availability_zones_by_product" "zone" { product = "postgres" } -data "tencentcloud_security_groups" "internal" { - name = "default" -} - -locals { - sg_id = data.tencentcloud_security_groups.internal.security_groups.0.security_group_id -} - resource "tencentcloud_postgresql_instance" "test" { name = "tf_postsql_pre" availability_zone = data.tencentcloud_availability_zones_by_product.zone.zones[5].name @@ -539,7 +515,7 @@ resource "tencentcloud_postgresql_instance" "test" { subnet_id = local.subnet_id engine_version = "13.3" root_password = "t1qaA2k1wgvfa3?ZZZ" - security_groups = [local.sg_id] + security_groups = ["sg-5275dorp"] charset = "LATIN1" project_id = 0 memory = 2 @@ -558,7 +534,7 @@ resource "tencentcloud_postgresql_instance" "test" { charset = "LATIN1" project_id = 0 public_access_switch = true - security_groups = [local.sg_id] + security_groups = ["sg-5275dorp"] memory = 4 storage = 250 backup_plan { @@ -608,7 +584,7 @@ resource "tencentcloud_postgresql_instance" "test" { charset = "LATIN1" project_id = 0 public_access_switch = false - security_groups = [local.sg_id] + security_groups = ["sg-5275dorp"] memory = 4 storage = 250 backup_plan { @@ -638,7 +614,7 @@ resource "tencentcloud_postgresql_instance" "test" { charset = "LATIN1" project_id = 0 public_access_switch = false - security_groups = [local.sg_id] + security_groups = ["sg-5275dorp"] memory = 4 storage = 250 backup_plan { diff --git a/tencentcloud/services/teo/resource_tc_teo_rule_engine.go b/tencentcloud/services/teo/resource_tc_teo_rule_engine.go index 3580239a6b..730ba11b28 100644 --- a/tencentcloud/services/teo/resource_tc_teo_rule_engine.go +++ b/tencentcloud/services/teo/resource_tc_teo_rule_engine.go @@ -113,7 +113,7 @@ func ResourceTencentCloudTeoRuleEngine() *schema.Resource { }, "actions": { Type: schema.TypeList, - Required: true, + Optional: true, Description: "Feature to be executed.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -309,7 +309,7 @@ func ResourceTencentCloudTeoRuleEngine() *schema.Resource { }, "actions": { Type: schema.TypeList, - Required: true, + Optional: true, Description: "The feature to be executed.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -471,7 +471,7 @@ func resourceTencentCloudTeoRuleEngineCreate(d *schema.ResourceData, meta interf zoneId = v.(string) } - request.ZoneId = &zoneId + request.ZoneId = helper.String(zoneId) if v, ok := d.GetOk("rule_name"); ok { request.RuleName = helper.String(v.(string)) @@ -657,9 +657,9 @@ func resourceTencentCloudTeoRuleEngineCreate(d *schema.ResourceData, meta interf actionsMap := item.(map[string]interface{}) action := teo.Action{} if normalActionMap, ok := helper.ConvertInterfacesHeadToMap(actionsMap["normal_action"]); ok { - normalAction := teo.NormalAction{} + normalAction2 := teo.NormalAction{} if v, ok := normalActionMap["action"]; ok { - normalAction.Action = helper.String(v.(string)) + normalAction2.Action = helper.String(v.(string)) } if v, ok := normalActionMap["parameters"]; ok { for _, item := range v.([]interface{}) { @@ -675,15 +675,15 @@ func resourceTencentCloudTeoRuleEngineCreate(d *schema.ResourceData, meta interf ruleNormalActionParams.Values = append(ruleNormalActionParams.Values, helper.String(values)) } } - normalAction.Parameters = append(normalAction.Parameters, &ruleNormalActionParams) + normalAction2.Parameters = append(normalAction2.Parameters, &ruleNormalActionParams) } } - action.NormalAction = &normalAction + action.NormalAction = &normalAction2 } if rewriteActionMap, ok := helper.ConvertInterfacesHeadToMap(actionsMap["rewrite_action"]); ok { - rewriteAction := teo.RewriteAction{} + rewriteAction2 := teo.RewriteAction{} if v, ok := rewriteActionMap["action"]; ok { - rewriteAction.Action = helper.String(v.(string)) + rewriteAction2.Action = helper.String(v.(string)) } if v, ok := rewriteActionMap["parameters"]; ok { for _, item := range v.([]interface{}) { @@ -702,15 +702,15 @@ func resourceTencentCloudTeoRuleEngineCreate(d *schema.ResourceData, meta interf ruleRewriteActionParams.Values = append(ruleRewriteActionParams.Values, helper.String(values)) } } - rewriteAction.Parameters = append(rewriteAction.Parameters, &ruleRewriteActionParams) + rewriteAction2.Parameters = append(rewriteAction2.Parameters, &ruleRewriteActionParams) } } - action.RewriteAction = &rewriteAction + action.RewriteAction = &rewriteAction2 } if codeActionMap, ok := helper.ConvertInterfacesHeadToMap(actionsMap["code_action"]); ok { - codeAction := teo.CodeAction{} + codeAction2 := teo.CodeAction{} if v, ok := codeActionMap["action"]; ok { - codeAction.Action = helper.String(v.(string)) + codeAction2.Action = helper.String(v.(string)) } if v, ok := codeActionMap["parameters"]; ok { for _, item := range v.([]interface{}) { @@ -729,10 +729,10 @@ func resourceTencentCloudTeoRuleEngineCreate(d *schema.ResourceData, meta interf ruleCodeActionParams.Values = append(ruleCodeActionParams.Values, helper.String(values)) } } - codeAction.Parameters = append(codeAction.Parameters, &ruleCodeActionParams) + codeAction2.Parameters = append(codeAction2.Parameters, &ruleCodeActionParams) } } - action.CodeAction = &codeAction + action.CodeAction = &codeAction2 } subRule.Actions = append(subRule.Actions, &action) } @@ -1171,9 +1171,9 @@ func resourceTencentCloudTeoRuleEngineUpdate(d *schema.ResourceData, meta interf if needChange { request := teo.NewModifyRuleRequest() - request.ZoneId = &zoneId + request.ZoneId = helper.String(zoneId) - request.RuleId = &ruleId + request.RuleId = helper.String(ruleId) if v, ok := d.GetOk("rule_name"); ok { request.RuleName = helper.String(v.(string)) @@ -1359,9 +1359,9 @@ func resourceTencentCloudTeoRuleEngineUpdate(d *schema.ResourceData, meta interf actionsMap := item.(map[string]interface{}) action := teo.Action{} if normalActionMap, ok := helper.ConvertInterfacesHeadToMap(actionsMap["normal_action"]); ok { - normalAction := teo.NormalAction{} + normalAction2 := teo.NormalAction{} if v, ok := normalActionMap["action"]; ok { - normalAction.Action = helper.String(v.(string)) + normalAction2.Action = helper.String(v.(string)) } if v, ok := normalActionMap["parameters"]; ok { for _, item := range v.([]interface{}) { @@ -1377,15 +1377,15 @@ func resourceTencentCloudTeoRuleEngineUpdate(d *schema.ResourceData, meta interf ruleNormalActionParams.Values = append(ruleNormalActionParams.Values, helper.String(values)) } } - normalAction.Parameters = append(normalAction.Parameters, &ruleNormalActionParams) + normalAction2.Parameters = append(normalAction2.Parameters, &ruleNormalActionParams) } } - action.NormalAction = &normalAction + action.NormalAction = &normalAction2 } if rewriteActionMap, ok := helper.ConvertInterfacesHeadToMap(actionsMap["rewrite_action"]); ok { - rewriteAction := teo.RewriteAction{} + rewriteAction2 := teo.RewriteAction{} if v, ok := rewriteActionMap["action"]; ok { - rewriteAction.Action = helper.String(v.(string)) + rewriteAction2.Action = helper.String(v.(string)) } if v, ok := rewriteActionMap["parameters"]; ok { for _, item := range v.([]interface{}) { @@ -1404,15 +1404,15 @@ func resourceTencentCloudTeoRuleEngineUpdate(d *schema.ResourceData, meta interf ruleRewriteActionParams.Values = append(ruleRewriteActionParams.Values, helper.String(values)) } } - rewriteAction.Parameters = append(rewriteAction.Parameters, &ruleRewriteActionParams) + rewriteAction2.Parameters = append(rewriteAction2.Parameters, &ruleRewriteActionParams) } } - action.RewriteAction = &rewriteAction + action.RewriteAction = &rewriteAction2 } if codeActionMap, ok := helper.ConvertInterfacesHeadToMap(actionsMap["code_action"]); ok { - codeAction := teo.CodeAction{} + codeAction2 := teo.CodeAction{} if v, ok := codeActionMap["action"]; ok { - codeAction.Action = helper.String(v.(string)) + codeAction2.Action = helper.String(v.(string)) } if v, ok := codeActionMap["parameters"]; ok { for _, item := range v.([]interface{}) { @@ -1431,10 +1431,10 @@ func resourceTencentCloudTeoRuleEngineUpdate(d *schema.ResourceData, meta interf ruleCodeActionParams.Values = append(ruleCodeActionParams.Values, helper.String(values)) } } - codeAction.Parameters = append(codeAction.Parameters, &ruleCodeActionParams) + codeAction2.Parameters = append(codeAction2.Parameters, &ruleCodeActionParams) } } - action.CodeAction = &codeAction + action.CodeAction = &codeAction2 } subRule.Actions = append(subRule.Actions, &action) } @@ -1493,13 +1493,9 @@ func resourceTencentCloudTeoRuleEngineDelete(d *schema.ResourceData, meta interf response = teo.NewDeleteRulesResponse() ) - if v, ok := d.GetOk("zone_id"); ok { - zoneId = v.(string) - } + request.ZoneId = helper.String(zoneId) - request.ZoneId = &zoneId - - request.RuleIds = []*string{&ruleId} + request.RuleIds = []*string{helper.String(ruleId)} err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseTeoClient().DeleteRulesWithContext(ctx, request) @@ -1512,7 +1508,7 @@ func resourceTencentCloudTeoRuleEngineDelete(d *schema.ResourceData, meta interf return nil }) if err != nil { - log.Printf("[CRITAL]%s create teo rule engine failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s delete teo rule engine failed, reason:%+v", logId, err) return err } diff --git a/tencentcloud/services/teo/resource_tc_teo_rule_engine_test.go b/tencentcloud/services/teo/resource_tc_teo_rule_engine_test.go index 89622285ac..f64108ccba 100644 --- a/tencentcloud/services/teo/resource_tc_teo_rule_engine_test.go +++ b/tencentcloud/services/teo/resource_tc_teo_rule_engine_test.go @@ -80,6 +80,26 @@ func TestAccTencentCloudTeoRuleEngine_basic(t *testing.T) { resource.TestCheckResourceAttr("tencentcloud_teo_rule_engine.basic", "tags.#", "2"), ), }, + { + Config: testAccTeoRuleEngineActionUp, + Check: resource.ComposeTestCheckFunc( + testAccCheckRuleEngineExists("tencentcloud_teo_rule_engine.basic"), + resource.TestCheckResourceAttrSet("tencentcloud_teo_rule_engine.basic", "zone_id"), + resource.TestCheckResourceAttr("tencentcloud_teo_rule_engine.basic", "rule_name", "rule-up"), + resource.TestCheckResourceAttr("tencentcloud_teo_rule_engine.basic", "status", "enable"), + resource.TestCheckResourceAttr("tencentcloud_teo_rule_engine.basic", "rules.#", "1"), + resource.TestCheckResourceAttr("tencentcloud_teo_rule_engine.basic", "rules.0.or.#", "1"), + resource.TestCheckResourceAttr("tencentcloud_teo_rule_engine.basic", "rules.0.sub_rules.#", "1"), + resource.TestCheckResourceAttr("tencentcloud_teo_rule_engine.basic", "rules.0.sub_rules.0.tags.#", "1"), + resource.TestCheckResourceAttr("tencentcloud_teo_rule_engine.basic", "rules.0.sub_rules.0.rules.0.or.#", "1"), + resource.TestCheckResourceAttr("tencentcloud_teo_rule_engine.basic", "rules.0.sub_rules.0.rules.0.or.0.and.#", "1"), + resource.TestCheckResourceAttr("tencentcloud_teo_rule_engine.basic", "rules.0.sub_rules.0.rules.0.or.0.and.0.operator", "equal"), + resource.TestCheckResourceAttr("tencentcloud_teo_rule_engine.basic", "rules.0.sub_rules.0.rules.0.or.0.and.0.target", "filename"), + resource.TestCheckResourceAttr("tencentcloud_teo_rule_engine.basic", "rules.0.sub_rules.0.rules.0.or.0.and.0.ignore_case", "false"), + resource.TestCheckResourceAttr("tencentcloud_teo_rule_engine.basic", "rules.0.sub_rules.0.rules.0.or.0.and.0.values.#", "1"), + resource.TestCheckResourceAttr("tencentcloud_teo_rule_engine.basic", "tags.#", "2"), + ), + }, }, }) } @@ -139,12 +159,18 @@ func testAccCheckRuleEngineExists(r string) resource.TestCheckFunc { } } -const testAccTeoRuleEngine = testAccTeoZone + ` +const testAccZoneVar = ` +variable "zone_id" { + default = "zone-2qtuhspy7cr6" +} +` + +const testAccTeoRuleEngine = testAccZoneVar + ` resource "tencentcloud_teo_rule_engine" "basic" { rule_name = "rule-1" status = "enable" - zone_id = tencentcloud_teo_zone.basic.id + zone_id = var.zone_id rules { actions { @@ -197,12 +223,12 @@ resource "tencentcloud_teo_rule_engine" "basic" { } ` -const testAccTeoRuleEngineUp = testAccTeoZone + ` +const testAccTeoRuleEngineUp = testAccZoneVar + ` resource "tencentcloud_teo_rule_engine" "basic" { rule_name = "rule-up" status = "enable" - zone_id = tencentcloud_teo_zone.basic.id + zone_id = var.zone_id tags = ["keep-test-np1", "keep-test-np2"] @@ -256,3 +282,48 @@ resource "tencentcloud_teo_rule_engine" "basic" { } } ` + +const testAccTeoRuleEngineActionUp = testAccZoneVar + ` + +resource "tencentcloud_teo_rule_engine" "basic" { + rule_name = "rule-up" + status = "enable" + zone_id = var.zone_id + + tags = ["keep-test-np1", "keep-test-np2"] + + rules { + or { + and { + operator = "equal" + target = "extension" + values = [ + "11", + ] + } + } + sub_rules { + tags = ["test-tag",] + rules { + or { + and { + operator = "equal" + target = "filename" + ignore_case = false + values = ["test.txt"] + } + } + actions { + normal_action { + action = "HostHeader" + parameters { + name = "ServerName" + values = ["terraform-test.com"] + } + } + } + } + } + } + } +` diff --git a/tencentcloud/services/teo/service_tencentcloud_teo.go b/tencentcloud/services/teo/service_tencentcloud_teo.go index 13dbe0adc6..ab3e68198b 100644 --- a/tencentcloud/services/teo/service_tencentcloud_teo.go +++ b/tencentcloud/services/teo/service_tencentcloud_teo.go @@ -954,10 +954,10 @@ func (me *TeoService) DescribeTeoRuleEngineById(ctx context.Context, zoneId stri logId := tccommon.GetLogId(ctx) request := teo.NewDescribeRulesRequest() - request.ZoneId = &zoneId + request.ZoneId = helper.String(zoneId) filter := &teo.Filter{ Name: helper.String("rule-id"), - Values: []*string{&ruleId}, + Values: []*string{helper.String(ruleId)}, } request.Filters = append(request.Filters, filter) diff --git a/tencentcloud/services/trocket/resource_tc_tdmq_rocketmq_vip_instance_test.go b/tencentcloud/services/trocket/resource_tc_tdmq_rocketmq_vip_instance_test.go index 3ada3467e0..5455445039 100644 --- a/tencentcloud/services/trocket/resource_tc_tdmq_rocketmq_vip_instance_test.go +++ b/tencentcloud/services/trocket/resource_tc_tdmq_rocketmq_vip_instance_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "testing" + "time" tcacctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" @@ -14,8 +15,8 @@ import ( sdkErrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" ) -// go test -i; go test -test.run TestAccTencentCloudNeedFixTdmqRocketmqVipInstanceResource_basic -v -func TestAccTencentCloudNeedFixTdmqRocketmqVipInstanceResource_basic(t *testing.T) { +// go test -i; go test -test.run TestAccTencentCloudTdmqRocketmqVipInstanceResource_basic -v -timeout=0 +func TestAccTencentCloudTdmqRocketmqVipInstanceResource_basic(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ PreCheck: func() { @@ -33,6 +34,7 @@ func TestAccTencentCloudNeedFixTdmqRocketmqVipInstanceResource_basic(t *testing. resource.TestCheckResourceAttrSet("tencentcloud_tdmq_rocketmq_vip_instance.example", "spec"), resource.TestCheckResourceAttrSet("tencentcloud_tdmq_rocketmq_vip_instance.example", "node_count"), resource.TestCheckResourceAttrSet("tencentcloud_tdmq_rocketmq_vip_instance.example", "storage_size"), + tcacctest.AccStepTimeSleepDuration(1*time.Minute), ), }, { @@ -44,6 +46,7 @@ func TestAccTencentCloudNeedFixTdmqRocketmqVipInstanceResource_basic(t *testing. resource.TestCheckResourceAttrSet("tencentcloud_tdmq_rocketmq_vip_instance.example", "spec"), resource.TestCheckResourceAttrSet("tencentcloud_tdmq_rocketmq_vip_instance.example", "node_count"), resource.TestCheckResourceAttrSet("tencentcloud_tdmq_rocketmq_vip_instance.example", "storage_size"), + tcacctest.AccStepTimeSleepDuration(1*time.Minute), ), }, }, @@ -100,7 +103,7 @@ func testAccCheckTdmqRocketmqVipInstanceExists(r string) resource.TestCheckFunc } } -const testAccTdmqRocketmqVipInstance = tcacctest.DefaultVpcSubnets + ` +const testAccTdmqRocketmqVipInstance = ` data "tencentcloud_availability_zones" "zones" {} # create vpc diff --git a/website/docs/r/clb_instance.html.markdown b/website/docs/r/clb_instance.html.markdown index ae62a8d54b..a19dec78e9 100644 --- a/website/docs/r/clb_instance.html.markdown +++ b/website/docs/r/clb_instance.html.markdown @@ -48,6 +48,22 @@ resource "tencentcloud_clb_instance" "internal_clb" { ### OPEN CLB +```hcl +resource "tencentcloud_clb_instance" "open_clb" { + network_type = "OPEN" + clb_name = "myclb" + project_id = 0 + vpc_id = "vpc-da7ffa61" + security_groups = ["sg-o0ek7r93"] + + tags = { + test = "tf" + } +} +``` + +### SUPPORT CORS + ```hcl resource "tencentcloud_clb_instance" "open_clb" { network_type = "OPEN" @@ -298,8 +314,10 @@ The `snat_ips` object supports the following: In addition to all arguments above, the following attributes are exported: * `id` - ID of the resource. +* `address_ipv6` - The IPv6 address of the load balancing instance. * `clb_vips` - The virtual service address table of the CLB. * `domain` - Domain name of the CLB instance. +* `ipv6_mode` - This field is meaningful when the IP address version is ipv6, `IPv6Nat64` | `IPv6FullChain`. ## Import diff --git a/website/docs/r/cvm_renew_instance.html.markdown b/website/docs/r/cvm_renew_instance.html.markdown index f9f5107600..779cb4c1fd 100644 --- a/website/docs/r/cvm_renew_instance.html.markdown +++ b/website/docs/r/cvm_renew_instance.html.markdown @@ -73,21 +73,14 @@ resource "tencentcloud_cvm_renew_instance" "example" { The following arguments are supported: -* `instance_id` - (Required, String, ForceNew) Instance ID. +* `instance_id` - (Required, String, ForceNew) Instance ID. To obtain the instance IDs, you can call DescribeInstances and look for InstanceId in the response. * `instance_charge_prepaid` - (Optional, List, ForceNew) Prepaid mode, that is, yearly and monthly subscription related parameter settings. Through this parameter, you can specify the renewal duration of the Subscription instance, whether to set automatic renewal, and other attributes. For yearly and monthly subscription instances, this parameter is required. -* `renew_portable_data_disk` - (Optional, Bool, ForceNew) Whether to renew the elastic data disk. Valid values: -- `TRUE`: Indicates to renew the subscription instance and renew the attached elastic data disk at the same time -- `FALSE`: Indicates that the subscription instance will be renewed and the elastic data disk attached to it will not be renewed -Default value: TRUE. +* `renew_portable_data_disk` - (Optional, Bool, ForceNew) Whether to renew the elastic data disk. Valid values:
  • TRUE: Indicates to renew the subscription instance and renew the attached elastic data disk at the same time
  • FALSE: Indicates that the subscription instance will be renewed and the elastic data disk attached to it will not be renewed

    Default value: TRUE. The `instance_charge_prepaid` object supports the following: * `period` - (Required, Int) Subscription period; unit: month; valid values: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 24, 36, 48, 60. Note: This field may return null, indicating that no valid value is found. -* `renew_flag` - (Optional, String) Auto renewal flag. Valid values: -- `NOTIFY_AND_AUTO_RENEW`: notify upon expiration and renew automatically; -- `NOTIFY_AND_MANUAL_RENEW`: notify upon expiration but do not renew automatically; -- `DISABLE_NOTIFY_AND_MANUAL_RENEW`: neither notify upon expiration nor renew automatically; -Default value: NOTIFY_AND_MANUAL_RENEW. If this parameter is specified as NOTIFY_AND_AUTO_RENEW, the instance will be automatically renewed on a monthly basis if the account balance is sufficient. Note: This field may return null, indicating that no valid value is found. +* `renew_flag` - (Optional, String) Auto renewal flag. Valid values:
  • NOTIFY_AND_AUTO_RENEW: notify upon expiration and renew automatically
  • NOTIFY_AND_MANUAL_RENEW: notify upon expiration but do not renew automatically
  • DISABLE_NOTIFY_AND_MANUAL_RENEW: neither notify upon expiration nor renew automatically

    Default value: NOTIFY_AND_MANUAL_RENEW. If this parameter is specified as NOTIFY_AND_AUTO_RENEW, the instance will be automatically renewed on a monthly basis if the account balance is sufficient. Note: This field may return null, indicating that no valid value is found. ## Attributes Reference diff --git a/website/docs/r/cvm_security_group_attachment.html.markdown b/website/docs/r/cvm_security_group_attachment.html.markdown index 1b411ac3d4..97d59c39f3 100644 --- a/website/docs/r/cvm_security_group_attachment.html.markdown +++ b/website/docs/r/cvm_security_group_attachment.html.markdown @@ -75,8 +75,8 @@ resource "tencentcloud_cvm_security_group_attachment" "example" { The following arguments are supported: -* `instance_id` - (Required, String, ForceNew) Instance id. -* `security_group_id` - (Required, String, ForceNew) Security group id. +* `instance_id` - (Required, String, ForceNew) Instance ID. To obtain the instance IDs, you can call DescribeInstances and look for InstanceId in the response. +* `security_group_id` - (Required, String, ForceNew) ID of the security group to be associated, such as sg-efil73jd. Only one security group can be associated. ## Attributes Reference diff --git a/website/docs/r/postgresql_instance.html.markdown b/website/docs/r/postgresql_instance.html.markdown index a9560336b6..ac51ba09a2 100644 --- a/website/docs/r/postgresql_instance.html.markdown +++ b/website/docs/r/postgresql_instance.html.markdown @@ -12,41 +12,44 @@ description: |- Use this resource to create postgresql instance. -> **Note:** To update the charge type, please update the `charge_type` and specify the `period` for the charging period. It only supports updating from `POSTPAID_BY_HOUR` to `PREPAID`, and the `period` field only valid in that upgrading case. +-> **Note:** If no values are set for the two parameters: `db_major_version` and `engine_version`, then `engine_version` is set to `10.4` by default. Suggest using parameter `db_major_version` to create an instance ## Example Usage ```hcl variable "availability_zone" { - default = "ap-guangzhou-1" + default = "ap-guangzhou-3" } # create vpc resource "tencentcloud_vpc" "vpc" { - name = "guagua_vpc_instance_test" + name = "vpc" cidr_block = "10.0.0.0/16" } # create vpc subnet resource "tencentcloud_subnet" "subnet" { availability_zone = var.availability_zone - name = "guagua_vpc_subnet_test" + name = "subnet" vpc_id = tencentcloud_vpc.vpc.id cidr_block = "10.0.20.0/28" is_multicast = false } # create postgresql -resource "tencentcloud_postgresql_instance" "foo" { +resource "tencentcloud_postgresql_instance" "example" { name = "example" availability_zone = var.availability_zone charge_type = "POSTPAID_BY_HOUR" vpc_id = tencentcloud_vpc.vpc.id subnet_id = tencentcloud_subnet.subnet.id - engine_version = "10.4" + db_major_version = "10" + engine_version = "10.23" root_user = "root123" root_password = "Root123$" charset = "UTF8" project_id = 0 + cpu = 1 memory = 2 storage = 10 @@ -69,27 +72,27 @@ variable "standby_availability_zone" { # create vpc resource "tencentcloud_vpc" "vpc" { - name = "guagua_vpc_instance_test" + name = "vpc" cidr_block = "10.0.0.0/16" } # create vpc subnet resource "tencentcloud_subnet" "subnet" { availability_zone = var.availability_zone - name = "guagua_vpc_subnet_test" + name = "subnet" vpc_id = tencentcloud_vpc.vpc.id cidr_block = "10.0.20.0/28" is_multicast = false } # create postgresql -resource "tencentcloud_postgresql_instance" "foo" { +resource "tencentcloud_postgresql_instance" "example" { name = "example" availability_zone = var.availability_zone charge_type = "POSTPAID_BY_HOUR" vpc_id = tencentcloud_vpc.vpc.id subnet_id = tencentcloud_subnet.subnet.id - engine_version = "10.4" + db_major_version = "10" root_user = "root123" root_password = "Root123$" charset = "UTF8" @@ -102,6 +105,7 @@ resource "tencentcloud_postgresql_instance" "foo" { role = "Primary" zone = var.availability_zone } + db_node_set { zone = var.standby_availability_zone } @@ -115,19 +119,23 @@ resource "tencentcloud_postgresql_instance" "foo" { ### create pgsql with kms key ```hcl -resource "tencentcloud_postgresql_instance" "pg" { +variable "availability_zone" { + default = "ap-guangzhou-6" +} + +resource "tencentcloud_postgresql_instance" "example" { name = "tf_postsql_instance" - availability_zone = "ap-guangzhou-6" + availability_zone = var.availability_zone charge_type = "POSTPAID_BY_HOUR" vpc_id = "vpc-86v957zb" subnet_id = "subnet-enm92y0m" + db_major_version = "11" engine_version = "11.12" - # db_major_vesion = "11" db_kernel_version = "v11.12_r1.3" need_support_tde = 1 kms_key_id = "788c606a-c7b7-11ec-82d1-5254001e5c4e" kms_region = "ap-guangzhou" - root_password = "xxxxxxxxxx" + root_password = "Root123$" charset = "LATIN1" project_id = 0 memory = 4 @@ -149,20 +157,25 @@ resource "tencentcloud_postgresql_instance" "pg" { ### upgrade kernel version ```hcl -resource "tencentcloud_postgresql_instance" "test" { - name = "tf_postsql_instance_update" - availability_zone = data.tencentcloud_availability_zones_by_product.zone.zones[5].name +variable "availability_zone" { + default = "ap-guangzhou-6" +} + +resource "tencentcloud_postgresql_instance" "example" { + name = "tf_postsql_instance_update_kernel" + availability_zone = var.availability_zone charge_type = "POSTPAID_BY_HOUR" - vpc_id = local.vpc_id - subnet_id = local.subnet_id + vpc_id = "vpc-86v957zb" + subnet_id = "subnet-enm92y0m" engine_version = "13.3" - root_password = "*" + root_password = "Root123$" charset = "LATIN1" project_id = 0 public_access_switch = false - security_groups = [local.sg_id] + security_groups = ["sg-cm7fbbf3"] memory = 4 storage = 250 + backup_plan { min_backup_start_time = "01:10:11" max_backup_start_time = "02:10:11" @@ -173,7 +186,7 @@ resource "tencentcloud_postgresql_instance" "test" { db_kernel_version = "v13.3_r1.4" # eg:from v13.3_r1.1 to v13.3_r1.4 tags = { - tf = "teest" + tf = "test" } } ``` @@ -196,10 +209,10 @@ The following arguments are supported: * `charset` - (Optional, String, ForceNew) Charset of the root account. Valid values are `UTF8`,`LATIN1`. * `cpu` - (Optional, Int) Number of CPU cores. Allowed value must be equal `cpu` that data source `tencentcloud_postgresql_specinfos` provides. * `db_kernel_version` - (Optional, String) PostgreSQL kernel version number. If it is specified, an instance running kernel DBKernelVersion will be created. It supports updating the minor kernel version immediately. -* `db_major_version` - (Optional, String) PostgreSQL major version number. Valid values: 10, 11, 12, 13. If it is specified, an instance running the latest kernel of PostgreSQL DBMajorVersion will be created. -* `db_major_vesion` - (Optional, String, **Deprecated**) `db_major_vesion` will be deprecated, use `db_major_version` instead. PostgreSQL major version number. Valid values: 10, 11, 12, 13. If it is specified, an instance running the latest kernel of PostgreSQL DBMajorVersion will be created. +* `db_major_version` - (Optional, String) PostgreSQL major version number. Valid values: 10, 11, 12, 13, 14, 15, 16. If it is specified, an instance running the latest kernel of PostgreSQL DBMajorVersion will be created. +* `db_major_vesion` - (Optional, String, **Deprecated**) `db_major_vesion` will be deprecated, use `db_major_version` instead. PostgreSQL major version number. Valid values: 10, 11, 12, 13, 14, 15, 16. If it is specified, an instance running the latest kernel of PostgreSQL DBMajorVersion will be created. * `db_node_set` - (Optional, Set) Specify instance node info for disaster migration. -* `engine_version` - (Optional, String, ForceNew) Version of the postgresql database engine. Valid values: `10.4`, `11.8`, `12.4`. +* `engine_version` - (Optional, String) Version of the postgresql database engine. Valid values: `10.4`, `10.17`, `10.23`, `11.8`, `11.12`, `11.22`, `12.4`, `12.7`, `12.18`, `13.3`, `14.2`, `14.11`, `15.1`, `16.0`. * `kms_key_id` - (Optional, String) KeyId of the custom key. * `kms_region` - (Optional, String) Region of the custom key. * `max_standby_archive_delay` - (Optional, Int) max_standby_archive_delay applies when WAL data is being read from WAL archive (and is therefore not current). Units are milliseconds if not specified. @@ -243,6 +256,6 @@ In addition to all arguments above, the following attributes are exported: postgresql instance can be imported using the id, e.g. ``` -$ terraform import tencentcloud_postgresql_instance.foo postgres-cda1iex1 +$ terraform import tencentcloud_postgresql_instance.example postgres-cda1iex1 ``` diff --git a/website/docs/r/teo_rule_engine.html.markdown b/website/docs/r/teo_rule_engine.html.markdown index be901fc523..1441618a18 100644 --- a/website/docs/r/teo_rule_engine.html.markdown +++ b/website/docs/r/teo_rule_engine.html.markdown @@ -289,14 +289,14 @@ The `rewrite_action` object of `actions` supports the following: The `rules` object of `sub_rules` supports the following: -* `actions` - (Required, List) The feature to be executed. * `or` - (Required, List) The condition that determines if a feature should run. Note: If any condition in the array is met, the feature will run. +* `actions` - (Optional, List) The feature to be executed. The `rules` object supports the following: -* `actions` - (Required, List) Feature to be executed. * `or` - (Required, List) OR Conditions list of the rule. Rule would be triggered if any of the condition is true. +* `actions` - (Optional, List) Feature to be executed. * `sub_rules` - (Optional, List) The nested rule. The `sub_rules` object of `rules` supports the following: