diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_chc_denied_actions.go b/tencentcloud/services/cvm/data_source_tc_cvm_chc_denied_actions.go index a50dd1b8c1..2e7c1c2b16 100644 --- a/tencentcloud/services/cvm/data_source_tc_cvm_chc_denied_actions.go +++ b/tencentcloud/services/cvm/data_source_tc_cvm_chc_denied_actions.go @@ -1,14 +1,14 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( "context" - 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,17 +17,17 @@ func DataSourceTencentCloudCvmChcDeniedActions() *schema.Resource { Read: dataSourceTencentCloudCvmChcDeniedActionsRead, Schema: map[string]*schema.Schema{ "chc_ids": { - Required: true, - Type: schema.TypeSet, + Type: schema.TypeSet, + Required: true, + Description: "CHC host IDs.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Description: "CHC host IDs.", }, "chc_host_denied_action_set": { - Computed: true, Type: schema.TypeList, + Computed: true, Description: "Actions not allowed for the CHC instance.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -42,12 +42,12 @@ func DataSourceTencentCloudCvmChcDeniedActions() *schema.Resource { Description: "CHC instance status.", }, "deny_actions": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Computed: true, + Description: "Actions not allowed for the current CHC instance.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Computed: true, - Description: "Actions not allowed for the current CHC instance.", }, }, }, @@ -66,64 +66,70 @@ func dataSourceTencentCloudCvmChcDeniedActionsRead(d *schema.ResourceData, meta defer tccommon.LogElapsed("data_source.tencentcloud_cvm_chc_denied_actions.read")() defer tccommon.InconsistentCheck(d, meta)() - logId := tccommon.GetLogId(tccommon.ContextNil) + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} paramMap := make(map[string]interface{}) if v, ok := d.GetOk("chc_ids"); ok { + chcIdsList := []*string{} chcIdsSet := v.(*schema.Set).List() - paramMap["chc_ids"] = helper.InterfacesStrings(chcIdsSet) + for i := range chcIdsSet { + chcIds := chcIdsSet[i].(string) + chcIdsList = append(chcIdsList, helper.String(chcIds)) + } + paramMap["ChcIds"] = chcIdsList } - service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - - var chcHostDeniedActionSet []*cvm.ChcHostDeniedActions - + var respData []*cvm.ChcHostDeniedActions err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { result, e := service.DescribeCvmChcDeniedActionsByFilter(ctx, paramMap) if e != nil { return tccommon.RetryError(e) } - chcHostDeniedActionSet = result + respData = result return nil }) if err != nil { return err } - ids := make([]string, 0, len(chcHostDeniedActionSet)) - tmpList := make([]map[string]interface{}, 0, len(chcHostDeniedActionSet)) - - if len(chcHostDeniedActionSet) > 0 { - for _, chcHostDeniedActions := range chcHostDeniedActionSet { - chcHostDeniedActionsMap := map[string]interface{}{} + chcIds := make([]string, 0, len(respData)) + chcHostDeniedActionSetList := make([]map[string]interface{}, 0, len(respData)) + if respData != nil { + for _, chcHostDeniedActionSet := range respData { + chcHostDeniedActionSetMap := map[string]interface{}{} - if chcHostDeniedActions.ChcId != nil { - chcHostDeniedActionsMap["chc_id"] = chcHostDeniedActions.ChcId + var chcId string + if chcHostDeniedActionSet.ChcId != nil { + chcHostDeniedActionSetMap["chc_id"] = chcHostDeniedActionSet.ChcId + chcId = *chcHostDeniedActionSet.ChcId } - if chcHostDeniedActions.State != nil { - chcHostDeniedActionsMap["state"] = chcHostDeniedActions.State + if chcHostDeniedActionSet.State != nil { + chcHostDeniedActionSetMap["state"] = chcHostDeniedActionSet.State } - if chcHostDeniedActions.DenyActions != nil { - chcHostDeniedActionsMap["deny_actions"] = chcHostDeniedActions.DenyActions + if chcHostDeniedActionSet.DenyActions != nil { + chcHostDeniedActionSetMap["deny_actions"] = chcHostDeniedActionSet.DenyActions } - ids = append(ids, *chcHostDeniedActions.ChcId) - tmpList = append(tmpList, chcHostDeniedActionsMap) + chcIds = append(chcIds, chcId) + chcHostDeniedActionSetList = append(chcHostDeniedActionSetList, chcHostDeniedActionSetMap) } - _ = d.Set("chc_host_denied_action_set", tmpList) + _ = d.Set("chc_host_denied_action_set", chcHostDeniedActionSetList) } - d.SetId(helper.DataResourceIdsHash(ids)) + d.SetId(helper.DataResourceIdsHash(chcIds)) + output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if e := tccommon.WriteToFile(output.(string), tmpList); e != nil { + if e := tccommon.WriteToFile(output.(string), chcHostDeniedActionSetList); e != nil { return e } } + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_chc_denied_actions_extension.go b/tencentcloud/services/cvm/data_source_tc_cvm_chc_denied_actions_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_cvm_chc_denied_actions_extension.go @@ -0,0 +1 @@ +package cvm diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_chc_hosts.go b/tencentcloud/services/cvm/data_source_tc_cvm_chc_hosts.go index 24698a492f..93a2cbb467 100644 --- a/tencentcloud/services/cvm/data_source_tc_cvm_chc_hosts.go +++ b/tencentcloud/services/cvm/data_source_tc_cvm_chc_hosts.go @@ -1,14 +1,14 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( "context" - 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,23 +17,18 @@ func DataSourceTencentCloudCvmChcHosts() *schema.Resource { Read: dataSourceTencentCloudCvmChcHostsRead, Schema: map[string]*schema.Schema{ "chc_ids": { - Optional: true, - Type: schema.TypeSet, + Type: schema.TypeSet, + Optional: true, + Description: "CHC host ID. Up to 100 instances per request is allowed. ChcIds and Filters cannot be specified at the same time.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Description: "CHC host ID. Up to 100 instances per request is allowed. ChcIds and Filters cannot be specified at the same time.", }, "filters": { - Optional: true, - Type: schema.TypeList, - Description: "- `zone` Filter by the availability zone, such as ap-guangzhou-1. Valid values: See [Regions and Availability Zones](https://www.tencentcloud.com/document/product/213/6091?from_cn_redirect=1).\n" + - "- `instance-name` Filter by the instance name.\n" + - "- `instance-state` Filter by the instance status. For status details, see [InstanceStatus](https://www.tencentcloud.com/document/api/213/15753?from_cn_redirect=1#InstanceStatus).\n" + - "- `device-type` Filter by the device type.\n" + - "- `vpc-id` Filter by the unique VPC ID.\n" + - "- `subnet-id` Filter by the unique VPC subnet ID.", + Type: schema.TypeList, + Optional: true, + Description: "- `zone` Filter by the availability zone, such as ap-guangzhou-1. Valid values: See [Regions and Availability Zones](https://www.tencentcloud.com/document/product/213/6091?from_cn_redirect=1).\n- `instance-name` Filter by the instance name.\n- `instance-state` Filter by the instance status. For status details, see [InstanceStatus](https://www.tencentcloud.com/document/api/213/15753?from_cn_redirect=1#InstanceStatus).\n- `device-type` Filter by the device type.\n- `vpc-id` Filter by the unique VPC ID.\n- `subnet-id` Filter by the unique VPC subnet ID.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { @@ -42,20 +37,20 @@ func DataSourceTencentCloudCvmChcHosts() *schema.Resource { Description: "Filter name.", }, "values": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Required: true, + Description: "Filter values.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Required: true, - Description: "Filter values.", }, }, }, }, "chc_host_set": { - Computed: true, Type: schema.TypeList, + Computed: true, Description: "List of returned instances.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -101,12 +96,12 @@ func DataSourceTencentCloudCvmChcHosts() *schema.Resource { Description: "ID of the project to which the instance belongs. This parameter can be obtained from the projectId returned by DescribeProject. If this is left empty, the default project is used.", }, "host_ids": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Computed: true, + Description: "ID list of CDHs from which the instance can be created. If you have purchased CDHs and specify this parameter, the instances you purchase will be randomly deployed on the CDHs.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Computed: true, - Description: "ID list of CDHs from which the instance can be created. If you have purchased CDHs and specify this parameter, the instances you purchase will be randomly deployed on the CDHs.", }, "host_ips": { Type: schema.TypeSet, @@ -145,12 +140,12 @@ func DataSourceTencentCloudCvmChcHosts() *schema.Resource { Description: "Whether to use a CVM instance as a public gateway. The public gateway is only available when the instance has a public IP and resides in a VPC. Valid values:<br><li>TRUE: yes;<br><li>FALSE: no<br><br>Default: FALSE.", }, "private_ip_addresses": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Computed: true, + Description: "Array of VPC subnet IPs. You can use this parameter when creating instances or modifying VPC attributes of instances. Currently you can specify multiple IPs in one subnet only when creating multiple instances at the same time.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Computed: true, - Description: "Array of VPC subnet IPs. You can use this parameter when creating instances or modifying VPC attributes of instances. Currently you can specify multiple IPs in one subnet only when creating multiple instances at the same time.", }, "ipv6_address_count": { Type: schema.TypeInt, @@ -166,12 +161,12 @@ func DataSourceTencentCloudCvmChcHosts() *schema.Resource { Description: "Out-of-band network IPNote: This field may return null, indicating that no valid values can be obtained.", }, "bmc_security_group_ids": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Computed: true, + Description: "Out-of-band network security group IDNote: This field may return null, indicating that no valid values can be obtained.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Computed: true, - Description: "Out-of-band network security group IDNote: This field may return null, indicating that no valid values can be obtained.", }, "deploy_virtual_private_cloud": { Type: schema.TypeList, @@ -195,12 +190,12 @@ func DataSourceTencentCloudCvmChcHosts() *schema.Resource { Description: "Whether to use a CVM instance as a public gateway. The public gateway is only available when the instance has a public IP and resides in a VPC. Valid values:<br><li>TRUE: yes;<br><li>FALSE: no<br><br>Default: FALSE.", }, "private_ip_addresses": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Computed: true, + Description: "Array of VPC subnet IPs. You can use this parameter when creating instances or modifying VPC attributes of instances. Currently you can specify multiple IPs in one subnet only when creating multiple instances at the same time.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Computed: true, - Description: "Array of VPC subnet IPs. You can use this parameter when creating instances or modifying VPC attributes of instances. Currently you can specify multiple IPs in one subnet only when creating multiple instances at the same time.", }, "ipv6_address_count": { Type: schema.TypeInt, @@ -216,12 +211,12 @@ func DataSourceTencentCloudCvmChcHosts() *schema.Resource { Description: "Deployment network IPNote: This field may return null, indicating that no valid values can be obtained.", }, "deploy_security_group_ids": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Computed: true, + Description: "Deployment network security group IDNote: This field may return null, indicating that no valid values can be obtained.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Computed: true, - Description: "Deployment network security group IDNote: This field may return null, indicating that no valid values can be obtained.", }, "cvm_instance_id": { Type: schema.TypeString, @@ -285,92 +280,97 @@ func dataSourceTencentCloudCvmChcHostsRead(d *schema.ResourceData, meta interfac defer tccommon.LogElapsed("data_source.tencentcloud_cvm_chc_hosts.read")() defer tccommon.InconsistentCheck(d, meta)() - logId := tccommon.GetLogId(tccommon.ContextNil) + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} paramMap := make(map[string]interface{}) if v, ok := d.GetOk("chc_ids"); ok { + chcIdsList := []*string{} chcIdsSet := v.(*schema.Set).List() - paramMap["ChcIds"] = helper.InterfacesStringsPoint(chcIdsSet) + for i := range chcIdsSet { + chcIds := chcIdsSet[i].(string) + chcIdsList = append(chcIdsList, helper.String(chcIds)) + } + paramMap["ChcIds"] = chcIdsList } 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{} - filterMap := item.(map[string]interface{}) - - if v, ok := filterMap["name"]; ok { + if v, ok := filtersMap["name"]; ok { filter.Name = helper.String(v.(string)) } - if v, ok := filterMap["values"]; ok { + if v, ok := filtersMap["values"]; ok { valuesSet := v.(*schema.Set).List() - filter.Values = helper.InterfacesStringsPoint(valuesSet) + for i := range valuesSet { + values := valuesSet[i].(string) + filter.Values = append(filter.Values, helper.String(values)) + } } tmpSet = append(tmpSet, &filter) } - paramMap["filters"] = tmpSet + paramMap["Filters"] = tmpSet } - service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - - var chcHostSet []*cvm.ChcHost - + var respData []*cvm.ChcHost err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { result, e := service.DescribeCvmChcHostsByFilter(ctx, paramMap) if e != nil { return tccommon.RetryError(e) } - chcHostSet = result + respData = result return nil }) if err != nil { return err } - ids := make([]string, 0, len(chcHostSet)) - tmpList := make([]map[string]interface{}, 0, len(chcHostSet)) + var chcIds []string + chcHostSetList := make([]map[string]interface{}, 0, len(respData)) + if respData != nil { + for _, chcHostSet := range respData { + chcHostSetMap := map[string]interface{}{} - if chcHostSet != nil { - for _, chcHost := range chcHostSet { - chcHostMap := map[string]interface{}{} - - if chcHost.ChcId != nil { - chcHostMap["chc_id"] = chcHost.ChcId + var chcId string + if chcHostSet.ChcId != nil { + chcHostSetMap["chc_id"] = chcHostSet.ChcId + chcId = *chcHostSet.ChcId } - if chcHost.InstanceName != nil { - chcHostMap["instance_name"] = chcHost.InstanceName + if chcHostSet.InstanceName != nil { + chcHostSetMap["instance_name"] = chcHostSet.InstanceName } - if chcHost.SerialNumber != nil { - chcHostMap["serial_number"] = chcHost.SerialNumber + if chcHostSet.SerialNumber != nil { + chcHostSetMap["serial_number"] = chcHostSet.SerialNumber } - if chcHost.InstanceState != nil { - chcHostMap["instance_state"] = chcHost.InstanceState + if chcHostSet.InstanceState != nil { + chcHostSetMap["instance_state"] = chcHostSet.InstanceState } - if chcHost.DeviceType != nil { - chcHostMap["device_type"] = chcHost.DeviceType + if chcHostSet.DeviceType != nil { + chcHostSetMap["device_type"] = chcHostSet.DeviceType } - if chcHost.Placement != nil { - placementMap := map[string]interface{}{} + placementMap := map[string]interface{}{} - if chcHost.Placement.Zone != nil { - placementMap["zone"] = chcHost.Placement.Zone + if chcHostSet.Placement != nil { + if chcHostSet.Placement.Zone != nil { + placementMap["zone"] = chcHostSet.Placement.Zone } - if chcHost.Placement.ProjectId != nil { - placementMap["project_id"] = chcHost.Placement.ProjectId + if chcHostSet.Placement.ProjectId != nil { + placementMap["project_id"] = chcHostSet.Placement.ProjectId } - if chcHost.Placement.HostIds != nil { - placementMap["host_ids"] = chcHost.Placement.HostIds + if chcHostSet.Placement.HostIds != nil { + placementMap["host_ids"] = chcHostSet.Placement.HostIds } // It has been deprecated from version 1.81.108 @@ -378,130 +378,132 @@ func dataSourceTencentCloudCvmChcHostsRead(d *schema.ResourceData, meta interfac // placementMap["host_ips"] = chcHost.Placement.HostIps //} - if chcHost.Placement.HostId != nil { - placementMap["host_id"] = chcHost.Placement.HostId + if chcHostSet.Placement.HostId != nil { + placementMap["host_id"] = chcHostSet.Placement.HostId } - chcHostMap["placement"] = []interface{}{placementMap} + chcHostSetMap["placement"] = []interface{}{placementMap} } - if chcHost.BmcVirtualPrivateCloud != nil { - bmcVirtualPrivateCloudMap := map[string]interface{}{} + bmcVirtualPrivateCloudMap := map[string]interface{}{} - if chcHost.BmcVirtualPrivateCloud.VpcId != nil { - bmcVirtualPrivateCloudMap["vpc_id"] = chcHost.BmcVirtualPrivateCloud.VpcId + if chcHostSet.BmcVirtualPrivateCloud != nil { + if chcHostSet.BmcVirtualPrivateCloud.VpcId != nil { + bmcVirtualPrivateCloudMap["vpc_id"] = chcHostSet.BmcVirtualPrivateCloud.VpcId } - if chcHost.BmcVirtualPrivateCloud.SubnetId != nil { - bmcVirtualPrivateCloudMap["subnet_id"] = chcHost.BmcVirtualPrivateCloud.SubnetId + if chcHostSet.BmcVirtualPrivateCloud.SubnetId != nil { + bmcVirtualPrivateCloudMap["subnet_id"] = chcHostSet.BmcVirtualPrivateCloud.SubnetId } - if chcHost.BmcVirtualPrivateCloud.AsVpcGateway != nil { - bmcVirtualPrivateCloudMap["as_vpc_gateway"] = chcHost.BmcVirtualPrivateCloud.AsVpcGateway + if chcHostSet.BmcVirtualPrivateCloud.AsVpcGateway != nil { + bmcVirtualPrivateCloudMap["as_vpc_gateway"] = chcHostSet.BmcVirtualPrivateCloud.AsVpcGateway } - if chcHost.BmcVirtualPrivateCloud.PrivateIpAddresses != nil { - bmcVirtualPrivateCloudMap["private_ip_addresses"] = chcHost.BmcVirtualPrivateCloud.PrivateIpAddresses + if chcHostSet.BmcVirtualPrivateCloud.PrivateIpAddresses != nil { + bmcVirtualPrivateCloudMap["private_ip_addresses"] = chcHostSet.BmcVirtualPrivateCloud.PrivateIpAddresses } - if chcHost.BmcVirtualPrivateCloud.Ipv6AddressCount != nil { - bmcVirtualPrivateCloudMap["ipv6_address_count"] = chcHost.BmcVirtualPrivateCloud.Ipv6AddressCount + if chcHostSet.BmcVirtualPrivateCloud.Ipv6AddressCount != nil { + bmcVirtualPrivateCloudMap["ipv6_address_count"] = chcHostSet.BmcVirtualPrivateCloud.Ipv6AddressCount } - chcHostMap["bmc_virtual_private_cloud"] = []interface{}{bmcVirtualPrivateCloudMap} + chcHostSetMap["bmc_virtual_private_cloud"] = []interface{}{bmcVirtualPrivateCloudMap} } - if chcHost.BmcIp != nil { - chcHostMap["bmc_ip"] = chcHost.BmcIp + if chcHostSet.BmcIp != nil { + chcHostSetMap["bmc_ip"] = chcHostSet.BmcIp } - if chcHost.BmcSecurityGroupIds != nil { - chcHostMap["bmc_security_group_ids"] = chcHost.BmcSecurityGroupIds + if chcHostSet.BmcSecurityGroupIds != nil { + chcHostSetMap["bmc_security_group_ids"] = chcHostSet.BmcSecurityGroupIds } - if chcHost.DeployVirtualPrivateCloud != nil { - deployVirtualPrivateCloudMap := map[string]interface{}{} + deployVirtualPrivateCloudMap := map[string]interface{}{} - if chcHost.DeployVirtualPrivateCloud.VpcId != nil { - deployVirtualPrivateCloudMap["vpc_id"] = chcHost.DeployVirtualPrivateCloud.VpcId + if chcHostSet.DeployVirtualPrivateCloud != nil { + if chcHostSet.DeployVirtualPrivateCloud.VpcId != nil { + deployVirtualPrivateCloudMap["vpc_id"] = chcHostSet.DeployVirtualPrivateCloud.VpcId } - if chcHost.DeployVirtualPrivateCloud.SubnetId != nil { - deployVirtualPrivateCloudMap["subnet_id"] = chcHost.DeployVirtualPrivateCloud.SubnetId + if chcHostSet.DeployVirtualPrivateCloud.SubnetId != nil { + deployVirtualPrivateCloudMap["subnet_id"] = chcHostSet.DeployVirtualPrivateCloud.SubnetId } - if chcHost.DeployVirtualPrivateCloud.AsVpcGateway != nil { - deployVirtualPrivateCloudMap["as_vpc_gateway"] = chcHost.DeployVirtualPrivateCloud.AsVpcGateway + if chcHostSet.DeployVirtualPrivateCloud.AsVpcGateway != nil { + deployVirtualPrivateCloudMap["as_vpc_gateway"] = chcHostSet.DeployVirtualPrivateCloud.AsVpcGateway } - if chcHost.DeployVirtualPrivateCloud.PrivateIpAddresses != nil { - deployVirtualPrivateCloudMap["private_ip_addresses"] = chcHost.DeployVirtualPrivateCloud.PrivateIpAddresses + if chcHostSet.DeployVirtualPrivateCloud.PrivateIpAddresses != nil { + deployVirtualPrivateCloudMap["private_ip_addresses"] = chcHostSet.DeployVirtualPrivateCloud.PrivateIpAddresses } - if chcHost.DeployVirtualPrivateCloud.Ipv6AddressCount != nil { - deployVirtualPrivateCloudMap["ipv6_address_count"] = chcHost.DeployVirtualPrivateCloud.Ipv6AddressCount + if chcHostSet.DeployVirtualPrivateCloud.Ipv6AddressCount != nil { + deployVirtualPrivateCloudMap["ipv6_address_count"] = chcHostSet.DeployVirtualPrivateCloud.Ipv6AddressCount } - chcHostMap["deploy_virtual_private_cloud"] = []interface{}{deployVirtualPrivateCloudMap} + chcHostSetMap["deploy_virtual_private_cloud"] = []interface{}{deployVirtualPrivateCloudMap} } - if chcHost.DeployIp != nil { - chcHostMap["deploy_ip"] = chcHost.DeployIp + if chcHostSet.DeployIp != nil { + chcHostSetMap["deploy_ip"] = chcHostSet.DeployIp } - if chcHost.DeploySecurityGroupIds != nil { - chcHostMap["deploy_security_group_ids"] = chcHost.DeploySecurityGroupIds + if chcHostSet.DeploySecurityGroupIds != nil { + chcHostSetMap["deploy_security_group_ids"] = chcHostSet.DeploySecurityGroupIds } - if chcHost.CvmInstanceId != nil { - chcHostMap["cvm_instance_id"] = chcHost.CvmInstanceId + if chcHostSet.CvmInstanceId != nil { + chcHostSetMap["cvm_instance_id"] = chcHostSet.CvmInstanceId } - if chcHost.CreatedTime != nil { - chcHostMap["created_time"] = chcHost.CreatedTime + if chcHostSet.CreatedTime != nil { + chcHostSetMap["created_time"] = chcHostSet.CreatedTime } - if chcHost.HardwareDescription != nil { - chcHostMap["hardware_description"] = chcHost.HardwareDescription + if chcHostSet.HardwareDescription != nil { + chcHostSetMap["hardware_description"] = chcHostSet.HardwareDescription } - if chcHost.CPU != nil { - chcHostMap["cpu"] = chcHost.CPU + if chcHostSet.CPU != nil { + chcHostSetMap["cpu"] = chcHostSet.CPU } - if chcHost.Memory != nil { - chcHostMap["memory"] = chcHost.Memory + if chcHostSet.Memory != nil { + chcHostSetMap["memory"] = chcHostSet.Memory } - if chcHost.Disk != nil { - chcHostMap["disk"] = chcHost.Disk + if chcHostSet.Disk != nil { + chcHostSetMap["disk"] = chcHostSet.Disk } - if chcHost.BmcMAC != nil { - chcHostMap["bmc_mac"] = chcHost.BmcMAC + if chcHostSet.BmcMAC != nil { + chcHostSetMap["bmc_mac"] = chcHostSet.BmcMAC } - if chcHost.DeployMAC != nil { - chcHostMap["deploy_mac"] = chcHost.DeployMAC + if chcHostSet.DeployMAC != nil { + chcHostSetMap["deploy_mac"] = chcHostSet.DeployMAC } - if chcHost.TenantType != nil { - chcHostMap["tenant_type"] = chcHost.TenantType + if chcHostSet.TenantType != nil { + chcHostSetMap["tenant_type"] = chcHostSet.TenantType } - ids = append(ids, *chcHost.ChcId) - tmpList = append(tmpList, chcHostMap) + chcIds = append(chcIds, chcId) + chcHostSetList = append(chcHostSetList, chcHostSetMap) } - _ = d.Set("chc_host_set", tmpList) + _ = d.Set("chc_host_set", chcHostSetList) } - d.SetId(helper.DataResourceIdsHash(ids)) + d.SetId(helper.DataResourceIdsHash(chcIds)) + output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if e := tccommon.WriteToFile(output.(string), tmpList); e != nil { + if e := tccommon.WriteToFile(output.(string), chcHostSetList); e != nil { return e } } + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_chc_hosts_extension.go b/tencentcloud/services/cvm/data_source_tc_cvm_chc_hosts_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_cvm_chc_hosts_extension.go @@ -0,0 +1 @@ +package cvm diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_chc_hosts_test.go b/tencentcloud/services/cvm/data_source_tc_cvm_chc_hosts_test.go index 9f9e1bba2c..a036785f71 100644 --- a/tencentcloud/services/cvm/data_source_tc_cvm_chc_hosts_test.go +++ b/tencentcloud/services/cvm/data_source_tc_cvm_chc_hosts_test.go @@ -4,6 +4,7 @@ import ( "testing" resource "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + acctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" ) @@ -33,11 +34,6 @@ data "tencentcloud_security_groups" "security_groups2" { } data "tencentcloud_cvm_chc_hosts" "chc_hosts" { chc_ids = [tencentcloud_cvm_chc_config.chc_config.chc_id] - - filters { - values = ["ap-guangzhou-7"] - name = "zone" - } } resource "tencentcloud_vpc" "vpc" { name = "tf-cvm-vpc" diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_disaster_recover_group_quota.go b/tencentcloud/services/cvm/data_source_tc_cvm_disaster_recover_group_quota.go index 2960dd400f..c0581eb531 100644 --- a/tencentcloud/services/cvm/data_source_tc_cvm_disaster_recover_group_quota.go +++ b/tencentcloud/services/cvm/data_source_tc_cvm_disaster_recover_group_quota.go @@ -1,16 +1,14 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( - "fmt" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "context" "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" - "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/ratelimit" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" ) func DataSourceTencentCloudCvmDisasterRecoverGroupQuota() *schema.Resource { @@ -18,32 +16,32 @@ func DataSourceTencentCloudCvmDisasterRecoverGroupQuota() *schema.Resource { Read: dataSourceTencentCloudCvmDisasterRecoverGroupQuotaRead, Schema: map[string]*schema.Schema{ "group_quota": { - Computed: true, Type: schema.TypeInt, + Computed: true, Description: "The maximum number of placement groups that can be created.", }, "current_num": { - Computed: true, Type: schema.TypeInt, + Computed: true, Description: "The number of placement groups that have been created by the current user.", }, "cvm_in_host_group_quota": { - Computed: true, Type: schema.TypeInt, + Computed: true, Description: "Quota on instances in a physical-machine-type disaster recovery group.", }, "cvm_in_sw_group_quota": { - Computed: true, Type: schema.TypeInt, + Computed: true, Description: "Quota on instances in a switch-type disaster recovery group.", }, "cvm_in_rack_group_quota": { - Computed: true, Type: schema.TypeInt, + Computed: true, Description: "Quota on instances in a rack-type disaster recovery group.", }, @@ -60,43 +58,55 @@ func dataSourceTencentCloudCvmDisasterRecoverGroupQuotaRead(d *schema.ResourceDa defer tccommon.LogElapsed("data_source.tencentcloud_cvm_disaster_recover_group_quota.read")() defer tccommon.InconsistentCheck(d, meta)() - var response *cvm.DescribeDisasterRecoverGroupQuotaResponse + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - request := cvm.NewDescribeDisasterRecoverGroupQuotaRequest() + paramMap := make(map[string]interface{}) + var respData *cvm.DescribeDisasterRecoverGroupQuotaResponseParams err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - ratelimit.Check(request.GetAction()) - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().DescribeDisasterRecoverGroupQuota(request) + result, e := service.DescribeCvmDisasterRecoverGroupQuotaByFilter(ctx, paramMap) if e != nil { return tccommon.RetryError(e) } - response = result + respData = result return nil }) if err != nil { return err } - if response == nil || response.Response == nil { - d.SetId("") - return fmt.Errorf("Response is nil") + + if respData.GroupQuota != nil { + _ = d.Set("group_quota", respData.GroupQuota) + } + + if respData.CurrentNum != nil { + _ = d.Set("current_num", respData.CurrentNum) + } + + if respData.CvmInHostGroupQuota != nil { + _ = d.Set("cvm_in_host_group_quota", respData.CvmInHostGroupQuota) + } + + if respData.CvmInSwGroupQuota != nil { + _ = d.Set("cvm_in_sw_group_quota", respData.CvmInSwGroupQuota) + } + + if respData.CvmInRackGroupQuota != nil { + _ = d.Set("cvm_in_rack_group_quota", respData.CvmInRackGroupQuota) + } + + if err := dataSourceTencentCloudCvmDisasterRecoverGroupQuotaReadPostHandleResponse0(ctx, paramMap, respData); err != nil { + return err } - _ = d.Set("group_quota", response.Response.GroupQuota) - _ = d.Set("current_num", response.Response.CurrentNum) - _ = d.Set("cvm_in_host_group_quota", response.Response.CvmInHostGroupQuota) - _ = d.Set("cvm_in_sw_group_quota", response.Response.CvmInSwGroupQuota) - _ = d.Set("cvm_in_rack_group_quota", response.Response.CvmInRackGroupQuota) - d.SetId(helper.BuildToken()) output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if e := tccommon.WriteToFile(output.(string), map[string]interface{}{ - "group_quota": response.Response.GroupQuota, - "current_num": response.Response.CurrentNum, - "cvm_in_host_group_quota": response.Response.CvmInHostGroupQuota, - "cvm_in_sw_group_quota": response.Response.CvmInSwGroupQuota, - "cvm_in_rack_group_quota": response.Response.CvmInRackGroupQuota, - }); e != nil { + if e := tccommon.WriteToFile(output.(string), dataSourceTencentCloudCvmDisasterRecoverGroupQuotaReadOutputContent(ctx)); e != nil { return e } } + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_disaster_recover_group_quota_extension.go b/tencentcloud/services/cvm/data_source_tc_cvm_disaster_recover_group_quota_extension.go new file mode 100644 index 0000000000..50abcbe42a --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_cvm_disaster_recover_group_quota_extension.go @@ -0,0 +1,30 @@ +package cvm + +import ( + "context" + + 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 dataSourceTencentCloudCvmDisasterRecoverGroupQuotaReadOutputContent(ctx context.Context) interface{} { + d := tccommon.ResourceDataFromContext(ctx) + + return map[string]interface{}{ + "group_quota": d.Get("group_quota"), + "current_num": d.Get("current_num"), + "cvm_in_host_group_quota": d.Get("cvm_in_host_group_quota"), + "cvm_in_sw_group_quota": d.Get("cvm_in_sw_group_quota"), + "cvm_in_rack_group_quota": d.Get("cvm_in_rack_group_quota"), + } +} + +func dataSourceTencentCloudCvmDisasterRecoverGroupQuotaReadPostHandleResponse0(ctx context.Context, req map[string]interface{}, resp *cvm.DescribeDisasterRecoverGroupQuotaResponseParams) error { + d := tccommon.ResourceDataFromContext(ctx) + + d.SetId(helper.BuildToken()) + + return nil +} diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_disaster_recover_group_quota_test.go b/tencentcloud/services/cvm/data_source_tc_cvm_disaster_recover_group_quota_test.go index 89833cbae0..c386ad6913 100644 --- a/tencentcloud/services/cvm/data_source_tc_cvm_disaster_recover_group_quota_test.go +++ b/tencentcloud/services/cvm/data_source_tc_cvm_disaster_recover_group_quota_test.go @@ -4,6 +4,7 @@ import ( "testing" resource "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + acctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" ) diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_image_quota.go b/tencentcloud/services/cvm/data_source_tc_cvm_image_quota.go index b98fefd2e3..dfd8d4cc04 100644 --- a/tencentcloud/services/cvm/data_source_tc_cvm_image_quota.go +++ b/tencentcloud/services/cvm/data_source_tc_cvm_image_quota.go @@ -1,14 +1,14 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( "context" - 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 DataSourceTencentCloudCvmImageQuota() *schema.Resource { @@ -16,8 +16,8 @@ func DataSourceTencentCloudCvmImageQuota() *schema.Resource { Read: dataSourceTencentCloudCvmImageQuotaRead, Schema: map[string]*schema.Schema{ "image_num_quota": { - Computed: true, Type: schema.TypeInt, + Computed: true, Description: "The image quota of an account.", }, @@ -34,36 +34,39 @@ func dataSourceTencentCloudCvmImageQuotaRead(d *schema.ResourceData, meta interf defer tccommon.LogElapsed("data_source.tencentcloud_cvm_image_quota.read")() defer tccommon.InconsistentCheck(d, meta)() - logId := tccommon.GetLogId(tccommon.ContextNil) - - var imageNumQuota int64 - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - paramMap := make(map[string]interface{}) service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + paramMap := make(map[string]interface{}) + var respData *cvm.DescribeImageQuotaResponseParams err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { result, e := service.DescribeCvmImageQuotaByFilter(ctx, paramMap) if e != nil { return tccommon.RetryError(e) } - imageNumQuota = result + respData = result return nil }) if err != nil { return err } - _ = d.Set("image_num_quota", imageNumQuota) + if respData.ImageNumQuota != nil { + _ = d.Set("image_num_quota", respData.ImageNumQuota) + } + + if err := dataSourceTencentCloudCvmImageQuotaReadPostHandleResponse0(ctx, paramMap, respData); err != nil { + return err + } - d.SetId(helper.BuildToken()) output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if e := tccommon.WriteToFile(output.(string), map[string]interface{}{ - "image_num_quota": imageNumQuota, - }); e != nil { + if e := tccommon.WriteToFile(output.(string), dataSourceTencentCloudCvmImageQuotaReadOutputContent(ctx)); e != nil { return e } } + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_image_quota_extension.go b/tencentcloud/services/cvm/data_source_tc_cvm_image_quota_extension.go new file mode 100644 index 0000000000..9f8425c7f7 --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_cvm_image_quota_extension.go @@ -0,0 +1,26 @@ +package cvm + +import ( + "context" + + 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 dataSourceTencentCloudCvmImageQuotaReadOutputContent(ctx context.Context) interface{} { + d := tccommon.ResourceDataFromContext(ctx) + + return map[string]interface{}{ + "image_num_quota": d.Get("image_num_quota"), + } +} + +func dataSourceTencentCloudCvmImageQuotaReadPostHandleResponse0(ctx context.Context, req map[string]interface{}, resp *cvm.DescribeImageQuotaResponseParams) error { + d := tccommon.ResourceDataFromContext(ctx) + + d.SetId(helper.BuildToken()) + + return nil +} diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_image_quota_test.go b/tencentcloud/services/cvm/data_source_tc_cvm_image_quota_test.go index ad8c11a369..dd0ff9f1b6 100644 --- a/tencentcloud/services/cvm/data_source_tc_cvm_image_quota_test.go +++ b/tencentcloud/services/cvm/data_source_tc_cvm_image_quota_test.go @@ -4,6 +4,7 @@ import ( "testing" resource "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + acctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" ) diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_image_share_permission.go b/tencentcloud/services/cvm/data_source_tc_cvm_image_share_permission.go index 25bd95d412..792b4e7efb 100644 --- a/tencentcloud/services/cvm/data_source_tc_cvm_image_share_permission.go +++ b/tencentcloud/services/cvm/data_source_tc_cvm_image_share_permission.go @@ -1,14 +1,14 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( "context" - 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,14 +17,14 @@ func DataSourceTencentCloudCvmImageSharePermission() *schema.Resource { Read: dataSourceTencentCloudCvmImageSharePermissionRead, Schema: map[string]*schema.Schema{ "image_id": { - Required: true, Type: schema.TypeString, + Required: true, Description: "The ID of the image to be shared.", }, "share_permission_set": { - Computed: true, Type: schema.TypeList, + Computed: true, Description: "Information on image sharing.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -55,59 +55,60 @@ func dataSourceTencentCloudCvmImageSharePermissionRead(d *schema.ResourceData, m defer tccommon.LogElapsed("data_source.tencentcloud_cvm_image_share_permission.read")() defer tccommon.InconsistentCheck(d, meta)() - logId := tccommon.GetLogId(tccommon.ContextNil) + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} paramMap := make(map[string]interface{}) if v, ok := d.GetOk("image_id"); ok { paramMap["ImageId"] = helper.String(v.(string)) } - service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - - var sharePermissionSet []*cvm.SharePermission - + var respData []*cvm.SharePermission err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { result, e := service.DescribeCvmImageSharePermissionByFilter(ctx, paramMap) if e != nil { return tccommon.RetryError(e) } - sharePermissionSet = result + respData = result return nil }) if err != nil { return err } - ids := make([]string, 0, len(sharePermissionSet)) - tmpList := make([]map[string]interface{}, 0, len(sharePermissionSet)) + ids := make([]string, 0, len(respData)) + sharePermissionSetList := make([]map[string]interface{}, 0, len(respData)) + if respData != nil { + for _, sharePermissionSet := range respData { + sharePermissionSetMap := map[string]interface{}{} - if sharePermissionSet != nil { - for _, sharePermission := range sharePermissionSet { - sharePermissionMap := map[string]interface{}{} - - if sharePermission.CreatedTime != nil { - sharePermissionMap["created_time"] = sharePermission.CreatedTime + if sharePermissionSet.CreatedTime != nil { + sharePermissionSetMap["created_time"] = sharePermissionSet.CreatedTime } - if sharePermission.AccountId != nil { - sharePermissionMap["account_id"] = sharePermission.AccountId + var accountId string + if sharePermissionSet.AccountId != nil { + sharePermissionSetMap["account_id"] = sharePermissionSet.AccountId + accountId = *sharePermissionSet.AccountId } - ids = append(ids, *sharePermission.AccountId) - tmpList = append(tmpList, sharePermissionMap) + ids = append(ids, accountId) + sharePermissionSetList = append(sharePermissionSetList, sharePermissionSetMap) } - _ = d.Set("share_permission_set", tmpList) + _ = d.Set("share_permission_set", sharePermissionSetList) } d.SetId(helper.DataResourceIdsHash(ids)) + output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if e := tccommon.WriteToFile(output.(string), tmpList); e != nil { + if e := tccommon.WriteToFile(output.(string), sharePermissionSetList); e != nil { return e } } + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_image_share_permission_extension.go b/tencentcloud/services/cvm/data_source_tc_cvm_image_share_permission_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_cvm_image_share_permission_extension.go @@ -0,0 +1 @@ +package cvm diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_import_image_os.go b/tencentcloud/services/cvm/data_source_tc_cvm_import_image_os.go index f117587d89..be35bb3be0 100644 --- a/tencentcloud/services/cvm/data_source_tc_cvm_import_image_os.go +++ b/tencentcloud/services/cvm/data_source_tc_cvm_import_image_os.go @@ -1,15 +1,14 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( - "fmt" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "context" "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 DataSourceTencentCloudCvmImportImageOs() *schema.Resource { @@ -17,34 +16,34 @@ func DataSourceTencentCloudCvmImportImageOs() *schema.Resource { Read: dataSourceTencentCloudCvmImportImageOsRead, Schema: map[string]*schema.Schema{ "import_image_os_list_supported": { - Computed: true, Type: schema.TypeList, + Computed: true, Description: "Supported operating system types of imported images.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "windows": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Computed: true, + Description: "Supported Windows OS Note: This field may return null, indicating that no valid values can be obtained.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Computed: true, - Description: "Supported Windows OS Note: This field may return null, indicating that no valid values can be obtained.", }, "linux": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Computed: true, + Description: "Supported Linux OS Note: This field may return null, indicating that no valid values can be obtained.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Computed: true, - Description: "Supported Linux OS Note: This field may return null, indicating that no valid values can be obtained.", }, }, }, }, "import_image_os_version_set": { - Computed: true, Type: schema.TypeList, + Computed: true, Description: "Supported operating system versions of imported images.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -54,20 +53,20 @@ func DataSourceTencentCloudCvmImportImageOs() *schema.Resource { Description: "Operating system type.", }, "os_versions": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Computed: true, + Description: "Supported operating system versions.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Computed: true, - Description: "Supported operating system versions.", }, "architecture": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Computed: true, + Description: "Supported operating system architecture.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Computed: true, - Description: "Supported operating system architecture.", }, }, }, @@ -86,80 +85,72 @@ func dataSourceTencentCloudCvmImportImageOsRead(d *schema.ResourceData, meta int defer tccommon.LogElapsed("data_source.tencentcloud_cvm_import_image_os.read")() defer tccommon.InconsistentCheck(d, meta)() - var ( - request = cvm.NewDescribeImportImageOsRequest() - response = cvm.NewDescribeImportImageOsResponse() - ) + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + paramMap := make(map[string]interface{}) + var respData *cvm.DescribeImportImageOsResponseParams err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - resule, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().DescribeImportImageOs(request) + result, e := service.DescribeCvmImportImageOsByFilter(ctx, paramMap) if e != nil { return tccommon.RetryError(e) } - response = resule + respData = result return nil }) if err != nil { return err } - if response == nil || response.Response == nil { - d.SetId("") - return fmt.Errorf("Response is null") - } - imageOsList := response.Response.ImportImageOsListSupported - importImageOsVersionSet := response.Response.ImportImageOsVersionSet - result := make(map[string]interface{}) - if imageOsList != nil { - imageOsListMap := make(map[string]interface{}) - - if len(imageOsList.Windows) != 0 { - windowsList := make([]string, 0, len(imageOsList.Windows)) - for _, v := range imageOsList.Windows { - windowsList = append(windowsList, *v) - } - imageOsListMap["windows"] = windowsList + importImageOsListSupportedMap := map[string]interface{}{} + + if respData.ImportImageOsListSupported != nil { + if respData.ImportImageOsListSupported.Windows != nil { + importImageOsListSupportedMap["windows"] = respData.ImportImageOsListSupported.Windows } - if len(imageOsList.Linux) != 0 { - linuxList := make([]string, 0, len(imageOsList.Linux)) - for _, v := range imageOsList.Linux { - linuxList = append(linuxList, *v) - } - imageOsListMap["linux"] = linuxList + if respData.ImportImageOsListSupported.Linux != nil { + importImageOsListSupportedMap["linux"] = respData.ImportImageOsListSupported.Linux } - result["import_image_os_list_supported"] = imageOsListMap - _ = d.Set("import_image_os_list_supported", []map[string]interface{}{imageOsListMap}) + _ = d.Set("import_image_os_list_supported", []interface{}{importImageOsListSupportedMap}) } - if importImageOsVersionSet != nil { - tmpList := make([]map[string]interface{}, 0) - for _, osVersion := range importImageOsVersionSet { - osVersionMap := map[string]interface{}{} - if osVersion.OsName != nil { - osVersionMap["os_name"] = osVersion.OsName + importImageOsVersionSetList := make([]map[string]interface{}, 0, len(respData.ImportImageOsVersionSet)) + if respData.ImportImageOsVersionSet != nil { + for _, importImageOsVersionSet := range respData.ImportImageOsVersionSet { + importImageOsVersionSetMap := map[string]interface{}{} + + if importImageOsVersionSet.OsName != nil { + importImageOsVersionSetMap["os_name"] = importImageOsVersionSet.OsName } - if osVersion.OsVersions != nil { - osVersionMap["os_versions"] = osVersion.OsVersions + if importImageOsVersionSet.OsVersions != nil { + importImageOsVersionSetMap["os_versions"] = importImageOsVersionSet.OsVersions } - if osVersion.Architecture != nil { - osVersionMap["architecture"] = osVersion.Architecture + if importImageOsVersionSet.Architecture != nil { + importImageOsVersionSetMap["architecture"] = importImageOsVersionSet.Architecture } - tmpList = append(tmpList, osVersionMap) + importImageOsVersionSetList = append(importImageOsVersionSetList, importImageOsVersionSetMap) } - result["import_image_os_version_set"] = tmpList - _ = d.Set("import_image_os_version_set", tmpList) + + _ = d.Set("import_image_os_version_set", importImageOsVersionSetList) + } + + if err := dataSourceTencentCloudCvmImportImageOsReadPostHandleResponse0(ctx, paramMap, respData); err != nil { + return err } - d.SetId(helper.BuildToken()) output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if e := tccommon.WriteToFile(output.(string), result); e != nil { + if e := tccommon.WriteToFile(output.(string), dataSourceTencentCloudCvmImportImageOsReadOutputContent(ctx)); e != nil { return e } } + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_import_image_os_extension.go b/tencentcloud/services/cvm/data_source_tc_cvm_import_image_os_extension.go new file mode 100644 index 0000000000..ce4409eeea --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_cvm_import_image_os_extension.go @@ -0,0 +1,28 @@ +package cvm + +import ( + "context" + + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" + + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" +) + +func dataSourceTencentCloudCvmImportImageOsReadOutputContent(ctx context.Context) interface{} { + d := tccommon.ResourceDataFromContext(ctx) + + return map[string]interface{}{ + "import_image_os_list_supported": d.Get("import_image_os_list_supported"), + "import_image_os_version_set": d.Get("import_image_os_version_set"), + } +} + +func dataSourceTencentCloudCvmImportImageOsReadPostHandleResponse0(ctx context.Context, req map[string]interface{}, resp *cvm.DescribeImportImageOsResponseParams) error { + d := tccommon.ResourceDataFromContext(ctx) + + d.SetId(helper.BuildToken()) + + return nil +} diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_instance_vnc_url.go b/tencentcloud/services/cvm/data_source_tc_cvm_instance_vnc_url.go index 9e4954611c..00a9f2310d 100644 --- a/tencentcloud/services/cvm/data_source_tc_cvm_instance_vnc_url.go +++ b/tencentcloud/services/cvm/data_source_tc_cvm_instance_vnc_url.go @@ -1,14 +1,14 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( - "fmt" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "context" "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,14 +17,14 @@ func DataSourceTencentCloudCvmInstanceVncUrl() *schema.Resource { Read: dataSourceTencentCloudCvmInstanceVncUrlRead, Schema: map[string]*schema.Schema{ "instance_id": { - Required: true, Type: schema.TypeString, + Required: true, Description: "Instance ID. To obtain the instance IDs, you can call `DescribeInstances` and look for `InstanceId` in the response.", }, "instance_vnc_url": { - Computed: true, Type: schema.TypeString, + Computed: true, Description: "Instance VNC URL.", }, @@ -41,38 +41,47 @@ func dataSourceTencentCloudCvmInstanceVncUrlRead(d *schema.ResourceData, meta in defer tccommon.LogElapsed("data_source.tencentcloud_cvm_instance_vnc_url.read")() defer tccommon.InconsistentCheck(d, meta)() - var response *cvm.DescribeInstanceVncUrlResponse - request := cvm.NewDescribeInstanceVncUrlRequest() - instanceId := d.Get("instance_id").(string) - request.InstanceId = helper.String(instanceId) - err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().DescribeInstanceVncUrl(request) + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + var ( + instanceId string + ) + if v, ok := d.GetOk("instance_id"); ok { + instanceId = v.(string) + } + paramMap := make(map[string]interface{}) + if v, ok := d.GetOk("instance_id"); ok { + paramMap["InstanceId"] = helper.String(v.(string)) + } + + var respData *cvm.DescribeInstanceVncUrlResponseParams + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + result, e := service.DescribeCvmInstanceVncUrlByFilter(ctx, paramMap) if e != nil { return tccommon.RetryError(e) } - response = result + respData = result return nil }) if err != nil { return err } - if response == nil || response.Response == nil { - d.SetId("") - return fmt.Errorf("Response is nil") - + if respData.InstanceVncUrl != nil { + _ = d.Set("instance_vnc_url", respData.InstanceVncUrl) } + d.SetId(instanceId) - _ = d.Set("instance_vnc_url", *response.Response.InstanceVncUrl) output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if e := tccommon.WriteToFile(output.(string), map[string]interface{}{ - "instance_vnc_url": *response.Response.InstanceVncUrl, - }); e != nil { + if e := tccommon.WriteToFile(output.(string), dataSourceTencentCloudCvmInstanceVncUrlReadOutputContent(ctx)); e != nil { return e } } + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_instance_vnc_url_extension.go b/tencentcloud/services/cvm/data_source_tc_cvm_instance_vnc_url_extension.go new file mode 100644 index 0000000000..e6285f813f --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_cvm_instance_vnc_url_extension.go @@ -0,0 +1,18 @@ +package cvm + +import ( + "context" + "fmt" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" +) + +func dataSourceTencentCloudCvmInstanceVncUrlReadOutputContent(ctx context.Context) interface{} { + d := tccommon.ResourceDataFromContext(ctx) + if d == nil { + return fmt.Errorf("resource data can not be nil") + } + return map[string]interface{}{ + "instance_vnc_url": d.Get("instance_vnc_url"), + } +} diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_instances_modification.go b/tencentcloud/services/cvm/data_source_tc_cvm_instances_modification.go index c8cff821c4..098101ea6b 100644 --- a/tencentcloud/services/cvm/data_source_tc_cvm_instances_modification.go +++ b/tencentcloud/services/cvm/data_source_tc_cvm_instances_modification.go @@ -1,33 +1,33 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( - "log" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "context" "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 DataSourceTencentCloudCvmInstancesModification() *schema.Resource { return &schema.Resource{ Read: dataSourceTencentCloudCvmInstancesModificationRead, - Schema: map[string]*schema.Schema{ "instance_ids": { - Optional: true, - Type: schema.TypeSet, + Type: schema.TypeSet, + Optional: true, + Description: "One or more instance ID to be queried. It can be obtained from the InstanceId in the returned value of API DescribeInstances. The maximum number of instances in batch for each request is 20.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Description: "One or more instance ID to be queried. It can be obtained from the InstanceId in the returned value of API DescribeInstances. The maximum number of instances in batch for each request is 20.", }, + "filters": { - Optional: true, Type: schema.TypeList, + Optional: true, Description: "The upper limit of Filters for each request is 10 and the upper limit for Filter.Values is 2.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -37,26 +37,20 @@ func DataSourceTencentCloudCvmInstancesModification() *schema.Resource { Description: "Fields to be filtered.", }, "values": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Required: true, + Description: "Value of the field.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Required: true, - Description: "Value of the field.", }, }, }, }, - "result_output_file": { - Type: schema.TypeString, - Optional: true, - Description: "Used to save results.", - }, - "instance_type_config_status_list": { - Computed: true, Type: schema.TypeList, + Computed: true, Description: "The list of model configurations that can be adjusted by the instance.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -117,85 +111,135 @@ func DataSourceTencentCloudCvmInstancesModification() *schema.Resource { }, }, }, + + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, }, } } func dataSourceTencentCloudCvmInstancesModificationRead(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("data_source.tencentcloud_cvm_instances_modification.read")() - logId := tccommon.GetLogId(tccommon.ContextNil) + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - var ( - request = cvm.NewDescribeInstancesModificationRequest() - response = cvm.NewDescribeInstancesModificationResponse() - ) + paramMap := make(map[string]interface{}) if v, ok := d.GetOk("instance_ids"); ok { - request.InstanceIds = helper.InterfacesStringsPoint(v.(*schema.Set).List()) + instanceIdsList := []*string{} + instanceIdsSet := v.(*schema.Set).List() + for i := range instanceIdsSet { + instanceIds := instanceIdsSet[i].(string) + instanceIdsList = append(instanceIdsList, helper.String(instanceIds)) + } + paramMap["InstanceIds"] = instanceIdsList } if v, ok := d.GetOk("filters"); ok { - filters := make([]*cvm.Filter, 0) - for _, item := range v.(*schema.Set).List() { - filter := item.(map[string]interface{}) - name := filter["name"].(string) - filters = append(filters, &cvm.Filter{ - Name: &name, - Values: helper.StringsStringsPoint(filter["values"].([]string)), - }) + 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) } - request.Filters = filters + paramMap["Filters"] = tmpSet } - instanceTypeConfigStatusList := make([]map[string]interface{}, 0) - - var innerErr error + var respData []*cvm.InstanceTypeConfigStatus err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - response, innerErr = meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().DescribeInstancesModification(request) - if innerErr != nil { - return tccommon.RetryError(innerErr) + result, e := service.DescribeCvmInstancesModificationByFilter(ctx, paramMap) + if e != nil { + return tccommon.RetryError(e) } + respData = result return nil }) if err != nil { return err } - ids := make([]string, 0) - for _, instanceTypeConfigStatusSetItem := range response.Response.InstanceTypeConfigStatusSet { - instanceTypeConfigStatus := make(map[string]interface{}) - instanceTypeConfigStatus["status"] = instanceTypeConfigStatusSetItem.Status - instanceTypeConfigStatus["message"] = instanceTypeConfigStatusSetItem.Message - - instanceTypeConfigMaps := make([]map[string]interface{}, 0) - instanceTypeConfigMap := make(map[string]interface{}) - instanceTypeConfig := instanceTypeConfigStatusSetItem.InstanceTypeConfig - instanceTypeConfigMap["zone"] = instanceTypeConfig.Zone - ids = append(ids, *instanceTypeConfig.InstanceType) - instanceTypeConfigMap["instance_type"] = instanceTypeConfig.InstanceType - instanceTypeConfigMap["instance_family"] = instanceTypeConfig.InstanceFamily - instanceTypeConfigMap["gpu"] = instanceTypeConfig.GPU - instanceTypeConfigMap["cpu"] = instanceTypeConfig.CPU - instanceTypeConfigMap["memory"] = instanceTypeConfig.Memory - instanceTypeConfigMap["fpga"] = instanceTypeConfig.FPGA - instanceTypeConfigMaps = append(instanceTypeConfigMaps, instanceTypeConfigMap) - instanceTypeConfigStatus["instance_type_config"] = instanceTypeConfigMaps - - instanceTypeConfigStatusList = append(instanceTypeConfigStatusList, instanceTypeConfigStatus) + var ids []string + instanceTypeConfigStatusSetList := make([]map[string]interface{}, 0, len(respData)) + if respData != nil { + for _, instanceTypeConfigStatusSet := range respData { + instanceTypeConfigStatusSetMap := map[string]interface{}{} + + var instanceType string + if instanceTypeConfigStatusSet.Status != nil { + instanceTypeConfigStatusSetMap["status"] = instanceTypeConfigStatusSet.Status + } + + if instanceTypeConfigStatusSet.Message != nil { + instanceTypeConfigStatusSetMap["message"] = instanceTypeConfigStatusSet.Message + } + + instanceTypeConfigMap := map[string]interface{}{} + + if instanceTypeConfigStatusSet.InstanceTypeConfig != nil { + if instanceTypeConfigStatusSet.InstanceTypeConfig.Zone != nil { + instanceTypeConfigMap["zone"] = instanceTypeConfigStatusSet.InstanceTypeConfig.Zone + } + + if instanceTypeConfigStatusSet.InstanceTypeConfig.InstanceType != nil { + instanceTypeConfigMap["instance_type"] = instanceTypeConfigStatusSet.InstanceTypeConfig.InstanceType + instanceType = *instanceTypeConfigStatusSet.InstanceTypeConfig.InstanceType + } + + if instanceTypeConfigStatusSet.InstanceTypeConfig.InstanceFamily != nil { + instanceTypeConfigMap["instance_family"] = instanceTypeConfigStatusSet.InstanceTypeConfig.InstanceFamily + } + + if instanceTypeConfigStatusSet.InstanceTypeConfig.GPU != nil { + instanceTypeConfigMap["gpu"] = instanceTypeConfigStatusSet.InstanceTypeConfig.GPU + } + + if instanceTypeConfigStatusSet.InstanceTypeConfig.CPU != nil { + instanceTypeConfigMap["cpu"] = instanceTypeConfigStatusSet.InstanceTypeConfig.CPU + } + + if instanceTypeConfigStatusSet.InstanceTypeConfig.Memory != nil { + instanceTypeConfigMap["memory"] = instanceTypeConfigStatusSet.InstanceTypeConfig.Memory + } + + if instanceTypeConfigStatusSet.InstanceTypeConfig.FPGA != nil { + instanceTypeConfigMap["fpga"] = instanceTypeConfigStatusSet.InstanceTypeConfig.FPGA + } + + instanceTypeConfigStatusSetMap["instance_type_config"] = []interface{}{instanceTypeConfigMap} + } + + ids = append(ids, instanceType) + instanceTypeConfigStatusSetList = append(instanceTypeConfigStatusSetList, instanceTypeConfigStatusSetMap) + } + + _ = d.Set("instance_type_config_status_list", instanceTypeConfigStatusSetList) } d.SetId(helper.DataResourceIdsHash(ids)) - err = d.Set("instance_type_config_status_list", instanceTypeConfigStatusList) - if err != nil { - log.Printf("[CRITAL]%s provider set instance list fail, reason:%s\n ", logId, err.Error()) - return err - } output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if err := tccommon.WriteToFile(output.(string), instanceTypeConfigStatusList); err != nil { - return err + if e := tccommon.WriteToFile(output.(string), instanceTypeConfigStatusSetList); e != nil { + return e } } - return nil + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_cvm_instances_modification_extension.go b/tencentcloud/services/cvm/data_source_tc_cvm_instances_modification_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_cvm_instances_modification_extension.go @@ -0,0 +1 @@ +package cvm diff --git a/tencentcloud/services/cvm/data_source_tc_eip_address_quota.go b/tencentcloud/services/cvm/data_source_tc_eip_address_quota.go index 1533b2abe7..ef8d23cacc 100644 --- a/tencentcloud/services/cvm/data_source_tc_eip_address_quota.go +++ b/tencentcloud/services/cvm/data_source_tc_eip_address_quota.go @@ -1,15 +1,14 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( "context" - 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" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" ) @@ -18,8 +17,8 @@ func DataSourceTencentCloudEipAddressQuota() *schema.Resource { Read: dataSourceTencentCloudEipAddressQuotaRead, Schema: map[string]*schema.Schema{ "quota_set": { - Computed: true, Type: schema.TypeList, + Computed: true, Description: "The specified account EIP quota information.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -52,61 +51,63 @@ func DataSourceTencentCloudEipAddressQuota() *schema.Resource { } func dataSourceTencentCloudEipAddressQuotaRead(d *schema.ResourceData, meta interface{}) error { - defer tccommon.LogElapsed("data_source.tencentcloud_vpc_address_quota.read")() + defer tccommon.LogElapsed("data_source.tencentcloud_eip_address_quota.read")() defer tccommon.InconsistentCheck(d, meta)() - logId := tccommon.GetLogId(tccommon.ContextNil) + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - - service := svcvpc.NewVpcService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) - - var quotaSet []*vpc.Quota + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + paramMap := make(map[string]interface{}) + var respData []*vpc.Quota err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - result, e := service.DescribeEipAddressQuota(ctx) + result, e := service.DescribeEipAddressQuotaByFilter(ctx, paramMap) if e != nil { return tccommon.RetryError(e) } - quotaSet = result + respData = result return nil }) if err != nil { return err } - ids := make([]string, 0, len(quotaSet)) - tmpList := make([]map[string]interface{}, 0, len(quotaSet)) - - if quotaSet != nil { - for _, quota := range quotaSet { - quotaMap := map[string]interface{}{} + var ids []string + quotaSetList := make([]map[string]interface{}, 0, len(respData)) + if respData != nil { + for _, quotaSet := range respData { + quotaSetMap := map[string]interface{}{} - if quota.QuotaId != nil { - quotaMap["quota_id"] = quota.QuotaId + var quotaId string + if quotaSet.QuotaId != nil { + quotaSetMap["quota_id"] = quotaSet.QuotaId + quotaId = *quotaSet.QuotaId } - if quota.QuotaCurrent != nil { - quotaMap["quota_current"] = quota.QuotaCurrent + if quotaSet.QuotaCurrent != nil { + quotaSetMap["quota_current"] = quotaSet.QuotaCurrent } - if quota.QuotaLimit != nil { - quotaMap["quota_limit"] = quota.QuotaLimit + if quotaSet.QuotaLimit != nil { + quotaSetMap["quota_limit"] = quotaSet.QuotaLimit } - ids = append(ids, *quota.QuotaId) - tmpList = append(tmpList, quotaMap) + ids = append(ids, quotaId) + quotaSetList = append(quotaSetList, quotaSetMap) } - _ = d.Set("quota_set", tmpList) + _ = d.Set("quota_set", quotaSetList) } d.SetId(helper.DataResourceIdsHash(ids)) + output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if e := tccommon.WriteToFile(output.(string), tmpList); e != nil { + if e := tccommon.WriteToFile(output.(string), quotaSetList); e != nil { return e } } + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_eip_address_quota_extension.go b/tencentcloud/services/cvm/data_source_tc_eip_address_quota_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_eip_address_quota_extension.go @@ -0,0 +1 @@ +package cvm diff --git a/tencentcloud/services/cvm/data_source_tc_eip_network_account_type.go b/tencentcloud/services/cvm/data_source_tc_eip_network_account_type.go index 88551782c7..5dd73f70f2 100644 --- a/tencentcloud/services/cvm/data_source_tc_eip_network_account_type.go +++ b/tencentcloud/services/cvm/data_source_tc_eip_network_account_type.go @@ -1,13 +1,14 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( "context" - 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" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" ) func DataSourceTencentCloudEipNetworkAccountType() *schema.Resource { @@ -15,8 +16,8 @@ func DataSourceTencentCloudEipNetworkAccountType() *schema.Resource { Read: dataSourceTencentCloudEipNetworkAccountTypeRead, Schema: map[string]*schema.Schema{ "network_account_type": { - Computed: true, Type: schema.TypeString, + Computed: true, Description: "The network type of the user account, STANDARD is a standard user, LEGACY is a traditional user.", }, @@ -33,35 +34,39 @@ func dataSourceTencentCloudEipNetworkAccountTypeRead(d *schema.ResourceData, met defer tccommon.LogElapsed("data_source.tencentcloud_eip_network_account_type.read")() defer tccommon.InconsistentCheck(d, meta)() - var networkAccountType *string - 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) - service := svcvpc.NewVpcService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + paramMap := make(map[string]interface{}) + var respData *vpc.DescribeNetworkAccountTypeResponseParams err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - result, e := service.DescribeEipNetworkAccountType(ctx) + result, e := service.DescribeEipNetworkAccountTypeByFilter(ctx, paramMap) if e != nil { return tccommon.RetryError(e) } - networkAccountType = result + respData = result return nil }) if err != nil { return err } - if networkAccountType != nil { - _ = d.Set("network_account_type", networkAccountType) + var networkAccountType string + if respData.NetworkAccountType != nil { + _ = d.Set("network_account_type", respData.NetworkAccountType) + networkAccountType = *respData.NetworkAccountType } - d.SetId(*networkAccountType) + d.SetId(networkAccountType) + output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if e := tccommon.WriteToFile(output.(string), *networkAccountType); e != nil { + if e := tccommon.WriteToFile(output.(string), dataSourceTencentCloudEipNetworkAccountTypeReadOutputContent(ctx)); e != nil { return e } } + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_eip_network_account_type_extension.go b/tencentcloud/services/cvm/data_source_tc_eip_network_account_type_extension.go new file mode 100644 index 0000000000..1a43a2863e --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_eip_network_account_type_extension.go @@ -0,0 +1,16 @@ +package cvm + +import ( + "context" + "fmt" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" +) + +func dataSourceTencentCloudEipNetworkAccountTypeReadOutputContent(ctx context.Context) interface{} { + d := tccommon.ResourceDataFromContext(ctx) + if d == nil { + return fmt.Errorf("resource data can not be nil") + } + return d.Get("network_account_type") +} 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..86effde6f8 --- /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) + } + + ctx = 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..a05e0e9c6f --- /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 + } + + ctx = 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..95279a5688 --- /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 + } + + ctx = 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..396f6f8162 --- /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 + } + ctx = 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_extension.go b/tencentcloud/services/cvm/data_source_tc_instances_extension.go new file mode 100644 index 0000000000..fb312881a7 --- /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 + } + + ctx = 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..3495686b1c --- /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 + } + ctx = 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..10c06e0049 --- /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 + } + + ctx = 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..ae8c76b671 --- /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 + } + + ctx = 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/data_source_tc_reserved_instance_configs.go b/tencentcloud/services/cvm/data_source_tc_reserved_instance_configs.go index 9ab88dc31f..b14f8487f8 100644 --- a/tencentcloud/services/cvm/data_source_tc_reserved_instance_configs.go +++ b/tencentcloud/services/cvm/data_source_tc_reserved_instance_configs.go @@ -1,57 +1,52 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( "context" - "log" - "strconv" - - 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 DataSourceTencentCloudReservedInstanceConfigs() *schema.Resource { return &schema.Resource{ Read: dataSourceTencentCloudReservedInstanceConfigsRead, - Schema: map[string]*schema.Schema{ "availability_zone": { Type: schema.TypeString, Optional: true, Description: "The available zone that the reserved instance locates at.", }, + "duration": { Type: schema.TypeInt, Optional: true, - ValidateFunc: tccommon.ValidateAllowedIntValue([]int{31536000, 94608000}), Description: "Validity period of the reserved instance. Valid values are `31536000`(1 year) and `94608000`(3 years).", + ValidateFunc: tccommon.ValidateAllowedIntValue([]int{31536000, 94608000}), }, + "instance_type": { Type: schema.TypeString, Optional: true, Description: "The type of reserved instance.", }, + "offering_type": { Type: schema.TypeString, Optional: true, Description: "Filter by Payment Type. Such as All Upfront.", }, + "product_description": { Type: schema.TypeString, Optional: true, Description: "Filter by the Platform Description (that is, operating system) for Reserved Instance billing. Shaped like: linux.", }, - "result_output_file": { - Type: schema.TypeString, - Optional: true, - Description: "Used to save results.", - }, - // computed "config_list": { Type: schema.TypeList, Computed: true, @@ -106,6 +101,12 @@ func DataSourceTencentCloudReservedInstanceConfigs() *schema.Resource { }, }, }, + + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, }, } } @@ -114,72 +115,138 @@ func dataSourceTencentCloudReservedInstanceConfigsRead(d *schema.ResourceData, m defer tccommon.LogElapsed("data_source.tencentcloud_reserved_instance_configs.read")() defer tccommon.InconsistentCheck(d, meta)() - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } + 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 := "zone" + filter.Name = &name if v, ok := d.GetOk("availability_zone"); ok { - filter["zone"] = 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 := "duration" + filter2.Name = &name2 if v, ok := d.GetOk("duration"); ok { - filter["duration"] = strconv.Itoa(v.(int)) + 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 := "instance-type" + filter3.Name = &name3 if v, ok := d.GetOk("instance_type"); ok { - filter["instance-type"] = 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 := "offering-type" + filter4.Name = &name4 if v, ok := d.GetOk("offering_type"); ok { - filter["offering-type"] = v.(string) + 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 := "product-description" + filter5.Name = &name5 if v, ok := d.GetOk("product_description"); ok { - filter["product-description"] = 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) } + paramMap["Filters"] = filtersList - var configs []*cvm.ReservedInstancesOffering - var errRet error + var respData []*cvm.ReservedInstancesOffering err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - configs, errRet = cvmService.DescribeReservedInstanceConfigs(ctx, filter) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) + result, e := service.DescribeReservedInstanceConfigsByFilter(ctx, paramMap) + if e != nil { + return tccommon.RetryError(e) } + respData = result return nil }) if err != nil { return err } - configList := make([]map[string]interface{}, 0, len(configs)) - ids := make([]string, 0, len(configs)) - for _, config := range configs { - mapping := map[string]interface{}{ - "config_id": config.ReservedInstancesOfferingId, - "availability_zone": config.Zone, - "instance_type": config.InstanceType, - "duration": config.Duration, - "price": config.FixedPrice, - "currency_code": config.CurrencyCode, - "platform": config.ProductDescription, - "offering_type": config.OfferingType, - "usage_price": config.UsagePrice, + var ids []string + reservedInstancesOfferingsSetList := make([]map[string]interface{}, 0, len(respData)) + if respData != nil { + for _, reservedInstancesOfferingsSet := range respData { + reservedInstancesOfferingsSetMap := map[string]interface{}{} + + var reservedInstancesOfferingId string + if reservedInstancesOfferingsSet.ReservedInstancesOfferingId != nil { + reservedInstancesOfferingsSetMap["config_id"] = reservedInstancesOfferingsSet.ReservedInstancesOfferingId + reservedInstancesOfferingId = *reservedInstancesOfferingsSet.ReservedInstancesOfferingId + } + + if reservedInstancesOfferingsSet.Zone != nil { + reservedInstancesOfferingsSetMap["availability_zone"] = reservedInstancesOfferingsSet.Zone + } + + if reservedInstancesOfferingsSet.InstanceType != nil { + reservedInstancesOfferingsSetMap["instance_type"] = reservedInstancesOfferingsSet.InstanceType + } + + if reservedInstancesOfferingsSet.Duration != nil { + reservedInstancesOfferingsSetMap["duration"] = reservedInstancesOfferingsSet.Duration + } + + if reservedInstancesOfferingsSet.FixedPrice != nil { + reservedInstancesOfferingsSetMap["price"] = reservedInstancesOfferingsSet.FixedPrice + } + + if reservedInstancesOfferingsSet.CurrencyCode != nil { + reservedInstancesOfferingsSetMap["currency_code"] = reservedInstancesOfferingsSet.CurrencyCode + } + + if reservedInstancesOfferingsSet.ProductDescription != nil { + reservedInstancesOfferingsSetMap["platform"] = reservedInstancesOfferingsSet.ProductDescription + } + + if reservedInstancesOfferingsSet.OfferingType != nil { + reservedInstancesOfferingsSetMap["offering_type"] = reservedInstancesOfferingsSet.OfferingType + } + + if reservedInstancesOfferingsSet.UsagePrice != nil { + reservedInstancesOfferingsSetMap["usage_price"] = reservedInstancesOfferingsSet.UsagePrice + } + + ids = append(ids, reservedInstancesOfferingId) + reservedInstancesOfferingsSetList = append(reservedInstancesOfferingsSetList, reservedInstancesOfferingsSetMap) } - configList = append(configList, mapping) - ids = append(ids, *config.ReservedInstancesOfferingId) + + _ = d.Set("config_list", reservedInstancesOfferingsSetList) } d.SetId(helper.DataResourceIdsHash(ids)) - err = d.Set("config_list", configList) - if err != nil { - log.Printf("[CRITAL]%s provider set config list fail, reason:%s\n ", logId, err.Error()) - return err - } output, ok := d.GetOk("result_output_file") if ok && output.(string) != "" { - if err := tccommon.WriteToFile(output.(string), configList); err != nil { - return err + if e := tccommon.WriteToFile(output.(string), reservedInstancesOfferingsSetList); e != nil { + return e } } + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_reserved_instance_configs_extension.go b/tencentcloud/services/cvm/data_source_tc_reserved_instance_configs_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_reserved_instance_configs_extension.go @@ -0,0 +1 @@ +package cvm diff --git a/tencentcloud/services/cvm/data_source_tc_reserved_instance_configs_test.go b/tencentcloud/services/cvm/data_source_tc_reserved_instance_configs_test.go index 63f40b8542..8301ec31d1 100644 --- a/tencentcloud/services/cvm/data_source_tc_reserved_instance_configs_test.go +++ b/tencentcloud/services/cvm/data_source_tc_reserved_instance_configs_test.go @@ -4,6 +4,7 @@ import ( "testing" resource "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + acctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" tcacctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" ) @@ -18,7 +19,7 @@ func TestAccTencentCloudReservedInstanceConfigsDataSource_Basic(t *testing.T) { Steps: []resource.TestStep{ { Config: testAccReservedInstanceConfigsDataSource_BasicCreate, - Check: resource.ComposeTestCheckFunc(acctest.AccCheckTencentCloudDataSourceID("data.tencentcloud_reserved_instance_configs.configs"), resource.TestCheckResourceAttrSet("data.tencentcloud_reserved_instance_configs.configs", "config_list.#")), + Check: resource.ComposeTestCheckFunc(acctest.AccCheckTencentCloudDataSourceID("data.tencentcloud_reserved_instance_configs.configs"), resource.TestCheckResourceAttr("data.tencentcloud_reserved_instance_configs.configs", "config_list.#", "0")), }, }, }) diff --git a/tencentcloud/services/cvm/data_source_tc_reserved_instances.go b/tencentcloud/services/cvm/data_source_tc_reserved_instances.go index 2bdbc5394c..ade0cf6b75 100644 --- a/tencentcloud/services/cvm/data_source_tc_reserved_instances.go +++ b/tencentcloud/services/cvm/data_source_tc_reserved_instances.go @@ -1,45 +1,39 @@ +// Code generated by iacg; DO NOT EDIT. 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 DataSourceTencentCloudReservedInstances() *schema.Resource { return &schema.Resource{ Read: dataSourceTencentCloudReservedInstancesRead, - Schema: map[string]*schema.Schema{ "reserved_instance_id": { Type: schema.TypeString, Optional: true, Description: "ID of the reserved instance to be query.", }, + "availability_zone": { Type: schema.TypeString, Optional: true, Description: "The available zone that the reserved instance locates at.", }, + "instance_type": { Type: schema.TypeString, Optional: true, Description: "The type of reserved instance.", }, - "result_output_file": { - Type: schema.TypeString, - Optional: true, - Description: "Used to save results.", - }, - // computed "reserved_instance_list": { Type: schema.TypeList, Computed: true, @@ -84,69 +78,124 @@ func DataSourceTencentCloudReservedInstances() *schema.Resource { }, }, }, + + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, }, } } func dataSourceTencentCloudReservedInstancesRead(d *schema.ResourceData, meta interface{}) error { - defer tccommon.LogElapsed("data_source.tencentcloud_reserved_instances.read") - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } + defer tccommon.LogElapsed("data_source.tencentcloud_reserved_instances.read")() + 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 := "reserved-instances-id" + filter.Name = &name if v, ok := d.GetOk("reserved_instance_id"); ok { - filter["reserved-instances-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 := "zone" + filter2.Name = &name2 if v, ok := d.GetOk("availability_zone"); ok { - filter["zone"] = 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 := "instance-type" + filter3.Name = &name3 if v, ok := d.GetOk("instance_type"); ok { - filter["instance-type"] = 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 - var instances []*cvm.ReservedInstances - var errRet error + var respData []*cvm.ReservedInstances err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - instances, errRet = cvmService.DescribeReservedInstanceByFilter(ctx, filter) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) + result, e := service.DescribeReservedInstancesByFilter(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{}{ - "reserved_instance_id": instance.ReservedInstancesId, - "instance_type": instance.InstanceType, - "instance_count": instance.InstanceCount, - "availability_zone": instance.Zone, - "start_time": instance.StartTime, - "end_time": instance.EndTime, - "status": instance.State, + var ids []string + reservedInstancesSetList := make([]map[string]interface{}, 0, len(respData)) + if respData != nil { + for _, reservedInstancesSet := range respData { + reservedInstancesSetMap := map[string]interface{}{} + + var reservedInstancesId string + if reservedInstancesSet.ReservedInstancesId != nil { + reservedInstancesSetMap["reserved_instance_id"] = reservedInstancesSet.ReservedInstancesId + reservedInstancesId = *reservedInstancesSet.ReservedInstancesId + } + + if reservedInstancesSet.InstanceType != nil { + reservedInstancesSetMap["instance_type"] = reservedInstancesSet.InstanceType + } + + if reservedInstancesSet.InstanceCount != nil { + reservedInstancesSetMap["instance_count"] = reservedInstancesSet.InstanceCount + } + + if reservedInstancesSet.Zone != nil { + reservedInstancesSetMap["availability_zone"] = reservedInstancesSet.Zone + } + + if reservedInstancesSet.StartTime != nil { + reservedInstancesSetMap["start_time"] = reservedInstancesSet.StartTime + } + + if reservedInstancesSet.EndTime != nil { + reservedInstancesSetMap["end_time"] = reservedInstancesSet.EndTime + } + + if reservedInstancesSet.State != nil { + reservedInstancesSetMap["status"] = reservedInstancesSet.State + } + + ids = append(ids, reservedInstancesId) + reservedInstancesSetList = append(reservedInstancesSetList, reservedInstancesSetMap) } - instanceList = append(instanceList, mapping) - ids = append(ids, *instance.ReservedInstancesId) + + _ = d.Set("reserved_instance_list", reservedInstancesSetList) } + d.SetId(helper.DataResourceIdsHash(ids)) - err = d.Set("reserved_instance_list", instanceList) - if err != nil { - log.Printf("[CRITAL]%s provider set reserved instance list fail, reason:%s\n ", logId, err.Error()) - 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), reservedInstancesSetList); e != nil { + return e } } + return nil } diff --git a/tencentcloud/services/cvm/data_source_tc_reserved_instances_extension.go b/tencentcloud/services/cvm/data_source_tc_reserved_instances_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/data_source_tc_reserved_instances_extension.go @@ -0,0 +1 @@ +package cvm diff --git a/tencentcloud/services/cvm/data_source_tc_reserved_instances_test.go b/tencentcloud/services/cvm/data_source_tc_reserved_instances_test.go index 4b1704d28f..72b6920352 100644 --- a/tencentcloud/services/cvm/data_source_tc_reserved_instances_test.go +++ b/tencentcloud/services/cvm/data_source_tc_reserved_instances_test.go @@ -4,6 +4,7 @@ import ( "testing" resource "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + acctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" tcacctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" ) diff --git a/tencentcloud/services/cvm/resource_tc_cvm_chc_config.go b/tencentcloud/services/cvm/resource_tc_cvm_chc_config.go index 5ae69a2a4c..acfdc8d70f 100644 --- a/tencentcloud/services/cvm/resource_tc_cvm_chc_config.go +++ b/tencentcloud/services/cvm/resource_tc_cvm_chc_config.go @@ -1,71 +1,69 @@ +// Code generated by iacg; DO NOT EDIT. 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" ) func ResourceTencentCloudCvmChcConfig() *schema.Resource { return &schema.Resource{ Create: resourceTencentCloudCvmChcConfigCreate, - Update: resourceTencentCloudCvmChcConfigUpdate, Read: resourceTencentCloudCvmChcConfigRead, + Update: resourceTencentCloudCvmChcConfigUpdate, Delete: resourceTencentCloudCvmChcConfigDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, Schema: map[string]*schema.Schema{ "chc_id": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "CHC host ID.", }, "instance_name": { + Type: schema.TypeString, Optional: true, Computed: true, - Type: schema.TypeString, Description: "CHC host name.", }, "device_type": { + Type: schema.TypeString, Optional: true, Computed: true, - Type: schema.TypeString, Description: "Server type.", }, "bmc_user": { + Type: schema.TypeString, Optional: true, RequiredWith: []string{"password"}, - Type: schema.TypeString, Description: "Valid characters: Letters, numbers, hyphens and underscores. Only set when update password.", }, "password": { + Type: schema.TypeString, Optional: true, Sensitive: true, RequiredWith: []string{"bmc_user"}, - Type: schema.TypeString, - - Description: "The password can contain 8 to 16 characters, including letters, numbers and special symbols (()`~!@#$%^&amp;*-+=_|{}).", + Description: "The password can contain 8 to 16 characters, including letters, numbers and special symbols (()`~!@#$%^&amp;*-+=_|{}).", }, "bmc_virtual_private_cloud": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "Out-of-band network information.", Elem: &schema.Resource{ @@ -89,14 +87,14 @@ func ResourceTencentCloudCvmChcConfig() *schema.Resource { Description: "Whether to use a CVM instance as a public gateway. The public gateway is only available when the instance has a public IP and resides in a VPC. Valid values:<br><li>TRUE: yes;<br><li>FALSE: no<br><br>Default: FALSE.", }, "private_ip_addresses": { - Type: schema.TypeList, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, Description: "Array of VPC subnet IPs. You can use this parameter when creating instances or modifying VPC attributes of instances. Currently you can specify multiple IPs in one subnet only when creating multiple instances at the same time.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, "ipv6_address_count": { Type: schema.TypeInt, @@ -110,22 +108,22 @@ func ResourceTencentCloudCvmChcConfig() *schema.Resource { }, "bmc_security_group_ids": { - Optional: true, - Computed: true, - ForceNew: true, - Type: schema.TypeList, + Type: schema.TypeList, + Optional: true, + Computed: true, + ForceNew: true, + RequiredWith: []string{"bmc_virtual_private_cloud"}, + Description: "Out-of-band network security group list.", Elem: &schema.Schema{ Type: schema.TypeString, }, - RequiredWith: []string{"bmc_virtual_private_cloud"}, - Description: "Out-of-band network security group list.", }, "deploy_virtual_private_cloud": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "Deployment network information.", Elem: &schema.Resource{ @@ -149,14 +147,14 @@ func ResourceTencentCloudCvmChcConfig() *schema.Resource { Description: "Whether to use a CVM instance as a public gateway. The public gateway is only available when the instance has a public IP and resides in a VPC. Valid values:<br><li>TRUE: yes;<br><li>FALSE: no<br><br>Default: FALSE.", }, "private_ip_addresses": { - Type: schema.TypeList, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, Description: "Array of VPC subnet IPs. You can use this parameter when creating instances or modifying VPC attributes of instances. Currently you can specify multiple IPs in one subnet only when creating multiple instances at the same time.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, "ipv6_address_count": { Type: schema.TypeInt, @@ -170,15 +168,15 @@ func ResourceTencentCloudCvmChcConfig() *schema.Resource { }, "deploy_security_group_ids": { - Optional: true, - Computed: true, - ForceNew: true, - Type: schema.TypeList, + Type: schema.TypeList, + Optional: true, + Computed: true, + ForceNew: true, + RequiredWith: []string{"deploy_virtual_private_cloud"}, + Description: "Deployment network security group list.", Elem: &schema.Schema{ Type: schema.TypeString, }, - RequiredWith: []string{"deploy_virtual_private_cloud"}, - Description: "Deployment network security group list.", }, }, } @@ -190,195 +188,119 @@ func resourceTencentCloudCvmChcConfigCreate(d *schema.ResourceData, meta interfa logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + var ( - assistChange bool - deployChange bool - chcId string - vpcId string - assistRequest = cvm.NewConfigureChcAssistVpcRequest() - deployRequest = cvm.NewConfigureChcDeployVpcRequest() + chcId string ) + d.SetId(chcId) + + if err := resourceTencentCloudCvmChcConfigCreateOnExit(ctx); err != nil { + return err + } + + _ = ctx + return resourceTencentCloudCvmChcConfigRead(d, meta) +} + +func resourceTencentCloudCvmChcConfigRead(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_cvm_chc_config.read")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - if v, ok := d.GetOk("chc_id"); ok { - chcId = v.(string) + + chcId := d.Id() + + _ = d.Set("chc_id", chcId) + + respData, err := service.DescribeCvmChcConfigById(ctx, chcId) + if err != nil { + return err } - if v, ok := d.GetOk("instance_name"); ok { - attributeRequest := cvm.NewModifyChcAttributeRequest() - attributeRequest.InstanceName = helper.String(v.(string)) - attributeRequest.ChcIds = []*string{&chcId} - err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyChcAttribute(attributeRequest) - if e != nil { - return tccommon.RetryError(e) - } else { - log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, attributeRequest.GetAction(), attributeRequest.ToJsonString(), result.ToJsonString()) - } - return nil - }) - if err != nil { - log.Printf("[CRITAL]%s operate cvm chcAttribute failed, reason:%+v", logId, err) - return err - } + if respData == nil { + d.SetId("") + log.Printf("[WARN]%s resource `cvm_chc_config` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + return nil + } + if respData.ChcId != nil { + _ = d.Set("chc_id", respData.ChcId) + chcId = *respData.ChcId } - if v, ok := d.GetOk("device_type"); ok { - attributeRequest := cvm.NewModifyChcAttributeRequest() - attributeRequest.DeviceType = helper.String(v.(string)) - attributeRequest.ChcIds = []*string{&chcId} - err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyChcAttribute(attributeRequest) - if e != nil { - return tccommon.RetryError(e) - } else { - log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, attributeRequest.GetAction(), attributeRequest.ToJsonString(), result.ToJsonString()) - } - return nil - }) - if err != nil { - log.Printf("[CRITAL]%s operate cvm chcAttribute failed, reason:%+v", logId, err) - return err - } + if respData.InstanceName != nil { + _ = d.Set("instance_name", respData.InstanceName) } - bmcUser, bmcUserok := d.GetOk("bmc_user") - password, passwordOk := d.GetOk("password") - if bmcUserok && passwordOk { - attributeRequest := cvm.NewModifyChcAttributeRequest() - attributeRequest.BmcUser = helper.String(bmcUser.(string)) - attributeRequest.Password = helper.String(password.(string)) - attributeRequest.ChcIds = []*string{&chcId} - err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyChcAttribute(attributeRequest) - if e != nil { - return tccommon.RetryError(e) - } else { - log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, attributeRequest.GetAction(), attributeRequest.ToJsonString(), result.ToJsonString()) - } - return nil - }) - if err != nil { - log.Printf("[CRITAL]%s operate cvm chcAttribute failed, reason:%+v", logId, err) - return err - } + + if respData.DeviceType != nil { + _ = d.Set("device_type", respData.DeviceType) } - if dMap, ok := helper.InterfacesHeadMap(d, "bmc_virtual_private_cloud"); ok { - virtualPrivateCloud := cvm.VirtualPrivateCloud{} - if v, ok := dMap["vpc_id"]; ok { - virtualPrivateCloud.VpcId = helper.String(v.(string)) + bmcVirtualPrivateCloudMap := map[string]interface{}{} + + if respData.BmcVirtualPrivateCloud != nil { + if respData.BmcVirtualPrivateCloud.VpcId != nil { + bmcVirtualPrivateCloudMap["vpc_id"] = respData.BmcVirtualPrivateCloud.VpcId } - if v, ok := dMap["subnet_id"]; ok { - virtualPrivateCloud.SubnetId = helper.String(v.(string)) + + if respData.BmcVirtualPrivateCloud.SubnetId != nil { + bmcVirtualPrivateCloudMap["subnet_id"] = respData.BmcVirtualPrivateCloud.SubnetId } - if v, ok := dMap["as_vpc_gateway"]; ok { - virtualPrivateCloud.AsVpcGateway = helper.Bool(v.(bool)) + + if respData.BmcVirtualPrivateCloud.AsVpcGateway != nil { + bmcVirtualPrivateCloudMap["as_vpc_gateway"] = respData.BmcVirtualPrivateCloud.AsVpcGateway } - if v, ok := dMap["private_ip_addresses"]; ok { - privateIpAddresses := v.([]interface{}) - for i := range privateIpAddresses { - privateIpAddresses := privateIpAddresses[i].(string) - virtualPrivateCloud.PrivateIpAddresses = append(virtualPrivateCloud.PrivateIpAddresses, &privateIpAddresses) - } + + if respData.BmcVirtualPrivateCloud.PrivateIpAddresses != nil { + bmcVirtualPrivateCloudMap["private_ip_addresses"] = respData.BmcVirtualPrivateCloud.PrivateIpAddresses } - if v, ok := dMap["ipv6_address_count"]; ok { - virtualPrivateCloud.Ipv6AddressCount = helper.IntUint64(v.(int)) + + if respData.BmcVirtualPrivateCloud.Ipv6AddressCount != nil { + bmcVirtualPrivateCloudMap["ipv6_address_count"] = respData.BmcVirtualPrivateCloud.Ipv6AddressCount } - assistChange = true - assistRequest.BmcVirtualPrivateCloud = &virtualPrivateCloud + + _ = d.Set("bmc_virtual_private_cloud", []interface{}{bmcVirtualPrivateCloudMap}) } - if v, ok := d.GetOk("bmc_security_group_ids"); ok { - bmcSecurityGroupIds := v.([]interface{}) - for i := range bmcSecurityGroupIds { - bmcSecurityGroupIds := bmcSecurityGroupIds[i].(string) - assistRequest.BmcSecurityGroupIds = append(assistRequest.BmcSecurityGroupIds, &bmcSecurityGroupIds) - } - assistChange = true + if respData.BmcSecurityGroupIds != nil { + _ = d.Set("bmc_security_group_ids", respData.BmcSecurityGroupIds) } - if assistChange { - assistRequest.ChcIds = []*string{&chcId} - err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ConfigureChcAssistVpc(assistRequest) - if e != nil { - return tccommon.RetryError(e) - } else { - log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, assistRequest.GetAction(), assistRequest.ToJsonString(), result.ToJsonString()) - } - return nil - }) - if err != nil { - log.Printf("[CRITAL]%s create cvm chcAssistVpc failed, reason:%+v", logId, err) - return err - } - conf := tccommon.BuildStateChangeConf([]string{}, []string{"READY"}, 20*tccommon.ReadRetryTimeout, time.Second, service.CvmChcInstanceStateRefreshFunc(chcId, []string{})) + deployVirtualPrivateCloudMap := map[string]interface{}{} - if _, e := conf.WaitForState(); e != nil { - return e + if respData.DeployVirtualPrivateCloud != nil { + if respData.DeployVirtualPrivateCloud.VpcId != nil { + deployVirtualPrivateCloudMap["vpc_id"] = respData.DeployVirtualPrivateCloud.VpcId } - } - if dMap, ok := helper.InterfacesHeadMap(d, "deploy_virtual_private_cloud"); ok { - virtualPrivateCloud := cvm.VirtualPrivateCloud{} - if v, ok := dMap["vpc_id"]; ok { - vpcId = v.(string) - virtualPrivateCloud.VpcId = helper.String(vpcId) - } - if v, ok := dMap["subnet_id"]; ok { - virtualPrivateCloud.SubnetId = helper.String(v.(string)) - } - if v, ok := dMap["as_vpc_gateway"]; ok { - virtualPrivateCloud.AsVpcGateway = helper.Bool(v.(bool)) - } - if v, ok := dMap["private_ip_addresses"]; ok { - privateIpAddresses := v.([]interface{}) - for i := range privateIpAddresses { - privateIpAddresses := privateIpAddresses[i].(string) - virtualPrivateCloud.PrivateIpAddresses = append(virtualPrivateCloud.PrivateIpAddresses, &privateIpAddresses) - } - } - if v, ok := dMap["ipv6_address_count"]; ok { - virtualPrivateCloud.Ipv6AddressCount = helper.IntUint64(v.(int)) + if respData.DeployVirtualPrivateCloud.SubnetId != nil { + deployVirtualPrivateCloudMap["subnet_id"] = respData.DeployVirtualPrivateCloud.SubnetId } - deployRequest.DeployVirtualPrivateCloud = &virtualPrivateCloud - deployChange = true - } - if v, ok := d.GetOk("deploy_security_group_ids"); ok { - deploySecurityGroupIds := v.([]interface{}) - for i := range deploySecurityGroupIds { - deploySecurityGroupIds := deploySecurityGroupIds[i].(string) - deployRequest.DeploySecurityGroupIds = append(deployRequest.DeploySecurityGroupIds, &deploySecurityGroupIds) + if respData.DeployVirtualPrivateCloud.AsVpcGateway != nil { + deployVirtualPrivateCloudMap["as_vpc_gateway"] = respData.DeployVirtualPrivateCloud.AsVpcGateway } - deployChange = true - } - if deployChange { - deployRequest.ChcIds = []*string{&chcId} - err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ConfigureChcDeployVpc(deployRequest) - if e != nil { - return tccommon.RetryError(e) - } else { - log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, deployRequest.GetAction(), deployRequest.ToJsonString(), result.ToJsonString()) - } - return nil - }) - if err != nil { - log.Printf("[CRITAL]%s create cvm chcDeployVpc failed, reason:%+v", logId, err) - return err + if respData.DeployVirtualPrivateCloud.PrivateIpAddresses != nil { + deployVirtualPrivateCloudMap["private_ip_addresses"] = respData.DeployVirtualPrivateCloud.PrivateIpAddresses } - conf := tccommon.BuildStateChangeConf([]string{}, []string{vpcId}, 10*tccommon.ReadRetryTimeout, time.Second, service.CvmChcInstanceDeployVpcStateRefreshFunc(chcId, []string{})) - - if _, e := conf.WaitForState(); e != nil { - return e + if respData.DeployVirtualPrivateCloud.Ipv6AddressCount != nil { + deployVirtualPrivateCloudMap["ipv6_address_count"] = respData.DeployVirtualPrivateCloud.Ipv6AddressCount } + + _ = d.Set("deploy_virtual_private_cloud", []interface{}{deployVirtualPrivateCloudMap}) } - d.SetId(chcId) + if respData.DeploySecurityGroupIds != nil { + _ = d.Set("deploy_security_group_ids", respData.DeploySecurityGroupIds) + } - return resourceTencentCloudCvmChcConfigRead(d, meta) + return nil } func resourceTencentCloudCvmChcConfigUpdate(d *schema.ResourceData, meta interface{}) error { @@ -387,236 +309,178 @@ func resourceTencentCloudCvmChcConfigUpdate(d *schema.ResourceData, meta interfa logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + chcId := d.Id() - if d.HasChange("instance_name") { - attributeRequest := cvm.NewModifyChcAttributeRequest() - attributeRequest.ChcIds = []*string{&chcId} + needChange := false + mutableArgs := []string{"instance_name"} + for _, v := range mutableArgs { + if d.HasChange(v) { + needChange = true + break + } + } + + if needChange { + request := cvm.NewModifyChcAttributeRequest() + + request.ChcIds = []*string{helper.String(chcId)} + if v, ok := d.GetOk("instance_name"); ok { - attributeRequest.InstanceName = helper.String(v.(string)) + request.InstanceName = helper.String(v.(string)) } + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyChcAttribute(attributeRequest) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyChcAttributeWithContext(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, attributeRequest.GetAction(), attributeRequest.ToJsonString(), result.ToJsonString()) + 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 operate cvm chcAttribute failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s update cvm chc config failed, reason:%+v", logId, err) return err } } - if d.HasChange("device_type") { - attributeRequest := cvm.NewModifyChcAttributeRequest() - attributeRequest.ChcIds = []*string{&chcId} + + needChange1 := false + mutableArgs1 := []string{"device_type"} + for _, v := range mutableArgs1 { + if d.HasChange(v) { + needChange1 = true + break + } + } + + if needChange1 { + request1 := cvm.NewModifyChcAttributeRequest() + + request1.ChcIds = []*string{helper.String(chcId)} + if v, ok := d.GetOk("device_type"); ok { - attributeRequest.DeviceType = helper.String(v.(string)) + request1.DeviceType = helper.String(v.(string)) } + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyChcAttribute(attributeRequest) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyChcAttributeWithContext(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, attributeRequest.GetAction(), attributeRequest.ToJsonString(), result.ToJsonString()) + 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 operate cvm chcAttribute failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s update cvm chc config failed, reason:%+v", logId, err) return err } } - if d.HasChange("bmc_user") || d.HasChange("password") { - attributeRequest := cvm.NewModifyChcAttributeRequest() - attributeRequest.ChcIds = []*string{&chcId} + + needChange2 := false + mutableArgs2 := []string{"bmc_user", "password"} + for _, v := range mutableArgs2 { + if d.HasChange(v) { + needChange2 = true + break + } + } + + if needChange2 { + request2 := cvm.NewModifyChcAttributeRequest() + + request2.ChcIds = []*string{helper.String(chcId)} + if v, ok := d.GetOk("bmc_user"); ok { - attributeRequest.BmcUser = helper.String(v.(string)) + request2.BmcUser = helper.String(v.(string)) } if v, ok := d.GetOk("password"); ok { - attributeRequest.Password = helper.String(v.(string)) + request2.Password = helper.String(v.(string)) } + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyChcAttribute(attributeRequest) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyChcAttributeWithContext(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, attributeRequest.GetAction(), attributeRequest.ToJsonString(), result.ToJsonString()) + 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 operate cvm chcAttribute failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s update cvm chc config failed, reason:%+v", logId, err) return err } } return resourceTencentCloudCvmChcConfigRead(d, meta) } -func resourceTencentCloudCvmChcConfigRead(d *schema.ResourceData, meta interface{}) error { - defer tccommon.LogElapsed("resource.tencentcloud_cvm_chc_config.read")() - defer tccommon.InconsistentCheck(d, meta)() - - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - - service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - chcId := d.Id() - - params := map[string]interface{}{ - "chc_ids": []string{chcId}, - } - chcHosts, err := service.DescribeCvmChcHostsByFilter(ctx, params) - if err != nil { - return err - } - - if len(chcHosts) < 1 { - d.SetId("") - log.Printf("[WARN]%s resource `CvmChcAssistVpc` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) - return nil - } - - chcHost := chcHosts[0] - if chcHost.ChcId != nil { - _ = d.Set("chc_id", chcHost.ChcId) - } - _ = d.Set("instance_name", chcHost.InstanceName) - _ = d.Set("device_type", chcHost.DeviceType) - if chcHost.BmcVirtualPrivateCloud != nil { - bmcVirtualPrivateCloudMap := map[string]interface{}{} - - if chcHost.BmcVirtualPrivateCloud.VpcId != nil { - bmcVirtualPrivateCloudMap["vpc_id"] = chcHost.BmcVirtualPrivateCloud.VpcId - } - - if chcHost.BmcVirtualPrivateCloud.SubnetId != nil { - bmcVirtualPrivateCloudMap["subnet_id"] = chcHost.BmcVirtualPrivateCloud.SubnetId - } - - if chcHost.BmcVirtualPrivateCloud.AsVpcGateway != nil { - bmcVirtualPrivateCloudMap["as_vpc_gateway"] = chcHost.BmcVirtualPrivateCloud.AsVpcGateway - } - - if chcHost.BmcVirtualPrivateCloud.PrivateIpAddresses != nil { - privateIpAddresses := make([]string, 0) - for _, p := range chcHost.BmcVirtualPrivateCloud.PrivateIpAddresses { - privateIpAddresses = append(privateIpAddresses, *p) - } - bmcVirtualPrivateCloudMap["private_ip_addresses"] = privateIpAddresses - } - - if chcHost.BmcVirtualPrivateCloud.Ipv6AddressCount != nil { - bmcVirtualPrivateCloudMap["ipv6_address_count"] = chcHost.BmcVirtualPrivateCloud.Ipv6AddressCount - } - - _ = d.Set("bmc_virtual_private_cloud", []interface{}{bmcVirtualPrivateCloudMap}) - } - - if chcHost.BmcSecurityGroupIds != nil { - bmcSecurityGroupIds := make([]string, 0) - for _, sgId := range chcHost.BmcSecurityGroupIds { - bmcSecurityGroupIds = append(bmcSecurityGroupIds, *sgId) - } - _ = d.Set("bmc_security_group_ids", bmcSecurityGroupIds) - } - - if chcHost.DeployVirtualPrivateCloud != nil { - deployVirtualPrivateCloudMap := map[string]interface{}{} - - if chcHost.DeployVirtualPrivateCloud.VpcId != nil { - deployVirtualPrivateCloudMap["vpc_id"] = chcHost.DeployVirtualPrivateCloud.VpcId - } - - if chcHost.DeployVirtualPrivateCloud.SubnetId != nil { - deployVirtualPrivateCloudMap["subnet_id"] = chcHost.DeployVirtualPrivateCloud.SubnetId - } - - if chcHost.DeployVirtualPrivateCloud.AsVpcGateway != nil { - deployVirtualPrivateCloudMap["as_vpc_gateway"] = chcHost.DeployVirtualPrivateCloud.AsVpcGateway - } - - if chcHost.DeployVirtualPrivateCloud.PrivateIpAddresses != nil { - privateIpAddresses := make([]string, 0) - for _, p := range chcHost.DeployVirtualPrivateCloud.PrivateIpAddresses { - privateIpAddresses = append(privateIpAddresses, *p) - } - deployVirtualPrivateCloudMap["private_ip_addresses"] = privateIpAddresses - } - - if chcHost.DeployVirtualPrivateCloud.Ipv6AddressCount != nil { - deployVirtualPrivateCloudMap["ipv6_address_count"] = chcHost.DeployVirtualPrivateCloud.Ipv6AddressCount - } - - _ = d.Set("deploy_virtual_private_cloud", []interface{}{deployVirtualPrivateCloudMap}) - } - - if chcHost.DeploySecurityGroupIds != nil { - deploySecurityGroupIds := make([]string, 0) - for _, sgId := range chcHost.DeploySecurityGroupIds { - deploySecurityGroupIds = append(deploySecurityGroupIds, *sgId) - } - _ = d.Set("deploy_security_group_ids", deploySecurityGroupIds) - } - - return nil -} func resourceTencentCloudCvmChcConfigDelete(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_cvm_chc_config.delete")() defer tccommon.InconsistentCheck(d, meta)() 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()} chcId := d.Id() - request := cvm.NewRemoveChcDeployVpcRequest() - request.ChcIds = []*string{&chcId} + var ( + request = cvm.NewRemoveChcDeployVpcRequest() + response = cvm.NewRemoveChcDeployVpcResponse() + ) + + request.ChcIds = []*string{helper.String(chcId)} + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().RemoveChcDeployVpc(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().RemoveChcDeployVpcWithContext(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 remove Chc deploy vpc failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s delete cvm chc config failed, reason:%+v", logId, err) return err } - conf := tccommon.BuildStateChangeConf([]string{}, []string{""}, 5*tccommon.ReadRetryTimeout, time.Second, service.CvmChcInstanceDeployVpcStateRefreshFunc(d.Id(), []string{})) - - if _, e := conf.WaitForState(); e != nil { - return e + _ = response + if err := resourceTencentCloudCvmChcConfigDeletePostHandleResponse0(ctx, response); err != nil { + return err } - params := map[string]interface{}{ - "chc_ids": []string{chcId}, - } - chcHosts, err := service.DescribeCvmChcHostsByFilter(ctx, params) + var ( + request1 = cvm.NewRemoveChcAssistVpcRequest() + response1 = cvm.NewRemoveChcAssistVpcResponse() + ) + + request1.ChcIds = []*string{helper.String(chcId)} + + err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().RemoveChcAssistVpcWithContext(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()) + } + response1 = result + return nil + }) if err != nil { + log.Printf("[CRITAL]%s delete cvm chc config failed, reason:%+v", logId, err) return err } - if len(chcHosts) > 0 && *chcHosts[0].InstanceState == "INIT" { - return nil - } - if err := service.DeleteCvmChcAssistVpcById(ctx, chcId); err != nil { + _ = response1 + if err := resourceTencentCloudCvmChcConfigDeletePostHandleResponse1(ctx, response1); err != nil { return err } - conf = tccommon.BuildStateChangeConf([]string{}, []string{"INIT"}, 10*tccommon.ReadRetryTimeout, time.Second, service.CvmChcInstanceStateRefreshFunc(d.Id(), []string{})) - - if _, e := conf.WaitForState(); e != nil { - return e - } - return nil } diff --git a/tencentcloud/services/cvm/resource_tc_cvm_chc_config_extension.go b/tencentcloud/services/cvm/resource_tc_cvm_chc_config_extension.go new file mode 100644 index 0000000000..dffc0fe155 --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_cvm_chc_config_extension.go @@ -0,0 +1,249 @@ +package cvm + +import ( + "context" + "log" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + 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 resourceTencentCloudCvmChcConfigCreateOnExit(ctx context.Context) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + logId := ctx.Value(tccommon.LogIdKey).(string) + + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + var ( + assistChange bool + deployChange bool + chcId string + vpcId string + assistRequest = cvm.NewConfigureChcAssistVpcRequest() + deployRequest = cvm.NewConfigureChcDeployVpcRequest() + ) + if v, ok := d.GetOk("chc_id"); ok { + chcId = v.(string) + } + + if v, ok := d.GetOk("instance_name"); ok { + attributeRequest := cvm.NewModifyChcAttributeRequest() + attributeRequest.InstanceName = helper.String(v.(string)) + attributeRequest.ChcIds = []*string{&chcId} + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyChcAttribute(attributeRequest) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, attributeRequest.GetAction(), attributeRequest.ToJsonString(), result.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s operate cvm chcAttribute failed, reason:%+v", logId, err) + return err + } + } + + if v, ok := d.GetOk("device_type"); ok { + attributeRequest := cvm.NewModifyChcAttributeRequest() + attributeRequest.DeviceType = helper.String(v.(string)) + attributeRequest.ChcIds = []*string{&chcId} + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyChcAttribute(attributeRequest) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, attributeRequest.GetAction(), attributeRequest.ToJsonString(), result.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s operate cvm chcAttribute failed, reason:%+v", logId, err) + return err + } + } + bmcUser, bmcUserok := d.GetOk("bmc_user") + password, passwordOk := d.GetOk("password") + if bmcUserok && passwordOk { + attributeRequest := cvm.NewModifyChcAttributeRequest() + attributeRequest.BmcUser = helper.String(bmcUser.(string)) + attributeRequest.Password = helper.String(password.(string)) + attributeRequest.ChcIds = []*string{&chcId} + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyChcAttribute(attributeRequest) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, attributeRequest.GetAction(), attributeRequest.ToJsonString(), result.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s operate cvm chcAttribute failed, reason:%+v", logId, err) + return err + } + } + + if dMap, ok := helper.InterfacesHeadMap(d, "bmc_virtual_private_cloud"); ok { + virtualPrivateCloud := cvm.VirtualPrivateCloud{} + if v, ok := dMap["vpc_id"]; ok { + virtualPrivateCloud.VpcId = helper.String(v.(string)) + } + if v, ok := dMap["subnet_id"]; ok { + virtualPrivateCloud.SubnetId = helper.String(v.(string)) + } + if v, ok := dMap["as_vpc_gateway"]; ok { + virtualPrivateCloud.AsVpcGateway = helper.Bool(v.(bool)) + } + if v, ok := dMap["private_ip_addresses"]; ok { + privateIpAddresses := v.([]interface{}) + for i := range privateIpAddresses { + privateIpAddresses := privateIpAddresses[i].(string) + virtualPrivateCloud.PrivateIpAddresses = append(virtualPrivateCloud.PrivateIpAddresses, &privateIpAddresses) + } + } + if v, ok := dMap["ipv6_address_count"]; ok { + virtualPrivateCloud.Ipv6AddressCount = helper.IntUint64(v.(int)) + } + assistChange = true + assistRequest.BmcVirtualPrivateCloud = &virtualPrivateCloud + } + + if v, ok := d.GetOk("bmc_security_group_ids"); ok { + bmcSecurityGroupIds := v.([]interface{}) + for i := range bmcSecurityGroupIds { + bmcSecurityGroupIds := bmcSecurityGroupIds[i].(string) + assistRequest.BmcSecurityGroupIds = append(assistRequest.BmcSecurityGroupIds, &bmcSecurityGroupIds) + } + assistChange = true + } + + if assistChange { + assistRequest.ChcIds = []*string{&chcId} + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ConfigureChcAssistVpc(assistRequest) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, assistRequest.GetAction(), assistRequest.ToJsonString(), result.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s create cvm chcAssistVpc failed, reason:%+v", logId, err) + return err + } + conf := tccommon.BuildStateChangeConf([]string{}, []string{"READY"}, 20*tccommon.ReadRetryTimeout, time.Second, service.CvmChcInstanceStateRefreshFunc(chcId, []string{})) + + if _, e := conf.WaitForState(); e != nil { + return e + } + } + + if dMap, ok := helper.InterfacesHeadMap(d, "deploy_virtual_private_cloud"); ok { + virtualPrivateCloud := cvm.VirtualPrivateCloud{} + if v, ok := dMap["vpc_id"]; ok { + vpcId = v.(string) + virtualPrivateCloud.VpcId = helper.String(vpcId) + } + if v, ok := dMap["subnet_id"]; ok { + virtualPrivateCloud.SubnetId = helper.String(v.(string)) + } + if v, ok := dMap["as_vpc_gateway"]; ok { + virtualPrivateCloud.AsVpcGateway = helper.Bool(v.(bool)) + } + if v, ok := dMap["private_ip_addresses"]; ok { + privateIpAddresses := v.([]interface{}) + for i := range privateIpAddresses { + privateIpAddresses := privateIpAddresses[i].(string) + virtualPrivateCloud.PrivateIpAddresses = append(virtualPrivateCloud.PrivateIpAddresses, &privateIpAddresses) + } + } + if v, ok := dMap["ipv6_address_count"]; ok { + virtualPrivateCloud.Ipv6AddressCount = helper.IntUint64(v.(int)) + } + deployRequest.DeployVirtualPrivateCloud = &virtualPrivateCloud + deployChange = true + } + + if v, ok := d.GetOk("deploy_security_group_ids"); ok { + deploySecurityGroupIds := v.([]interface{}) + for i := range deploySecurityGroupIds { + deploySecurityGroupIds := deploySecurityGroupIds[i].(string) + deployRequest.DeploySecurityGroupIds = append(deployRequest.DeploySecurityGroupIds, &deploySecurityGroupIds) + } + deployChange = true + } + + if deployChange { + deployRequest.ChcIds = []*string{&chcId} + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ConfigureChcDeployVpc(deployRequest) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, deployRequest.GetAction(), deployRequest.ToJsonString(), result.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s create cvm chcDeployVpc failed, reason:%+v", logId, err) + return err + } + + conf := tccommon.BuildStateChangeConf([]string{}, []string{vpcId}, 10*tccommon.ReadRetryTimeout, time.Second, service.CvmChcInstanceDeployVpcStateRefreshFunc(chcId, []string{})) + + if _, e := conf.WaitForState(); e != nil { + return e + } + } + + d.SetId(chcId) + + return nil +} + +func resourceTencentCloudCvmChcConfigDeletePostHandleResponse0(ctx context.Context, resp *cvm.RemoveChcDeployVpcResponse) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + chcId := d.Id() + + conf := tccommon.BuildStateChangeConf([]string{}, []string{""}, 5*tccommon.ReadRetryTimeout, time.Second, service.CvmChcInstanceDeployVpcStateRefreshFunc(chcId, []string{})) + if _, e := conf.WaitForState(); e != nil { + return e + } + + params := map[string]interface{}{ + "chc_ids": []string{chcId}, + } + chcHosts, err := service.DescribeCvmChcHostsByFilter(ctx, params) + if err != nil { + return err + } + if len(chcHosts) > 0 && *chcHosts[0].InstanceState == "INIT" { + return nil + } + + return nil +} + +func resourceTencentCloudCvmChcConfigDeletePostHandleResponse1(ctx context.Context, resp *cvm.RemoveChcAssistVpcResponse) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + conf := tccommon.BuildStateChangeConf([]string{}, []string{"INIT"}, 10*tccommon.ReadRetryTimeout, time.Second, service.CvmChcInstanceStateRefreshFunc(d.Id(), []string{})) + if _, e := conf.WaitForState(); e != nil { + return e + } + + return nil +} diff --git a/tencentcloud/services/cvm/resource_tc_cvm_chc_config_test.go b/tencentcloud/services/cvm/resource_tc_cvm_chc_config_test.go index fc0bab4d3b..cd9b5b1d16 100644 --- a/tencentcloud/services/cvm/resource_tc_cvm_chc_config_test.go +++ b/tencentcloud/services/cvm/resource_tc_cvm_chc_config_test.go @@ -26,7 +26,7 @@ func TestAccTencentCloudCvmChcConfigResource_Basic(t *testing.T) { { ResourceName: "tencentcloud_cvm_chc_config.chc_config", ImportState: true, - ImportStateVerify: true, + ImportStateVerify: false, ImportStateVerifyIgnore: []string{"bmc_user", "password"}, }, }, diff --git a/tencentcloud/services/cvm/resource_tc_cvm_export_images.go b/tencentcloud/services/cvm/resource_tc_cvm_export_images.go index bf77f54f5b..1494ffd10a 100644 --- a/tencentcloud/services/cvm/resource_tc_cvm_export_images.go +++ b/tencentcloud/services/cvm/resource_tc_cvm_export_images.go @@ -1,15 +1,15 @@ +// Code generated by iacg; DO NOT EDIT. 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,53 +18,56 @@ func ResourceTencentCloudCvmExportImages() *schema.Resource { Create: resourceTencentCloudCvmExportImagesCreate, Read: resourceTencentCloudCvmExportImagesRead, Delete: resourceTencentCloudCvmExportImagesDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, Schema: map[string]*schema.Schema{ "bucket_name": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "COS bucket name.", }, "image_id": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "Image ID.", }, "file_name_prefix": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "Prefix of exported file.", }, "export_format": { + Type: schema.TypeString, Optional: true, ForceNew: true, - Type: schema.TypeString, Description: "Format of the exported image file. Valid values: RAW, QCOW2, VHD and VMDK. Default value: RAW.", }, "only_export_root_disk": { + Type: schema.TypeBool, Optional: true, ForceNew: true, - Type: schema.TypeBool, Description: "Whether to export only the system disk.", }, "dry_run": { + Type: schema.TypeBool, Optional: true, ForceNew: true, - Type: schema.TypeBool, Description: "Check whether the image can be exported.", }, "role_name": { + Type: schema.TypeString, Optional: true, ForceNew: true, - Type: schema.TypeString, Description: "Role name (Default: CVM_QcsRole). Before exporting the images, make sure the role exists, and it has write permission to COS.", }, }, @@ -77,28 +80,39 @@ func resourceTencentCloudCvmExportImagesCreate(d *schema.ResourceData, meta inte logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + var ( + imageId string + ) var ( - request = cvm.NewExportImagesRequest() - imageId string - bucketName string - fileNamePrefix string + request = cvm.NewExportImagesRequest() + response = cvm.NewExportImagesResponse() ) - imageId = d.Get("image_id").(string) - bucketName = d.Get("bucket_name").(string) - fileNamePrefix = d.Get("file_name_prefix").(string) - request.ImageIds = []*string{&imageId} - request.BucketName = helper.String(bucketName) - request.FileNamePrefixList = []*string{&fileNamePrefix} + + if v, ok := d.GetOk("image_id"); ok { + imageId = v.(string) + } + + if v, ok := d.GetOk("bucket_name"); ok { + request.BucketName = helper.String(v.(string)) + } + + request.ImageIds = []*string{helper.String(imageId)} if v, ok := d.GetOk("export_format"); ok { request.ExportFormat = helper.String(v.(string)) } - if v, _ := d.GetOk("only_export_root_disk"); v != nil { + if v, ok := d.GetOk("file_name_prefix_list"); ok { + request.FileNamePrefixList = []*string{helper.String(v.(string))} + } + + if v, ok := d.GetOkExists("only_export_root_disk"); ok { request.OnlyExportRootDisk = helper.Bool(v.(bool)) } - if v, _ := d.GetOk("dry_run"); v != nil { + if v, ok := d.GetOkExists("dry_run"); ok { request.DryRun = helper.Bool(v.(bool)) } @@ -107,27 +121,26 @@ func resourceTencentCloudCvmExportImagesCreate(d *schema.ResourceData, meta inte } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ExportImages(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ExportImagesWithContext(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 exportImages failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s create cvm export images 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{})) + d.SetId(imageId) - if _, e := conf.WaitForState(); e != nil { - return e + if err := resourceTencentCloudCvmExportImagesCreateOnExit(ctx); err != nil { + return err } return resourceTencentCloudCvmExportImagesRead(d, meta) diff --git a/tencentcloud/services/cvm/resource_tc_cvm_export_images_extension.go b/tencentcloud/services/cvm/resource_tc_cvm_export_images_extension.go new file mode 100644 index 0000000000..503bf2f05f --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_cvm_export_images_extension.go @@ -0,0 +1,21 @@ +package cvm + +import ( + "context" + "time" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" +) + +func resourceTencentCloudCvmExportImagesCreateOnExit(ctx context.Context) 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_cvm_hpc_cluster.go b/tencentcloud/services/cvm/resource_tc_cvm_hpc_cluster.go index 70f450f5a7..67b5baa5f1 100644 --- a/tencentcloud/services/cvm/resource_tc_cvm_hpc_cluster.go +++ b/tencentcloud/services/cvm/resource_tc_cvm_hpc_cluster.go @@ -1,3 +1,4 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( @@ -5,12 +6,11 @@ import ( "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" ) @@ -25,20 +25,20 @@ func ResourceTencentCloudCvmHpcCluster() *schema.Resource { }, Schema: map[string]*schema.Schema{ "zone": { - Required: true, Type: schema.TypeString, + Required: true, Description: "Available zone.", }, "name": { - Required: true, Type: schema.TypeString, + Required: true, Description: "Name of Hpc Cluster.", }, "remark": { - Optional: true, Type: schema.TypeString, + Optional: true, Description: "Remark of Hpc Cluster.", }, }, @@ -51,11 +51,16 @@ func resourceTencentCloudCvmHpcClusterCreate(d *schema.ResourceData, meta interf logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + var ( - request = cvm.NewCreateHpcClusterRequest() - response = cvm.NewCreateHpcClusterResponse() hpcClusterId string ) + var ( + request = cvm.NewCreateHpcClusterRequest() + response = cvm.NewCreateHpcClusterResponse() + ) + if v, ok := d.GetOk("zone"); ok { request.Zone = helper.String(v.(string)) } @@ -69,7 +74,7 @@ func resourceTencentCloudCvmHpcClusterCreate(d *schema.ResourceData, meta interf } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().CreateHpcCluster(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().CreateHpcClusterWithContext(ctx, request) if e != nil { return tccommon.RetryError(e) } else { @@ -79,7 +84,7 @@ func resourceTencentCloudCvmHpcClusterCreate(d *schema.ResourceData, meta interf return nil }) if err != nil { - log.Printf("[CRITAL]%s create cvm hpcCluster failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s create cvm hpc cluster failed, reason:%+v", logId, err) return err } @@ -88,6 +93,7 @@ func resourceTencentCloudCvmHpcClusterCreate(d *schema.ResourceData, meta interf } hpcClusterId = *response.Response.HpcClusterSet[0].HpcClusterId + d.SetId(hpcClusterId) return resourceTencentCloudCvmHpcClusterRead(d, meta) @@ -99,32 +105,32 @@ func resourceTencentCloudCvmHpcClusterRead(d *schema.ResourceData, meta interfac 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()} hpcClusterId := d.Id() - hpcCluster, err := service.DescribeCvmHpcClusterById(ctx, hpcClusterId) + respData, err := service.DescribeCvmHpcClusterById(ctx, hpcClusterId) if err != nil { return err } - if hpcCluster == nil { + if respData == nil { d.SetId("") - return fmt.Errorf("resource `tencentcloud_cvm_hpc_cluster` %s does not exist", d.Id()) + log.Printf("[WARN]%s resource `cvm_hpc_cluster` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + return nil } - - if hpcCluster.Zone != nil { - _ = d.Set("zone", hpcCluster.Zone) + if respData.Zone != nil { + _ = d.Set("zone", respData.Zone) } - if hpcCluster.Name != nil { - _ = d.Set("name", hpcCluster.Name) + if respData.Name != nil { + _ = d.Set("name", respData.Name) } - if hpcCluster.Remark != nil { - _ = d.Set("remark", hpcCluster.Remark) + if respData.Remark != nil { + _ = d.Set("remark", respData.Remark) } return nil @@ -136,36 +142,51 @@ func resourceTencentCloudCvmHpcClusterUpdate(d *schema.ResourceData, meta interf logId := tccommon.GetLogId(tccommon.ContextNil) - request := cvm.NewModifyHpcClusterAttributeRequest() + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + immutableArgs := []string{"zone"} + for _, v := range immutableArgs { + if d.HasChange(v) { + return fmt.Errorf("argument `%s` cannot be changed", v) + } + } hpcClusterId := d.Id() - request.HpcClusterId = &hpcClusterId + needChange := false + mutableArgs := []string{"name", "remark"} + for _, v := range mutableArgs { + if d.HasChange(v) { + needChange = true + break + } + } + + if needChange { + request := cvm.NewModifyHpcClusterAttributeRequest() + + request.HpcClusterId = helper.String(hpcClusterId) - if d.HasChange("name") { if v, ok := d.GetOk("name"); ok { request.Name = helper.String(v.(string)) } - } - if d.HasChange("remark") { if v, ok := d.GetOk("remark"); ok { request.Remark = helper.String(v.(string)) } - } - err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyHpcClusterAttribute(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()) + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyHpcClusterAttributeWithContext(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 cvm hpc cluster failed, reason:%+v", logId, err) + return err } - return nil - }) - if err != nil { - log.Printf("[CRITAL]%s create cvm hpcCluster failed, reason:%+v", logId, err) - return nil } return resourceTencentCloudCvmHpcClusterRead(d, meta) @@ -176,14 +197,32 @@ func resourceTencentCloudCvmHpcClusterDelete(d *schema.ResourceData, meta interf defer tccommon.InconsistentCheck(d, meta)() 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()} hpcClusterId := d.Id() - if err := service.DeleteCvmHpcClusterById(ctx, hpcClusterId); err != nil { + var ( + request = cvm.NewDeleteHpcClustersRequest() + response = cvm.NewDeleteHpcClustersResponse() + ) + + request.HpcClusterIds = []*string{helper.String(hpcClusterId)} + + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().DeleteHpcClustersWithContext(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 hpc cluster failed, reason:%+v", logId, err) + return err } + _ = response return nil } diff --git a/tencentcloud/services/cvm/resource_tc_cvm_hpc_cluster_extension.go b/tencentcloud/services/cvm/resource_tc_cvm_hpc_cluster_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_cvm_hpc_cluster_extension.go @@ -0,0 +1 @@ +package cvm diff --git a/tencentcloud/services/cvm/resource_tc_cvm_image_share_permission.go b/tencentcloud/services/cvm/resource_tc_cvm_image_share_permission.go index e50943bb2e..d7e1e70a10 100644 --- a/tencentcloud/services/cvm/resource_tc_cvm_image_share_permission.go +++ b/tencentcloud/services/cvm/resource_tc_cvm_image_share_permission.go @@ -1,42 +1,42 @@ +// Code generated by iacg; DO NOT EDIT. 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 ResourceTencentCloudCvmImageSharePermission() *schema.Resource { return &schema.Resource{ Create: resourceTencentCloudCvmImageSharePermissionCreate, - Update: resourceTencentCloudCvmImageSharePermissionUpdate, Read: resourceTencentCloudCvmImageSharePermissionRead, + Update: resourceTencentCloudCvmImageSharePermissionUpdate, Delete: resourceTencentCloudCvmImageSharePermissionDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, Schema: map[string]*schema.Schema{ "image_id": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "Image ID such as `img-gvbnzy6f`. You can only specify an image in the NORMAL state.", }, "account_ids": { - Required: true, - Type: schema.TypeSet, + Type: schema.TypeSet, + Required: true, + Description: "List of account IDs with which an image is shared.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Description: "List of account IDs with which an image is shared.", }, }, } @@ -48,135 +48,145 @@ func resourceTencentCloudCvmImageSharePermissionCreate(d *schema.ResourceData, m logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + var ( - request = cvm.NewModifyImageSharePermissionRequest() imageId string ) + var ( + request = cvm.NewModifyImageSharePermissionRequest() + response = cvm.NewModifyImageSharePermissionResponse() + ) + if v, ok := d.GetOk("image_id"); ok { imageId = v.(string) - request.ImageId = helper.String(imageId) } + request.ImageId = &imageId + if v, ok := d.GetOk("account_ids"); ok { accountIdsSet := v.(*schema.Set).List() for i := range accountIdsSet { accountIds := accountIdsSet[i].(string) - request.AccountIds = append(request.AccountIds, &accountIds) + request.AccountIds = append(request.AccountIds, helper.String(accountIds)) } } - request.Permission = helper.String(IMAGE_SHARE_PERMISSION_SHARE) + permission := "SHARE" + request.Permission = &permission err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyImageSharePermission(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyImageSharePermissionWithContext(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 modifyImageSharePermission failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s create cvm image share permission failed, reason:%+v", logId, err) return err } + _ = response + d.SetId(imageId) return resourceTencentCloudCvmImageSharePermissionRead(d, meta) } -func resourceTencentCloudCvmImageSharePermissionUpdate(d *schema.ResourceData, meta interface{}) error { - defer tccommon.LogElapsed("resource.tencentcloud_cvm_image_share_permission.update")() +func resourceTencentCloudCvmImageSharePermissionRead(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_cvm_image_share_permission.read")() defer tccommon.InconsistentCheck(d, meta)() 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()} - if d.HasChange("account_ids") { - old, new := d.GetChange("account_ids") - oldSet := old.(*schema.Set) - newSet := new.(*schema.Set) - add := newSet.Difference(oldSet).List() - remove := oldSet.Difference(newSet).List() - if len(add) > 0 { - addError := service.ModifyImageSharePermission(ctx, d.Id(), IMAGE_SHARE_PERMISSION_SHARE, helper.InterfacesStrings(add)) - if addError != nil { - return addError - } - } - if len(remove) > 0 { - removeError := service.ModifyImageSharePermission(ctx, d.Id(), IMAGE_SHARE_PERMISSION_CANCEL, helper.InterfacesStrings(remove)) - if removeError != nil { - return removeError - } - } + imageId := d.Id() + + _ = d.Set("image_id", imageId) + + respData, err := service.DescribeCvmImageSharePermissionById(ctx, imageId) + if err != nil { + return err } - return resourceTencentCloudCvmImageSharePermissionRead(d, meta) + if respData == nil { + d.SetId("") + log.Printf("[WARN]%s resource `cvm_image_share_permission` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + return nil + } + if err := resourceTencentCloudCvmImageSharePermissionReadPreHandleResponse0(ctx, respData); err != nil { + return err + } + + return nil } -func resourceTencentCloudCvmImageSharePermissionRead(d *schema.ResourceData, meta interface{}) error { - defer tccommon.LogElapsed("resource.tencentcloud_cvm_image_share_permission.read")() +func resourceTencentCloudCvmImageSharePermissionUpdate(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_cvm_image_share_permission.update")() defer tccommon.InconsistentCheck(d, meta)() logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - var sharePermissionSet []*cvm.SharePermission - service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - result, e := service.DescribeCvmImageSharePermissionByFilter(ctx, map[string]interface{}{"ImageId": helper.String(d.Id())}) - if e != nil { - return tccommon.RetryError(e) - } - sharePermissionSet = result - return nil - }) - if err != nil { - return err - } + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + imageId := d.Id() - accountIds := make([]string, 0) - for _, sharePermission := range sharePermissionSet { - accountIds = append(accountIds, *sharePermission.AccountId) + if err := resourceTencentCloudCvmImageSharePermissionUpdateOnStart(ctx); err != nil { + return err } - _ = d.Set("account_ids", accountIds) - _ = d.Set("image_id", d.Id()) - return nil + _ = imageId + return resourceTencentCloudCvmImageSharePermissionRead(d, meta) } func resourceTencentCloudCvmImageSharePermissionDelete(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_cvm_image_share_permission.delete")() defer tccommon.InconsistentCheck(d, meta)() + logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - var sharePermissionSet []*cvm.SharePermission + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - result, e := service.DescribeCvmImageSharePermissionByFilter(ctx, map[string]interface{}{"ImageId": helper.String(d.Id())}) + imageId := d.Id() + + var ( + request = cvm.NewModifyImageSharePermissionRequest() + response = cvm.NewModifyImageSharePermissionResponse() + ) + + if v, ok := d.GetOk("image_id"); ok { + request.ImageId = helper.String(v.(string)) + } + + permission := "CANCEL" + request.Permission = &permission + + if err := resourceTencentCloudCvmImageSharePermissionDeletePostFillRequest0(ctx, request); err != nil { + return err + } + + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyImageSharePermissionWithContext(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()) } - sharePermissionSet = result + response = result return nil }) if err != nil { + log.Printf("[CRITAL]%s create cvm image share permission failed, reason:%+v", logId, err) return err } - accountIds := make([]string, 0) - for _, sharePermission := range sharePermissionSet { - accountIds = append(accountIds, *sharePermission.AccountId) - } - - err = service.ModifyImageSharePermission(ctx, d.Id(), IMAGE_SHARE_PERMISSION_CANCEL, accountIds) - if err != nil { - return err - } - + _ = response + _ = imageId return nil } diff --git a/tencentcloud/services/cvm/resource_tc_cvm_image_share_permission_extension.go b/tencentcloud/services/cvm/resource_tc_cvm_image_share_permission_extension.go new file mode 100644 index 0000000000..691b3fc4df --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_cvm_image_share_permission_extension.go @@ -0,0 +1,89 @@ +package cvm + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +func resourceTencentCloudCvmImageSharePermissionReadPreHandleResponse0(ctx context.Context, resp *cvm.DescribeImageSharePermissionResponseParams) error { + d := tccommon.ResourceDataFromContext(ctx) + + if len(resp.SharePermissionSet) < 1 { + return fmt.Errorf("resource `tencentcloud_cvm_image_share_permission` read failed") + } + sharePermissionSet := resp.SharePermissionSet + + accountIds := make([]string, 0) + for _, sharePermission := range sharePermissionSet { + accountIds = append(accountIds, *sharePermission.AccountId) + } + _ = d.Set("account_ids", accountIds) + + return nil +} + +func resourceTencentCloudCvmImageSharePermissionUpdateOnStart(ctx context.Context) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + if d.HasChange("account_ids") { + old, new := d.GetChange("account_ids") + oldSet := old.(*schema.Set) + newSet := new.(*schema.Set) + add := newSet.Difference(oldSet).List() + remove := oldSet.Difference(newSet).List() + if len(add) > 0 { + addError := service.ModifyImageSharePermission(ctx, d.Id(), IMAGE_SHARE_PERMISSION_SHARE, helper.InterfacesStrings(add)) + if addError != nil { + return addError + } + } + if len(remove) > 0 { + removeError := service.ModifyImageSharePermission(ctx, d.Id(), IMAGE_SHARE_PERMISSION_CANCEL, helper.InterfacesStrings(remove)) + if removeError != nil { + return removeError + } + } + } + + return nil +} + +func resourceTencentCloudCvmImageSharePermissionDeletePostFillRequest0(ctx context.Context, req *cvm.ModifyImageSharePermissionRequest) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + var sharePermissionSet []*cvm.SharePermission + + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + result, e := service.DescribeCvmImageSharePermissionByFilter(ctx, map[string]interface{}{"ImageId": helper.String(d.Id())}) + if e != nil { + return tccommon.RetryError(e) + } + sharePermissionSet = result + return nil + }) + if err != nil { + return err + } + + accountIds := make([]string, 0) + for _, sharePermission := range sharePermissionSet { + accountIds = append(accountIds, *sharePermission.AccountId) + } + req.AccountIds = helper.StringsStringsPoint(accountIds) + + return nil +} diff --git a/tencentcloud/services/cvm/resource_tc_cvm_import_image.go b/tencentcloud/services/cvm/resource_tc_cvm_import_image.go index c2179f5e7a..eb6e5d531d 100644 --- a/tencentcloud/services/cvm/resource_tc_cvm_import_image.go +++ b/tencentcloud/services/cvm/resource_tc_cvm_import_image.go @@ -1,14 +1,15 @@ +// Code generated by iacg; DO NOT EDIT. 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" ) @@ -22,65 +23,65 @@ func ResourceTencentCloudCvmImportImage() *schema.Resource { }, Schema: map[string]*schema.Schema{ "architecture": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "OS architecture of the image to be imported, `x86_64` or `i386`.", }, "os_type": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "OS type of the image to be imported. You can call `DescribeImportImageOs` to obtain the list of supported operating systems.", }, "os_version": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "OS version of the image to be imported. You can call `DescribeImportImageOs` to obtain the list of supported operating systems.", }, "image_url": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "Address on COS where the image to be imported is stored.", }, "image_name": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, - Description: "Image name.", + Description: "Image name", }, "image_description": { + Type: schema.TypeString, Optional: true, ForceNew: true, - Type: schema.TypeString, - Description: "Image description.", + Description: "Image description", }, "dry_run": { + Type: schema.TypeBool, Optional: true, ForceNew: true, - Type: schema.TypeBool, - Description: "Dry run to check the parameters without performing the operation.", + Description: "Dry run to check the parameters without performing the operation", }, "force": { + Type: schema.TypeBool, Optional: true, ForceNew: true, - Type: schema.TypeBool, Description: "Whether to force import the image.", }, "tag_specification": { + Type: schema.TypeList, Optional: true, ForceNew: true, - Type: schema.TypeList, Description: "Tag description list. This parameter is used to bind a tag to a custom image.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -113,16 +114,16 @@ func ResourceTencentCloudCvmImportImage() *schema.Resource { }, "license_type": { + Type: schema.TypeString, Optional: true, ForceNew: true, - Type: schema.TypeString, - Description: "The license type used to activate the OS after importing an image. Valid values: TencentCloud: Tencent Cloud official license BYOL: Bring Your Own License.", + Description: "The license type used to activate the OS after importing an image. Valid values: TencentCloud: Tencent Cloud official license BYOL: Bring Your Own License", }, "boot_mode": { + Type: schema.TypeString, Optional: true, ForceNew: true, - Type: schema.TypeString, Description: "Boot mode.", }, }, @@ -135,10 +136,20 @@ func resourceTencentCloudCvmImportImageCreate(d *schema.ResourceData, meta inter logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + var ( - request = cvm.NewImportImageRequest() imageUrl string ) + var ( + request = cvm.NewImportImageRequest() + response = cvm.NewImportImageResponse() + ) + + if v, ok := d.GetOk("image_url"); ok { + imageUrl = v.(string) + } + if v, ok := d.GetOk("architecture"); ok { request.Architecture = helper.String(v.(string)) } @@ -151,10 +162,7 @@ func resourceTencentCloudCvmImportImageCreate(d *schema.ResourceData, meta inter request.OsVersion = helper.String(v.(string)) } - if v, ok := d.GetOk("image_url"); ok { - imageUrl = v.(string) - request.ImageUrl = helper.String(imageUrl) - } + request.ImageUrl = &imageUrl if v, ok := d.GetOk("image_name"); ok { request.ImageName = helper.String(v.(string)) @@ -164,22 +172,22 @@ func resourceTencentCloudCvmImportImageCreate(d *schema.ResourceData, meta inter request.ImageDescription = helper.String(v.(string)) } - if v, _ := d.GetOk("dry_run"); v != nil { + if v, ok := d.GetOkExists("dry_run"); ok { request.DryRun = helper.Bool(v.(bool)) } - if v, _ := d.GetOk("force"); v != nil { + if v, ok := d.GetOkExists("force"); ok { request.Force = helper.Bool(v.(bool)) } if v, ok := d.GetOk("tag_specification"); ok { for _, item := range v.([]interface{}) { - dMap := item.(map[string]interface{}) + tagSpecificationMap := item.(map[string]interface{}) tagSpecification := cvm.TagSpecification{} - if v, ok := dMap["resource_type"]; ok { + if v, ok := tagSpecificationMap["resource_type"]; ok { tagSpecification.ResourceType = helper.String(v.(string)) } - if v, ok := dMap["tags"]; ok { + if v, ok := tagSpecificationMap["tags"]; ok { for _, item := range v.([]interface{}) { tagsMap := item.(map[string]interface{}) tag := cvm.Tag{} @@ -200,24 +208,27 @@ func resourceTencentCloudCvmImportImageCreate(d *schema.ResourceData, meta inter request.LicenseType = helper.String(v.(string)) } - if v, ok := d.GetOk("boot_mode"); ok { + if v, ok := d.GetOk("boot_modexwwwww"); ok { request.BootMode = helper.String(v.(string)) } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ImportImage(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ImportImageWithContext(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 importImage failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s create cvm import image failed, reason:%+v", logId, err) return err } + _ = response + d.SetId(imageUrl) return resourceTencentCloudCvmImportImageRead(d, meta) diff --git a/tencentcloud/services/cvm/resource_tc_cvm_import_image_extension.go b/tencentcloud/services/cvm/resource_tc_cvm_import_image_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_cvm_import_image_extension.go @@ -0,0 +1 @@ +package cvm diff --git a/tencentcloud/services/cvm/resource_tc_cvm_launch_template.go b/tencentcloud/services/cvm/resource_tc_cvm_launch_template.go index e9faf3e4d4..80f43a15c1 100644 --- a/tencentcloud/services/cvm/resource_tc_cvm_launch_template.go +++ b/tencentcloud/services/cvm/resource_tc_cvm_launch_template.go @@ -1,15 +1,15 @@ +// Code generated by iacg; DO NOT EDIT. 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" ) @@ -20,16 +20,16 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { Delete: resourceTencentCloudCvmLaunchTemplateDelete, Schema: map[string]*schema.Schema{ "launch_template_name": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "The name of launch template.", }, "placement": { + Type: schema.TypeList, Required: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "The location of instance.", Elem: &schema.Resource{ @@ -62,32 +62,32 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { }, "image_id": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "Image ID.", }, "launch_template_version_description": { + Type: schema.TypeString, Optional: true, ForceNew: true, - Type: schema.TypeString, Description: "Instance launch template version description.", }, "instance_type": { + Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeString, Description: "The type of the instance. If this parameter is not specified, the system will dynamically specify the default model according to the resource sales in the current region.", }, "system_disk": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "System disk configuration information of the instance. If this parameter is not specified, it is assigned according to the system default.", Elem: &schema.Resource{ @@ -117,9 +117,9 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { }, "data_disks": { + Type: schema.TypeList, Optional: true, ForceNew: true, - Type: schema.TypeList, Description: "Data disk configuration information of the instance.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -173,10 +173,10 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { }, "virtual_private_cloud": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "The configuration information of VPC. If this parameter is not specified, the basic network is used by default.", Elem: &schema.Resource{ @@ -197,12 +197,12 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { Description: "Is it used as a Public network gateway, TRUE or FALSE.", }, "private_ip_addresses": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Optional: true, + Description: "The address of private ip.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Optional: true, - Description: "The address of private ip.", }, "ipv6_address_count": { Type: schema.TypeInt, @@ -214,10 +214,10 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { }, "internet_accessible": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "The information settings of public network bandwidth. If you do not specify this parameter, the default Internet bandwidth is 0 Mbps.", Elem: &schema.Resource{ @@ -247,26 +247,26 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { }, "instance_count": { + Type: schema.TypeInt, Optional: true, ForceNew: true, Default: 1, - Type: schema.TypeInt, Description: "The number of instances purchased.", }, "instance_name": { + Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeString, Description: "The name of instance. If you do not specify an instance display name, 'Unnamed' is displayed by default.", }, "login_settings": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "The login settings of instance. By default, passwords are randomly generated and notified to users via internal messages.", Elem: &schema.Resource{ @@ -277,12 +277,12 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { Description: "The login password of instance.", }, "key_ids": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Optional: true, + Description: "List of key ID.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Optional: true, - Description: "List of key ID.", }, "keep_image_login": { Type: schema.TypeString, @@ -294,29 +294,29 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { }, "security_group_ids": { - Optional: true, - Computed: true, - ForceNew: true, - Type: schema.TypeSet, + Type: schema.TypeSet, + Optional: true, + Computed: true, + ForceNew: true, + Description: "The security group ID of instance. If this parameter is not specified, the default security group is bound.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Description: "The security group ID of instance. If this parameter is not specified, the default security group is bound.", }, "enhanced_service": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "Enhanced service. If this parameter is not specified, cloud monitoring and cloud security services will be enabled by default in public images.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "security_service": { Type: schema.TypeList, - MaxItems: 1, Optional: true, + MaxItems: 1, Description: "Enable cloud security service.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -330,8 +330,8 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { }, "monitor_service": { Type: schema.TypeList, - MaxItems: 1, Optional: true, + MaxItems: 1, Description: "Enable cloud monitor service.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -345,8 +345,8 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { }, "automation_service": { Type: schema.TypeList, - MaxItems: 1, Optional: true, + MaxItems: 1, Description: "Enable TencentCloud Automation Tools(TAT).", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -363,24 +363,24 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { }, "client_token": { + Type: schema.TypeString, Optional: true, ForceNew: true, - Type: schema.TypeString, Description: "A string to used guarantee request idempotency.", }, "host_name": { + Type: schema.TypeString, Optional: true, ForceNew: true, - Type: schema.TypeString, Description: "The host name of CVM.", }, "action_timer": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "Timed task.", Elem: &schema.Resource{ @@ -397,8 +397,8 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { }, "externals": { Type: schema.TypeList, - MaxItems: 1, Optional: true, + MaxItems: 1, Description: "Extended data.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -408,17 +408,17 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { Description: "Release address.", }, "unsupport_networks": { - Type: schema.TypeSet, + Type: schema.TypeSet, + Optional: true, + Description: "Unsupported network type.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Optional: true, - Description: "Unsupported network type.", }, "storage_block_attr": { Type: schema.TypeList, - MaxItems: 1, Optional: true, + MaxItems: 1, Description: "HDD local storage attributes.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -448,19 +448,19 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { }, "disaster_recover_group_ids": { - Optional: true, - ForceNew: true, - Type: schema.TypeSet, + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + Description: "The ID of disaster recover group.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Description: "The ID of disaster recover group.", }, "tag_specification": { + Type: schema.TypeList, Optional: true, ForceNew: true, - Type: schema.TypeList, Description: "Tag description list.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -493,17 +493,17 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { }, "instance_market_options": { + Type: schema.TypeList, Optional: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "The marketplace options of instance.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "spot_options": { Type: schema.TypeList, - MaxItems: 1, Required: true, + MaxItems: 1, Description: "Bidding related options.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -530,45 +530,45 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { }, "user_data": { + Type: schema.TypeString, Optional: true, ForceNew: true, - Type: schema.TypeString, Description: "The data of users.", }, "dry_run": { + Type: schema.TypeBool, Optional: true, ForceNew: true, - Type: schema.TypeBool, Description: "Whether to preflight only this request, true or false.", }, "cam_role_name": { + Type: schema.TypeString, Optional: true, ForceNew: true, - Type: schema.TypeString, Description: "The role name of CAM.", }, "hpc_cluster_id": { + Type: schema.TypeString, Optional: true, ForceNew: true, - Type: schema.TypeString, Description: "The ID of HPC cluster.", }, "instance_charge_type": { + Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeString, Description: "The charge type of instance. Default value: POSTPAID_BY_HOUR.", }, "instance_charge_prepaid": { + Type: schema.TypeList, Optional: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "The configuration of charge prepaid.", Elem: &schema.Resource{ @@ -588,16 +588,16 @@ func ResourceTencentCloudCvmLaunchTemplate() *schema.Resource { }, "disable_api_termination": { + Type: schema.TypeBool, Optional: true, ForceNew: true, - Type: schema.TypeBool, Description: "Instance destruction protection flag.", }, "tags": { Type: schema.TypeMap, - ForceNew: true, Optional: true, + ForceNew: true, Description: "Tag description list.", }, }, @@ -610,28 +610,33 @@ func resourceTencentCloudCvmLaunchTemplateCreate(d *schema.ResourceData, meta in logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + var ( - request = cvm.NewCreateLaunchTemplateRequest() - response = cvm.NewCreateLaunchTemplateResponse() launchTemplateId string ) + var ( + request = cvm.NewCreateLaunchTemplateRequest() + response = cvm.NewCreateLaunchTemplateResponse() + ) + if v, ok := d.GetOk("launch_template_name"); ok { request.LaunchTemplateName = helper.String(v.(string)) } - if dMap, ok := helper.InterfacesHeadMap(d, "placement"); ok { + if placementMap, ok := helper.InterfacesHeadMap(d, "placement"); ok { placement := cvm.Placement{} - if v, ok := dMap["zone"]; ok { + if v, ok := placementMap["zone"]; ok { placement.Zone = helper.String(v.(string)) } - if v, ok := dMap["project_id"]; ok { + if v, ok := placementMap["project_id"]; ok { placement.ProjectId = helper.IntInt64(v.(int)) } - if v, ok := dMap["host_ids"]; ok { + if v, ok := placementMap["host_ids"]; ok { hostIdsSet := v.(*schema.Set).List() for i := range hostIdsSet { hostIds := hostIdsSet[i].(string) - placement.HostIds = append(placement.HostIds, &hostIds) + placement.HostIds = append(placement.HostIds, helper.String(hostIds)) } } // It has been deprecated from version 1.81.108 @@ -642,7 +647,7 @@ func resourceTencentCloudCvmLaunchTemplateCreate(d *schema.ResourceData, meta in // placement.HostIps = append(placement.HostIps, &hostIps) // } //} - if v, ok := dMap["host_id"]; ok { + if v, ok := placementMap["host_id"]; ok { placement.HostId = helper.String(v.(string)) } request.Placement = &placement @@ -660,18 +665,18 @@ func resourceTencentCloudCvmLaunchTemplateCreate(d *schema.ResourceData, meta in request.InstanceType = helper.String(v.(string)) } - if dMap, ok := helper.InterfacesHeadMap(d, "system_disk"); ok { + if systemDiskMap, ok := helper.InterfacesHeadMap(d, "system_disk"); ok { systemDisk := cvm.SystemDisk{} - if v, ok := dMap["disk_type"]; ok { + if v, ok := systemDiskMap["disk_type"]; ok { systemDisk.DiskType = helper.String(v.(string)) } - if v, ok := dMap["disk_id"]; ok { + if v, ok := systemDiskMap["disk_id"]; ok { systemDisk.DiskId = helper.String(v.(string)) } - if v, ok := dMap["disk_size"]; ok { + if v, ok := systemDiskMap["disk_size"]; ok { systemDisk.DiskSize = helper.IntInt64(v.(int)) } - if v, ok := dMap["cdc_id"]; ok { + if v, ok := systemDiskMap["cdc_id"]; ok { systemDisk.CdcId = helper.String(v.(string)) } request.SystemDisk = &systemDisk @@ -679,81 +684,81 @@ func resourceTencentCloudCvmLaunchTemplateCreate(d *schema.ResourceData, meta in if v, ok := d.GetOk("data_disks"); ok { for _, item := range v.([]interface{}) { - dMap := item.(map[string]interface{}) + dataDisksMap := item.(map[string]interface{}) dataDisk := cvm.DataDisk{} - if v, ok := dMap["disk_size"]; ok { + if v, ok := dataDisksMap["disk_size"]; ok { dataDisk.DiskSize = helper.IntInt64(v.(int)) } - if v, ok := dMap["disk_type"]; ok { + if v, ok := dataDisksMap["disk_type"]; ok { dataDisk.DiskType = helper.String(v.(string)) } - if v, ok := dMap["disk_id"]; ok { + if v, ok := dataDisksMap["disk_id"]; ok { dataDisk.DiskId = helper.String(v.(string)) } - if v, ok := dMap["delete_with_instance"]; ok { + if v, ok := dataDisksMap["delete_with_instance"]; ok { dataDisk.DeleteWithInstance = helper.Bool(v.(bool)) } - if v, ok := dMap["snapshot_id"]; ok { + if v, ok := dataDisksMap["snapshot_id"]; ok { dataDisk.SnapshotId = helper.String(v.(string)) } - if v, ok := dMap["encrypt"]; ok { + if v, ok := dataDisksMap["encrypt"]; ok { dataDisk.Encrypt = helper.Bool(v.(bool)) } - if v, ok := dMap["kms_key_id"]; ok { + if v, ok := dataDisksMap["kms_key_id"]; ok { dataDisk.KmsKeyId = helper.String(v.(string)) } - if v, ok := dMap["throughput_performance"]; ok { + if v, ok := dataDisksMap["throughput_performance"]; ok { dataDisk.ThroughputPerformance = helper.IntInt64(v.(int)) } - if v, ok := dMap["cdc_id"]; ok { + if v, ok := dataDisksMap["cdc_id"]; ok { dataDisk.CdcId = helper.String(v.(string)) } request.DataDisks = append(request.DataDisks, &dataDisk) } } - if dMap, ok := helper.InterfacesHeadMap(d, "virtual_private_cloud"); ok { + if virtualPrivateCloudMap, ok := helper.InterfacesHeadMap(d, "virtual_private_cloud"); ok { virtualPrivateCloud := cvm.VirtualPrivateCloud{} - if v, ok := dMap["vpc_id"]; ok { + if v, ok := virtualPrivateCloudMap["vpc_id"]; ok { virtualPrivateCloud.VpcId = helper.String(v.(string)) } - if v, ok := dMap["subnet_id"]; ok { + if v, ok := virtualPrivateCloudMap["subnet_id"]; ok { virtualPrivateCloud.SubnetId = helper.String(v.(string)) } - if v, ok := dMap["as_vpc_gateway"]; ok { + if v, ok := virtualPrivateCloudMap["as_vpc_gateway"]; ok { virtualPrivateCloud.AsVpcGateway = helper.Bool(v.(bool)) } - if v, ok := dMap["private_ip_addresses"]; ok { + if v, ok := virtualPrivateCloudMap["private_ip_addresses"]; ok { privateIpAddressesSet := v.(*schema.Set).List() for i := range privateIpAddressesSet { privateIpAddresses := privateIpAddressesSet[i].(string) - virtualPrivateCloud.PrivateIpAddresses = append(virtualPrivateCloud.PrivateIpAddresses, &privateIpAddresses) + virtualPrivateCloud.PrivateIpAddresses = append(virtualPrivateCloud.PrivateIpAddresses, helper.String(privateIpAddresses)) } } - if v, ok := dMap["ipv6_address_count"]; ok { + if v, ok := virtualPrivateCloudMap["ipv6_address_count"]; ok { virtualPrivateCloud.Ipv6AddressCount = helper.IntUint64(v.(int)) } request.VirtualPrivateCloud = &virtualPrivateCloud } - if dMap, ok := helper.InterfacesHeadMap(d, "internet_accessible"); ok { + if internetAccessibleMap, ok := helper.InterfacesHeadMap(d, "internet_accessible"); ok { internetAccessible := cvm.InternetAccessible{} - if v, ok := dMap["internet_charge_type"]; ok { + if v, ok := internetAccessibleMap["internet_charge_type"]; ok { internetAccessible.InternetChargeType = helper.String(v.(string)) } - if v, ok := dMap["internet_max_bandwidth_out"]; ok { + if v, ok := internetAccessibleMap["internet_max_bandwidth_out"]; ok { internetAccessible.InternetMaxBandwidthOut = helper.IntInt64(v.(int)) } - if v, ok := dMap["public_ip_assigned"]; ok { + if v, ok := internetAccessibleMap["public_ip_assigned"]; ok { internetAccessible.PublicIpAssigned = helper.Bool(v.(bool)) } - if v, ok := dMap["bandwidth_package_id"]; ok { + if v, ok := internetAccessibleMap["bandwidth_package_id"]; ok { internetAccessible.BandwidthPackageId = helper.String(v.(string)) } request.InternetAccessible = &internetAccessible } - if v, _ := d.GetOk("instance_count"); v != nil { + if v, ok := d.GetOkExists("instance_count"); ok { request.InstanceCount = helper.IntInt64(v.(int)) } @@ -761,19 +766,19 @@ func resourceTencentCloudCvmLaunchTemplateCreate(d *schema.ResourceData, meta in request.InstanceName = helper.String(v.(string)) } - if dMap, ok := helper.InterfacesHeadMap(d, "login_settings"); ok { + if loginSettingsMap, ok := helper.InterfacesHeadMap(d, "login_settings"); ok { loginSettings := cvm.LoginSettings{} - if v, ok := dMap["password"]; ok { + if v, ok := loginSettingsMap["password"]; ok { loginSettings.Password = helper.String(v.(string)) } - if v, ok := dMap["key_ids"]; ok { + if v, ok := loginSettingsMap["key_ids"]; ok { keyIdsSet := v.(*schema.Set).List() for i := range keyIdsSet { keyIds := keyIdsSet[i].(string) - loginSettings.KeyIds = append(loginSettings.KeyIds, &keyIds) + loginSettings.KeyIds = append(loginSettings.KeyIds, helper.String(keyIds)) } } - if v, ok := dMap["keep_image_login"]; ok { + if v, ok := loginSettingsMap["keep_image_login"]; ok { loginSettings.KeepImageLogin = helper.String(v.(string)) } request.LoginSettings = &loginSettings @@ -783,27 +788,27 @@ func resourceTencentCloudCvmLaunchTemplateCreate(d *schema.ResourceData, meta in securityGroupIdsSet := v.(*schema.Set).List() for i := range securityGroupIdsSet { securityGroupIds := securityGroupIdsSet[i].(string) - request.SecurityGroupIds = append(request.SecurityGroupIds, &securityGroupIds) + request.SecurityGroupIds = append(request.SecurityGroupIds, helper.String(securityGroupIds)) } } - if dMap, ok := helper.InterfacesHeadMap(d, "enhanced_service"); ok { + if enhancedServiceMap, ok := helper.InterfacesHeadMap(d, "enhanced_service"); ok { enhancedService := cvm.EnhancedService{} - if securityServiceMap, ok := helper.InterfaceToMap(dMap, "security_service"); ok { + if securityServiceMap, ok := helper.ConvertInterfacesHeadToMap(enhancedServiceMap["security_service"]); ok { runSecurityServiceEnabled := cvm.RunSecurityServiceEnabled{} if v, ok := securityServiceMap["enabled"]; ok { runSecurityServiceEnabled.Enabled = helper.Bool(v.(bool)) } enhancedService.SecurityService = &runSecurityServiceEnabled } - if monitorServiceMap, ok := helper.InterfaceToMap(dMap, "monitor_service"); ok { + if monitorServiceMap, ok := helper.ConvertInterfacesHeadToMap(enhancedServiceMap["monitor_service"]); ok { runMonitorServiceEnabled := cvm.RunMonitorServiceEnabled{} if v, ok := monitorServiceMap["enabled"]; ok { runMonitorServiceEnabled.Enabled = helper.Bool(v.(bool)) } enhancedService.MonitorService = &runMonitorServiceEnabled } - if automationServiceMap, ok := helper.InterfaceToMap(dMap, "automation_service"); ok { + if automationServiceMap, ok := helper.ConvertInterfacesHeadToMap(enhancedServiceMap["automation_service"]); ok { runAutomationServiceEnabled := cvm.RunAutomationServiceEnabled{} if v, ok := automationServiceMap["enabled"]; ok { runAutomationServiceEnabled.Enabled = helper.Bool(v.(bool)) @@ -821,15 +826,15 @@ func resourceTencentCloudCvmLaunchTemplateCreate(d *schema.ResourceData, meta in request.HostName = helper.String(v.(string)) } - if dMap, ok := helper.InterfacesHeadMap(d, "action_timer"); ok { + if actionTimerMap, ok := helper.InterfacesHeadMap(d, "action_timer"); ok { actionTimer := cvm.ActionTimer{} - if v, ok := dMap["timer_action"]; ok { + if v, ok := actionTimerMap["timer_action"]; ok { actionTimer.TimerAction = helper.String(v.(string)) } - if v, ok := dMap["action_time"]; ok { + if v, ok := actionTimerMap["action_time"]; ok { actionTimer.ActionTime = helper.String(v.(string)) } - if externalsMap, ok := helper.InterfaceToMap(dMap, "externals"); ok { + if externalsMap, ok := helper.ConvertInterfacesHeadToMap(actionTimerMap["externals"]); ok { externals := cvm.Externals{} if v, ok := externalsMap["release_address"]; ok { externals.ReleaseAddress = helper.Bool(v.(bool)) @@ -838,10 +843,10 @@ func resourceTencentCloudCvmLaunchTemplateCreate(d *schema.ResourceData, meta in unsupportNetworksSet := v.(*schema.Set).List() for i := range unsupportNetworksSet { unsupportNetworks := unsupportNetworksSet[i].(string) - externals.UnsupportNetworks = append(externals.UnsupportNetworks, &unsupportNetworks) + externals.UnsupportNetworks = append(externals.UnsupportNetworks, helper.String(unsupportNetworks)) } } - if storageBlockAttrMap, ok := helper.InterfaceToMap(externalsMap, "storage_block_attr"); ok { + if storageBlockAttrMap, ok := helper.ConvertInterfacesHeadToMap(externalsMap["storage_block_attr"]); ok { storageBlock := cvm.StorageBlock{} if v, ok := storageBlockAttrMap["type"]; ok { storageBlock.Type = helper.String(v.(string)) @@ -863,18 +868,18 @@ func resourceTencentCloudCvmLaunchTemplateCreate(d *schema.ResourceData, meta in disasterRecoverGroupIdsSet := v.(*schema.Set).List() for i := range disasterRecoverGroupIdsSet { disasterRecoverGroupIds := disasterRecoverGroupIdsSet[i].(string) - request.DisasterRecoverGroupIds = append(request.DisasterRecoverGroupIds, &disasterRecoverGroupIds) + request.DisasterRecoverGroupIds = append(request.DisasterRecoverGroupIds, helper.String(disasterRecoverGroupIds)) } } if v, ok := d.GetOk("tag_specification"); ok { for _, item := range v.([]interface{}) { - dMap := item.(map[string]interface{}) + tagSpecificationMap := item.(map[string]interface{}) tagSpecification := cvm.TagSpecification{} - if v, ok := dMap["resource_type"]; ok { + if v, ok := tagSpecificationMap["resource_type"]; ok { tagSpecification.ResourceType = helper.String(v.(string)) } - if v, ok := dMap["tags"]; ok { + if v, ok := tagSpecificationMap["tags"]; ok { for _, item := range v.([]interface{}) { tagsMap := item.(map[string]interface{}) tag := cvm.Tag{} @@ -891,9 +896,9 @@ func resourceTencentCloudCvmLaunchTemplateCreate(d *schema.ResourceData, meta in } } - if dMap, ok := helper.InterfacesHeadMap(d, "instance_market_options"); ok { + if instanceMarketOptionsMap, ok := helper.InterfacesHeadMap(d, "instance_market_options"); ok { instanceMarketOptionsRequest := cvm.InstanceMarketOptionsRequest{} - if spotOptionsMap, ok := helper.InterfaceToMap(dMap, "spot_options"); ok { + if spotOptionsMap, ok := helper.ConvertInterfacesHeadToMap(instanceMarketOptionsMap["spot_options"]); ok { spotMarketOptions := cvm.SpotMarketOptions{} if v, ok := spotOptionsMap["max_price"]; ok { spotMarketOptions.MaxPrice = helper.String(v.(string)) @@ -903,7 +908,7 @@ func resourceTencentCloudCvmLaunchTemplateCreate(d *schema.ResourceData, meta in } instanceMarketOptionsRequest.SpotOptions = &spotMarketOptions } - if v, ok := dMap["market_type"]; ok { + if v, ok := instanceMarketOptionsMap["market_type"]; ok { instanceMarketOptionsRequest.MarketType = helper.String(v.(string)) } request.InstanceMarketOptions = &instanceMarketOptionsRequest @@ -913,7 +918,7 @@ func resourceTencentCloudCvmLaunchTemplateCreate(d *schema.ResourceData, meta in request.UserData = helper.String(v.(string)) } - if v, _ := d.GetOk("dry_run"); v != nil { + if v, ok := d.GetOkExists("dry_run"); ok { request.DryRun = helper.Bool(v.(bool)) } @@ -929,23 +934,23 @@ func resourceTencentCloudCvmLaunchTemplateCreate(d *schema.ResourceData, meta in request.InstanceChargeType = helper.String(v.(string)) } - if dMap, ok := helper.InterfacesHeadMap(d, "instance_charge_prepaid"); ok { + 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 { + if v, ok := instanceChargePrepaidMap["renew_flag"]; ok { instanceChargePrepaid.RenewFlag = helper.String(v.(string)) } request.InstanceChargePrepaid = &instanceChargePrepaid } - if v, _ := d.GetOk("disable_api_termination"); v != nil { + if v, ok := d.GetOkExists("disable_api_termination"); ok { request.DisableApiTermination = helper.Bool(v.(bool)) } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().CreateLaunchTemplate(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().CreateLaunchTemplateWithContext(ctx, request) if e != nil { return tccommon.RetryError(e) } else { @@ -955,11 +960,12 @@ func resourceTencentCloudCvmLaunchTemplateCreate(d *schema.ResourceData, meta in return nil }) if err != nil { - log.Printf("[CRITAL]%s create cvm launchTemplate failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s create cvm launch template failed, reason:%+v", logId, err) return err } launchTemplateId = *response.Response.LaunchTemplateId + d.SetId(launchTemplateId) return resourceTencentCloudCvmLaunchTemplateRead(d, meta) @@ -971,51 +977,61 @@ func resourceTencentCloudCvmLaunchTemplateRead(d *schema.ResourceData, meta inte 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()} launchTemplateId := d.Id() - launchTemplate, err := service.DescribeCvmLaunchTemplateById(ctx, launchTemplateId) + respData, err := service.DescribeCvmLaunchTemplateById(ctx, launchTemplateId) if err != nil { return err } - if launchTemplate == nil { + if respData == nil { d.SetId("") - log.Printf("[WARN]%s resource `CvmLaunchTemplate` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + log.Printf("[WARN]%s resource `cvm_launch_template` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) return nil } - - if launchTemplate.LaunchTemplateName != nil { - _ = d.Set("launch_template_name", launchTemplate.LaunchTemplateName) + if respData.LaunchTemplateName != nil { + _ = d.Set("launch_template_name", respData.LaunchTemplateName) } - launchTemplateVersion, err := service.DescribeLaunchTemplateVersionsById(ctx, launchTemplateId) + respData1, err := service.DescribeCvmLaunchTemplateById1(ctx, launchTemplateId) if err != nil { return err } - if launchTemplateVersion == nil { + if respData1 == nil { d.SetId("") - log.Printf("[WARN]%s resource `CvmLaunchTemplateVersion` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + log.Printf("[WARN]%s resource `cvm_launch_template` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) return nil } - - if launchTemplateVersion.LaunchTemplateVersionData != nil && launchTemplateVersion.LaunchTemplateVersionData.Placement != nil { + if respData1.LaunchTemplateVersionData != nil { placementMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.Placement.Zone != nil { - placementMap["zone"] = launchTemplateVersion.LaunchTemplateVersionData.Placement.Zone - } + if respData1.LaunchTemplateVersionData.Placement != nil { + if respData1.LaunchTemplateVersionData.Placement.Zone != nil { + placementMap["zone"] = respData1.LaunchTemplateVersionData.Placement.Zone + } + + if respData1.LaunchTemplateVersionData.Placement.ProjectId != nil { + placementMap["project_id"] = respData1.LaunchTemplateVersionData.Placement.ProjectId + } - if launchTemplateVersion.LaunchTemplateVersionData.Placement.ProjectId != nil { - placementMap["project_id"] = launchTemplateVersion.LaunchTemplateVersionData.Placement.ProjectId + if respData1.LaunchTemplateVersionData.Placement.HostIds != nil { + placementMap["host_ids"] = respData1.LaunchTemplateVersionData.Placement.HostIds + } + + if respData1.LaunchTemplateVersionData.Placement.HostId != nil { + placementMap["host_id"] = respData1.LaunchTemplateVersionData.Placement.HostId + } + + _ = d.Set("placement", []interface{}{placementMap}) } - if launchTemplateVersion.LaunchTemplateVersionData.Placement.HostIds != nil { - placementMap["host_ids"] = launchTemplateVersion.LaunchTemplateVersionData.Placement.HostIds + if respData1.LaunchTemplateVersionData.InstanceType != nil { + _ = d.Set("instance_type", respData1.LaunchTemplateVersionData.InstanceType) } // It has been deprecated from version 1.81.108 @@ -1023,359 +1039,337 @@ func resourceTencentCloudCvmLaunchTemplateRead(d *schema.ResourceData, meta inte // placementMap["host_ips"] = launchTemplateVersion.LaunchTemplateVersionData.Placement.HostIps //} - if launchTemplateVersion.LaunchTemplateVersionData.Placement.HostId != nil { - placementMap["host_id"] = launchTemplateVersion.LaunchTemplateVersionData.Placement.HostId + if respData1.LaunchTemplateVersionData.InstanceChargeType != nil { + _ = d.Set("instance_charge_type", respData1.LaunchTemplateVersionData.InstanceChargeType) } - _ = d.Set("placement", []interface{}{placementMap}) - } + systemDiskMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData != nil && launchTemplateVersion.LaunchTemplateVersionData.ImageId != nil { - _ = d.Set("image_id", launchTemplateVersion.LaunchTemplateVersionData.ImageId) - } + if respData1.LaunchTemplateVersionData.SystemDisk != nil { + if respData1.LaunchTemplateVersionData.SystemDisk.DiskType != nil { + systemDiskMap["disk_type"] = respData1.LaunchTemplateVersionData.SystemDisk.DiskType + } - if launchTemplateVersion.LaunchTemplateVersionDescription != nil { - _ = d.Set("launch_template_version_description", launchTemplateVersion.LaunchTemplateVersionDescription) - } + if respData1.LaunchTemplateVersionData.SystemDisk.DiskId != nil { + systemDiskMap["disk_id"] = respData1.LaunchTemplateVersionData.SystemDisk.DiskId + } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceType != nil { - _ = d.Set("instance_type", launchTemplateVersion.LaunchTemplateVersionData.InstanceType) - } + if respData1.LaunchTemplateVersionData.SystemDisk.DiskSize != nil { + systemDiskMap["disk_size"] = respData1.LaunchTemplateVersionData.SystemDisk.DiskSize + } - if launchTemplateVersion.LaunchTemplateVersionData != nil && launchTemplateVersion.LaunchTemplateVersionData.SystemDisk != nil { - systemDiskMap := map[string]interface{}{} + if respData1.LaunchTemplateVersionData.SystemDisk.CdcId != nil { + systemDiskMap["cdc_id"] = respData1.LaunchTemplateVersionData.SystemDisk.CdcId + } - if launchTemplateVersion.LaunchTemplateVersionData.SystemDisk.DiskType != nil { - systemDiskMap["disk_type"] = launchTemplateVersion.LaunchTemplateVersionData.SystemDisk.DiskType + _ = d.Set("system_disk", []interface{}{systemDiskMap}) } - if launchTemplateVersion.LaunchTemplateVersionData.SystemDisk.DiskId != nil { - systemDiskMap["disk_id"] = launchTemplateVersion.LaunchTemplateVersionData.SystemDisk.DiskId - } + dataDisksList := make([]map[string]interface{}, 0, len(respData1.LaunchTemplateVersionData.DataDisks)) + if respData1.LaunchTemplateVersionData.DataDisks != nil { + for _, dataDisks := range respData1.LaunchTemplateVersionData.DataDisks { + dataDisksMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.SystemDisk.DiskSize != nil { - systemDiskMap["disk_size"] = launchTemplateVersion.LaunchTemplateVersionData.SystemDisk.DiskSize - } + if dataDisks.DiskSize != nil { + dataDisksMap["disk_size"] = dataDisks.DiskSize + } - if launchTemplateVersion.LaunchTemplateVersionData.SystemDisk.CdcId != nil { - systemDiskMap["cdc_id"] = launchTemplateVersion.LaunchTemplateVersionData.SystemDisk.CdcId - } + if dataDisks.DiskType != nil { + dataDisksMap["disk_type"] = dataDisks.DiskType + } - _ = d.Set("system_disk", []interface{}{systemDiskMap}) - } + if dataDisks.DiskId != nil { + dataDisksMap["disk_id"] = dataDisks.DiskId + } + + if dataDisks.DeleteWithInstance != nil { + dataDisksMap["delete_with_instance"] = dataDisks.DeleteWithInstance + } - if launchTemplateVersion.LaunchTemplateVersionData.DataDisks != nil { - dataDisksList := []interface{}{} - for _, dataDisk := range launchTemplateVersion.LaunchTemplateVersionData.DataDisks { - dataDisksMap := map[string]interface{}{} + if dataDisks.SnapshotId != nil { + dataDisksMap["snapshot_id"] = dataDisks.SnapshotId + } - if dataDisk.DiskSize != nil { - dataDisksMap["disk_size"] = dataDisk.DiskSize - } + if dataDisks.Encrypt != nil { + dataDisksMap["encrypt"] = dataDisks.Encrypt + } - if dataDisk.DiskType != nil { - dataDisksMap["disk_type"] = dataDisk.DiskType - } + if dataDisks.KmsKeyId != nil { + dataDisksMap["kms_key_id"] = dataDisks.KmsKeyId + } - if dataDisk.DiskId != nil { - dataDisksMap["disk_id"] = dataDisk.DiskId - } + if dataDisks.ThroughputPerformance != nil { + dataDisksMap["throughput_performance"] = dataDisks.ThroughputPerformance + } - if dataDisk.DeleteWithInstance != nil { - dataDisksMap["delete_with_instance"] = dataDisk.DeleteWithInstance - } + if dataDisks.CdcId != nil { + dataDisksMap["cdc_id"] = dataDisks.CdcId + } - if dataDisk.SnapshotId != nil { - dataDisksMap["snapshot_id"] = dataDisk.SnapshotId + dataDisksList = append(dataDisksList, dataDisksMap) } - if dataDisk.Encrypt != nil { - dataDisksMap["encrypt"] = dataDisk.Encrypt + _ = d.Set("data_disks", dataDisksList) + } + internetAccessibleMap := map[string]interface{}{} + + if respData1.LaunchTemplateVersionData.InternetAccessible != nil { + if respData1.LaunchTemplateVersionData.InternetAccessible.InternetChargeType != nil { + internetAccessibleMap["internet_charge_type"] = respData1.LaunchTemplateVersionData.InternetAccessible.InternetChargeType } - if dataDisk.KmsKeyId != nil { - dataDisksMap["kms_key_id"] = dataDisk.KmsKeyId + if respData1.LaunchTemplateVersionData.InternetAccessible.InternetMaxBandwidthOut != nil { + internetAccessibleMap["internet_max_bandwidth_out"] = respData1.LaunchTemplateVersionData.InternetAccessible.InternetMaxBandwidthOut } - if dataDisk.ThroughputPerformance != nil { - dataDisksMap["throughput_performance"] = dataDisk.ThroughputPerformance + if respData1.LaunchTemplateVersionData.InternetAccessible.PublicIpAssigned != nil { + internetAccessibleMap["public_ip_assigned"] = respData1.LaunchTemplateVersionData.InternetAccessible.PublicIpAssigned } - if dataDisk.CdcId != nil { - dataDisksMap["cdc_id"] = dataDisk.CdcId + if respData1.LaunchTemplateVersionData.InternetAccessible.BandwidthPackageId != nil { + internetAccessibleMap["bandwidth_package_id"] = respData1.LaunchTemplateVersionData.InternetAccessible.BandwidthPackageId } - dataDisksList = append(dataDisksList, dataDisksMap) + _ = d.Set("internet_accessible", []interface{}{internetAccessibleMap}) } - _ = d.Set("data_disks", dataDisksList) - - } - - if launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud != nil { virtualPrivateCloudMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.VpcId != nil { - virtualPrivateCloudMap["vpc_id"] = launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.VpcId - } - - if launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.SubnetId != nil { - virtualPrivateCloudMap["subnet_id"] = launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.SubnetId - } - - if launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.AsVpcGateway != nil { - virtualPrivateCloudMap["as_vpc_gateway"] = launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.AsVpcGateway - } - - if launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.PrivateIpAddresses != nil { - virtualPrivateCloudMap["private_ip_addresses"] = launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.PrivateIpAddresses - } + if respData1.LaunchTemplateVersionData.VirtualPrivateCloud != nil { + if respData1.LaunchTemplateVersionData.VirtualPrivateCloud.VpcId != nil { + virtualPrivateCloudMap["vpc_id"] = respData1.LaunchTemplateVersionData.VirtualPrivateCloud.VpcId + } - if launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.Ipv6AddressCount != nil { - virtualPrivateCloudMap["ipv6_address_count"] = launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.Ipv6AddressCount - } + if respData1.LaunchTemplateVersionData.VirtualPrivateCloud.SubnetId != nil { + virtualPrivateCloudMap["subnet_id"] = respData1.LaunchTemplateVersionData.VirtualPrivateCloud.SubnetId + } - _ = d.Set("virtual_private_cloud", []interface{}{virtualPrivateCloudMap}) - } + if respData1.LaunchTemplateVersionData.VirtualPrivateCloud.AsVpcGateway != nil { + virtualPrivateCloudMap["as_vpc_gateway"] = respData1.LaunchTemplateVersionData.VirtualPrivateCloud.AsVpcGateway + } - if launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible != nil { - internetAccessibleMap := map[string]interface{}{} + if respData1.LaunchTemplateVersionData.VirtualPrivateCloud.PrivateIpAddresses != nil { + virtualPrivateCloudMap["private_ip_addresses"] = respData1.LaunchTemplateVersionData.VirtualPrivateCloud.PrivateIpAddresses + } - if launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible.InternetChargeType != nil { - internetAccessibleMap["internet_charge_type"] = launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible.InternetChargeType - } + if respData1.LaunchTemplateVersionData.VirtualPrivateCloud.Ipv6AddressCount != nil { + virtualPrivateCloudMap["ipv6_address_count"] = respData1.LaunchTemplateVersionData.VirtualPrivateCloud.Ipv6AddressCount + } - if launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible.InternetMaxBandwidthOut != nil { - internetAccessibleMap["internet_max_bandwidth_out"] = launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible.InternetMaxBandwidthOut + _ = d.Set("virtual_private_cloud", []interface{}{virtualPrivateCloudMap}) } - if launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible.PublicIpAssigned != nil { - internetAccessibleMap["public_ip_assigned"] = launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible.PublicIpAssigned + if respData1.LaunchTemplateVersionData.ImageId != nil { + _ = d.Set("image_id", respData1.LaunchTemplateVersionData.ImageId) } - if launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible.BandwidthPackageId != nil { - internetAccessibleMap["bandwidth_package_id"] = launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible.BandwidthPackageId + if respData1.LaunchTemplateVersionData.SecurityGroupIds != nil { + _ = d.Set("security_group_ids", respData1.LaunchTemplateVersionData.SecurityGroupIds) } - _ = d.Set("internet_accessible", []interface{}{internetAccessibleMap}) - } + loginSettingsMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.InstanceCount != nil { - _ = d.Set("instance_count", launchTemplateVersion.LaunchTemplateVersionData.InstanceCount) - } + if respData1.LaunchTemplateVersionData.LoginSettings != nil { + if respData1.LaunchTemplateVersionData.LoginSettings.Password != nil { + loginSettingsMap["password"] = respData1.LaunchTemplateVersionData.LoginSettings.Password + } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceName != nil { - _ = d.Set("instance_name", launchTemplateVersion.LaunchTemplateVersionData.InstanceName) - } + if respData1.LaunchTemplateVersionData.LoginSettings.KeyIds != nil { + loginSettingsMap["key_ids"] = respData1.LaunchTemplateVersionData.LoginSettings.KeyIds + } - if launchTemplateVersion.LaunchTemplateVersionData.LoginSettings != nil { - loginSettingsMap := map[string]interface{}{} + if respData1.LaunchTemplateVersionData.LoginSettings.KeepImageLogin != nil { + loginSettingsMap["keep_image_login"] = respData1.LaunchTemplateVersionData.LoginSettings.KeepImageLogin + } - if launchTemplateVersion.LaunchTemplateVersionData.LoginSettings.Password != nil { - loginSettingsMap["password"] = launchTemplateVersion.LaunchTemplateVersionData.LoginSettings.Password + _ = d.Set("login_settings", []interface{}{loginSettingsMap}) } - if launchTemplateVersion.LaunchTemplateVersionData.LoginSettings.KeyIds != nil { - loginSettingsMap["key_ids"] = launchTemplateVersion.LaunchTemplateVersionData.LoginSettings.KeyIds + if respData1.LaunchTemplateVersionData.CamRoleName != nil { + _ = d.Set("cam_role_name", respData1.LaunchTemplateVersionData.CamRoleName) } - if launchTemplateVersion.LaunchTemplateVersionData.LoginSettings.KeepImageLogin != nil { - loginSettingsMap["keep_image_login"] = launchTemplateVersion.LaunchTemplateVersionData.LoginSettings.KeepImageLogin + if respData1.LaunchTemplateVersionData.HpcClusterId != nil { + _ = d.Set("hpc_cluster_id", respData1.LaunchTemplateVersionData.HpcClusterId) } - _ = d.Set("login_settings", []interface{}{loginSettingsMap}) - } - - if launchTemplateVersion.LaunchTemplateVersionData.SecurityGroupIds != nil { - _ = d.Set("security_group_ids", launchTemplateVersion.LaunchTemplateVersionData.SecurityGroupIds) - } + if respData1.LaunchTemplateVersionData.InstanceCount != nil { + _ = d.Set("instance_count", respData1.LaunchTemplateVersionData.InstanceCount) + } - if launchTemplateVersion.LaunchTemplateVersionData.EnhancedService != nil { enhancedServiceMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.SecurityService != nil { + if respData1.LaunchTemplateVersionData.EnhancedService != nil { securityServiceMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.SecurityService.Enabled != nil { - securityServiceMap["enabled"] = launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.SecurityService.Enabled - } + if respData1.LaunchTemplateVersionData.EnhancedService.SecurityService != nil { + if respData1.LaunchTemplateVersionData.EnhancedService.SecurityService.Enabled != nil { + securityServiceMap["enabled"] = respData1.LaunchTemplateVersionData.EnhancedService.SecurityService.Enabled + } - enhancedServiceMap["security_service"] = []interface{}{securityServiceMap} - } + enhancedServiceMap["security_service"] = []interface{}{securityServiceMap} + } - if launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.MonitorService != nil { monitorServiceMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.MonitorService.Enabled != nil { - monitorServiceMap["enabled"] = launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.MonitorService.Enabled - } + if respData1.LaunchTemplateVersionData.EnhancedService.MonitorService != nil { + if respData1.LaunchTemplateVersionData.EnhancedService.MonitorService.Enabled != nil { + monitorServiceMap["enabled"] = respData1.LaunchTemplateVersionData.EnhancedService.MonitorService.Enabled + } - enhancedServiceMap["monitor_service"] = []interface{}{monitorServiceMap} - } + enhancedServiceMap["monitor_service"] = []interface{}{monitorServiceMap} + } - if launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.AutomationService != nil { automationServiceMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.AutomationService.Enabled != nil { - automationServiceMap["enabled"] = launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.AutomationService.Enabled + if respData1.LaunchTemplateVersionData.EnhancedService.AutomationService != nil { + if respData1.LaunchTemplateVersionData.EnhancedService.AutomationService.Enabled != nil { + automationServiceMap["enabled"] = respData1.LaunchTemplateVersionData.EnhancedService.AutomationService.Enabled + } + + enhancedServiceMap["automation_service"] = []interface{}{automationServiceMap} } - enhancedServiceMap["automation_service"] = []interface{}{automationServiceMap} + _ = d.Set("enhanced_service", []interface{}{enhancedServiceMap}) } - _ = d.Set("enhanced_service", []interface{}{enhancedServiceMap}) - } - - if launchTemplateVersion.LaunchTemplateVersionData.ClientToken != nil { - _ = d.Set("client_token", launchTemplateVersion.LaunchTemplateVersionData.ClientToken) - } - - if launchTemplateVersion.LaunchTemplateVersionData.HostName != nil { - _ = d.Set("host_name", launchTemplateVersion.LaunchTemplateVersionData.HostName) - } - - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer != nil { - actionTimerMap := map[string]interface{}{} - - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.TimerAction != nil { - actionTimerMap["timer_action"] = launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.TimerAction + if respData1.LaunchTemplateVersionData.UserData != nil { + _ = d.Set("user_data", respData1.LaunchTemplateVersionData.UserData) } - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.ActionTime != nil { - actionTimerMap["action_time"] = launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.ActionTime + if respData1.LaunchTemplateVersionData.DisasterRecoverGroupIds != nil { + _ = d.Set("disaster_recover_group_ids", respData1.LaunchTemplateVersionData.DisasterRecoverGroupIds) } - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals != nil { - externalsMap := map[string]interface{}{} + actionTimerMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.ReleaseAddress != nil { - externalsMap["release_address"] = launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.ReleaseAddress + if respData1.LaunchTemplateVersionData.ActionTimer != nil { + if respData1.LaunchTemplateVersionData.ActionTimer.TimerAction != nil { + actionTimerMap["timer_action"] = respData1.LaunchTemplateVersionData.ActionTimer.TimerAction } - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.UnsupportNetworks != nil { - externalsMap["unsupport_networks"] = launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.UnsupportNetworks + if respData1.LaunchTemplateVersionData.ActionTimer.ActionTime != nil { + actionTimerMap["action_time"] = respData1.LaunchTemplateVersionData.ActionTimer.ActionTime } - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr != nil { - storageBlockAttrMap := map[string]interface{}{} - - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.Type != nil { - storageBlockAttrMap["type"] = launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.Type - } + externalsMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.MinSize != nil { - storageBlockAttrMap["min_size"] = launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.MinSize + if respData1.LaunchTemplateVersionData.ActionTimer.Externals != nil { + if respData1.LaunchTemplateVersionData.ActionTimer.Externals.ReleaseAddress != nil { + externalsMap["release_address"] = respData1.LaunchTemplateVersionData.ActionTimer.Externals.ReleaseAddress } - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.MaxSize != nil { - storageBlockAttrMap["max_size"] = launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.MaxSize + if respData1.LaunchTemplateVersionData.ActionTimer.Externals.UnsupportNetworks != nil { + externalsMap["unsupport_networks"] = respData1.LaunchTemplateVersionData.ActionTimer.Externals.UnsupportNetworks } - externalsMap["storage_block_attr"] = []interface{}{storageBlockAttrMap} - } + storageBlockAttrMap := map[string]interface{}{} - actionTimerMap["externals"] = []interface{}{externalsMap} - } + if respData1.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr != nil { + if respData1.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.Type != nil { + storageBlockAttrMap["type"] = respData1.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.Type + } - _ = d.Set("action_timer", []interface{}{actionTimerMap}) - } + if respData1.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.MinSize != nil { + storageBlockAttrMap["min_size"] = respData1.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.MinSize + } - if launchTemplateVersion.LaunchTemplateVersionData.DisasterRecoverGroupIds != nil { - _ = d.Set("disaster_recover_group_ids", launchTemplateVersion.LaunchTemplateVersionData.DisasterRecoverGroupIds) - } + if respData1.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.MaxSize != nil { + storageBlockAttrMap["max_size"] = respData1.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.MaxSize + } - if launchTemplateVersion.LaunchTemplateVersionData.TagSpecification != nil { - tagSpecificationList := []interface{}{} - for _, tagSpecification := range launchTemplateVersion.LaunchTemplateVersionData.TagSpecification { - tagSpecificationMap := map[string]interface{}{} + externalsMap["storage_block_attr"] = []interface{}{storageBlockAttrMap} + } - if tagSpecification.ResourceType != nil { - tagSpecificationMap["resource_type"] = tagSpecification.ResourceType + actionTimerMap["externals"] = []interface{}{externalsMap} } - if tagSpecification.Tags != nil { - tagsList := []interface{}{} - for _, tag := range tagSpecification.Tags { - tagsMap := map[string]interface{}{} + _ = d.Set("action_timer", []interface{}{actionTimerMap}) + } - if tag.Key != nil { - tagsMap["key"] = tag.Key - } + instanceMarketOptionsMap := map[string]interface{}{} - if tag.Value != nil { - tagsMap["value"] = tag.Value - } + if respData1.LaunchTemplateVersionData.InstanceMarketOptions != nil { + spotOptionsMap := map[string]interface{}{} - tagsList = append(tagsList, tagsMap) + if respData1.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions != nil { + if respData1.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions.MaxPrice != nil { + spotOptionsMap["max_price"] = respData1.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions.MaxPrice } - tagSpecificationMap["tags"] = []interface{}{tagsList} + if respData1.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions.SpotInstanceType != nil { + spotOptionsMap["spot_instance_type"] = respData1.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions.SpotInstanceType + } + + instanceMarketOptionsMap["spot_options"] = []interface{}{spotOptionsMap} } - tagSpecificationList = append(tagSpecificationList, tagSpecificationMap) - } + if respData1.LaunchTemplateVersionData.InstanceMarketOptions.MarketType != nil { + instanceMarketOptionsMap["market_type"] = respData1.LaunchTemplateVersionData.InstanceMarketOptions.MarketType + } - _ = d.Set("tag_specification", tagSpecificationList) + _ = d.Set("instance_market_options", []interface{}{instanceMarketOptionsMap}) + } - } + if respData1.LaunchTemplateVersionData.HostName != nil { + _ = d.Set("host_name", respData1.LaunchTemplateVersionData.HostName) + } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceMarketOptions != nil { - instanceMarketOptionsMap := map[string]interface{}{} + if respData1.LaunchTemplateVersionData.ClientToken != nil { + _ = d.Set("client_token", respData1.LaunchTemplateVersionData.ClientToken) + } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions != nil { - spotOptionsMap := map[string]interface{}{} + instanceChargePrepaidMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions.MaxPrice != nil { - spotOptionsMap["max_price"] = launchTemplateVersion.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions.MaxPrice + if respData1.LaunchTemplateVersionData.InstanceChargePrepaid != nil { + if respData1.LaunchTemplateVersionData.InstanceChargePrepaid.Period != nil { + instanceChargePrepaidMap["period"] = respData1.LaunchTemplateVersionData.InstanceChargePrepaid.Period } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions.SpotInstanceType != nil { - spotOptionsMap["spot_instance_type"] = launchTemplateVersion.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions.SpotInstanceType + if respData1.LaunchTemplateVersionData.InstanceChargePrepaid.RenewFlag != nil { + instanceChargePrepaidMap["renew_flag"] = respData1.LaunchTemplateVersionData.InstanceChargePrepaid.RenewFlag } - instanceMarketOptionsMap["spot_options"] = []interface{}{spotOptionsMap} + _ = d.Set("instance_charge_prepaid", []interface{}{instanceChargePrepaidMap}) } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceMarketOptions.MarketType != nil { - instanceMarketOptionsMap["market_type"] = launchTemplateVersion.LaunchTemplateVersionData.InstanceMarketOptions.MarketType - } - - _ = d.Set("instance_market_options", []interface{}{instanceMarketOptionsMap}) - } + tagSpecificationList := make([]map[string]interface{}, 0, len(respData1.LaunchTemplateVersionData.TagSpecification)) + if respData1.LaunchTemplateVersionData.TagSpecification != nil { + for _, tagSpecification := range respData1.LaunchTemplateVersionData.TagSpecification { + tagSpecificationMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.UserData != nil { - _ = d.Set("user_data", launchTemplateVersion.LaunchTemplateVersionData.UserData) - } + if tagSpecification.ResourceType != nil { + tagSpecificationMap["resource_type"] = tagSpecification.ResourceType + } - if launchTemplateVersion.LaunchTemplateVersionData.CamRoleName != nil { - _ = d.Set("cam_role_name", launchTemplateVersion.LaunchTemplateVersionData.CamRoleName) - } + tagsList := make([]map[string]interface{}, 0, len(tagSpecification.Tags)) + if tagSpecification.Tags != nil { + for _, tags := range tagSpecification.Tags { + tagsMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.HpcClusterId != nil { - _ = d.Set("hpc_cluster_id", launchTemplateVersion.LaunchTemplateVersionData.HpcClusterId) - } + if tags.Key != nil { + tagsMap["key"] = tags.Key + } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceChargeType != nil { - _ = d.Set("instance_charge_type", launchTemplateVersion.LaunchTemplateVersionData.InstanceChargeType) - } + if tags.Value != nil { + tagsMap["value"] = tags.Value + } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceChargePrepaid != nil { - instanceChargePrepaidMap := map[string]interface{}{} + tagsList = append(tagsList, tagsMap) + } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceChargePrepaid.Period != nil { - instanceChargePrepaidMap["period"] = launchTemplateVersion.LaunchTemplateVersionData.InstanceChargePrepaid.Period - } + tagSpecificationMap["tags"] = tagsList + } + tagSpecificationList = append(tagSpecificationList, tagSpecificationMap) + } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceChargePrepaid.RenewFlag != nil { - instanceChargePrepaidMap["renew_flag"] = launchTemplateVersion.LaunchTemplateVersionData.InstanceChargePrepaid.RenewFlag + _ = d.Set("tag_specification", tagSpecificationList) } - - _ = d.Set("instance_charge_prepaid", []interface{}{instanceChargePrepaidMap}) } - // if launchTemplateVersion.LaunchTemplateVersionData.DisableApiTermination != nil { - // _ = d.Set("disable_api_termination", launchTemplateVersion.LaunchTemplateVersionData.DisableApiTermination) - // } + if respData1.LaunchTemplateVersionDescription != nil { + _ = d.Set("launch_template_version_description", respData1.LaunchTemplateVersionDescription) + } return nil } @@ -1385,14 +1379,32 @@ func resourceTencentCloudCvmLaunchTemplateDelete(d *schema.ResourceData, meta in defer tccommon.InconsistentCheck(d, meta)() 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()} launchTemplateId := d.Id() - if err := service.DeleteCvmLaunchTemplateById(ctx, launchTemplateId); err != nil { + var ( + request = cvm.NewDeleteLaunchTemplateRequest() + response = cvm.NewDeleteLaunchTemplateResponse() + ) + + request.LaunchTemplateId = helper.String(launchTemplateId) + + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().DeleteLaunchTemplateWithContext(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 launch template failed, reason:%+v", logId, err) return err } + _ = response return nil } diff --git a/tencentcloud/services/cvm/resource_tc_cvm_launch_template_default_version.go b/tencentcloud/services/cvm/resource_tc_cvm_launch_template_default_version.go index a63ecaa7be..1baadfd38f 100644 --- a/tencentcloud/services/cvm/resource_tc_cvm_launch_template_default_version.go +++ b/tencentcloud/services/cvm/resource_tc_cvm_launch_template_default_version.go @@ -1,13 +1,16 @@ +// Code generated by iacg; DO NOT EDIT. 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 ResourceTencentCloudCvmLaunchTemplateDefaultVersion() *schema.Resource { @@ -21,15 +24,15 @@ func ResourceTencentCloudCvmLaunchTemplateDefaultVersion() *schema.Resource { }, Schema: map[string]*schema.Schema{ "launch_template_id": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "Instance launch template ID.", }, "default_version": { - Required: true, Type: schema.TypeInt, + Required: true, Description: "The number of the version that you want to set as the default version.", }, }, @@ -40,25 +43,16 @@ func resourceTencentCloudCvmLaunchTemplateDefaultVersionCreate(d *schema.Resourc defer tccommon.LogElapsed("resource.tencentcloud_cvm_launch_template_default_version.create")() defer tccommon.InconsistentCheck(d, meta)() - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - launchTemplateId := d.Get("launch_template_id").(string) - defaultVersion := d.Get("default_version").(int) - err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - e := service.ModifyLaunchTemplateDefaultVersion(ctx, launchTemplateId, defaultVersion) - if e != nil { - return tccommon.RetryError(e) - } - return nil - }) - if err != nil { - return err + var ( + launchTemplateId string + ) + if v, ok := d.GetOk("launch_template_id"); ok { + launchTemplateId = v.(string) } d.SetId(launchTemplateId) - return resourceTencentCloudCvmLaunchTemplateDefaultVersionRead(d, meta) + return resourceTencentCloudCvmLaunchTemplateDefaultVersionUpdate(d, meta) } func resourceTencentCloudCvmLaunchTemplateDefaultVersionRead(d *schema.ResourceData, meta interface{}) error { @@ -66,29 +60,28 @@ func resourceTencentCloudCvmLaunchTemplateDefaultVersionRead(d *schema.ResourceD defer tccommon.InconsistentCheck(d, meta)() 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()} launchTemplateId := d.Id() - launchTemplateVersions, err := service.DescribeLaunchTemplateVersions(ctx, launchTemplateId) + + _ = d.Set("launch_template_id", launchTemplateId) + + respData, err := service.DescribeCvmLaunchTemplateDefaultVersionById(ctx, launchTemplateId) if err != nil { return err } - if len(launchTemplateVersions) == 0 { + if respData == nil { d.SetId("") - log.Printf("[WARN]%s resource `CvmLaunchTemplateDefaultVersion` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + log.Printf("[WARN]%s resource `cvm_launch_template_default_version` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) return nil } - - for _, launchTemplateVersion := range launchTemplateVersions { - if *launchTemplateVersion.IsDefaultVersion { - _ = d.Set("default_version", launchTemplateVersion.LaunchTemplateVersion) - break - } + if respData.LaunchTemplateVersion != nil { + _ = d.Set("default_version", respData.LaunchTemplateVersion) } - _ = d.Set("launch_template_id", d.Id()) return nil } @@ -98,18 +91,40 @@ func resourceTencentCloudCvmLaunchTemplateDefaultVersionUpdate(d *schema.Resourc defer tccommon.InconsistentCheck(d, meta)() logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - if d.HasChange("default_version") { + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + launchTemplateId := d.Id() + + needChange := false + mutableArgs := []string{"default_version"} + for _, v := range mutableArgs { + if d.HasChange(v) { + needChange = true + break + } + } + + if needChange { + request := cvm.NewModifyLaunchTemplateDefaultVersionRequest() + + request.LaunchTemplateId = helper.String(launchTemplateId) + + if v, ok := d.GetOkExists("default_version"); ok { + request.DefaultVersion = helper.IntInt64(v.(int)) + } + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - e := service.ModifyLaunchTemplateDefaultVersion(ctx, d.Id(), d.Get("default_version").(int)) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyLaunchTemplateDefaultVersionWithContext(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 cvm launch template default version failed, reason:%+v", logId, err) return err } } diff --git a/tencentcloud/services/cvm/resource_tc_cvm_launch_template_default_version_extension.go b/tencentcloud/services/cvm/resource_tc_cvm_launch_template_default_version_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_cvm_launch_template_default_version_extension.go @@ -0,0 +1 @@ +package cvm diff --git a/tencentcloud/services/cvm/resource_tc_cvm_launch_template_extension.go b/tencentcloud/services/cvm/resource_tc_cvm_launch_template_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_cvm_launch_template_extension.go @@ -0,0 +1 @@ +package cvm diff --git a/tencentcloud/services/cvm/resource_tc_cvm_launch_template_version.go b/tencentcloud/services/cvm/resource_tc_cvm_launch_template_version.go index deda40a6f3..ce574cabf9 100644 --- a/tencentcloud/services/cvm/resource_tc_cvm_launch_template_version.go +++ b/tencentcloud/services/cvm/resource_tc_cvm_launch_template_version.go @@ -1,18 +1,17 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( "context" "fmt" "log" - "strconv" "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" ) @@ -26,9 +25,9 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { }, Schema: map[string]*schema.Schema{ "placement": { + Type: schema.TypeList, Required: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "Location of the instance. You can use this parameter to specify the attributes of the instance, such as its availability zone, project, and CDH (for dedicated CVMs).", Elem: &schema.Resource{ @@ -47,73 +46,73 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { Description: "ID of the project to which the instance belongs. This parameter can be obtained from the projectId returned by DescribeProject. If this is left empty, the default project is used.", }, "host_ids": { - Type: schema.TypeSet, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, + Type: schema.TypeSet, Optional: true, Computed: true, ForceNew: true, Description: "ID list of CDHs from which the instance can be created. If you have purchased CDHs and specify this parameter, the instances you purchase will be randomly deployed on the CDHs.", - }, - "host_ips": { - Type: schema.TypeSet, Elem: &schema.Schema{ Type: schema.TypeString, }, + }, + "host_ips": { + Type: schema.TypeSet, Optional: true, Computed: true, ForceNew: true, Description: "IPs of the hosts to create CVMs.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, }, }, }, "launch_template_id": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "Instance launch template ID. This parameter is used as a basis for creating new template versions.", }, "launch_template_version": { + Type: schema.TypeInt, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeInt, Description: "This parameter, when specified, is used to create instance launch templates. If this parameter is not specified, the default version will be used.", }, "launch_template_version_description": { + Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeString, Description: "Description of instance launch template versions. This parameter can contain 2-256 characters.", }, "instance_type": { + Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeString, Description: "The type of the instance. If this parameter is not specified, the system will dynamically specify the default model according to the resource sales in the current region.", }, "image_id": { + Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeString, Description: "Image ID.", }, "system_disk": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "System disk configuration information of the instance. If this parameter is not specified, it is assigned according to the system default.", Elem: &schema.Resource{ @@ -151,10 +150,10 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { }, "data_disks": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, Description: "The configuration information of instance data disks. If this parameter is not specified, no data disk will be purchased by default.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -225,10 +224,10 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { }, "virtual_private_cloud": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "Describes information on VPC, including subnets, IP addresses, etc.", Elem: &schema.Resource{ @@ -253,14 +252,14 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { Description: "Whether to use a CVM instance as a public gateway. The public gateway is only available when the instance has a public IP and resides in a VPC.", }, "private_ip_addresses": { - Type: schema.TypeSet, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, + Type: schema.TypeSet, Optional: true, Computed: true, ForceNew: true, Description: "Array of VPC subnet IPs. You can use this parameter when creating instances or modifying VPC attributes of instances. Currently you can specify multiple IPs in one subnet only when creating multiple instances at the same time.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, "ipv6_address_count": { Type: schema.TypeInt, @@ -274,10 +273,10 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { }, "internet_accessible": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "Describes the accessibility of an instance in the public network, including its network billing method, maximum bandwidth, etc.", Elem: &schema.Resource{ @@ -315,26 +314,26 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { }, "instance_count": { + Type: schema.TypeInt, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeInt, Description: "The number of instances to be purchased.", }, "instance_name": { + Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeString, Description: "Instance name to be displayed.", }, "login_settings": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "Describes login settings of an instance.", Elem: &schema.Resource{ @@ -347,14 +346,14 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { Description: "Login password of the instance.", }, "key_ids": { - Type: schema.TypeSet, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, + Type: schema.TypeSet, Optional: true, Computed: true, ForceNew: true, Description: "List of key IDs. After an instance is associated with a key, you can access the instance with the private key in the key pair.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, "keep_image_login": { Type: schema.TypeString, @@ -368,31 +367,31 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { }, "security_group_ids": { - Optional: true, - Computed: true, - ForceNew: true, - Type: schema.TypeSet, + Type: schema.TypeSet, + Optional: true, + Computed: true, + ForceNew: true, + Description: "Security groups to which the instance belongs. If this parameter is not specified, the instance will be associated with default security groups.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Description: "Security groups to which the instance belongs. If this parameter is not specified, the instance will be associated with default security groups.", }, "enhanced_service": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "Enhanced service. You can use this parameter to specify whether to enable services such as Anti-DDoS and Cloud Monitor. If this parameter is not specified, Cloud Monitor and Anti-DDoS are enabled for public images by default.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "security_service": { Type: schema.TypeList, - MaxItems: 1, Optional: true, Computed: true, ForceNew: true, + MaxItems: 1, Description: "Enables cloud security service. If this parameter is not specified, the cloud security service will be enabled by default.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -407,10 +406,10 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { }, "monitor_service": { Type: schema.TypeList, - MaxItems: 1, Optional: true, Computed: true, ForceNew: true, + MaxItems: 1, Description: "Enables cloud monitor service. If this parameter is not specified, the cloud monitor service will be enabled by default.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -426,10 +425,10 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { }, "automation_service": { Type: schema.TypeList, - MaxItems: 1, Optional: true, Computed: true, ForceNew: true, + MaxItems: 1, Description: "Whether to enable the TAT service. If this parameter is not specified, the TAT service is enabled for public images and disabled for other images by default.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -448,26 +447,26 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { }, "client_token": { + Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeString, Description: "A unique string supplied by the client to ensure that the request is idempotent. Its maximum length is 64 ASCII characters. If this parameter is not specified, the idem-potency of the request cannot be guaranteed.", }, "host_name": { + Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeString, Description: "Hostname of a CVM.", }, "action_timer": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "Scheduled tasks.", Elem: &schema.Resource{ @@ -488,10 +487,10 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { }, "externals": { Type: schema.TypeList, - MaxItems: 1, Optional: true, Computed: true, ForceNew: true, + MaxItems: 1, Description: "Additional data.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -503,21 +502,21 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { Description: "Release address.", }, "unsupport_networks": { - Type: schema.TypeSet, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, + Type: schema.TypeSet, Optional: true, Computed: true, ForceNew: true, Description: "Not supported network.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, "storage_block_attr": { Type: schema.TypeList, - MaxItems: 1, Optional: true, Computed: true, ForceNew: true, + MaxItems: 1, Description: "Information on local HDD storage.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -550,20 +549,20 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { }, "disaster_recover_group_ids": { - Optional: true, - ForceNew: true, - Type: schema.TypeSet, + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + Description: "Placement group ID. You can only specify one.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Description: "Placement group ID. You can only specify one.", }, "tag_specification": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, Description: "Description of tags associated with resource instances during instance creation.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -599,19 +598,19 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { }, "instance_market_options": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "Options related to bidding requests.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "spot_options": { Type: schema.TypeList, - MaxItems: 1, Required: true, ForceNew: true, + MaxItems: 1, Description: "Options related to bidding.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -643,50 +642,50 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { }, "user_data": { + Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeString, Description: "User data provided to the instance. This parameter needs to be encoded in base64 format with the maximum size of 16 KB.", }, "dry_run": { + Type: schema.TypeBool, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeBool, Description: "Whether the request is a dry run only.", }, "cam_role_name": { + Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeString, Description: "The role name of CAM.", }, "hpc_cluster_id": { + Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeString, Description: "HPC cluster ID. The HPC cluster must and can only be specified for a high-performance computing instance.", }, "instance_charge_type": { + Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeString, Description: "The charge type of instance.", }, "instance_charge_prepaid": { + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "Describes the billing method of an instance.", Elem: &schema.Resource{ @@ -709,10 +708,10 @@ func ResourceTencentCloudCvmLaunchTemplateVersion() *schema.Resource { }, "disable_api_termination": { + Type: schema.TypeBool, Optional: true, Computed: true, ForceNew: true, - Type: schema.TypeBool, Description: "Whether the termination protection is enabled. `TRUE`: Enable instance protection, which means that this instance can not be deleted by an API action.`FALSE`: Do not enable the instance protection. Default value: `FALSE`.", }, }, @@ -725,24 +724,34 @@ func resourceTencentCloudCvmLaunchTemplateVersionCreate(d *schema.ResourceData, logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + var ( - request = cvm.NewCreateLaunchTemplateVersionRequest() - response = cvm.NewCreateLaunchTemplateVersionResponse() - launchTemplateId string + launchTemplateId string + launchTemplateVersionNumber int64 ) - if dMap, ok := helper.InterfacesHeadMap(d, "placement"); ok { + var ( + request = cvm.NewCreateLaunchTemplateVersionRequest() + response = cvm.NewCreateLaunchTemplateVersionResponse() + ) + + if v, ok := d.GetOk("launch_template_id"); ok { + launchTemplateId = v.(string) + } + + if placementMap, ok := helper.InterfacesHeadMap(d, "placement"); ok { placement := cvm.Placement{} - if v, ok := dMap["zone"]; ok { + if v, ok := placementMap["zone"]; ok { placement.Zone = helper.String(v.(string)) } - if v, ok := dMap["project_id"]; ok { + if v, ok := placementMap["project_id"]; ok { placement.ProjectId = helper.IntInt64(v.(int)) } - if v, ok := dMap["host_ids"]; ok { + if v, ok := placementMap["host_ids"]; ok { hostIdsSet := v.(*schema.Set).List() for i := range hostIdsSet { hostIds := hostIdsSet[i].(string) - placement.HostIds = append(placement.HostIds, &hostIds) + placement.HostIds = append(placement.HostIds, helper.String(hostIds)) } } //if v, ok := dMap["host_ips"]; ok { @@ -756,8 +765,7 @@ func resourceTencentCloudCvmLaunchTemplateVersionCreate(d *schema.ResourceData, } if v, ok := d.GetOk("launch_template_id"); ok { - launchTemplateId = v.(string) - request.LaunchTemplateId = helper.String(launchTemplateId) + request.LaunchTemplateId = helper.String(v.(string)) } if v, ok := d.GetOkExists("launch_template_version"); ok { @@ -776,18 +784,18 @@ func resourceTencentCloudCvmLaunchTemplateVersionCreate(d *schema.ResourceData, request.ImageId = helper.String(v.(string)) } - if dMap, ok := helper.InterfacesHeadMap(d, "system_disk"); ok { + if systemDiskMap, ok := helper.InterfacesHeadMap(d, "system_disk"); ok { systemDisk := cvm.SystemDisk{} - if v, ok := dMap["disk_type"]; ok { + if v, ok := systemDiskMap["disk_type"]; ok { systemDisk.DiskType = helper.String(v.(string)) } - if v, ok := dMap["disk_id"]; ok { + if v, ok := systemDiskMap["disk_id"]; ok { systemDisk.DiskId = helper.String(v.(string)) } - if v, ok := dMap["disk_size"]; ok { + if v, ok := systemDiskMap["disk_size"]; ok { systemDisk.DiskSize = helper.IntInt64(v.(int)) } - if v, ok := dMap["cdc_id"]; ok { + if v, ok := systemDiskMap["cdc_id"]; ok { systemDisk.CdcId = helper.String(v.(string)) } request.SystemDisk = &systemDisk @@ -795,75 +803,75 @@ func resourceTencentCloudCvmLaunchTemplateVersionCreate(d *schema.ResourceData, if v, ok := d.GetOk("data_disks"); ok { for _, item := range v.([]interface{}) { - dMap := item.(map[string]interface{}) + dataDisksMap := item.(map[string]interface{}) dataDisk := cvm.DataDisk{} - if v, ok := dMap["disk_size"]; ok { + if v, ok := dataDisksMap["disk_size"]; ok { dataDisk.DiskSize = helper.IntInt64(v.(int)) } - if v, ok := dMap["disk_type"]; ok { + if v, ok := dataDisksMap["disk_type"]; ok { dataDisk.DiskType = helper.String(v.(string)) } - if v, ok := dMap["disk_id"]; ok { + if v, ok := dataDisksMap["disk_id"]; ok { dataDisk.DiskId = helper.String(v.(string)) } - if v, ok := dMap["delete_with_instance"]; ok { + if v, ok := dataDisksMap["delete_with_instance"]; ok { dataDisk.DeleteWithInstance = helper.Bool(v.(bool)) } - if v, ok := dMap["snapshot_id"]; ok { + if v, ok := dataDisksMap["snapshot_id"]; ok { dataDisk.SnapshotId = helper.String(v.(string)) } - if v, ok := dMap["encrypt"]; ok { + if v, ok := dataDisksMap["encrypt"]; ok { dataDisk.Encrypt = helper.Bool(v.(bool)) } - if v, ok := dMap["kms_key_id"]; ok { + if v, ok := dataDisksMap["kms_key_id"]; ok { dataDisk.KmsKeyId = helper.String(v.(string)) } - if v, ok := dMap["throughput_performance"]; ok { + if v, ok := dataDisksMap["throughput_performance"]; ok { dataDisk.ThroughputPerformance = helper.IntInt64(v.(int)) } - if v, ok := dMap["cdc_id"]; ok { + if v, ok := dataDisksMap["cdc_id"]; ok { dataDisk.CdcId = helper.String(v.(string)) } request.DataDisks = append(request.DataDisks, &dataDisk) } } - if dMap, ok := helper.InterfacesHeadMap(d, "virtual_private_cloud"); ok { + if virtualPrivateCloudMap, ok := helper.InterfacesHeadMap(d, "virtual_private_cloud"); ok { virtualPrivateCloud := cvm.VirtualPrivateCloud{} - if v, ok := dMap["vpc_id"]; ok { + if v, ok := virtualPrivateCloudMap["vpc_id"]; ok { virtualPrivateCloud.VpcId = helper.String(v.(string)) } - if v, ok := dMap["subnet_id"]; ok { + if v, ok := virtualPrivateCloudMap["subnet_id"]; ok { virtualPrivateCloud.SubnetId = helper.String(v.(string)) } - if v, ok := dMap["as_vpc_gateway"]; ok { + if v, ok := virtualPrivateCloudMap["as_vpc_gateway"]; ok { virtualPrivateCloud.AsVpcGateway = helper.Bool(v.(bool)) } - if v, ok := dMap["private_ip_addresses"]; ok { + if v, ok := virtualPrivateCloudMap["private_ip_addresses"]; ok { privateIpAddressesSet := v.(*schema.Set).List() for i := range privateIpAddressesSet { privateIpAddresses := privateIpAddressesSet[i].(string) - virtualPrivateCloud.PrivateIpAddresses = append(virtualPrivateCloud.PrivateIpAddresses, &privateIpAddresses) + virtualPrivateCloud.PrivateIpAddresses = append(virtualPrivateCloud.PrivateIpAddresses, helper.String(privateIpAddresses)) } } - if v, ok := dMap["ipv6_address_count"]; ok { + if v, ok := virtualPrivateCloudMap["ipv6_address_count"]; ok { virtualPrivateCloud.Ipv6AddressCount = helper.IntUint64(v.(int)) } request.VirtualPrivateCloud = &virtualPrivateCloud } - if dMap, ok := helper.InterfacesHeadMap(d, "internet_accessible"); ok { + if internetAccessibleMap, ok := helper.InterfacesHeadMap(d, "internet_accessible"); ok { internetAccessible := cvm.InternetAccessible{} - if v, ok := dMap["internet_charge_type"]; ok { + if v, ok := internetAccessibleMap["internet_charge_type"]; ok { internetAccessible.InternetChargeType = helper.String(v.(string)) } - if v, ok := dMap["internet_max_bandwidth_out"]; ok { + if v, ok := internetAccessibleMap["internet_max_bandwidth_out"]; ok { internetAccessible.InternetMaxBandwidthOut = helper.IntInt64(v.(int)) } - if v, ok := dMap["public_ip_assigned"]; ok { + if v, ok := internetAccessibleMap["public_ip_assigned"]; ok { internetAccessible.PublicIpAssigned = helper.Bool(v.(bool)) } - if v, ok := dMap["bandwidth_package_id"]; ok { + if v, ok := internetAccessibleMap["bandwidth_package_id"]; ok { internetAccessible.BandwidthPackageId = helper.String(v.(string)) } request.InternetAccessible = &internetAccessible @@ -877,19 +885,19 @@ func resourceTencentCloudCvmLaunchTemplateVersionCreate(d *schema.ResourceData, request.InstanceName = helper.String(v.(string)) } - if dMap, ok := helper.InterfacesHeadMap(d, "login_settings"); ok { + if loginSettingsMap, ok := helper.InterfacesHeadMap(d, "login_settings"); ok { loginSettings := cvm.LoginSettings{} - if v, ok := dMap["password"]; ok { + if v, ok := loginSettingsMap["password"]; ok { loginSettings.Password = helper.String(v.(string)) } - if v, ok := dMap["key_ids"]; ok { + if v, ok := loginSettingsMap["key_ids"]; ok { keyIdsSet := v.(*schema.Set).List() for i := range keyIdsSet { keyIds := keyIdsSet[i].(string) - loginSettings.KeyIds = append(loginSettings.KeyIds, &keyIds) + loginSettings.KeyIds = append(loginSettings.KeyIds, helper.String(keyIds)) } } - if v, ok := dMap["keep_image_login"]; ok { + if v, ok := loginSettingsMap["keep_image_login"]; ok { loginSettings.KeepImageLogin = helper.String(v.(string)) } request.LoginSettings = &loginSettings @@ -899,27 +907,27 @@ func resourceTencentCloudCvmLaunchTemplateVersionCreate(d *schema.ResourceData, securityGroupIdsSet := v.(*schema.Set).List() for i := range securityGroupIdsSet { securityGroupIds := securityGroupIdsSet[i].(string) - request.SecurityGroupIds = append(request.SecurityGroupIds, &securityGroupIds) + request.SecurityGroupIds = append(request.SecurityGroupIds, helper.String(securityGroupIds)) } } - if dMap, ok := helper.InterfacesHeadMap(d, "enhanced_service"); ok { + if enhancedServiceMap, ok := helper.InterfacesHeadMap(d, "enhanced_service"); ok { enhancedService := cvm.EnhancedService{} - if securityServiceMap, ok := helper.InterfaceToMap(dMap, "security_service"); ok { + if securityServiceMap, ok := helper.ConvertInterfacesHeadToMap(enhancedServiceMap["security_service"]); ok { runSecurityServiceEnabled := cvm.RunSecurityServiceEnabled{} if v, ok := securityServiceMap["enabled"]; ok { runSecurityServiceEnabled.Enabled = helper.Bool(v.(bool)) } enhancedService.SecurityService = &runSecurityServiceEnabled } - if monitorServiceMap, ok := helper.InterfaceToMap(dMap, "monitor_service"); ok { + if monitorServiceMap, ok := helper.ConvertInterfacesHeadToMap(enhancedServiceMap["monitor_service"]); ok { runMonitorServiceEnabled := cvm.RunMonitorServiceEnabled{} if v, ok := monitorServiceMap["enabled"]; ok { runMonitorServiceEnabled.Enabled = helper.Bool(v.(bool)) } enhancedService.MonitorService = &runMonitorServiceEnabled } - if automationServiceMap, ok := helper.InterfaceToMap(dMap, "automation_service"); ok { + if automationServiceMap, ok := helper.ConvertInterfacesHeadToMap(enhancedServiceMap["automation_service"]); ok { runAutomationServiceEnabled := cvm.RunAutomationServiceEnabled{} if v, ok := automationServiceMap["enabled"]; ok { runAutomationServiceEnabled.Enabled = helper.Bool(v.(bool)) @@ -937,15 +945,15 @@ func resourceTencentCloudCvmLaunchTemplateVersionCreate(d *schema.ResourceData, request.HostName = helper.String(v.(string)) } - if dMap, ok := helper.InterfacesHeadMap(d, "action_timer"); ok { + if actionTimerMap, ok := helper.InterfacesHeadMap(d, "action_timer"); ok { actionTimer := cvm.ActionTimer{} - if v, ok := dMap["timer_action"]; ok { + if v, ok := actionTimerMap["timer_action"]; ok { actionTimer.TimerAction = helper.String(v.(string)) } - if v, ok := dMap["action_time"]; ok { + if v, ok := actionTimerMap["action_time"]; ok { actionTimer.ActionTime = helper.String(v.(string)) } - if externalsMap, ok := helper.InterfaceToMap(dMap, "externals"); ok { + if externalsMap, ok := helper.ConvertInterfacesHeadToMap(actionTimerMap["externals"]); ok { externals := cvm.Externals{} if v, ok := externalsMap["release_address"]; ok { externals.ReleaseAddress = helper.Bool(v.(bool)) @@ -954,10 +962,10 @@ func resourceTencentCloudCvmLaunchTemplateVersionCreate(d *schema.ResourceData, unsupportNetworksSet := v.(*schema.Set).List() for i := range unsupportNetworksSet { unsupportNetworks := unsupportNetworksSet[i].(string) - externals.UnsupportNetworks = append(externals.UnsupportNetworks, &unsupportNetworks) + externals.UnsupportNetworks = append(externals.UnsupportNetworks, helper.String(unsupportNetworks)) } } - if storageBlockAttrMap, ok := helper.InterfaceToMap(externalsMap, "storage_block_attr"); ok { + if storageBlockAttrMap, ok := helper.ConvertInterfacesHeadToMap(externalsMap["storage_block_attr"]); ok { storageBlock := cvm.StorageBlock{} if v, ok := storageBlockAttrMap["type"]; ok { storageBlock.Type = helper.String(v.(string)) @@ -979,18 +987,18 @@ func resourceTencentCloudCvmLaunchTemplateVersionCreate(d *schema.ResourceData, disasterRecoverGroupIdsSet := v.(*schema.Set).List() for i := range disasterRecoverGroupIdsSet { disasterRecoverGroupIds := disasterRecoverGroupIdsSet[i].(string) - request.DisasterRecoverGroupIds = append(request.DisasterRecoverGroupIds, &disasterRecoverGroupIds) + request.DisasterRecoverGroupIds = append(request.DisasterRecoverGroupIds, helper.String(disasterRecoverGroupIds)) } } if v, ok := d.GetOk("tag_specification"); ok { for _, item := range v.([]interface{}) { - dMap := item.(map[string]interface{}) + tagSpecificationMap := item.(map[string]interface{}) tagSpecification := cvm.TagSpecification{} - if v, ok := dMap["resource_type"]; ok { + if v, ok := tagSpecificationMap["resource_type"]; ok { tagSpecification.ResourceType = helper.String(v.(string)) } - if v, ok := dMap["tags"]; ok { + if v, ok := tagSpecificationMap["tags"]; ok { for _, item := range v.([]interface{}) { tagsMap := item.(map[string]interface{}) tag := cvm.Tag{} @@ -1007,9 +1015,9 @@ func resourceTencentCloudCvmLaunchTemplateVersionCreate(d *schema.ResourceData, } } - if dMap, ok := helper.InterfacesHeadMap(d, "instance_market_options"); ok { + if instanceMarketOptionsMap, ok := helper.InterfacesHeadMap(d, "instance_market_options"); ok { instanceMarketOptionsRequest := cvm.InstanceMarketOptionsRequest{} - if spotOptionsMap, ok := helper.InterfaceToMap(dMap, "spot_options"); ok { + if spotOptionsMap, ok := helper.ConvertInterfacesHeadToMap(instanceMarketOptionsMap["spot_options"]); ok { spotMarketOptions := cvm.SpotMarketOptions{} if v, ok := spotOptionsMap["max_price"]; ok { spotMarketOptions.MaxPrice = helper.String(v.(string)) @@ -1019,7 +1027,7 @@ func resourceTencentCloudCvmLaunchTemplateVersionCreate(d *schema.ResourceData, } instanceMarketOptionsRequest.SpotOptions = &spotMarketOptions } - if v, ok := dMap["market_type"]; ok { + if v, ok := instanceMarketOptionsMap["market_type"]; ok { instanceMarketOptionsRequest.MarketType = helper.String(v.(string)) } request.InstanceMarketOptions = &instanceMarketOptionsRequest @@ -1045,12 +1053,12 @@ func resourceTencentCloudCvmLaunchTemplateVersionCreate(d *schema.ResourceData, request.InstanceChargeType = helper.String(v.(string)) } - if dMap, ok := helper.InterfacesHeadMap(d, "instance_charge_prepaid"); ok { + 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 { + if v, ok := instanceChargePrepaidMap["renew_flag"]; ok { instanceChargePrepaid.RenewFlag = helper.String(v.(string)) } request.InstanceChargePrepaid = &instanceChargePrepaid @@ -1061,7 +1069,7 @@ func resourceTencentCloudCvmLaunchTemplateVersionCreate(d *schema.ResourceData, } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().CreateLaunchTemplateVersion(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().CreateLaunchTemplateVersionWithContext(ctx, request) if e != nil { return tccommon.RetryError(e) } else { @@ -1071,13 +1079,13 @@ func resourceTencentCloudCvmLaunchTemplateVersionCreate(d *schema.ResourceData, return nil }) if err != nil { - log.Printf("[CRITAL]%s create cvm launchTemplateVersion failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s create cvm launch template version failed, reason:%+v", logId, err) return err } - launchTemplateVersionNumber := *response.Response.LaunchTemplateVersionNumber - launchTemplateVersionNumberString := strconv.FormatInt(launchTemplateVersionNumber, 10) - d.SetId(launchTemplateId + tccommon.FILED_SP + launchTemplateVersionNumberString) + launchTemplateVersionNumber = *response.Response.LaunchTemplateVersionNumber + + d.SetId(strings.Join([]string{launchTemplateId, helper.Int64ToStr(launchTemplateVersionNumber)}, tccommon.FILED_SP)) return resourceTencentCloudCvmLaunchTemplateVersionRead(d, meta) } @@ -1088,7 +1096,7 @@ func resourceTencentCloudCvmLaunchTemplateVersionRead(d *schema.ResourceData, me 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()} @@ -1099,51 +1107,52 @@ func resourceTencentCloudCvmLaunchTemplateVersionRead(d *schema.ResourceData, me launchTemplateId := idSplit[0] launchTemplateVersionNumber := idSplit[1] - launchTemplateVersion, err := service.DescribeCvmLaunchTemplateVersionById(ctx, launchTemplateId, launchTemplateVersionNumber) + _ = d.Set("launch_template_id", launchTemplateId) + + respData, err := service.DescribeCvmLaunchTemplateVersionById(ctx, launchTemplateId, launchTemplateVersionNumber) if err != nil { return err } - if launchTemplateVersion == nil { + if respData == nil { d.SetId("") - log.Printf("[WARN]%s resource `CvmLaunchTemplateVersion` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + log.Printf("[WARN]%s resource `cvm_launch_template_version` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) return nil } - - if launchTemplateVersion.LaunchTemplateId != nil { - _ = d.Set("launch_template_id", launchTemplateVersion.LaunchTemplateId) + if respData.LaunchTemplateId != nil { + _ = d.Set("launch_template_id", respData.LaunchTemplateId) } - if launchTemplateVersion.LaunchTemplateVersion != nil { - _ = d.Set("launch_template_version", launchTemplateVersion.LaunchTemplateVersion) + if respData.LaunchTemplateVersion != nil { + _ = d.Set("launch_template_version", respData.LaunchTemplateVersion) } - if launchTemplateVersion.LaunchTemplateVersionDescription != nil { - _ = d.Set("launch_template_version_description", launchTemplateVersion.LaunchTemplateVersionDescription) + if respData.LaunchTemplateVersionDescription != nil { + _ = d.Set("launch_template_version_description", respData.LaunchTemplateVersionDescription) } - if launchTemplateVersion.LaunchTemplateVersionData != nil { - if launchTemplateVersion.LaunchTemplateVersionData.InstanceType != nil { - _ = d.Set("instance_type", launchTemplateVersion.LaunchTemplateVersionData.InstanceType) + if respData.LaunchTemplateVersionData != nil { + if respData.LaunchTemplateVersionData.InstanceType != nil { + _ = d.Set("instance_type", respData.LaunchTemplateVersionData.InstanceType) } - if launchTemplateVersion.LaunchTemplateVersionData.ImageId != nil { - _ = d.Set("image_id", launchTemplateVersion.LaunchTemplateVersionData.ImageId) + if respData.LaunchTemplateVersionData.ImageId != nil { + _ = d.Set("image_id", respData.LaunchTemplateVersionData.ImageId) } - if launchTemplateVersion.LaunchTemplateVersionData.Placement != nil { - placementMap := map[string]interface{}{} + placementMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.Placement.Zone != nil { - placementMap["zone"] = launchTemplateVersion.LaunchTemplateVersionData.Placement.Zone + if respData.LaunchTemplateVersionData.Placement != nil { + if respData.LaunchTemplateVersionData.Placement.Zone != nil { + placementMap["zone"] = respData.LaunchTemplateVersionData.Placement.Zone } - if launchTemplateVersion.LaunchTemplateVersionData.Placement.ProjectId != nil { - placementMap["project_id"] = launchTemplateVersion.LaunchTemplateVersionData.Placement.ProjectId + if respData.LaunchTemplateVersionData.Placement.ProjectId != nil { + placementMap["project_id"] = respData.LaunchTemplateVersionData.Placement.ProjectId } - if launchTemplateVersion.LaunchTemplateVersionData.Placement.HostIds != nil { - placementMap["host_ids"] = launchTemplateVersion.LaunchTemplateVersionData.Placement.HostIds + if respData.LaunchTemplateVersionData.Placement.HostIds != nil { + placementMap["host_ids"] = respData.LaunchTemplateVersionData.Placement.HostIds } //if launchTemplateVersion.LaunchTemplateVersionData.Placement.HostIps != nil { @@ -1153,182 +1162,180 @@ func resourceTencentCloudCvmLaunchTemplateVersionRead(d *schema.ResourceData, me _ = d.Set("placement", []interface{}{placementMap}) } - if launchTemplateVersion.LaunchTemplateVersionData.SystemDisk != nil { - systemDiskMap := map[string]interface{}{} + systemDiskMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.SystemDisk.DiskType != nil { - systemDiskMap["disk_type"] = launchTemplateVersion.LaunchTemplateVersionData.SystemDisk.DiskType + if respData.LaunchTemplateVersionData.SystemDisk != nil { + if respData.LaunchTemplateVersionData.SystemDisk.DiskType != nil { + systemDiskMap["disk_type"] = respData.LaunchTemplateVersionData.SystemDisk.DiskType } - if launchTemplateVersion.LaunchTemplateVersionData.SystemDisk.DiskId != nil { - systemDiskMap["disk_id"] = launchTemplateVersion.LaunchTemplateVersionData.SystemDisk.DiskId + if respData.LaunchTemplateVersionData.SystemDisk.DiskId != nil { + systemDiskMap["disk_id"] = respData.LaunchTemplateVersionData.SystemDisk.DiskId } - if launchTemplateVersion.LaunchTemplateVersionData.SystemDisk.DiskSize != nil { - systemDiskMap["disk_size"] = launchTemplateVersion.LaunchTemplateVersionData.SystemDisk.DiskSize + if respData.LaunchTemplateVersionData.SystemDisk.DiskSize != nil { + systemDiskMap["disk_size"] = respData.LaunchTemplateVersionData.SystemDisk.DiskSize } - if launchTemplateVersion.LaunchTemplateVersionData.SystemDisk.CdcId != nil { - systemDiskMap["cdc_id"] = launchTemplateVersion.LaunchTemplateVersionData.SystemDisk.CdcId + if respData.LaunchTemplateVersionData.SystemDisk.CdcId != nil { + systemDiskMap["cdc_id"] = respData.LaunchTemplateVersionData.SystemDisk.CdcId } _ = d.Set("system_disk", []interface{}{systemDiskMap}) } - if launchTemplateVersion.LaunchTemplateVersionData.DataDisks != nil { - dataDisksList := []interface{}{} - for _, dataDisk := range launchTemplateVersion.LaunchTemplateVersionData.DataDisks { + dataDisksList := make([]map[string]interface{}, 0, len(respData.LaunchTemplateVersionData.DataDisks)) + if respData.LaunchTemplateVersionData.DataDisks != nil { + for _, dataDisks := range respData.LaunchTemplateVersionData.DataDisks { dataDisksMap := map[string]interface{}{} - if dataDisk.DiskSize != nil { - dataDisksMap["disk_size"] = dataDisk.DiskSize + if dataDisks.DiskSize != nil { + dataDisksMap["disk_size"] = dataDisks.DiskSize } - if dataDisk.DiskType != nil { - dataDisksMap["disk_type"] = dataDisk.DiskType + if dataDisks.DiskType != nil { + dataDisksMap["disk_type"] = dataDisks.DiskType } - if dataDisk.DiskId != nil { - dataDisksMap["disk_id"] = dataDisk.DiskId + if dataDisks.DiskId != nil { + dataDisksMap["disk_id"] = dataDisks.DiskId } - if dataDisk.DeleteWithInstance != nil { - dataDisksMap["delete_with_instance"] = dataDisk.DeleteWithInstance + if dataDisks.DeleteWithInstance != nil { + dataDisksMap["delete_with_instance"] = dataDisks.DeleteWithInstance } - if dataDisk.SnapshotId != nil { - dataDisksMap["snapshot_id"] = dataDisk.SnapshotId + if dataDisks.SnapshotId != nil { + dataDisksMap["snapshot_id"] = dataDisks.SnapshotId } - if dataDisk.Encrypt != nil { - dataDisksMap["encrypt"] = dataDisk.Encrypt + if dataDisks.Encrypt != nil { + dataDisksMap["encrypt"] = dataDisks.Encrypt } - if dataDisk.KmsKeyId != nil { - dataDisksMap["kms_key_id"] = dataDisk.KmsKeyId + if dataDisks.KmsKeyId != nil { + dataDisksMap["kms_key_id"] = dataDisks.KmsKeyId } - if dataDisk.ThroughputPerformance != nil { - dataDisksMap["throughput_performance"] = dataDisk.ThroughputPerformance + if dataDisks.ThroughputPerformance != nil { + dataDisksMap["throughput_performance"] = dataDisks.ThroughputPerformance } - if dataDisk.CdcId != nil { - dataDisksMap["cdc_id"] = dataDisk.CdcId + if dataDisks.CdcId != nil { + dataDisksMap["cdc_id"] = dataDisks.CdcId } dataDisksList = append(dataDisksList, dataDisksMap) } _ = d.Set("data_disks", dataDisksList) - } + virtualPrivateCloudMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud != nil { - virtualPrivateCloudMap := map[string]interface{}{} - - if launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.VpcId != nil { - virtualPrivateCloudMap["vpc_id"] = launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.VpcId + if respData.LaunchTemplateVersionData.VirtualPrivateCloud != nil { + if respData.LaunchTemplateVersionData.VirtualPrivateCloud.VpcId != nil { + virtualPrivateCloudMap["vpc_id"] = respData.LaunchTemplateVersionData.VirtualPrivateCloud.VpcId } - if launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.SubnetId != nil { - virtualPrivateCloudMap["subnet_id"] = launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.SubnetId + if respData.LaunchTemplateVersionData.VirtualPrivateCloud.SubnetId != nil { + virtualPrivateCloudMap["subnet_id"] = respData.LaunchTemplateVersionData.VirtualPrivateCloud.SubnetId } - if launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.AsVpcGateway != nil { - virtualPrivateCloudMap["as_vpc_gateway"] = launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.AsVpcGateway + if respData.LaunchTemplateVersionData.VirtualPrivateCloud.AsVpcGateway != nil { + virtualPrivateCloudMap["as_vpc_gateway"] = respData.LaunchTemplateVersionData.VirtualPrivateCloud.AsVpcGateway } - if launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.PrivateIpAddresses != nil { - virtualPrivateCloudMap["private_ip_addresses"] = launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.PrivateIpAddresses + if respData.LaunchTemplateVersionData.VirtualPrivateCloud.PrivateIpAddresses != nil { + virtualPrivateCloudMap["private_ip_addresses"] = respData.LaunchTemplateVersionData.VirtualPrivateCloud.PrivateIpAddresses } - if launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.Ipv6AddressCount != nil { - virtualPrivateCloudMap["ipv6_address_count"] = launchTemplateVersion.LaunchTemplateVersionData.VirtualPrivateCloud.Ipv6AddressCount + if respData.LaunchTemplateVersionData.VirtualPrivateCloud.Ipv6AddressCount != nil { + virtualPrivateCloudMap["ipv6_address_count"] = respData.LaunchTemplateVersionData.VirtualPrivateCloud.Ipv6AddressCount } _ = d.Set("virtual_private_cloud", []interface{}{virtualPrivateCloudMap}) } - if launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible != nil { - internetAccessibleMap := map[string]interface{}{} + internetAccessibleMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible.InternetChargeType != nil { - internetAccessibleMap["internet_charge_type"] = launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible.InternetChargeType + if respData.LaunchTemplateVersionData.InternetAccessible != nil { + if respData.LaunchTemplateVersionData.InternetAccessible.InternetChargeType != nil { + internetAccessibleMap["internet_charge_type"] = respData.LaunchTemplateVersionData.InternetAccessible.InternetChargeType } - if launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible.InternetMaxBandwidthOut != nil { - internetAccessibleMap["internet_max_bandwidth_out"] = launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible.InternetMaxBandwidthOut + if respData.LaunchTemplateVersionData.InternetAccessible.InternetMaxBandwidthOut != nil { + internetAccessibleMap["internet_max_bandwidth_out"] = respData.LaunchTemplateVersionData.InternetAccessible.InternetMaxBandwidthOut } - if launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible.PublicIpAssigned != nil { - internetAccessibleMap["public_ip_assigned"] = launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible.PublicIpAssigned + if respData.LaunchTemplateVersionData.InternetAccessible.PublicIpAssigned != nil { + internetAccessibleMap["public_ip_assigned"] = respData.LaunchTemplateVersionData.InternetAccessible.PublicIpAssigned } - if launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible.BandwidthPackageId != nil { - internetAccessibleMap["bandwidth_package_id"] = launchTemplateVersion.LaunchTemplateVersionData.InternetAccessible.BandwidthPackageId + if respData.LaunchTemplateVersionData.InternetAccessible.BandwidthPackageId != nil { + internetAccessibleMap["bandwidth_package_id"] = respData.LaunchTemplateVersionData.InternetAccessible.BandwidthPackageId } _ = d.Set("internet_accessible", []interface{}{internetAccessibleMap}) } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceCount != nil { - _ = d.Set("instance_count", launchTemplateVersion.LaunchTemplateVersionData.InstanceCount) + if respData.LaunchTemplateVersionData.InstanceCount != nil { + _ = d.Set("instance_count", respData.LaunchTemplateVersionData.InstanceCount) } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceName != nil { - _ = d.Set("instance_name", launchTemplateVersion.LaunchTemplateVersionData.InstanceName) + if respData.LaunchTemplateVersionData.InstanceName != nil { + _ = d.Set("instance_name", respData.LaunchTemplateVersionData.InstanceName) } - if launchTemplateVersion.LaunchTemplateVersionData.LoginSettings != nil { - loginSettingsMap := map[string]interface{}{} + loginSettingsMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.LoginSettings.Password != nil { - loginSettingsMap["password"] = launchTemplateVersion.LaunchTemplateVersionData.LoginSettings.Password + if respData.LaunchTemplateVersionData.LoginSettings != nil { + if respData.LaunchTemplateVersionData.LoginSettings.Password != nil { + loginSettingsMap["password"] = respData.LaunchTemplateVersionData.LoginSettings.Password } - if launchTemplateVersion.LaunchTemplateVersionData.LoginSettings.KeyIds != nil { - loginSettingsMap["key_ids"] = launchTemplateVersion.LaunchTemplateVersionData.LoginSettings.KeyIds + if respData.LaunchTemplateVersionData.LoginSettings.KeyIds != nil { + loginSettingsMap["key_ids"] = respData.LaunchTemplateVersionData.LoginSettings.KeyIds } - if launchTemplateVersion.LaunchTemplateVersionData.LoginSettings.KeepImageLogin != nil { - loginSettingsMap["keep_image_login"] = launchTemplateVersion.LaunchTemplateVersionData.LoginSettings.KeepImageLogin + if respData.LaunchTemplateVersionData.LoginSettings.KeepImageLogin != nil { + loginSettingsMap["keep_image_login"] = respData.LaunchTemplateVersionData.LoginSettings.KeepImageLogin } _ = d.Set("login_settings", []interface{}{loginSettingsMap}) } - if launchTemplateVersion.LaunchTemplateVersionData.SecurityGroupIds != nil { - _ = d.Set("security_group_ids", launchTemplateVersion.LaunchTemplateVersionData.SecurityGroupIds) + if respData.LaunchTemplateVersionData.SecurityGroupIds != nil { + _ = d.Set("security_group_ids", respData.LaunchTemplateVersionData.SecurityGroupIds) } - if launchTemplateVersion.LaunchTemplateVersionData.EnhancedService != nil { - enhancedServiceMap := map[string]interface{}{} + enhancedServiceMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.SecurityService != nil { - securityServiceMap := map[string]interface{}{} + if respData.LaunchTemplateVersionData.EnhancedService != nil { + securityServiceMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.SecurityService.Enabled != nil { - securityServiceMap["enabled"] = launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.SecurityService.Enabled + if respData.LaunchTemplateVersionData.EnhancedService.SecurityService != nil { + if respData.LaunchTemplateVersionData.EnhancedService.SecurityService.Enabled != nil { + securityServiceMap["enabled"] = respData.LaunchTemplateVersionData.EnhancedService.SecurityService.Enabled } enhancedServiceMap["security_service"] = []interface{}{securityServiceMap} } - if launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.MonitorService != nil { - monitorServiceMap := map[string]interface{}{} + monitorServiceMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.MonitorService.Enabled != nil { - monitorServiceMap["enabled"] = launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.MonitorService.Enabled + if respData.LaunchTemplateVersionData.EnhancedService.MonitorService != nil { + if respData.LaunchTemplateVersionData.EnhancedService.MonitorService.Enabled != nil { + monitorServiceMap["enabled"] = respData.LaunchTemplateVersionData.EnhancedService.MonitorService.Enabled } enhancedServiceMap["monitor_service"] = []interface{}{monitorServiceMap} } - if launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.AutomationService != nil { - automationServiceMap := map[string]interface{}{} + automationServiceMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.AutomationService.Enabled != nil { - automationServiceMap["enabled"] = launchTemplateVersion.LaunchTemplateVersionData.EnhancedService.AutomationService.Enabled + if respData.LaunchTemplateVersionData.EnhancedService.AutomationService != nil { + if respData.LaunchTemplateVersionData.EnhancedService.AutomationService.Enabled != nil { + automationServiceMap["enabled"] = respData.LaunchTemplateVersionData.EnhancedService.AutomationService.Enabled } enhancedServiceMap["automation_service"] = []interface{}{automationServiceMap} @@ -1337,49 +1344,49 @@ func resourceTencentCloudCvmLaunchTemplateVersionRead(d *schema.ResourceData, me _ = d.Set("enhanced_service", []interface{}{enhancedServiceMap}) } - if launchTemplateVersion.LaunchTemplateVersionData.ClientToken != nil { - _ = d.Set("client_token", launchTemplateVersion.LaunchTemplateVersionData.ClientToken) + if respData.LaunchTemplateVersionData.ClientToken != nil { + _ = d.Set("client_token", respData.LaunchTemplateVersionData.ClientToken) } - if launchTemplateVersion.LaunchTemplateVersionData.HostName != nil { - _ = d.Set("host_name", launchTemplateVersion.LaunchTemplateVersionData.HostName) + if respData.LaunchTemplateVersionData.HostName != nil { + _ = d.Set("host_name", respData.LaunchTemplateVersionData.HostName) } - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer != nil { - actionTimerMap := map[string]interface{}{} + actionTimerMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.TimerAction != nil { - actionTimerMap["timer_action"] = launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.TimerAction + if respData.LaunchTemplateVersionData.ActionTimer != nil { + if respData.LaunchTemplateVersionData.ActionTimer.TimerAction != nil { + actionTimerMap["timer_action"] = respData.LaunchTemplateVersionData.ActionTimer.TimerAction } - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.ActionTime != nil { - actionTimerMap["action_time"] = launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.ActionTime + if respData.LaunchTemplateVersionData.ActionTimer.ActionTime != nil { + actionTimerMap["action_time"] = respData.LaunchTemplateVersionData.ActionTimer.ActionTime } - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals != nil { - externalsMap := map[string]interface{}{} + externalsMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.ReleaseAddress != nil { - externalsMap["release_address"] = launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.ReleaseAddress + if respData.LaunchTemplateVersionData.ActionTimer.Externals != nil { + if respData.LaunchTemplateVersionData.ActionTimer.Externals.ReleaseAddress != nil { + externalsMap["release_address"] = respData.LaunchTemplateVersionData.ActionTimer.Externals.ReleaseAddress } - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.UnsupportNetworks != nil { - externalsMap["unsupport_networks"] = launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.UnsupportNetworks + if respData.LaunchTemplateVersionData.ActionTimer.Externals.UnsupportNetworks != nil { + externalsMap["unsupport_networks"] = respData.LaunchTemplateVersionData.ActionTimer.Externals.UnsupportNetworks } - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr != nil { - storageBlockAttrMap := map[string]interface{}{} + storageBlockAttrMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.Type != nil { - storageBlockAttrMap["type"] = launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.Type + if respData.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr != nil { + if respData.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.Type != nil { + storageBlockAttrMap["type"] = respData.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.Type } - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.MinSize != nil { - storageBlockAttrMap["min_size"] = launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.MinSize + if respData.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.MinSize != nil { + storageBlockAttrMap["min_size"] = respData.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.MinSize } - if launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.MaxSize != nil { - storageBlockAttrMap["max_size"] = launchTemplateVersion.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.MaxSize + if respData.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.MaxSize != nil { + storageBlockAttrMap["max_size"] = respData.LaunchTemplateVersionData.ActionTimer.Externals.StorageBlockAttr.MaxSize } externalsMap["storage_block_attr"] = []interface{}{storageBlockAttrMap} @@ -1391,102 +1398,100 @@ func resourceTencentCloudCvmLaunchTemplateVersionRead(d *schema.ResourceData, me _ = d.Set("action_timer", []interface{}{actionTimerMap}) } - if launchTemplateVersion.LaunchTemplateVersionData.DisasterRecoverGroupIds != nil { - _ = d.Set("disaster_recover_group_ids", launchTemplateVersion.LaunchTemplateVersionData.DisasterRecoverGroupIds) + if respData.LaunchTemplateVersionData.DisasterRecoverGroupIds != nil { + _ = d.Set("disaster_recover_group_ids", respData.LaunchTemplateVersionData.DisasterRecoverGroupIds) } - if launchTemplateVersion.LaunchTemplateVersionData.TagSpecification != nil { - tagSpecificationList := []interface{}{} - for _, tagSpecification := range launchTemplateVersion.LaunchTemplateVersionData.TagSpecification { + tagSpecificationList := make([]map[string]interface{}, 0, len(respData.LaunchTemplateVersionData.TagSpecification)) + if respData.LaunchTemplateVersionData.TagSpecification != nil { + for _, tagSpecification := range respData.LaunchTemplateVersionData.TagSpecification { tagSpecificationMap := map[string]interface{}{} if tagSpecification.ResourceType != nil { tagSpecificationMap["resource_type"] = tagSpecification.ResourceType } + tagsList := make([]map[string]interface{}, 0, len(tagSpecification.Tags)) if tagSpecification.Tags != nil { - tagsList := []interface{}{} - for _, tag := range tagSpecification.Tags { + for _, tags := range tagSpecification.Tags { tagsMap := map[string]interface{}{} - if tag.Key != nil { - tagsMap["key"] = tag.Key + if tags.Key != nil { + tagsMap["key"] = tags.Key } - if tag.Value != nil { - tagsMap["value"] = tag.Value + if tags.Value != nil { + tagsMap["value"] = tags.Value } tagsList = append(tagsList, tagsMap) } - tagSpecificationMap["tags"] = []interface{}{tagsList} + tagSpecificationMap["tags"] = tagsList } - tagSpecificationList = append(tagSpecificationList, tagSpecificationMap) } _ = d.Set("tag_specification", tagSpecificationList) - } + instanceMarketOptionsMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.InstanceMarketOptions != nil { - instanceMarketOptionsMap := map[string]interface{}{} + if respData.LaunchTemplateVersionData.InstanceMarketOptions != nil { + spotOptionsMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions != nil { - spotOptionsMap := map[string]interface{}{} - - if launchTemplateVersion.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions.MaxPrice != nil { - spotOptionsMap["max_price"] = launchTemplateVersion.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions.MaxPrice + if respData.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions != nil { + if respData.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions.MaxPrice != nil { + spotOptionsMap["max_price"] = respData.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions.MaxPrice } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions.SpotInstanceType != nil { - spotOptionsMap["spot_instance_type"] = launchTemplateVersion.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions.SpotInstanceType + if respData.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions.SpotInstanceType != nil { + spotOptionsMap["spot_instance_type"] = respData.LaunchTemplateVersionData.InstanceMarketOptions.SpotOptions.SpotInstanceType } instanceMarketOptionsMap["spot_options"] = []interface{}{spotOptionsMap} } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceMarketOptions.MarketType != nil { - instanceMarketOptionsMap["market_type"] = launchTemplateVersion.LaunchTemplateVersionData.InstanceMarketOptions.MarketType + if respData.LaunchTemplateVersionData.InstanceMarketOptions.MarketType != nil { + instanceMarketOptionsMap["market_type"] = respData.LaunchTemplateVersionData.InstanceMarketOptions.MarketType } _ = d.Set("instance_market_options", []interface{}{instanceMarketOptionsMap}) } - if launchTemplateVersion.LaunchTemplateVersionData.UserData != nil { - _ = d.Set("user_data", launchTemplateVersion.LaunchTemplateVersionData.UserData) + if respData.LaunchTemplateVersionData.UserData != nil { + _ = d.Set("user_data", respData.LaunchTemplateVersionData.UserData) } - if launchTemplateVersion.LaunchTemplateVersionData.CamRoleName != nil { - _ = d.Set("cam_role_name", launchTemplateVersion.LaunchTemplateVersionData.CamRoleName) + if respData.LaunchTemplateVersionData.CamRoleName != nil { + _ = d.Set("cam_role_name", respData.LaunchTemplateVersionData.CamRoleName) } - if launchTemplateVersion.LaunchTemplateVersionData.HpcClusterId != nil { - _ = d.Set("hpc_cluster_id", launchTemplateVersion.LaunchTemplateVersionData.HpcClusterId) + if respData.LaunchTemplateVersionData.HpcClusterId != nil { + _ = d.Set("hpc_cluster_id", respData.LaunchTemplateVersionData.HpcClusterId) } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceChargeType != nil { - _ = d.Set("instance_charge_type", launchTemplateVersion.LaunchTemplateVersionData.InstanceChargeType) + if respData.LaunchTemplateVersionData.InstanceChargeType != nil { + _ = d.Set("instance_charge_type", respData.LaunchTemplateVersionData.InstanceChargeType) } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceChargePrepaid != nil { - instanceChargePrepaidMap := map[string]interface{}{} + instanceChargePrepaidMap := map[string]interface{}{} - if launchTemplateVersion.LaunchTemplateVersionData.InstanceChargePrepaid.Period != nil { - instanceChargePrepaidMap["period"] = launchTemplateVersion.LaunchTemplateVersionData.InstanceChargePrepaid.Period + if respData.LaunchTemplateVersionData.InstanceChargePrepaid != nil { + if respData.LaunchTemplateVersionData.InstanceChargePrepaid.Period != nil { + instanceChargePrepaidMap["period"] = respData.LaunchTemplateVersionData.InstanceChargePrepaid.Period } - if launchTemplateVersion.LaunchTemplateVersionData.InstanceChargePrepaid.RenewFlag != nil { - instanceChargePrepaidMap["renew_flag"] = launchTemplateVersion.LaunchTemplateVersionData.InstanceChargePrepaid.RenewFlag + if respData.LaunchTemplateVersionData.InstanceChargePrepaid.RenewFlag != nil { + instanceChargePrepaidMap["renew_flag"] = respData.LaunchTemplateVersionData.InstanceChargePrepaid.RenewFlag } _ = d.Set("instance_charge_prepaid", []interface{}{instanceChargePrepaidMap}) } - if launchTemplateVersion.LaunchTemplateVersionData.DisableApiTermination != nil { - _ = d.Set("disable_api_termination", launchTemplateVersion.LaunchTemplateVersionData.DisableApiTermination) + if respData.LaunchTemplateVersionData.DisableApiTermination != nil { + _ = d.Set("disable_api_termination", respData.LaunchTemplateVersionData.DisableApiTermination) } + } return nil @@ -1497,9 +1502,7 @@ func resourceTencentCloudCvmLaunchTemplateVersionDelete(d *schema.ResourceData, defer tccommon.InconsistentCheck(d, meta)() logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - - service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) idSplit := strings.Split(d.Id(), tccommon.FILED_SP) if len(idSplit) != 2 { @@ -1508,9 +1511,30 @@ func resourceTencentCloudCvmLaunchTemplateVersionDelete(d *schema.ResourceData, launchTemplateId := idSplit[0] launchTemplateVersionNumber := idSplit[1] - if err := service.DeleteCvmLaunchTemplateVersionById(ctx, launchTemplateId, launchTemplateVersionNumber); err != nil { + var ( + request = cvm.NewDeleteLaunchTemplateVersionsRequest() + response = cvm.NewDeleteLaunchTemplateVersionsResponse() + ) + + request.LaunchTemplateId = helper.String(launchTemplateId) + + request.LaunchTemplateVersions = []*int64{helper.StrToInt64Point(launchTemplateVersionNumber)} + + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().DeleteLaunchTemplateVersionsWithContext(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 launch template version failed, reason:%+v", logId, err) return err } + _ = response return nil } diff --git a/tencentcloud/services/cvm/resource_tc_cvm_launch_template_version_extension.go b/tencentcloud/services/cvm/resource_tc_cvm_launch_template_version_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_cvm_launch_template_version_extension.go @@ -0,0 +1 @@ +package cvm diff --git a/tencentcloud/services/cvm/resource_tc_cvm_modify_instance_disk_type.go b/tencentcloud/services/cvm/resource_tc_cvm_modify_instance_disk_type.go index 293b3f8f2c..67a2a6b6fe 100644 --- a/tencentcloud/services/cvm/resource_tc_cvm_modify_instance_disk_type.go +++ b/tencentcloud/services/cvm/resource_tc_cvm_modify_instance_disk_type.go @@ -1,14 +1,15 @@ +// Code generated by iacg; DO NOT EDIT. 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" ) @@ -22,16 +23,16 @@ func ResourceTencentCloudCvmModifyInstanceDiskType() *schema.Resource { }, Schema: map[string]*schema.Schema{ "instance_id": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "Instance ID. To obtain the instance IDs, you can call DescribeInstances and look for InstanceId in the response.", }, "data_disks": { + Type: schema.TypeList, Optional: true, ForceNew: true, - Type: schema.TypeList, Description: "For instance data disk configuration information, you only need to specify the media type of the target cloud disk to be converted, and specify the value of DiskType. Currently, only one data disk conversion is supported. The CdcId parameter is only supported for instances of the CDHPAID type.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -41,20 +42,9 @@ func ResourceTencentCloudCvmModifyInstanceDiskType() *schema.Resource { Description: "Data disk size (in GB). The minimum adjustment increment is 10 GB. The value range varies by data disk type. The default value is 0, indicating that no data disk is purchased. For more information, see the product documentation.", }, "disk_type": { - Type: schema.TypeString, - Optional: true, - Description: "Data disk type. Valid values:\n" + - "- LOCAL_BASIC: local hard disk;\n" + - "- LOCAL_SSD: local SSD hard disk;\n" + - "- LOCAL_NVME: local NVME hard disk, which is strongly related to InstanceType and cannot be specified;\n" + - "- LOCAL_PRO: local HDD hard disk, which is strongly related to InstanceType and cannot be specified;\n" + - "- CLOUD_BASIC: ordinary cloud disk;\n" + - "- CLOUD_PREMIUM: high-performance cloud disk;\n" + - "- CLOUD_SSD:SSD cloud disk;\n" + - "- CLOUD_HSSD: enhanced SSD cloud disk;\n" + - "- CLOUD_TSSD: extremely fast SSD cloud disk;\n" + - "- CLOUD_BSSD: general-purpose SSD cloud disk;\n" + - "Default value: LOCAL_BASIC.", + Type: schema.TypeString, + Optional: true, + Description: "Data disk type. Valid values:\n- LOCAL_BASIC: local hard disk;\n- LOCAL_SSD: local SSD hard disk;\n- LOCAL_NVME: local NVME hard disk, which is strongly related to InstanceType and cannot be specified;\n- LOCAL_PRO: local HDD hard disk, which is strongly related to InstanceType and cannot be specified;\n- CLOUD_BASIC: ordinary cloud disk;\n- CLOUD_PREMIUM: high-performance cloud disk;\n- CLOUD_SSD:SSD cloud disk;\n- CLOUD_HSSD: enhanced SSD cloud disk;\n- CLOUD_TSSD: extremely fast SSD cloud disk;\n- CLOUD_BSSD: general-purpose SSD cloud disk;\nDefault value: LOCAL_BASIC.\n", }, "disk_id": { Type: schema.TypeString, @@ -62,12 +52,9 @@ func ResourceTencentCloudCvmModifyInstanceDiskType() *schema.Resource { Description: "Data disk ID. Note that it's not available for LOCAL_BASIC and LOCAL_SSD disks.", }, "delete_with_instance": { - Type: schema.TypeBool, - Optional: true, - Description: "Whether to terminate the data disk when its CVM is terminated. Valid values:\n" + - "- TRUE: terminate the data disk when its CVM is terminated. This value only supports pay-as-you-go cloud disks billed on an hourly basis.\n" + - "- FALSE: retain the data disk when its CVM is terminated.\n" + - "Default value: TRUE.", + Type: schema.TypeBool, + Optional: true, + Description: "Whether to terminate the data disk when its CVM is terminated. Valid values:\n- TRUE: terminate the data disk when its CVM is terminated. This value only supports pay-as-you-go cloud disks billed on an hourly basis.\n- FALSE: retain the data disk when its CVM is terminated.\nDefault value: TRUE.\n", }, "snapshot_id": { Type: schema.TypeString, @@ -75,12 +62,9 @@ func ResourceTencentCloudCvmModifyInstanceDiskType() *schema.Resource { Description: "Data disk snapshot ID. The size of the selected data disk snapshot must be smaller than that of the data disk.", }, "encrypt": { - Type: schema.TypeBool, - Optional: true, - Description: "Specifies whether the data disk is encrypted. Valid values:\n" + - "- TRUE: encrypted\n" + - "- FALSE: not encrypted\n" + - "Default value: FALSE.", + Type: schema.TypeBool, + Optional: true, + Description: "Specifies whether the data disk is encrypted. Valid values:\n- TRUE: encrypted\n- FALSE: not encrypted\nDefault value: FALSE.\n", }, "kms_key_id": { Type: schema.TypeString, @@ -102,24 +86,17 @@ func ResourceTencentCloudCvmModifyInstanceDiskType() *schema.Resource { }, "system_disk": { + Type: schema.TypeList, Optional: true, ForceNew: true, - Type: schema.TypeList, MaxItems: 1, Description: "For instance system disk configuration information, you only need to specify the nature type of the target cloud disk to be converted, and specify the value of DiskType. Only CDHPAID type instances are supported to specify Cd.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "disk_type": { - Type: schema.TypeString, - Optional: true, - Description: "System disk type. Valid values:" + - "- LOCAL_BASIC: local disk\n" + - "- LOCAL_SSD: local SSD disk\n" + - "- CLOUD_BASIC: ordinary cloud disk\n" + - "- CLOUD_SSD: SSD cloud disk\n" + - "- CLOUD_PREMIUM: Premium cloud storage\n" + - "- CLOUD_BSSD: Balanced SSD\n" + - "The disk currently in stock will be used by default.", + Type: schema.TypeString, + Optional: true, + Description: "System disk type. Valid values:\n- LOCAL_BASIC: local disk\n- LOCAL_SSD: local SSD disk\n- CLOUD_BASIC: ordinary cloud disk\n- CLOUD_SSD: SSD cloud disk\n- CLOUD_PREMIUM: Premium cloud storage\n- CLOUD_BSSD: Balanced SSD\nThe disk currently in stock will be used by default.\n", }, "disk_id": { Type: schema.TypeString, @@ -149,81 +126,93 @@ func resourceTencentCloudCvmModifyInstanceDiskTypeCreate(d *schema.ResourceData, logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + var ( - request = cvm.NewModifyInstanceDiskTypeRequest() instanceId string ) + var ( + request = cvm.NewModifyInstanceDiskTypeRequest() + response = cvm.NewModifyInstanceDiskTypeResponse() + ) + if v, ok := d.GetOk("instance_id"); ok { - instanceId := v.(string) - request.InstanceId = helper.String(instanceId) + instanceId = v.(string) + } + + if v, ok := d.GetOk("instance_id"); ok { + request.InstanceId = helper.String(v.(string)) } if v, ok := d.GetOk("data_disks"); ok { for _, item := range v.([]interface{}) { - dMap := item.(map[string]interface{}) + dataDisksMap := item.(map[string]interface{}) dataDisk := cvm.DataDisk{} - if v, ok := dMap["disk_size"]; ok { + if v, ok := dataDisksMap["disk_size"]; ok { dataDisk.DiskSize = helper.IntInt64(v.(int)) } - if v, ok := dMap["disk_type"]; ok { + if v, ok := dataDisksMap["disk_type"]; ok { dataDisk.DiskType = helper.String(v.(string)) } - if v, ok := dMap["disk_id"]; ok { + if v, ok := dataDisksMap["disk_id"]; ok { dataDisk.DiskId = helper.String(v.(string)) } - if v, ok := dMap["delete_with_instance"]; ok { + if v, ok := dataDisksMap["delete_with_instance"]; ok { dataDisk.DeleteWithInstance = helper.Bool(v.(bool)) } - if v, ok := dMap["snapshot_id"]; ok { + if v, ok := dataDisksMap["snapshot_id"]; ok { dataDisk.SnapshotId = helper.String(v.(string)) } - if v, ok := dMap["encrypt"]; ok { + if v, ok := dataDisksMap["encrypt"]; ok { dataDisk.Encrypt = helper.Bool(v.(bool)) } - if v, ok := dMap["kms_key_id"]; ok { + if v, ok := dataDisksMap["kms_key_id"]; ok { dataDisk.KmsKeyId = helper.String(v.(string)) } - if v, ok := dMap["throughput_performance"]; ok { + if v, ok := dataDisksMap["throughput_performance"]; ok { dataDisk.ThroughputPerformance = helper.IntInt64(v.(int)) } - if v, ok := dMap["cdc_id"]; ok { + if v, ok := dataDisksMap["cdc_id"]; ok { dataDisk.CdcId = helper.String(v.(string)) } request.DataDisks = append(request.DataDisks, &dataDisk) } } - if dMap, ok := helper.InterfacesHeadMap(d, "system_disk"); ok { + if systemDiskMap, ok := helper.InterfacesHeadMap(d, "system_disk"); ok { systemDisk := cvm.SystemDisk{} - if v, ok := dMap["disk_type"]; ok { + if v, ok := systemDiskMap["disk_type"]; ok { systemDisk.DiskType = helper.String(v.(string)) } - if v, ok := dMap["disk_id"]; ok { + if v, ok := systemDiskMap["disk_id"]; ok { systemDisk.DiskId = helper.String(v.(string)) } - if v, ok := dMap["disk_size"]; ok { + if v, ok := systemDiskMap["disk_size"]; ok { systemDisk.DiskSize = helper.IntInt64(v.(int)) } - if v, ok := dMap["cdc_id"]; ok { + if v, ok := systemDiskMap["cdc_id"]; ok { systemDisk.CdcId = helper.String(v.(string)) } request.SystemDisk = &systemDisk } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyInstanceDiskType(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyInstanceDiskTypeWithContext(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 modifyInstanceDiskType failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s create cvm modify instance disk type failed, reason:%+v", logId, err) return err } + _ = response + d.SetId(instanceId) return resourceTencentCloudCvmModifyInstanceDiskTypeRead(d, meta) diff --git a/tencentcloud/services/cvm/resource_tc_cvm_modify_instance_disk_type_extension.go b/tencentcloud/services/cvm/resource_tc_cvm_modify_instance_disk_type_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_cvm_modify_instance_disk_type_extension.go @@ -0,0 +1 @@ +package cvm diff --git a/tencentcloud/services/cvm/resource_tc_cvm_program_fpga_image.go b/tencentcloud/services/cvm/resource_tc_cvm_program_fpga_image.go index 006cee2ac6..3b99e9401b 100644 --- a/tencentcloud/services/cvm/resource_tc_cvm_program_fpga_image.go +++ b/tencentcloud/services/cvm/resource_tc_cvm_program_fpga_image.go @@ -1,14 +1,15 @@ +// Code generated by iacg; DO NOT EDIT. 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" ) @@ -22,33 +23,33 @@ func ResourceTencentCloudCvmProgramFpgaImage() *schema.Resource { }, Schema: map[string]*schema.Schema{ "instance_id": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "The ID information of the instance.", }, "fpga_url": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "COS URL address of the FPGA image file.", }, "dbd_fs": { - Optional: true, - ForceNew: true, - Type: schema.TypeSet, + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + Description: "The DBDF number of the FPGA card on the instance, if left blank, the FPGA image will be burned to all FPGA cards owned by the instance by default.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Description: "The DBDF number of the FPGA card on the instance, if left blank, the FPGA image will be burned to all FPGA cards owned by the instance by default.", }, "dry_run": { + Type: schema.TypeBool, Optional: true, ForceNew: true, - Type: schema.TypeBool, Description: "Trial run, will not perform the actual burning action, the default is False.", }, }, @@ -61,11 +62,23 @@ func resourceTencentCloudCvmProgramFpgaImageCreate(d *schema.ResourceData, meta logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + var ( + instanceId string + ) var ( - request = cvm.NewProgramFpgaImageRequest() + request = cvm.NewProgramFpgaImageRequest() + response = cvm.NewProgramFpgaImageResponse() ) - instanceId := d.Get("instance_id").(string) - request.InstanceId = helper.String(instanceId) + + 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)) + } if v, ok := d.GetOk("fpga_url"); ok { request.FPGAUrl = helper.String(v.(string)) @@ -75,28 +88,31 @@ func resourceTencentCloudCvmProgramFpgaImageCreate(d *schema.ResourceData, meta dBDFsSet := v.(*schema.Set).List() for i := range dBDFsSet { dBDFs := dBDFsSet[i].(string) - request.DBDFs = append(request.DBDFs, &dBDFs) + request.DBDFs = append(request.DBDFs, helper.String(dBDFs)) } } - if v, _ := d.GetOk("dry_run"); v != nil { + if v, ok := d.GetOkExists("dry_run"); ok { request.DryRun = helper.Bool(v.(bool)) } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ProgramFpgaImage(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ProgramFpgaImageWithContext(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 programFpgaImage failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s create cvm program fpga image failed, reason:%+v", logId, err) return err } + _ = response + d.SetId(instanceId) return resourceTencentCloudCvmProgramFpgaImageRead(d, meta) diff --git a/tencentcloud/services/cvm/resource_tc_cvm_program_fpga_image_extension.go b/tencentcloud/services/cvm/resource_tc_cvm_program_fpga_image_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_cvm_program_fpga_image_extension.go @@ -0,0 +1 @@ +package cvm diff --git a/tencentcloud/services/cvm/resource_tc_cvm_reboot_instance.go b/tencentcloud/services/cvm/resource_tc_cvm_reboot_instance.go index ff6da860f8..ac03c6c12c 100644 --- a/tencentcloud/services/cvm/resource_tc_cvm_reboot_instance.go +++ b/tencentcloud/services/cvm/resource_tc_cvm_reboot_instance.go @@ -1,14 +1,15 @@ +// Code generated by iacg; DO NOT EDIT. 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,28 +18,27 @@ func ResourceTencentCloudCvmRebootInstance() *schema.Resource { Create: resourceTencentCloudCvmRebootInstanceCreate, Read: resourceTencentCloudCvmRebootInstanceRead, Delete: resourceTencentCloudCvmRebootInstanceDelete, - Schema: map[string]*schema.Schema{ "instance_id": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "Instance ID.", }, "force_reboot": { + Type: schema.TypeBool, Optional: true, ForceNew: true, - Type: schema.TypeBool, ConflictsWith: []string{"stop_type"}, - Deprecated: "It has been deprecated from version 1.81.21. Please use `stop_type` instead.", Description: "This parameter has been disused. We recommend using StopType instead. Note that ForceReboot and StopType parameters cannot be specified at the same time. Whether to forcibly restart an instance after a normal restart fails. Valid values are `TRUE` and `FALSE`. Default value: FALSE.", + Deprecated: "It has been deprecated from version 1.81.21. Please use `stop_type` instead.", }, "stop_type": { + Type: schema.TypeString, Optional: true, ForceNew: true, - Type: schema.TypeString, ConflictsWith: []string{"force_reboot"}, Description: "Shutdown type. Valid values: `SOFT`: soft shutdown; `HARD`: hard shutdown; `SOFT_FIRST`: perform a soft shutdown first, and perform a hard shutdown if the soft shutdown fails. Default value: SOFT.", }, @@ -52,14 +52,26 @@ func resourceTencentCloudCvmRebootInstanceCreate(d *schema.ResourceData, meta in logId := tccommon.GetLogId(tccommon.ContextNil) - request := cvm.NewRebootInstancesRequest() - instanceId := d.Get("instance_id").(string) - request.InstanceIds = []*string{&instanceId} + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - if v, _ := d.GetOk("force_reboot"); v != nil { - if _, ok := d.GetOk("stop_type"); !ok { - request.ForceReboot = helper.Bool(v.(bool)) - } + var ( + instanceId string + ) + var ( + request = cvm.NewRebootInstancesRequest() + response = cvm.NewRebootInstancesResponse() + ) + + if v, ok := d.GetOk("instance_id"); ok { + instanceId = v.(string) + } + + if v, ok := d.GetOk("instance_id"); ok { + request.InstanceIds = []*string{helper.String(v.(string))} + } + + if v, ok := d.GetOkExists("force_reboot"); ok { + request.ForceReboot = helper.Bool(v.(bool)) } if v, ok := d.GetOk("stop_type"); ok { @@ -67,19 +79,22 @@ func resourceTencentCloudCvmRebootInstanceCreate(d *schema.ResourceData, meta in } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().RebootInstances(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().RebootInstancesWithContext(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 rebootInstance failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s create cvm reboot instance failed, reason:%+v", logId, err) return err } + _ = response + d.SetId(instanceId) return resourceTencentCloudCvmRebootInstanceRead(d, meta) diff --git a/tencentcloud/services/cvm/resource_tc_cvm_reboot_instance_extension.go b/tencentcloud/services/cvm/resource_tc_cvm_reboot_instance_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_cvm_reboot_instance_extension.go @@ -0,0 +1 @@ +package cvm diff --git a/tencentcloud/services/cvm/resource_tc_cvm_renew_host.go b/tencentcloud/services/cvm/resource_tc_cvm_renew_host.go index 2ab672b4c9..0bcfc80560 100644 --- a/tencentcloud/services/cvm/resource_tc_cvm_renew_host.go +++ b/tencentcloud/services/cvm/resource_tc_cvm_renew_host.go @@ -1,14 +1,15 @@ +// Code generated by iacg; DO NOT EDIT. 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" ) @@ -19,16 +20,16 @@ func ResourceTencentCloudCvmRenewHost() *schema.Resource { Delete: resourceTencentCloudCvmRenewHostDelete, Schema: map[string]*schema.Schema{ "host_id": { + Type: schema.TypeString, Required: true, ForceNew: true, - Type: schema.TypeString, Description: "CDH instance ID.", }, "host_charge_prepaid": { + Type: schema.TypeList, Required: 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 attributes such as the purchase duration of the Subscription instance and whether to set automatic renewal. If the payment mode of the specified instance is prepaid, this parameter must be passed.", Elem: &schema.Resource{ @@ -56,37 +57,56 @@ func resourceTencentCloudCvmRenewHostCreate(d *schema.ResourceData, meta interfa logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + var ( - request = cvm.NewRenewHostsRequest() + hostId string ) - hostId := d.Get("host_id").(string) - request.HostIds = []*string{&hostId} + var ( + request = cvm.NewRenewHostsRequest() + response = cvm.NewRenewHostsResponse() + ) + + if v, ok := d.GetOk("host_id"); ok { + hostId = v.(string) + } - if dMap, ok := helper.InterfacesHeadMap(d, "host_charge_prepaid"); ok { + if v, ok := d.GetOk("host_id"); ok { + hostIdsSet := v.(*schema.Set).List() + for i := range hostIdsSet { + hostIds := hostIdsSet[i].(string) + request.HostIds = append(request.HostIds, helper.String(hostIds)) + } + } + + if hostChargePrepaidMap, ok := helper.InterfacesHeadMap(d, "host_charge_prepaid"); ok { chargePrepaid := cvm.ChargePrepaid{} - if v, ok := dMap["period"]; ok { + if v, ok := hostChargePrepaidMap["period"]; ok { chargePrepaid.Period = helper.IntUint64(v.(int)) } - if v, ok := dMap["renew_flag"]; ok { + if v, ok := hostChargePrepaidMap["renew_flag"]; ok { chargePrepaid.RenewFlag = helper.String(v.(string)) } request.HostChargePrepaid = &chargePrepaid } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().RenewHosts(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().RenewHostsWithContext(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 renewHost failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s create cvm renew host failed, reason:%+v", logId, err) return err } + _ = response + d.SetId(hostId) return resourceTencentCloudCvmRenewHostRead(d, meta) diff --git a/tencentcloud/services/cvm/resource_tc_cvm_renew_host_extension.go b/tencentcloud/services/cvm/resource_tc_cvm_renew_host_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_cvm_renew_host_extension.go @@ -0,0 +1 @@ +package cvm 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/resource_tc_image.go b/tencentcloud/services/cvm/resource_tc_image.go index 57d1e8ffbc..4d7a3bf3c6 100644 --- a/tencentcloud/services/cvm/resource_tc_image.go +++ b/tencentcloud/services/cvm/resource_tc_image.go @@ -1,3 +1,4 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( @@ -5,15 +6,13 @@ import ( "fmt" "log" - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" - svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag" - "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" - "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/ratelimit" + svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag" ) func ResourceTencentCloudImage() *schema.Resource { @@ -25,13 +24,13 @@ func ResourceTencentCloudImage() *schema.Resource { Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, - Schema: map[string]*schema.Schema{ "image_name": { Type: schema.TypeString, Required: true, Description: "Image name.", }, + "instance_id": { Type: schema.TypeString, Optional: true, @@ -39,46 +38,52 @@ func ResourceTencentCloudImage() *schema.Resource { ExactlyOneOf: []string{"snapshot_ids"}, Description: "Cloud server instance ID.", }, + "snapshot_ids": { Type: schema.TypeSet, Optional: true, ForceNew: true, ExactlyOneOf: []string{"instance_id"}, + Description: "Cloud disk snapshot ID list; creating a mirror based on a snapshot must include a system disk snapshot. It cannot be passed in simultaneously with InstanceId.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Description: "Cloud disk snapshot ID list; creating a mirror based on a snapshot must include a system disk snapshot. It cannot be passed in simultaneously with InstanceId.", }, + "image_description": { Type: schema.TypeString, Optional: true, Description: "Image Description.", }, + "force_poweroff": { Type: schema.TypeBool, Optional: true, Default: false, Description: "Set whether to force shutdown during mirroring. The default value is `false`, when set to true, it means that the mirror will be made after shutdown.", }, + "sysprep": { Type: schema.TypeBool, Optional: true, Description: "Sysprep function under Windows. When creating a Windows image, you can select true or false to enable or disable the Syspre function.", }, + "data_disk_ids": { - Type: schema.TypeSet, - Optional: true, - Computed: true, - ForceNew: true, + Type: schema.TypeSet, + Optional: true, + Computed: true, + ForceNew: true, + Description: "Cloud disk ID list, When creating a whole machine image based on an instance, specify the data disk ID contained in the image.", Elem: &schema.Schema{ Type: schema.TypeString, }, - Description: "Cloud disk ID list, When creating a whole machine image based on an instance, specify the data disk ID contained in the image.", }, + "tags": { Type: schema.TypeMap, Optional: true, - Description: "Tags of the image.", + Description: "Tag description list.", }, }, } @@ -86,110 +91,84 @@ func ResourceTencentCloudImage() *schema.Resource { func resourceTencentCloudImageCreate(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_image.create")() + defer tccommon.InconsistentCheck(d, meta)() + logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + var ( + imageId string + ) + var ( + request = cvm.NewCreateImageRequest() + response = cvm.NewCreateImageResponse() + ) + + if v, ok := d.GetOk("image_name"); ok { + request.ImageName = helper.String(v.(string)) } - request := cvm.NewCreateImageRequest() - request.ImageName = helper.String(d.Get("image_name").(string)) - if d.Get("force_poweroff").(bool) { - request.ForcePoweroff = helper.String(TRUE) - } else { - request.ForcePoweroff = helper.String(FALSE) + if v, ok := d.GetOk("instance_id"); ok { + request.InstanceId = helper.String(v.(string)) } if v, ok := d.GetOk("image_description"); ok { request.ImageDescription = helper.String(v.(string)) } - if v, ok := d.GetOkExists("sysprep"); ok { - value := v.(bool) - if value { - request.Sysprep = helper.String(TRUE) - } else { - request.Sysprep = helper.String(FALSE) - } - } + if v, ok := d.GetOk("data_disk_ids"); ok { - diskIds := v.(*schema.Set).List() - diskArr := make([]*string, 0, len(diskIds)) - for _, id := range diskIds { - diskArr = append(diskArr, helper.String(id.(string))) + dataDiskIdsSet := v.(*schema.Set).List() + for i := range dataDiskIdsSet { + dataDiskIds := dataDiskIdsSet[i].(string) + request.DataDiskIds = append(request.DataDiskIds, helper.String(dataDiskIds)) } - request.DataDiskIds = diskArr - } - if v, ok := d.GetOk("instance_id"); ok { - request.InstanceId = helper.String(v.(string)) } + if v, ok := d.GetOk("snapshot_ids"); ok { - ids := v.(*schema.Set).List() - snapshotIds := make([]*string, 0, len(ids)) - for _, v := range ids { - snapshotIds = append(snapshotIds, helper.String(v.(string))) + snapshotIdsSet := v.(*schema.Set).List() + for i := range snapshotIdsSet { + snapshotIds := snapshotIdsSet[i].(string) + request.SnapshotIds = append(request.SnapshotIds, helper.String(snapshotIds)) } - request.SnapshotIds = snapshotIds } - if len(request.SnapshotIds) > 0 && len(request.DataDiskIds) > 0 { - return fmt.Errorf("`%s` and `%s` Can't appear in the profile China at the same time,The parameter `%s` depends on the pre_parameter `%s`", - "snapshot_ids", "data_disk_ids", "data_disk_ids", "instance_id") - } - - if v := helper.GetTags(d, "tags"); len(v) > 0 { - tags := make([]*cvm.Tag, 0) - for tagKey, tagValue := range v { - tag := cvm.Tag{ - Key: helper.String(tagKey), - Value: helper.String(tagValue), - } - tags = append(tags, &tag) - } - tagSpecification := cvm.TagSpecification{ - ResourceType: helper.String("image"), - Tags: tags, - } - request.TagSpecification = append(request.TagSpecification, &tagSpecification) + if err := resourceTencentCloudImageCreatePostFillRequest0(ctx, request); err != nil { + return err } - imageId := "" err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - ratelimit.Check(request.GetAction()) - response, err := cvmService.client.UseCvmClient().CreateImage(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) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().CreateImageWithContext(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()) } - imageId = *response.Response.ImageId + response = result return nil }) if err != nil { + log.Printf("[CRITAL]%s create image failed, reason:%+v", logId, err) + return err + } + + imageId = *response.Response.ImageId + + if err := resourceTencentCloudImageCreatePostHandleResponse0(ctx, response); err != nil { return err } + d.SetId(imageId) - // Wait for the tags attached to the vm since tags attachment it's async while vm creation. if tags := helper.GetTags(d, "tags"); len(tags) > 0 { - tcClient := meta.(tccommon.ProviderMeta).GetAPIV3Conn() - tagService := svctag.NewTagService(tcClient) - resourceName := tccommon.BuildTagResourceName("cvm", "image", tcClient.Region, imageId) + tagService := svctag.NewTagService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) + region := meta.(tccommon.ProviderMeta).GetAPIV3Conn().Region + resourceName := fmt.Sprintf("qcs::cvm:%s:uin/:image/%s", region, d.Id()) if err := tagService.ModifyTags(ctx, resourceName, tags, nil); err != nil { - // If tags attachment failed, the user will be notified, then plan/apply/update with terraform. return err } } - // wait for status - _, has, errRet := cvmService.DescribeImageById(ctx, imageId, false) - if errRet != nil { - return errRet - } - if !has { - return fmt.Errorf("[CRITAL]%s creating cvm image failed, image doesn't exist", logId) - } - return resourceTencentCloudImageRead(d, meta) } @@ -198,84 +177,113 @@ func resourceTencentCloudImageRead(d *schema.ResourceData, meta interface{}) err defer tccommon.InconsistentCheck(d, meta)() 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()} imageId := d.Id() - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } - image, has, errRet := cvmService.DescribeImageById(ctx, imageId, false) - if errRet != nil { - return errRet - } - if !has { - d.SetId("") + var respData *cvm.Image + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + result, e := service.DescribeImageById(ctx, imageId) + if e != nil { + return tccommon.RetryError(e) + } + if err := resourceTencentCloudImageReadRequestOnSuccess0(ctx, result); err != nil { + return err + } + respData = result return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read image failed, reason:%+v", logId, err) + return err } - _ = d.Set("image_name", image.ImageName) - if image.ImageDescription != nil && *image.ImageDescription != "" { - _ = d.Set("image_description", image.ImageDescription) + if respData == nil { + d.SetId("") + log.Printf("[WARN]%s resource `image` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + return nil } - - // Use the resource value when the instance_id in the resource is not empty. - // the instance ID is not returned in the query response body. - instanceId := "" - if v, ok := d.GetOk("instance_id"); ok { - instanceId = v.(string) + if respData.ImageName != nil { + _ = d.Set("image_name", respData.ImageName) } - snapShotSysDisk := make([]interface{}, 0, len(image.SnapshotSet)) - for _, v := range image.SnapshotSet { - snapShotSysDisk = append(snapShotSysDisk, v.SnapshotId) + if respData.ImageDescription != nil { + _ = d.Set("image_description", respData.ImageDescription) } - if instanceId != "" { - _ = d.Set("instance_id", helper.String(instanceId)) - } else { - _ = d.Set("snapshot_ids", snapShotSysDisk) + if err := resourceTencentCloudImageReadPostHandleResponse0(ctx, respData); err != nil { + return err } - client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() - tagService := svctag.NewTagService(client) - - tags, err := tagService.DescribeResourceTags(ctx, "cvm", "image", client.Region, d.Id()) + tcClient := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + tagService := svctag.NewTagService(tcClient) + tags, err := tagService.DescribeResourceTags(ctx, "cvm", "image", tcClient.Region, d.Id()) if err != nil { return err } _ = d.Set("tags", tags) + return nil } func resourceTencentCloudImageUpdate(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_image.update")() + defer tccommon.InconsistentCheck(d, meta)() logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - instanceId := d.Id() - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + imageId := d.Id() + + needChange := false + mutableArgs := []string{"image_name", "image_description"} + for _, v := range mutableArgs { + if d.HasChange(v) { + needChange = true + break + } } - if d.HasChange("image_name") || d.HasChange("image_description") { - imageName := d.Get("image_name").(string) - imageDesc := d.Get("image_description").(string) + if needChange { + request := cvm.NewModifyImageAttributeRequest() - if err := cvmService.ModifyImage(ctx, instanceId, imageName, imageDesc); nil != err { + request.ImageId = helper.String(imageId) + + if v, ok := d.GetOk("image_name"); ok { + request.ImageName = helper.String(v.(string)) + } + + if v, ok := d.GetOk("image_description"); ok { + request.ImageDescription = helper.String(v.(string)) + } + + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyImageAttributeWithContext(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 image failed, reason:%+v", logId, err) return err } } if d.HasChange("tags") { - oldInterface, newInterface := d.GetChange("tags") - replaceTags, deleteTags := svctag.DiffTags(oldInterface.(map[string]interface{}), newInterface.(map[string]interface{})) - tagService := svctag.NewTagService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) - region := meta.(tccommon.ProviderMeta).GetAPIV3Conn().Region - resourceName := tccommon.BuildTagResourceName("cvm", "image", region, instanceId) - err := tagService.ModifyTags(ctx, resourceName, replaceTags, deleteTags) - if err != nil { + ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + tcClient := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + tagService := svctag.NewTagService(tcClient) + oldTags, newTags := d.GetChange("tags") + replaceTags, deleteTags := svctag.DiffTags(oldTags.(map[string]interface{}), newTags.(map[string]interface{})) + resourceName := tccommon.BuildTagResourceName("cvm", "image", tcClient.Region, d.Id()) + if err := tagService.ModifyTags(ctx, resourceName, replaceTags, deleteTags); err != nil { return err } } @@ -285,37 +293,37 @@ func resourceTencentCloudImageUpdate(d *schema.ResourceData, meta interface{}) e func resourceTencentCloudImageDelete(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_image.delete")() + defer tccommon.InconsistentCheck(d, meta)() logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) imageId := d.Id() - if err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - e := cvmService.DeleteImage(ctx, imageId) + var ( + request = cvm.NewDeleteImagesRequest() + response = cvm.NewDeleteImagesResponse() + ) + + request.ImageIds = []*string{helper.String(imageId)} + + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().DeleteImagesWithContext(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 - }); nil != err { + }) + if err != nil { + log.Printf("[CRITAL]%s delete image failed, reason:%+v", logId, err) return err } - //check image - if err := resource.Retry(3*tccommon.ReadRetryTimeout, func() *resource.RetryError { - _, has, err := cvmService.DescribeImageById(ctx, imageId, true) - if err != nil { - return tccommon.RetryError(err) - } - if has { - return resource.RetryableError(fmt.Errorf("image exits error,image_id = %s", imageId)) - } - return nil - }); nil != err { + _ = response + if err := resourceTencentCloudImageDeletePostHandleResponse0(ctx, response); err != nil { return err } diff --git a/tencentcloud/services/cvm/resource_tc_image_extension.go b/tencentcloud/services/cvm/resource_tc_image_extension.go new file mode 100644 index 0000000000..413a13c8c6 --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_image_extension.go @@ -0,0 +1,140 @@ +package cvm + +import ( + "context" + "fmt" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + 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 resourceTencentCloudImageCreatePostFillRequest0(ctx context.Context, req *cvm.CreateImageRequest) error { + d := tccommon.ResourceDataFromContext(ctx) + + if d.Get("force_poweroff").(bool) { + req.ForcePoweroff = helper.String(TRUE) + } else { + req.ForcePoweroff = helper.String(FALSE) + } + + if v, ok := d.GetOkExists("sysprep"); ok { + value := v.(bool) + if value { + req.Sysprep = helper.String(TRUE) + } else { + req.Sysprep = helper.String(FALSE) + } + } + + if len(req.SnapshotIds) > 0 && len(req.DataDiskIds) > 0 { + return fmt.Errorf("`%s` and `%s` Can't appear in the profile China at the same time,The parameter `%s` depends on the pre_parameter `%s`", + "snapshot_ids", "data_disk_ids", "data_disk_ids", "instance_id") + } + + if v := helper.GetTags(d, "tags"); len(v) > 0 { + tags := make([]*cvm.Tag, 0) + for tagKey, tagValue := range v { + tag := cvm.Tag{ + Key: helper.String(tagKey), + Value: helper.String(tagValue), + } + tags = append(tags, &tag) + } + tagSpecification := cvm.TagSpecification{ + ResourceType: helper.String("image"), + Tags: tags, + } + req.TagSpecification = append(req.TagSpecification, &tagSpecification) + } + + return nil +} + +func resourceTencentCloudImageCreatePostHandleResponse0(ctx context.Context, resp *cvm.CreateImageResponse) error { + meta := tccommon.ProviderMetaFromContext(ctx) + logId := ctx.Value(tccommon.LogIdKey) + + cvmService := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + imageId := *resp.Response.ImageId + + // wait for status + image, errRet := cvmService.DescribeImageById(ctx, imageId) + if errRet != nil { + return errRet + } + if image == nil { + return fmt.Errorf("[CRITAL]%s creating cvm image failed, image doesn't exist", logId) + } + return nil +} + +func resourceTencentCloudImageReadRequestOnSuccess0(ctx context.Context, resp *cvm.Image) *resource.RetryError { + logId := ctx.Value(tccommon.LogIdKey) + + if resp != nil { + if *resp.ImageState == "CREATEFAILED" { + return resource.NonRetryableError(fmt.Errorf("[CRITAL]%s Create Image is failed", logId)) + } + if *resp.ImageState != "NORMAL" { + return resource.RetryableError(fmt.Errorf("iamge instance status is processing")) + } + } + return nil +} + +func resourceTencentCloudImageReadPostHandleResponse0(ctx context.Context, resp *cvm.Image) error { + d := tccommon.ResourceDataFromContext(ctx) + + // Use the resource value when the instance_id in the resource is not empty. + // the instance ID is not returned in the query response body. + instanceId := "" + if v, ok := d.GetOk("instance_id"); ok { + instanceId = v.(string) + } + + snapShotSysDisk := make([]interface{}, 0, len(resp.SnapshotSet)) + for _, v := range resp.SnapshotSet { + snapShotSysDisk = append(snapShotSysDisk, v.SnapshotId) + } + + if instanceId != "" { + _ = d.Set("instance_id", helper.String(instanceId)) + } else { + _ = d.Set("snapshot_ids", snapShotSysDisk) + } + + return nil +} + +func resourceTencentCloudImageDeletePostHandleResponse0(ctx context.Context, resp *cvm.DeleteImagesResponse) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + logId := ctx.Value(tccommon.LogIdKey) + + cvmService := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + imageId := d.Id() + + //check image + err := resource.Retry(3*tccommon.ReadRetryTimeout, func() *resource.RetryError { + result, e := cvmService.DescribeImageById(ctx, imageId) + if e != nil { + return tccommon.RetryError(e) + } + if result != nil { + return resource.RetryableError(fmt.Errorf("image exits error,image_id = %s", imageId)) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read image failed, reason:%+v", logId, err) + return err + } + return nil +} diff --git a/tencentcloud/services/cvm/resource_tc_image_test.go b/tencentcloud/services/cvm/resource_tc_image_test.go index 37f2aee1c7..a20f8d510d 100644 --- a/tencentcloud/services/cvm/resource_tc_image_test.go +++ b/tencentcloud/services/cvm/resource_tc_image_test.go @@ -211,14 +211,14 @@ func testAccCheckCvmImageDestroy(s *terraform.State) error { continue } - _, has, err := cvmService.DescribeImageById(ctx, rs.Primary.ID, true) - if err != nil || has { + image, err := cvmService.DescribeImageById(ctx, rs.Primary.ID) + if err != nil || image != nil { err = resource.Retry(3*tccommon.ReadRetryTimeout, func() *resource.RetryError { - _, has, err = cvmService.DescribeImageById(ctx, rs.Primary.ID, true) + image, err = cvmService.DescribeImageById(ctx, rs.Primary.ID) if nil != err { return tccommon.RetryError(err) } - if has { + if image != nil { return resource.RetryableError(fmt.Errorf("image still exists: %s", rs.Primary.ID)) } return nil @@ -227,7 +227,7 @@ func testAccCheckCvmImageDestroy(s *terraform.State) error { if err != nil { return err } - if has { + if image != nil { return fmt.Errorf("image still exists: %s", rs.Primary.ID) } } @@ -248,11 +248,11 @@ func testAccCheckCvmImageExists(n string) resource.TestCheckFunc { return fmt.Errorf("image id is not set") } cvmService := svccvm.NewCvmService(tcacctest.AccProvider.Meta().(tccommon.ProviderMeta).GetAPIV3Conn()) - _, has, err := cvmService.DescribeImageById(ctx, rs.Primary.ID, false) + image, err := cvmService.DescribeImageById(ctx, rs.Primary.ID) if err != nil { return err } - if !has { + if image == nil { return fmt.Errorf("image doesn't exist: %s", rs.Primary.ID) } return nil diff --git a/tencentcloud/services/cvm/resource_tc_instance.go b/tencentcloud/services/cvm/resource_tc_instance.go index 627fcd9c4c..7dc4cafb80 100644 --- a/tencentcloud/services/cvm/resource_tc_instance.go +++ b/tencentcloud/services/cvm/resource_tc_instance.go @@ -1,27 +1,16 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( "context" - "encoding/base64" "fmt" - "log" - "sort" - "strconv" - "strings" - "time" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" - svccbs "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/cbs" - svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag" - "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" - sdkErrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" - cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" - + cvmv20170312 "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" - "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/ratelimit" + "log" + "time" ) func ResourceTencentCloudInstance() *schema.Resource { @@ -30,225 +19,232 @@ func ResourceTencentCloudInstance() *schema.Resource { Read: resourceTencentCloudInstanceRead, Update: resourceTencentCloudInstanceUpdate, Delete: resourceTencentCloudInstanceDelete, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(900000 * time.Millisecond), + }, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, - Timeouts: &schema.ResourceTimeout{ - Create: schema.DefaultTimeout(15 * time.Minute), - }, Schema: map[string]*schema.Schema{ "image_id": { Type: schema.TypeString, Required: true, Description: "The image to use for the instance. Changing `image_id` will cause the instance reset.", }, + "availability_zone": { Type: schema.TypeString, Required: true, ForceNew: true, Description: "The available zone for the CVM instance.", }, - "dedicated_cluster_id": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "Exclusive cluster id.", - }, + "instance_count": { Type: schema.TypeInt, Optional: true, + Description: "The number of instances to be purchased. Value range:[1,100]; default value: 1.", Deprecated: "It has been deprecated from version 1.59.18. Use built-in `count` instead.", ValidateFunc: tccommon.ValidateIntegerInRange(1, 100), - Description: "The number of instances to be purchased. Value range:[1,100]; default value: 1.", }, + "instance_name": { Type: schema.TypeString, Optional: true, Default: "Terraform-CVM-Instance", - ValidateFunc: tccommon.ValidateStringLengthInRange(2, 128), Description: "The name of the instance. The max length of instance_name is 60, and default value is `Terraform-CVM-Instance`.", + ValidateFunc: tccommon.ValidateStringLengthInRange(2, 128), }, + "instance_type": { Type: schema.TypeString, Optional: true, Computed: true, - ValidateFunc: tccommon.ValidateInstanceType, Description: "The type of the instance.", + ValidateFunc: tccommon.ValidateInstanceType, }, + "hostname": { Type: schema.TypeString, Optional: true, Description: "The hostname of the instance. Windows instance: The name should be a combination of 2 to 15 characters comprised of letters (case insensitive), numbers, and hyphens (-). Period (.) is not supported, and the name cannot be a string of pure numbers. Other types (such as Linux) of instances: The name should be a combination of 2 to 60 characters, supporting multiple periods (.). The piece between two periods is composed of letters (case insensitive), numbers, and hyphens (-). Modifying will cause the instance reset.", }, + "project_id": { Type: schema.TypeInt, Optional: true, Default: 0, Description: "The project the instance belongs to, default to 0.", }, + "running_flag": { Type: schema.TypeBool, Optional: true, Default: true, Description: "Set instance to running or stop. Default value is true, the instance will shutdown when this flag is false.", }, + "stopped_mode": { - Type: schema.TypeString, - Optional: true, - Description: "Billing method of a pay-as-you-go instance after shutdown. Available values: `KEEP_CHARGING`,`STOP_CHARGING`. Default `KEEP_CHARGING`.", - ValidateFunc: tccommon.ValidateAllowedStringValue([]string{ - CVM_STOP_MODE_KEEP_CHARGING, - CVM_STOP_MODE_STOP_CHARGING, - }), + Type: schema.TypeString, + Optional: true, + Description: "Billing method of a pay-as-you-go instance after shutdown. Available values: `KEEP_CHARGING`,`STOP_CHARGING`. Default `KEEP_CHARGING`.", + ValidateFunc: tccommon.ValidateAllowedStringValue([]string{CVM_STOP_MODE_KEEP_CHARGING, CVM_STOP_MODE_STOP_CHARGING}), }, + "placement_group_id": { Type: schema.TypeString, Optional: true, ForceNew: true, Description: "The ID of a placement group.", }, - // payment + "instance_charge_type": { Type: schema.TypeString, Optional: true, - Default: CVM_CHARGE_TYPE_POSTPAID, + Default: "POSTPAID_BY_HOUR", + Description: "The charge type of instance. Valid values are `PREPAID`, `POSTPAID_BY_HOUR`, `SPOTPAID` and `CDHPAID`. The default is `POSTPAID_BY_HOUR`. Note: TencentCloud International only supports `POSTPAID_BY_HOUR` and `CDHPAID`. `PREPAID` instance may not allow to delete before expired. `SPOTPAID` instance must set `spot_instance_type` and `spot_max_price` at the same time. `CDHPAID` instance must set `cdh_instance_type` and `cdh_host_id`.", ValidateFunc: tccommon.ValidateAllowedStringValue(CVM_CHARGE_TYPE), - Description: "The charge type of instance. Valid values are `PREPAID`, `POSTPAID_BY_HOUR`, `SPOTPAID`, `CDHPAID` and `CDCPAID`. The default is `POSTPAID_BY_HOUR`. Note: TencentCloud International only supports `POSTPAID_BY_HOUR` and `CDHPAID`. `PREPAID` instance may not allow to delete before expired. `SPOTPAID` instance must set `spot_instance_type` and `spot_max_price` at the same time. `CDHPAID` instance must set `cdh_instance_type` and `cdh_host_id`.", }, + "instance_charge_type_prepaid_period": { Type: schema.TypeInt, Optional: true, + Description: "The tenancy (time unit is month) of the prepaid instance, NOTE: it only works when instance_charge_type is set to `PREPAID`. Valid values are `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `24`, `36`.", ValidateFunc: tccommon.ValidateAllowedIntValue(CVM_PREPAID_PERIOD), - Description: "The tenancy (time unit is month) of the prepaid instance, NOTE: it only works when instance_charge_type is set to `PREPAID`. Valid values are `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `24`, `36`, `48`, `60`.", }, + "instance_charge_type_prepaid_renew_flag": { Type: schema.TypeString, Optional: true, Computed: true, - ValidateFunc: tccommon.ValidateAllowedStringValue(CVM_PREPAID_RENEW_FLAG), 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: it only works when instance_charge_type is set to `PREPAID`.", + ValidateFunc: tccommon.ValidateAllowedStringValue(CVM_PREPAID_RENEW_FLAG), }, + "spot_instance_type": { Type: schema.TypeString, Optional: true, - ValidateFunc: tccommon.ValidateAllowedStringValue(CVM_SPOT_INSTANCE_TYPE), Description: "Type of spot instance, only support `ONE-TIME` now. Note: it only works when instance_charge_type is set to `SPOTPAID`.", + ValidateFunc: tccommon.ValidateAllowedStringValue(CVM_SPOT_INSTANCE_TYPE), }, + "spot_max_price": { Type: schema.TypeString, Optional: true, ForceNew: true, - ValidateFunc: tccommon.ValidateStringNumber, Description: "Max price of a spot instance, is the format of decimal string, for example \"0.50\". Note: it only works when instance_charge_type is set to `SPOTPAID`.", + ValidateFunc: tccommon.ValidateStringNumber, }, + "cdh_instance_type": { Type: schema.TypeString, Optional: true, - ValidateFunc: tccommon.ValidateStringPrefix("CDH_"), Description: "Type of instance created on cdh, the value of this parameter is in the format of CDH_XCXG based on the number of CPU cores and memory capacity. Note: it only works when instance_charge_type is set to `CDHPAID`.", + ValidateFunc: tccommon.ValidateStringPrefix("CDH_"), }, + "cdh_host_id": { Type: schema.TypeString, Optional: true, ForceNew: true, Description: "Id of cdh instance. Note: it only works when instance_charge_type is set to `CDHPAID`.", }, - // network + "internet_charge_type": { - Type: schema.TypeString, - Optional: true, - Computed: true, - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - stopMode := d.Get("stopped_mode").(string) - if stopMode != CVM_STOP_MODE_STOP_CHARGING || !d.HasChange("running_flag") { - return old == new - } - return old == "" || new == "" - }, - ValidateFunc: tccommon.ValidateAllowedStringValue(CVM_INTERNET_CHARGE_TYPE), - Description: "Internet charge type of the instance, Valid values are `BANDWIDTH_PREPAID`, `TRAFFIC_POSTPAID_BY_HOUR`, `BANDWIDTH_POSTPAID_BY_HOUR` and `BANDWIDTH_PACKAGE`. If not set, internet charge type are consistent with the cvm charge type by default. This value takes NO Effect when changing and does not need to be set when `allocate_public_ip` is false.", + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Internet charge type of the instance, Valid values are `BANDWIDTH_PREPAID`, `TRAFFIC_POSTPAID_BY_HOUR`, `BANDWIDTH_POSTPAID_BY_HOUR` and `BANDWIDTH_PACKAGE`. If not set, internet charge type are consistent with the cvm charge type by default. This value takes NO Effect when changing and does not need to be set when `allocate_public_ip` is false.", + ValidateFunc: tccommon.ValidateAllowedStringValue(CVM_INTERNET_CHARGE_TYPE), + DiffSuppressFunc: internetChargeType, }, + "bandwidth_package_id": { Type: schema.TypeString, Optional: true, Description: "bandwidth package id. if user is standard user, then the bandwidth_package_id is needed, or default has bandwidth_package_id.", }, + "internet_max_bandwidth_out": { Type: schema.TypeInt, Optional: true, Computed: true, Description: "Maximum outgoing bandwidth to the public network, measured in Mbps (Mega bits per second). This value does not need to be set when `allocate_public_ip` is false.", }, + "allocate_public_ip": { Type: schema.TypeBool, Optional: true, - Default: false, ForceNew: true, + Default: false, Description: "Associate a public IP address with an instance in a VPC or Classic. Boolean value, Default is false.", }, - // vpc + "vpc_id": { Type: schema.TypeString, Optional: true, Computed: true, Description: "The ID of a VPC network. If you want to create instances in a VPC network, this parameter must be set.", }, + "subnet_id": { Type: schema.TypeString, Optional: true, Computed: true, Description: "The ID of a VPC subnet. If you want to create instances in a VPC network, this parameter must be set.", }, + "private_ip": { Type: schema.TypeString, Optional: true, Computed: true, Description: "The private IP to be assigned to this instance, must be in the provided subnet and available.", }, - // security group + "security_groups": { Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, Optional: true, Computed: true, ConflictsWith: []string{"orderly_security_groups"}, Description: "A list of security group IDs to associate with.", Deprecated: "It will be deprecated. Use `orderly_security_groups` instead.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, "orderly_security_groups": { Type: schema.TypeList, - Elem: &schema.Schema{Type: schema.TypeString}, Optional: true, Computed: true, ConflictsWith: []string{"security_groups"}, Description: "A list of orderly security group IDs to associate with.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, - // storage + "system_disk_type": { Type: schema.TypeString, Optional: true, - Default: CVM_DISK_TYPE_CLOUD_PREMIUM, - ValidateFunc: tccommon.ValidateAllowedStringValue(CVM_DISK_TYPE), + Default: "CLOUD_PREMIUM", Description: "System disk type. For more information on limits of system disk types, see [Storage Overview](https://intl.cloud.tencent.com/document/product/213/4952). Valid values: `LOCAL_BASIC`: local disk, `LOCAL_SSD`: local SSD disk, `CLOUD_BASIC`: cloud disk, `CLOUD_SSD`: cloud SSD disk, `CLOUD_PREMIUM`: Premium Cloud Storage, `CLOUD_BSSD`: Basic SSD, `CLOUD_HSSD`: Enhanced SSD, `CLOUD_TSSD`: Tremendous SSD. NOTE: If modified, the instance may force stop.", + ValidateFunc: tccommon.ValidateAllowedStringValue(CVM_DISK_TYPE), }, + "system_disk_size": { Type: schema.TypeInt, Optional: true, Default: 50, Description: "Size of the system disk. unit is GB, Default is 50GB. If modified, the instance may force stop.", }, + "system_disk_id": { Type: schema.TypeString, Optional: true, Computed: true, Description: "System disk snapshot ID used to initialize the system disk. When system disk type is `LOCAL_BASIC` and `LOCAL_SSD`, disk id is not supported.", }, - "system_disk_resize_online": { - Type: schema.TypeBool, - Optional: true, - Description: "Resize online.", - }, + "data_disks": { Type: schema.TypeList, Optional: true, @@ -264,9 +260,8 @@ func ResourceTencentCloudInstance() *schema.Resource { Description: "Data disk type. For more information about limits on different data disk types, see [Storage Overview](https://intl.cloud.tencent.com/document/product/213/4952). Valid values: LOCAL_BASIC: local disk, LOCAL_SSD: local SSD disk, LOCAL_NVME: local NVME disk, specified in the InstanceType, LOCAL_PRO: local HDD disk, specified in the InstanceType, CLOUD_BASIC: HDD cloud disk, CLOUD_PREMIUM: Premium Cloud Storage, CLOUD_SSD: SSD, CLOUD_HSSD: Enhanced SSD, CLOUD_TSSD: Tremendous SSD, CLOUD_BSSD: Balanced SSD.", }, "data_disk_size": { - Type: schema.TypeInt, - Required: true, - //ForceNew: true, + Type: schema.TypeInt, + Required: true, Description: "Size of the data disk, and unit is GB.", }, "data_disk_snapshot_id": { @@ -284,56 +279,51 @@ func ResourceTencentCloudInstance() *schema.Resource { "delete_with_instance": { Type: schema.TypeBool, Optional: true, - Default: true, ForceNew: true, + Default: true, Description: "Decides whether the disk is deleted with instance(only applied to `CLOUD_BASIC`, `CLOUD_SSD` and `CLOUD_PREMIUM` disk with `POSTPAID_BY_HOUR` instance), default is true.", }, - "delete_with_instance_prepaid": { - Type: schema.TypeBool, - Optional: true, - Default: false, - ForceNew: true, - Description: "Decides whether the disk is deleted with instance(only applied to `CLOUD_BASIC`, `CLOUD_SSD` and `CLOUD_PREMIUM` disk with `PREPAID` instance), default is false.", - }, "encrypt": { Type: schema.TypeBool, Optional: true, - Default: false, ForceNew: true, + Default: false, Description: "Decides whether the disk is encrypted. Default is `false`.", }, "throughput_performance": { Type: schema.TypeInt, Optional: true, - Default: 0, ForceNew: true, + Default: 0, Description: "Add extra performance to the data disk. Only works when disk type is `CLOUD_TSSD` or `CLOUD_HSSD`.", }, }, }, }, - // enhance services + "disable_security_service": { Type: schema.TypeBool, Optional: true, Default: false, Description: "Disable enhance service for security, it is enabled by default. When this options is set, security agent won't be installed. Modifying will cause the instance reset.", }, + "disable_monitor_service": { Type: schema.TypeBool, Optional: true, Default: false, Description: "Disable enhance service for monitor, it is enabled by default. When this options is set, monitor agent won't be installed. Modifying will cause the instance reset.", }, - // login + "key_name": { Type: schema.TypeString, Optional: true, Computed: true, - Deprecated: "Please use `key_ids` instead.", ConflictsWith: []string{"key_ids"}, Description: "The key pair to use for the instance, it looks like `skey-16jig7tx`. Modifying will cause the instance reset.", + Deprecated: "Please use `key_ids` instead.", }, + "key_ids": { Type: schema.TypeSet, Optional: true, @@ -341,28 +331,27 @@ func ResourceTencentCloudInstance() *schema.Resource { ConflictsWith: []string{"key_name", "password"}, Description: "The key pair to use for the instance, it looks like `skey-16jig7tx`. Modifying will cause the instance reset.", Set: schema.HashString, - Elem: &schema.Schema{Type: schema.TypeString}, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, + "password": { Type: schema.TypeString, Optional: true, Sensitive: true, Description: "Password for the instance. In order for the new password to take effect, the instance will be restarted after the password change. Modifying will cause the instance reset.", }, + "keep_image_login": { - Type: schema.TypeBool, - Optional: true, - Default: false, - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - if new == "false" && old == "" || old == "false" && new == "" { - return true - } else { - return old == new - } - }, - ConflictsWith: []string{"key_name", "key_ids", "password"}, - Description: "Whether to keep image login or not, default is `false`. When the image type is private or shared or imported, this parameter can be set `true`. Modifying will cause the instance reset.", + Type: schema.TypeBool, + Optional: true, + Default: false, + ConflictsWith: []string{"key_name", "key_ids", "password"}, + Description: "Whether to keep image login or not, default is `false`. When the image type is private or shared or imported, this parameter can be set `true`. Modifying will cause the instance reset.", + DiffSuppressFunc: keepImageLogin, }, + "user_data": { Type: schema.TypeString, Optional: true, @@ -370,6 +359,7 @@ func ResourceTencentCloudInstance() *schema.Resource { ConflictsWith: []string{"user_data_raw"}, Description: "The user data to be injected into this instance. Must be base64 encoded and up to 16 KB.", }, + "user_data_raw": { Type: schema.TypeString, Optional: true, @@ -377,66 +367,76 @@ func ResourceTencentCloudInstance() *schema.Resource { ConflictsWith: []string{"user_data"}, Description: "The user data to be injected into this instance, in plain text. Conflicts with `user_data`. Up to 16 KB after base64 encoded.", }, + "tags": { Type: schema.TypeMap, Optional: true, Description: "A mapping of tags to assign to the resource. For tag limits, please refer to [Use Limits](https://intl.cloud.tencent.com/document/product/651/13354).", }, + "force_delete": { Type: schema.TypeBool, Optional: true, Default: false, Description: "Indicate whether to force delete the instance. Default is `false`. If set true, the instance will be permanently deleted instead of being moved into the recycle bin. Note: only works for `PREPAID` instance.", }, + "disable_api_termination": { Type: schema.TypeBool, Optional: true, Default: false, Description: "Whether the termination protection is enabled. Default is `false`. If set true, which means that this instance can not be deleted by an API action.", }, - // role + "cam_role_name": { Type: schema.TypeString, - ForceNew: true, Optional: true, + ForceNew: true, Description: "CAM role name authorized to access.", }, - // Computed values. + "instance_status": { Type: schema.TypeString, Computed: true, Description: "Current status of the instance.", }, + "public_ip": { Type: schema.TypeString, Computed: true, Description: "Public IP of the instance.", }, + "uuid": { Type: schema.TypeString, Computed: true, Description: "Globally unique ID of the instance.", }, + "create_time": { Type: schema.TypeString, Computed: true, Description: "Create time of the instance.", }, + "expired_time": { Type: schema.TypeString, Computed: true, Description: "Expired time of the instance.", }, + "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, @@ -448,34 +448,39 @@ func ResourceTencentCloudInstance() *schema.Resource { func resourceTencentCloudInstanceCreate(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_instance.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) - ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - cvmService = CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + instanceId string + ) + var ( + request = cvmv20170312.NewRunInstancesRequest() + response = cvmv20170312.NewRunInstancesResponse() ) - request := cvm.NewRunInstancesRequest() - request.ImageId = helper.String(d.Get("image_id").(string)) - request.Placement = &cvm.Placement{ - Zone: helper.String(d.Get("availability_zone").(string)), + if v, ok := d.GetOk("image_id"); ok { + request.ImageId = helper.String(v.(string)) } - if v, ok := d.GetOk("dedicated_cluster_id"); ok { - request.DedicatedClusterId = helper.String(v.(string)) + placement := cvmv20170312.Placement{} + if v, ok := d.GetOk("availability_zone"); ok { + placement.Zone = helper.String(v.(string)) } - - if v, ok := d.GetOk("project_id"); ok { - projectId := int64(v.(int)) - request.Placement.ProjectId = &projectId + if v, ok := d.GetOkExists("project_id"); ok { + placement.ProjectId = helper.IntInt64(v.(int)) } + request.Placement = &placement if v, ok := d.GetOk("instance_name"); ok { request.InstanceName = helper.String(v.(string)) } - if v, ok := d.GetOk("instance_count"); ok { - request.InstanceCount = helper.Int64(int64(v.(int))) + if v, ok := d.GetOkExists("instance_count"); ok { + request.InstanceCount = helper.IntInt64(v.(int)) } if v, ok := d.GetOk("instance_type"); ok { @@ -490,336 +495,105 @@ func resourceTencentCloudInstanceCreate(d *schema.ResourceData, meta interface{} request.CamRoleName = helper.String(v.(string)) } - if v, ok := d.GetOk("instance_charge_type"); ok { - instanceChargeType := v.(string) - request.InstanceChargeType = &instanceChargeType - if instanceChargeType == CVM_CHARGE_TYPE_PREPAID || instanceChargeType == CVM_CHARGE_TYPE_UNDERWRITE { - request.InstanceChargePrepaid = &cvm.InstanceChargePrepaid{} - if period, ok := d.GetOk("instance_charge_type_prepaid_period"); ok { - periodInt64 := int64(period.(int)) - request.InstanceChargePrepaid.Period = &periodInt64 - } - - if renewFlag, ok := d.GetOk("instance_charge_type_prepaid_renew_flag"); ok { - request.InstanceChargePrepaid.RenewFlag = helper.String(renewFlag.(string)) - } - } - - if instanceChargeType == CVM_CHARGE_TYPE_SPOTPAID { - spotInstanceType, sitOk := d.GetOk("spot_instance_type") - spotMaxPrice, smpOk := d.GetOk("spot_max_price") - if sitOk || smpOk { - request.InstanceMarketOptions = &cvm.InstanceMarketOptionsRequest{} - request.InstanceMarketOptions.MarketType = helper.String(CVM_MARKET_TYPE_SPOT) - request.InstanceMarketOptions.SpotOptions = &cvm.SpotMarketOptions{} - } - - if sitOk { - request.InstanceMarketOptions.SpotOptions.SpotInstanceType = helper.String(strings.ToLower(spotInstanceType.(string))) - } - - if smpOk { - request.InstanceMarketOptions.SpotOptions.MaxPrice = helper.String(spotMaxPrice.(string)) - } - } - - if instanceChargeType == CVM_CHARGE_TYPE_CDHPAID { - if v, ok := d.GetOk("cdh_instance_type"); ok { - request.InstanceType = helper.String(v.(string)) - } else { - return fmt.Errorf("cdh_instance_type can not be empty when instance_charge_type is %s", instanceChargeType) - } - - if v, ok := d.GetOk("cdh_host_id"); ok { - request.Placement.HostIds = append(request.Placement.HostIds, helper.String(v.(string))) - } else { - return fmt.Errorf("cdh_host_id can not be empty when instance_charge_type is %s", instanceChargeType) - } - } - } - - if v, ok := d.GetOk("placement_group_id"); ok { - request.DisasterRecoverGroupIds = []*string{helper.String(v.(string))} - } - - // network - request.InternetAccessible = &cvm.InternetAccessible{} + internetAccessible := cvmv20170312.InternetAccessible{} if v, ok := d.GetOk("internet_charge_type"); ok { - request.InternetAccessible.InternetChargeType = helper.String(v.(string)) + internetAccessible.InternetChargeType = helper.String(v.(string)) } - - if v, ok := d.GetOk("internet_max_bandwidth_out"); ok { - maxBandwidthOut := int64(v.(int)) - request.InternetAccessible.InternetMaxBandwidthOut = &maxBandwidthOut + if v, ok := d.GetOkExists("internet_max_bandwidth_out"); ok { + internetAccessible.InternetMaxBandwidthOut = helper.IntInt64(v.(int)) } - if v, ok := d.GetOk("bandwidth_package_id"); ok { - request.InternetAccessible.BandwidthPackageId = helper.String(v.(string)) + internetAccessible.BandwidthPackageId = helper.String(v.(string)) } - if v, ok := d.GetOkExists("allocate_public_ip"); ok { - allocatePublicIp := v.(bool) - request.InternetAccessible.PublicIpAssigned = &allocatePublicIp - } - - // vpc - if v, ok := d.GetOk("vpc_id"); ok { - request.VirtualPrivateCloud = &cvm.VirtualPrivateCloud{} - request.VirtualPrivateCloud.VpcId = helper.String(v.(string)) - - if v, ok = d.GetOk("subnet_id"); ok { - request.VirtualPrivateCloud.SubnetId = helper.String(v.(string)) - } - - if v, ok = d.GetOk("private_ip"); ok { - request.VirtualPrivateCloud.PrivateIpAddresses = []*string{helper.String(v.(string))} - } + internetAccessible.PublicIpAssigned = helper.Bool(v.(bool)) } + request.InternetAccessible = &internetAccessible if v, ok := d.GetOk("security_groups"); ok { - securityGroups := v.(*schema.Set).List() - request.SecurityGroupIds = make([]*string, 0, len(securityGroups)) - for _, securityGroup := range securityGroups { - request.SecurityGroupIds = append(request.SecurityGroupIds, helper.String(securityGroup.(string))) - } - } - - if v, ok := d.GetOk("orderly_security_groups"); ok { - securityGroups := v.([]interface{}) - request.SecurityGroupIds = make([]*string, 0, len(securityGroups)) - for _, securityGroup := range securityGroups { - request.SecurityGroupIds = append(request.SecurityGroupIds, helper.String(securityGroup.(string))) + securityGroupIdsSet := v.(*schema.Set).List() + for i := range securityGroupIdsSet { + securityGroupIds := securityGroupIdsSet[i].(string) + request.SecurityGroupIds = append(request.SecurityGroupIds, helper.String(securityGroupIds)) } } - // storage - request.SystemDisk = &cvm.SystemDisk{} + systemDisk := cvmv20170312.SystemDisk{} if v, ok := d.GetOk("system_disk_type"); ok { - request.SystemDisk.DiskType = helper.String(v.(string)) + systemDisk.DiskType = helper.String(v.(string)) } - - if v, ok := d.GetOk("system_disk_size"); ok { - diskSize := int64(v.(int)) - request.SystemDisk.DiskSize = &diskSize + if v, ok := d.GetOkExists("system_disk_size"); ok { + systemDisk.DiskSize = helper.IntInt64(v.(int)) } - if v, ok := d.GetOk("system_disk_id"); ok { - request.SystemDisk.DiskId = helper.String(v.(string)) - } - - if v, ok := d.GetOk("data_disks"); ok { - dataDisks := v.([]interface{}) - request.DataDisks = make([]*cvm.DataDisk, 0, len(dataDisks)) - for _, d := range dataDisks { - value := d.(map[string]interface{}) - diskType := value["data_disk_type"].(string) - diskSize := int64(value["data_disk_size"].(int)) - throughputPerformance := int64(value["throughput_performance"].(int)) - dataDisk := cvm.DataDisk{ - DiskType: &diskType, - DiskSize: &diskSize, - ThroughputPerformance: &throughputPerformance, - } - - if v, ok := value["data_disk_snapshot_id"]; ok && v != nil { - snapshotId := v.(string) - if snapshotId != "" { - dataDisk.SnapshotId = helper.String(snapshotId) - } - } - - if value["data_disk_id"] != "" { - dataDisk.DiskId = helper.String(value["data_disk_id"].(string)) - } - - if deleteWithInstance, ok := value["delete_with_instance"]; ok { - deleteWithInstanceBool := deleteWithInstance.(bool) - dataDisk.DeleteWithInstance = &deleteWithInstanceBool - } - - if encrypt, ok := value["encrypt"]; ok { - encryptBool := encrypt.(bool) - dataDisk.Encrypt = &encryptBool - } - - request.DataDisks = append(request.DataDisks, &dataDisk) - } + systemDisk.DiskId = helper.String(v.(string)) } + request.SystemDisk = &systemDisk - // enhanced service - request.EnhancedService = &cvm.EnhancedService{} + enhancedService := cvmv20170312.EnhancedService{} + runSecurityServiceEnabled := cvmv20170312.RunSecurityServiceEnabled{} if v, ok := d.GetOkExists("disable_security_service"); ok { - securityService := !(v.(bool)) - request.EnhancedService.SecurityService = &cvm.RunSecurityServiceEnabled{ - Enabled: &securityService, - } + runSecurityServiceEnabled.Enabled = helper.Bool(v.(bool)) } - + enhancedService.SecurityService = &runSecurityServiceEnabled + runMonitorServiceEnabled := cvmv20170312.RunMonitorServiceEnabled{} if v, ok := d.GetOkExists("disable_monitor_service"); ok { - monitorService := !(v.(bool)) - request.EnhancedService.MonitorService = &cvm.RunMonitorServiceEnabled{ - Enabled: &monitorService, - } - } - - // login - request.LoginSettings = &cvm.LoginSettings{} - keyIds := d.Get("key_ids").(*schema.Set).List() - if len(keyIds) > 0 { - request.LoginSettings.KeyIds = helper.InterfacesStringsPoint(keyIds) - } else if v, ok := d.GetOk("key_name"); ok { - request.LoginSettings.KeyIds = []*string{helper.String(v.(string))} + runMonitorServiceEnabled.Enabled = helper.Bool(v.(bool)) } + enhancedService.MonitorService = &runMonitorServiceEnabled + request.EnhancedService = &enhancedService + loginSettings := cvmv20170312.LoginSettings{} if v, ok := d.GetOk("password"); ok { - request.LoginSettings.Password = helper.String(v.(string)) - } - - v := d.Get("keep_image_login").(bool) - if v { - request.LoginSettings.KeepImageLogin = helper.String(CVM_IMAGE_LOGIN) - } else { - request.LoginSettings.KeepImageLogin = helper.String(CVM_IMAGE_LOGIN_NOT) + loginSettings.Password = helper.String(v.(string)) } + request.LoginSettings = &loginSettings if v, ok := d.GetOk("user_data"); ok { request.UserData = helper.String(v.(string)) } - if v, ok := d.GetOk("user_data_raw"); ok { - userData := base64.StdEncoding.EncodeToString([]byte(v.(string))) - request.UserData = &userData - } - if v, ok := d.GetOkExists("disable_api_termination"); ok { request.DisableApiTermination = helper.Bool(v.(bool)) } - if v := helper.GetTags(d, "tags"); len(v) > 0 { - tags := make([]*cvm.Tag, 0) - for tagKey, tagValue := range v { - tag := cvm.Tag{ - Key: helper.String(tagKey), - Value: helper.String(tagValue), - } - - tags = append(tags, &tag) - } - - tagSpecification := cvm.TagSpecification{ - ResourceType: helper.String("instance"), - Tags: tags, - } - - request.TagSpecification = append(request.TagSpecification, &tagSpecification) + if err := resourceTencentCloudInstanceCreatePostFillRequest0(ctx, request); err != nil { + return err } - instanceId := "" err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - ratelimit.Check("create") - response, err := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().RunInstances(request) - if err != nil { - log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", - logId, request.GetAction(), request.ToJsonString(), err.Error()) - e, ok := err.(*sdkErrors.TencentCloudSDKError) - if ok && tccommon.IsContains(CVM_RETRYABLE_ERROR, e.Code) { - return resource.RetryableError(fmt.Errorf("cvm create error: %s, retrying", e.Error())) - } - - return resource.NonRetryableError(err) + if err := resourceTencentCloudInstanceCreatePreRequest0(ctx, request); err != nil { + return err } - 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.InstanceIdSet) < 1 { - err = fmt.Errorf("instance id is nil") - return resource.NonRetryableError(err) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmV20170312Client().RunInstancesWithContext(ctx, request) + if e != nil { + if err := resourceTencentCloudInstanceCreateRequestOnError0(ctx, request, e); err != nil { + return err + } + 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()) } - - instanceId = *response.Response.InstanceIdSet[0] + response = result return nil }) - if err != nil { + log.Printf("[CRITAL]%s create instance failed, reason:%+v", logId, err) return err } - d.SetId(instanceId) - - err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { - instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) - } - - if instance != nil && *instance.InstanceState == CVM_STATUS_LAUNCH_FAILED { - //LatestOperationCodeMode - if instance.LatestOperationErrorMsg != nil { - return resource.NonRetryableError(fmt.Errorf("cvm instance %s launch failed. Error msg: %s.\n", *instance.InstanceId, *instance.LatestOperationErrorMsg)) - } - - return resource.NonRetryableError(fmt.Errorf("cvm instance %s launch failed, this resource will not be stored to tfstate and will auto removed\n.", *instance.InstanceId)) - } - - if instance != nil && *instance.InstanceState == CVM_STATUS_RUNNING { - return nil - } - - return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState)) - }) - - if err != nil { - return err + if len(response.Response.InstanceIdSet) < 1 { + return fmt.Errorf("resource `tencentcloud_instance` create failed.") } - // Wait for the tags attached to the vm since tags attachment it's async while vm creation. - if tags := helper.GetTags(d, "tags"); len(tags) > 0 { - tcClient := meta.(tccommon.ProviderMeta).GetAPIV3Conn() - tagService := svctag.NewTagService(tcClient) - err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - actualTags, e := tagService.DescribeResourceTags(ctx, "cvm", "instance", tcClient.Region, instanceId) - if e != nil { - return resource.RetryableError(e) - } - - for tagKey, tagValue := range tags { - if v, ok := actualTags[tagKey]; !ok || v != tagValue { - return resource.RetryableError(fmt.Errorf("tag(%s, %s) modification is not completed", tagKey, tagValue)) - } - } - - return nil - }) + instanceId = *response.Response.InstanceIdSet[0] - if err != nil { - return err - } + if err := resourceTencentCloudInstanceCreatePostHandleResponse0(ctx, response); err != nil { + return err } - if !(d.Get("running_flag").(bool)) { - stoppedMode := d.Get("stopped_mode").(string) - err = cvmService.StopInstance(ctx, instanceId, stoppedMode) - if err != nil { - return err - } - - err = resource.Retry(2*tccommon.ReadRetryTimeout, func() *resource.RetryError { - instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) - } - - if instance != nil && *instance.InstanceState == CVM_STATUS_STOPPED { - return nil - } - - return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState)) - }) - - if err != nil { - return err - } - } + d.SetId(instanceId) return resourceTencentCloudInstanceRead(d, meta) } @@ -828,1242 +602,561 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{}) defer tccommon.LogElapsed("resource.tencentcloud_instance.read")() defer tccommon.InconsistentCheck(d, meta)() - var ( - logId = tccommon.GetLogId(tccommon.ContextNil) - ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - client = meta.(tccommon.ProviderMeta).GetAPIV3Conn() - cvmService = CvmService{client: client} - cbsService = svccbs.NewCbsService(client) - instanceId = d.Id() - ) + logId := tccommon.GetLogId(tccommon.ContextNil) - forceDelete := false - if v, ok := d.GetOkExists("force_delete"); ok { - forceDelete = v.(bool) - _ = d.Set("force_delete", forceDelete) - } + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - var instance *cvm.Instance - var errRet error - err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - instance, errRet = cvmService.DescribeInstanceById(ctx, instanceId) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) - } + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - if instance != nil && instance.LatestOperationState != nil && *instance.LatestOperationState == "OPERATING" { - return resource.RetryableError(fmt.Errorf("waiting for instance %s operation", *instance.InstanceId)) - } + instanceId := d.Id() + var respData *cvmv20170312.Instance + reqErr := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + result, e := service.DescribeInstanceById(ctx, instanceId) + if e != nil { + return tccommon.RetryError(e) + } + if err := resourceTencentCloudInstanceReadRequestOnSuccess0(ctx, result); err != nil { + return err + } + respData = result return nil }) - - if err != nil { - return err + if reqErr != nil { + log.Printf("[CRITAL]%s read instance failed, reason:%+v", logId, reqErr) + return reqErr } - if instance == nil || *instance.InstanceState == CVM_STATUS_LAUNCH_FAILED { + if respData == nil { d.SetId("") - log.Printf("[CRITAL]instance %s not exist or launch failed", instanceId) + log.Printf("[WARN]%s resource `instance` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) return nil } + if err := resourceTencentCloudInstanceReadPreHandleResponse0(ctx, respData); err != nil { + return err + } - var cvmImages []string - var response *cvm.DescribeImagesResponse - err = resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - request := cvm.NewDescribeImagesRequest() - response, errRet = client.UseCvmClient().DescribeImages(request) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) + if respData.Placement != nil { + if respData.Placement.Zone != nil { + _ = d.Set("availability_zone", respData.Placement.Zone) } - if *response.Response.TotalCount > 0 { - for i := range response.Response.ImageSet { - image := response.Response.ImageSet[i] - cvmImages = append(cvmImages, *image.ImageId) - } + if respData.Placement.ProjectId != nil { + _ = d.Set("project_id", respData.Placement.ProjectId) } - return nil - }) - - if err != nil { - return err } - if d.Get("image_id").(string) == "" || instance.ImageId == nil || !tccommon.IsContains(cvmImages, *instance.ImageId) { - _ = d.Set("image_id", instance.ImageId) + if respData.InstanceName != nil { + _ = d.Set("instance_name", respData.InstanceName) } - _ = d.Set("availability_zone", instance.Placement.Zone) - _ = d.Set("dedicated_cluster_id", instance.DedicatedClusterId) - _ = d.Set("instance_name", instance.InstanceName) - _ = d.Set("instance_type", instance.InstanceType) - _ = d.Set("project_id", instance.Placement.ProjectId) - _ = d.Set("instance_charge_type", instance.InstanceChargeType) - _ = d.Set("instance_charge_type_prepaid_renew_flag", instance.RenewFlag) - _ = d.Set("internet_charge_type", instance.InternetAccessible.InternetChargeType) - _ = d.Set("internet_max_bandwidth_out", instance.InternetAccessible.InternetMaxBandwidthOut) - _ = d.Set("vpc_id", instance.VirtualPrivateCloud.VpcId) - _ = d.Set("subnet_id", instance.VirtualPrivateCloud.SubnetId) - _ = d.Set("security_groups", instance.SecurityGroupIds) - _ = d.Set("orderly_security_groups", instance.SecurityGroupIds) - _ = d.Set("system_disk_type", instance.SystemDisk.DiskType) - _ = d.Set("system_disk_size", instance.SystemDisk.DiskSize) - _ = d.Set("system_disk_id", instance.SystemDisk.DiskId) - _ = d.Set("instance_status", instance.InstanceState) - _ = d.Set("create_time", instance.CreatedTime) - _ = d.Set("expired_time", instance.ExpiredTime) - _ = d.Set("cam_role_name", instance.CamRoleName) - _ = d.Set("disable_api_termination", instance.DisableApiTermination) - _ = d.Set("cpu", instance.CPU) - _ = d.Set("memory", instance.Memory) - _ = d.Set("os_name", instance.OsName) - - if instance.Uuid != nil { - _ = d.Set("uuid", instance.Uuid) + if respData.InstanceType != nil { + _ = d.Set("instance_type", respData.InstanceType) } - if *instance.InstanceChargeType == CVM_CHARGE_TYPE_CDHPAID { - _ = d.Set("cdh_instance_type", instance.InstanceType) + if respData.InstanceChargeType != nil { + _ = d.Set("instance_charge_type", respData.InstanceChargeType) } - if _, ok := d.GetOkExists("allocate_public_ip"); !ok { - _ = d.Set("allocate_public_ip", len(instance.PublicIpAddresses) > 0) + if respData.RenewFlag != nil { + _ = d.Set("instance_charge_type_prepaid_renew_flag", respData.RenewFlag) } - tagService := svctag.NewTagService(client) + if respData.InternetAccessible != nil { + if respData.InternetAccessible.InternetChargeType != nil { + _ = d.Set("internet_charge_type", respData.InternetAccessible.InternetChargeType) + } - tags, err := tagService.DescribeResourceTags(ctx, "cvm", "instance", client.Region, d.Id()) - if err != nil { - return err - } - - // as attachment add tencentcloud:autoscaling:auto-scaling-group-id tag automatically - // we should remove this tag, otherwise it will cause terraform state change - delete(tags, "tencentcloud:autoscaling:auto-scaling-group-id") - _ = d.Set("tags", tags) - - //set data_disks - var hasDataDisks, isCombineDataDisks bool - dataDiskList := make([]map[string]interface{}, 0, len(instance.DataDisks)) - diskSizeMap := map[string]*uint64{} - diskOrderMap := make(map[string]int) + if respData.InternetAccessible.InternetMaxBandwidthOut != nil { + _ = d.Set("internet_max_bandwidth_out", respData.InternetAccessible.InternetMaxBandwidthOut) + } - if _, ok := d.GetOk("data_disks"); ok { - hasDataDisks = true } - if len(instance.DataDisks) > 0 { - var diskIds []*string - for i := range instance.DataDisks { - id := instance.DataDisks[i].DiskId - size := instance.DataDisks[i].DiskSize - if id == nil { - continue - } - - if strings.HasPrefix(*id, "disk-") { - diskIds = append(diskIds, id) - } else { - diskSizeMap[*id] = helper.Int64Uint64(*size) - } + if respData.VirtualPrivateCloud != nil { + if respData.VirtualPrivateCloud.VpcId != nil { + _ = d.Set("vpc_id", respData.VirtualPrivateCloud.VpcId) } - err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - disks, err := cbsService.DescribeDiskList(ctx, diskIds) - if err != nil { - return resource.NonRetryableError(err) - } - - for i := range disks { - disk := disks[i] - if *disk.DiskState == "EXPANDING" { - return resource.RetryableError(fmt.Errorf("data_disk[%d] is expending", i)) - } - - diskSizeMap[*disk.DiskId] = disk.DiskSize - if hasDataDisks { - items := strings.Split(*disk.DiskName, "_") - diskOrder := items[len(items)-1] - diskOrderInt, err := strconv.Atoi(diskOrder) - if err != nil { - isCombineDataDisks = true - continue - } - - diskOrderMap[*disk.DiskId] = diskOrderInt - } - } + if respData.VirtualPrivateCloud.SubnetId != nil { + _ = d.Set("subnet_id", respData.VirtualPrivateCloud.SubnetId) + } - return nil - }) + } - if err != nil { - return err - } + if respData.SecurityGroupIds != nil { + _ = d.Set("security_groups", respData.SecurityGroupIds) } - tmpDataDisks := make([]interface{}, 0, len(instance.DataDisks)) - if v, ok := d.GetOk("data_disks"); ok { - tmpDataDisks = v.([]interface{}) + if respData.SecurityGroupIds != nil { + _ = d.Set("orderly_security_groups", respData.SecurityGroupIds) } - for index, disk := range instance.DataDisks { - dataDisk := make(map[string]interface{}, 5) - dataDisk["data_disk_id"] = disk.DiskId - if disk.DiskId == nil { - dataDisk["data_disk_size"] = disk.DiskSize - } else if size, ok := diskSizeMap[*disk.DiskId]; ok { - dataDisk["data_disk_size"] = size + if respData.SystemDisk != nil { + if respData.SystemDisk.DiskType != nil { + _ = d.Set("system_disk_type", respData.SystemDisk.DiskType) } - dataDisk["delete_with_instance_prepaid"] = false - if len(tmpDataDisks) == len(instance.DataDisks) { - tmpDataDisk := tmpDataDisks[index].(map[string]interface{}) - if deleteWithInstancePrepaid, ok := tmpDataDisk["delete_with_instance_prepaid"]; ok { - deleteWithInstancePrepaidBool := deleteWithInstancePrepaid.(bool) - dataDisk["delete_with_instance_prepaid"] = deleteWithInstancePrepaidBool - } + if respData.SystemDisk.DiskSize != nil { + _ = d.Set("system_disk_size", respData.SystemDisk.DiskSize) } - dataDisk["data_disk_type"] = disk.DiskType - dataDisk["data_disk_snapshot_id"] = disk.SnapshotId - dataDisk["delete_with_instance"] = disk.DeleteWithInstance - dataDisk["encrypt"] = disk.Encrypt - dataDisk["throughput_performance"] = disk.ThroughputPerformance - dataDiskList = append(dataDiskList, dataDisk) - } + if respData.SystemDisk.DiskId != nil { + _ = d.Set("system_disk_id", respData.SystemDisk.DiskId) + } - if hasDataDisks && !isCombineDataDisks { - sort.SliceStable(dataDiskList, func(idx1, idx2 int) bool { - dataDiskIdIdx1 := *dataDiskList[idx1]["data_disk_id"].(*string) - dataDiskIdIdx2 := *dataDiskList[idx2]["data_disk_id"].(*string) - return diskOrderMap[dataDiskIdIdx1] < diskOrderMap[dataDiskIdIdx2] - }) } - _ = d.Set("data_disks", dataDiskList) - - if len(instance.PrivateIpAddresses) > 0 { - _ = d.Set("private_ip", instance.PrivateIpAddresses[0]) + if respData.InstanceState != nil { + _ = d.Set("instance_status", respData.InstanceState) } - if len(instance.PublicIpAddresses) > 0 { - _ = d.Set("public_ip", instance.PublicIpAddresses[0]) + if respData.CreatedTime != nil { + _ = d.Set("create_time", respData.CreatedTime) } - if len(instance.LoginSettings.KeyIds) > 0 { - _ = d.Set("key_name", instance.LoginSettings.KeyIds[0]) - _ = d.Set("key_ids", instance.LoginSettings.KeyIds) - } else { - _ = d.Set("key_name", "") - _ = d.Set("key_ids", []*string{}) + if respData.ExpiredTime != nil { + _ = d.Set("expired_time", respData.ExpiredTime) } - if instance.LoginSettings.KeepImageLogin != nil { - _ = d.Set("keep_image_login", *instance.LoginSettings.KeepImageLogin == CVM_IMAGE_LOGIN) + if respData.CamRoleName != nil { + _ = d.Set("cam_role_name", respData.CamRoleName) } - if *instance.InstanceState == CVM_STATUS_STOPPED { - _ = d.Set("running_flag", false) - } else { - _ = d.Set("running_flag", true) + if respData.DisableApiTermination != nil { + _ = d.Set("disable_api_termination", respData.DisableApiTermination) } - return nil -} - -func resourceTencentCloudInstanceUpdate(d *schema.ResourceData, meta interface{}) (err error) { - defer tccommon.LogElapsed("resource.tencentcloud_instance.update")() - - var ( - logId = tccommon.GetLogId(tccommon.ContextNil) - ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - instanceId = d.Id() - cvmService = CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - ) + if respData.CPU != nil { + _ = d.Set("cpu", respData.CPU) + } - d.Partial(true) + if respData.Memory != nil { + _ = d.Set("memory", respData.Memory) + } - // Get the latest instance info from actual resource. - instanceInfo, err := cvmService.DescribeInstanceById(ctx, instanceId) - if err != nil { - return err + if respData.OsName != nil { + _ = d.Set("os_name", respData.OsName) } - var ( - periodSet = false - renewFlagSet = false - expectChargeType = CVM_CHARGE_TYPE_POSTPAID - currentChargeType = *instanceInfo.InstanceChargeType - ) + if respData.Uuid != nil { + _ = d.Set("uuid", respData.Uuid) + } - chargeType, chargeOk := d.GetOk("instance_charge_type") - if chargeOk { - expectChargeType = chargeType.(string) + if err := resourceTencentCloudInstanceReadPostHandleResponse0(ctx, respData); err != nil { + return err } - if d.HasChange("instance_charge_type") && expectChargeType != currentChargeType { - var ( - period = -1 - renewFlag string - ) + return nil +} - if v, ok := d.GetOk("instance_charge_type_prepaid_period"); ok { - period = v.(int) - } +func resourceTencentCloudInstanceUpdate(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_instance.update")() + defer tccommon.InconsistentCheck(d, meta)() - if v, ok := d.GetOk("instance_charge_type_prepaid_renew_flag"); ok { - renewFlag = v.(string) - } + logId := tccommon.GetLogId(tccommon.ContextNil) - // change charge type - err := cvmService.ModifyInstanceChargeType(ctx, instanceId, expectChargeType, period, renewFlag) - if err != nil { - return err - } + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - // query cvm status - err = waitForOperationFinished(d, meta, 5*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) - if err != nil { - return err + immutableArgs := []string{"instance_count", "stopped_mode", "spot_instance_type", "internet_charge_type", "bandwidth_package_id", "system_disk_id", "force_delete"} + for _, v := range immutableArgs { + if d.HasChange(v) { + return fmt.Errorf("argument `%s` cannot be changed", v) } - - periodSet = true - renewFlagSet = true } + instanceId := d.Id() - // When instance is prepaid but period was empty and set to 1, skip this case. - op, np := d.GetChange("instance_charge_type_prepaid_period") - if _, ok := op.(int); !ok && np.(int) == 1 { - periodSet = true + if err := resourceTencentCloudInstanceUpdateOnStart(ctx); err != nil { + return err } - if d.HasChange("instance_charge_type_prepaid_period") && !periodSet { - chargeType := d.Get("instance_charge_type").(string) - period := d.Get("instance_charge_type_prepaid_period").(int) - renewFlag := "" - - if v, ok := d.GetOk("instance_charge_type_prepaid_renew_flag"); ok { - renewFlag = v.(string) + needChange := false + mutableArgs := []string{"instance_name"} + for _, v := range mutableArgs { + if d.HasChange(v) { + needChange = true + break } + } - err := cvmService.ModifyInstanceChargeType(ctx, instanceId, chargeType, period, renewFlag) - if err != nil { - return err - } + if needChange { + request := cvmv20170312.NewModifyInstancesAttributeRequest() - // query cvm status - err = waitForOperationFinished(d, meta, 5*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) - if err != nil { - return err - } + request.InstanceIds = []*string{helper.String(instanceId)} - renewFlagSet = true - } - - if d.HasChange("instance_charge_type_prepaid_renew_flag") && !renewFlagSet { - //renew api - err := cvmService.ModifyRenewParam(ctx, instanceId, d.Get("instance_charge_type_prepaid_renew_flag").(string)) - if err != nil { - return err + if v, ok := d.GetOk("instance_name"); ok { + request.InstanceName = helper.String(v.(string)) } - //check success - err = waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmV20170312Client().ModifyInstancesAttributeWithContext(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 instance failed, reason:%+v", logId, err) return err } - - time.Sleep(tccommon.ReadRetryTimeout) } - if d.HasChange("instance_name") { - err := cvmService.ModifyInstanceName(ctx, instanceId, d.Get("instance_name").(string)) - if err != nil { - return err + needChange1 := false + mutableArgs1 := []string{"disable_api_termination"} + for _, v := range mutableArgs1 { + if d.HasChange(v) { + needChange1 = true + break } } - if d.HasChange("disable_api_termination") { - err := cvmService.ModifyDisableApiTermination(ctx, instanceId, d.Get("disable_api_termination").(bool)) - if err != nil { - return err - } - } + if needChange1 { + request1 := cvmv20170312.NewModifyInstancesAttributeRequest() - if d.HasChange("security_groups") { - securityGroups := d.Get("security_groups").(*schema.Set).List() - securityGroupIds := make([]*string, 0, len(securityGroups)) - for _, securityGroup := range securityGroups { - securityGroupIds = append(securityGroupIds, helper.String(securityGroup.(string))) - } + request1.InstanceIds = []*string{helper.String(instanceId)} - err := cvmService.ModifySecurityGroups(ctx, instanceId, securityGroupIds) - if err != nil { - return err - } - } - - if d.HasChange("orderly_security_groups") { - orderlySecurityGroups := d.Get("orderly_security_groups").([]interface{}) - orderlySecurityGroupIds := make([]*string, 0, len(orderlySecurityGroups)) - for _, securityGroup := range orderlySecurityGroups { - orderlySecurityGroupIds = append(orderlySecurityGroupIds, helper.String(securityGroup.(string))) + if v, ok := d.GetOkExists("disable_api_termination"); ok { + request1.DisableApiTermination = helper.Bool(v.(bool)) } - err := cvmService.ModifySecurityGroups(ctx, instanceId, orderlySecurityGroupIds) + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmV20170312Client().ModifyInstancesAttributeWithContext(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 instance failed, reason:%+v", logId, err) return err } } - if d.HasChange("project_id") { - projectId := d.Get("project_id").(int) - err := cvmService.ModifyProjectId(ctx, instanceId, int64(projectId)) - if err != nil { - return err + needChange2 := false + mutableArgs2 := []string{"security_groups"} + for _, v := range mutableArgs2 { + if d.HasChange(v) { + needChange2 = true + break } } - // Reset Instance - // Keep Login Info - if d.HasChange("image_id") || - d.HasChange("hostname") || - d.HasChange("disable_security_service") || - d.HasChange("disable_monitor_service") || - d.HasChange("keep_image_login") { + if needChange2 { + request2 := cvmv20170312.NewModifyInstancesAttributeRequest() - request := cvm.NewResetInstanceRequest() - request.InstanceId = helper.String(d.Id()) + request2.InstanceIds = []*string{helper.String(instanceId)} - if v, ok := d.GetOk("image_id"); ok { - request.ImageId = helper.String(v.(string)) - } - - if v, ok := d.GetOk("hostname"); ok { - request.HostName = helper.String(v.(string)) - } - - // enhanced service - request.EnhancedService = &cvm.EnhancedService{} - if d.HasChange("disable_security_service") { - v := d.Get("disable_security_service") - securityService := v.(bool) - request.EnhancedService.SecurityService = &cvm.RunSecurityServiceEnabled{ - Enabled: &securityService, + if v, ok := d.GetOk("security_groups"); ok { + securityGroupsSet := v.(*schema.Set).List() + for i := range securityGroupsSet { + securityGroups := securityGroupsSet[i].(string) + request2.SecurityGroups = append(request2.SecurityGroups, helper.String(securityGroups)) } } - if d.HasChange("disable_monitor_service") { - v := d.Get("disable_monitor_service") - monitorService := !(v.(bool)) - request.EnhancedService.MonitorService = &cvm.RunMonitorServiceEnabled{ - Enabled: &monitorService, + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmV20170312Client().ModifyInstancesAttributeWithContext(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()) } - } - - // Modify or keep login info when instance reset - request.LoginSettings = &cvm.LoginSettings{} - - if v, ok := d.GetOk("password"); ok { - request.LoginSettings.Password = helper.String(v.(string)) - } - - if v, ok := d.GetOk("key_ids"); ok { - request.LoginSettings.KeyIds = helper.InterfacesStringsPoint(v.(*schema.Set).List()) - } else if v, ok := d.GetOk("key_name"); ok { - request.LoginSettings.KeyIds = []*string{helper.String(v.(string))} - } - - if v := d.Get("keep_image_login").(bool); v { - request.LoginSettings.KeepImageLogin = helper.String(CVM_IMAGE_LOGIN) - } else { - request.LoginSettings.KeepImageLogin = helper.String(CVM_IMAGE_LOGIN_NOT) - } - - if err := cvmService.ResetInstance(ctx, request); err != nil { + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s update instance failed, reason:%+v", logId, err) return err } - // Modify Login Info Directly - } else { - if d.HasChange("password") { - err := cvmService.ModifyPassword(ctx, instanceId, d.Get("password").(string)) - if err != nil { - return err - } + } - err = waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) - if err != nil { - return err - } + needChange3 := false + mutableArgs3 := []string{"orderly_security_groups"} + for _, v := range mutableArgs3 { + if d.HasChange(v) { + needChange3 = true + break } + } - if d.HasChange("key_name") { - o, n := d.GetChange("key_name") - oldKeyId := o.(string) - keyId := n.(string) - - if oldKeyId != "" { - err := cvmService.UnbindKeyPair(ctx, []*string{&oldKeyId}, []*string{&instanceId}) - if err != nil { - return err - } - - err = waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) - if err != nil { - return err - } - } + if needChange3 { + request3 := cvmv20170312.NewModifyInstancesAttributeRequest() - if keyId != "" { - err = cvmService.BindKeyPair(ctx, []*string{&keyId}, instanceId) - if err != nil { - return err - } + request3.InstanceIds = []*string{helper.String(instanceId)} - err = waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) - if err != nil { - return err - } + if v, ok := d.GetOk("orderly_security_groups"); ok { + securityGroupsSet := v.([]interface{}) + for i := range securityGroupsSet { + securityGroups := securityGroupsSet[i].(string) + request3.SecurityGroups = append(request3.SecurityGroups, helper.String(securityGroups)) } } - // support remove old `key_name` to `key_ids`, so do not follow "else" - if d.HasChange("key_ids") { - o, n := d.GetChange("key_ids") - ov := o.(*schema.Set) - nv := n.(*schema.Set) - adds := nv.Difference(ov) - removes := ov.Difference(nv) - adds.Remove("") - removes.Remove("") - - if removes.Len() > 0 { - err := cvmService.UnbindKeyPair(ctx, helper.InterfacesStringsPoint(removes.List()), []*string{&instanceId}) - if err != nil { - return err - } - - err = waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) - if err != nil { - return err - } - } - - if adds.Len() > 0 { - err = cvmService.BindKeyPair(ctx, helper.InterfacesStringsPoint(adds.List()), instanceId) - if err != nil { - return err - } - - err = waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) - if err != nil { - return err - } + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmV20170312Client().ModifyInstancesAttributeWithContext(ctx, request3) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request3.GetAction(), request3.ToJsonString(), result.ToJsonString()) } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s update instance failed, reason:%+v", logId, err) + return err } } - if d.HasChange("data_disks") { - o, n := d.GetChange("data_disks") - ov := o.([]interface{}) - nv := n.([]interface{}) - - if len(ov) != len(nv) { - return fmt.Errorf("error: data disk count has changed (%d -> %d) but doesn't support add or remove for now", len(ov), len(nv)) - } - - cbsService := svccbs.NewCbsService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) - - for i := range nv { - sizeKey := fmt.Sprintf("data_disks.%d.data_disk_size", i) - idKey := fmt.Sprintf("data_disks.%d.data_disk_id", i) - if !d.HasChange(sizeKey) { - continue - } - - size := d.Get(sizeKey).(int) - diskId := d.Get(idKey).(string) - err := cbsService.ResizeDisk(ctx, diskId, size) - if err != nil { - return fmt.Errorf("an error occurred when modifying %s, reason: %s", sizeKey, err.Error()) - } + needChange4 := false + mutableArgs4 := []string{"project_id"} + for _, v := range mutableArgs4 { + if d.HasChange(v) { + needChange4 = true + break } } - var flag bool - if d.HasChange("running_flag") { - flag = d.Get("running_flag").(bool) - if err := switchInstance(&cvmService, ctx, d, flag); err != nil { - return err - } - } + if needChange4 { + request4 := cvmv20170312.NewModifyInstancesProjectRequest() - if d.HasChange("system_disk_size") || d.HasChange("system_disk_type") { - size := d.Get("system_disk_size").(int) - diskType := d.Get("system_disk_type").(string) - //diskId := d.Get("system_disk_id").(string) - req := cvm.NewResizeInstanceDisksRequest() - req.InstanceId = &instanceId - req.ForceStop = helper.Bool(true) - req.SystemDisk = &cvm.SystemDisk{ - DiskSize: helper.IntInt64(size), - DiskType: &diskType, - } - if v, ok := d.GetOkExists("system_disk_resize_online"); ok { - req.ResizeOnline = helper.Bool(v.(bool)) - } + request4.InstanceIds = []*string{helper.String(instanceId)} - err := cvmService.ResizeInstanceDisks(ctx, req) - if err != nil { - return fmt.Errorf("an error occurred when modifying system_disk, reason: %s", err.Error()) + if v, ok := d.GetOkExists("project_id"); ok { + request4.ProjectId = helper.IntInt64(v.(int)) } - err = resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - instance, err := cvmService.DescribeInstanceById(ctx, instanceId) - if err != nil { - return resource.NonRetryableError(err) - } - - if instance != nil && instance.LatestOperationState != nil { - if *instance.InstanceState == "FAILED" { - return resource.NonRetryableError(fmt.Errorf("instance operation failed")) - } - - if *instance.InstanceState == "OPERATING" { - return resource.RetryableError(fmt.Errorf("instance operating")) - } - } - - if instance != nil && instance.SystemDisk != nil { - //wait until disk result as expected - if *instance.SystemDisk.DiskType != diskType || int(*instance.SystemDisk.DiskSize) != size { - return resource.RetryableError(fmt.Errorf("waiting for expanding success")) - } + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmV20170312Client().ModifyInstancesProjectWithContext(ctx, request4) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request4.GetAction(), request4.ToJsonString(), result.ToJsonString()) } - return nil }) - if err != nil { + log.Printf("[CRITAL]%s update instance failed, reason:%+v", logId, err) return err } } - if d.HasChange("instance_type") { - err := cvmService.ModifyInstanceType(ctx, instanceId, d.Get("instance_type").(string)) - if err != nil { - return err - } - - err = waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) - if err != nil { - return err + needChange5 := false + mutableArgs5 := []string{"system_disk_size", "system_disk_type"} + for _, v := range mutableArgs5 { + if d.HasChange(v) { + needChange5 = true + break } } - if d.HasChange("cdh_instance_type") { - err := cvmService.ModifyInstanceType(ctx, instanceId, d.Get("cdh_instance_type").(string)) - if err != nil { - return err - } - - err = waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) - if err != nil { - return err - } - } + if needChange5 { + request5 := cvmv20170312.NewResizeInstanceDisksRequest() - if d.HasChange("vpc_id") || d.HasChange("subnet_id") || d.HasChange("private_ip") { - vpcId := d.Get("vpc_id").(string) - subnetId := d.Get("subnet_id").(string) - privateIp := d.Get("private_ip").(string) - err := cvmService.ModifyVpc(ctx, instanceId, vpcId, subnetId, privateIp) - if err != nil { - return err - } - } + response5 := cvmv20170312.NewResizeInstanceDisksResponse() - if d.HasChange("tags") { - oldInterface, newInterface := d.GetChange("tags") - replaceTags, deleteTags := svctag.DiffTags(oldInterface.(map[string]interface{}), newInterface.(map[string]interface{})) - tagService := svctag.NewTagService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) - region := meta.(tccommon.ProviderMeta).GetAPIV3Conn().Region - resourceName := tccommon.BuildTagResourceName("cvm", "instance", region, instanceId) - err := tagService.ModifyTags(ctx, resourceName, replaceTags, deleteTags) - if err != nil { - return err - } + request5.InstanceId = helper.String(instanceId) - //except instance ,system disk and data disk will be tagged - //keep logical consistence with the console - //tag system disk - if systemDiskId, ok := d.GetOk("system_disk_id"); ok { - if systemDiskId.(string) != "" { - resourceName = tccommon.BuildTagResourceName("cvm", "volume", region, systemDiskId.(string)) - if err := tagService.ModifyTags(ctx, resourceName, replaceTags, deleteTags); err != nil { - return err - } - } - } + forceStop := true + request5.ForceStop = &forceStop - //tag disk ids - if dataDisks, ok := d.GetOk("data_disks"); ok { - dataDiskList := dataDisks.([]interface{}) - for _, dataDisk := range dataDiskList { - disk := dataDisk.(map[string]interface{}) - dataDiskId := disk["data_disk_id"].(string) - resourceName = tccommon.BuildTagResourceName("cvm", "volume", region, dataDiskId) - if err := tagService.ModifyTags(ctx, resourceName, replaceTags, deleteTags); err != nil { - return err - } - } + systemDisk := cvmv20170312.SystemDisk{} + if v, ok := d.GetOkExists("system_disk_size"); ok { + systemDisk.DiskSize = helper.IntInt64(v.(int)) } - } - - if d.HasChange("internet_max_bandwidth_out") { - chargeType := d.Get("internet_charge_type").(string) - bandWidthOut := int64(d.Get("internet_max_bandwidth_out").(int)) - if chargeType != "TRAFFIC_POSTPAID_BY_HOUR" && chargeType != "BANDWIDTH_POSTPAID_BY_HOUR" && chargeType != "BANDWIDTH_PACKAGE" { - return fmt.Errorf("charge type should be one of `TRAFFIC_POSTPAID_BY_HOUR BANDWIDTH_POSTPAID_BY_HOUR BANDWIDTH_PACKAGE` when adjusting internet_max_bandwidth_out") + if v, ok := d.GetOk("system_disk_type"); ok { + systemDisk.DiskType = helper.String(v.(string)) } + request5.SystemDisk = &systemDisk - err := cvmService.ModifyInternetMaxBandwidthOut(ctx, instanceId, chargeType, bandWidthOut) + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmV20170312Client().ResizeInstanceDisksWithContext(ctx, request5) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request5.GetAction(), request5.ToJsonString(), result.ToJsonString()) + } + return nil + }) if err != nil { + log.Printf("[CRITAL]%s update instance failed, reason:%+v", logId, err) return err } - - err = waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) - if err != nil { + if err := resourceTencentCloudInstanceUpdatePreHandleResponse5(ctx, response5); err != nil { return err } - } - d.Partial(false) - - return resourceTencentCloudInstanceRead(d, meta) -} - -func resourceTencentCloudInstanceDelete(d *schema.ResourceData, meta interface{}) error { - defer tccommon.LogElapsed("resource.tencentcloud_instance.delete")() - - var ( - logId = tccommon.GetLogId(tccommon.ContextNil) - ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - cvmService = CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - ) - - instanceId := d.Id() - //check is force delete or not - forceDelete := d.Get("force_delete").(bool) - instanceChargeType := d.Get("instance_charge_type").(string) - - instance, err := cvmService.DescribeInstanceById(ctx, instanceId) - if err != nil { - return err } - err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - errRet := cvmService.DeleteInstance(ctx, instanceId) - if errRet != nil { - return tccommon.RetryError(errRet) + needChange6 := false + mutableArgs6 := []string{"instance_type"} + for _, v := range mutableArgs6 { + if d.HasChange(v) { + needChange6 = true + break } - - return nil - }) - - if err != nil { - return err } - //check recycling - notExist := false + if needChange6 { + request6 := cvmv20170312.NewResetInstancesTypeRequest() - //check exist - err = resource.Retry(5*tccommon.ReadRetryTimeout, func() *resource.RetryError { - instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) - } + response6 := cvmv20170312.NewResetInstancesTypeResponse() - if instance == nil { - notExist = true - return nil - } + request6.InstanceIds = []*string{helper.String(instanceId)} - if *instance.InstanceState == CVM_STATUS_SHUTDOWN && *instance.LatestOperationState != CVM_LATEST_OPERATION_STATE_OPERATING { - //in recycling - return nil + if v, ok := d.GetOk("instance_type"); ok { + request6.InstanceType = helper.String(v.(string)) } - return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState)) - }) - - if err != nil { - return err - } - - vpcService := vpc.NewVpcService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) - if notExist { - err := waitIpRelease(ctx, vpcService, instance) + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmV20170312Client().ResetInstancesTypeWithContext(ctx, request6) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request6.GetAction(), request6.ToJsonString(), result.ToJsonString()) + } + return nil + }) if err != nil { + log.Printf("[CRITAL]%s update instance failed, reason:%+v", logId, err) + return err + } + if err := resourceTencentCloudInstanceUpdatePreHandleResponse6(ctx, response6); err != nil { return err } - return nil } - if instanceChargeType == CVM_CHARGE_TYPE_PREPAID { - if v, ok := d.GetOk("data_disks"); ok { - dataDisks := v.([]interface{}) - for _, d := range dataDisks { - value := d.(map[string]interface{}) - deleteWithInstancePrepaid := value["delete_with_instance_prepaid"].(bool) - if deleteWithInstancePrepaid { - diskId := value["data_disk_id"].(string) - cbsService := svccbs.NewCbsService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) - err = resource.Retry(tccommon.ReadRetryTimeout*2, func() *resource.RetryError { - diskInfo, e := cbsService.DescribeDiskById(ctx, diskId) - if e != nil { - return tccommon.RetryError(e, tccommon.InternalError) - } - - if *diskInfo.DiskState != svccbs.CBS_STORAGE_STATUS_ATTACHED { - return resource.RetryableError(fmt.Errorf("cbs storage status is %s", *diskInfo.DiskState)) - } - - return nil - }) - - if err != nil { - log.Printf("[CRITAL]%s delete cbs failed, reason:%s\n ", logId, err.Error()) - return err - } - - err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - e := cbsService.DetachDisk(ctx, diskId, instanceId) - if e != nil { - return tccommon.RetryError(e, tccommon.InternalError) - } - - return nil - }) - - if err != nil { - log.Printf("[CRITAL]%s detach cbs failed, reason:%s\n ", logId, err.Error()) - return err - } - - err = resource.Retry(tccommon.ReadRetryTimeout*2, func() *resource.RetryError { - diskInfo, e := cbsService.DescribeDiskById(ctx, diskId) - if e != nil { - return tccommon.RetryError(e, tccommon.InternalError) - } - - if *diskInfo.DiskState != svccbs.CBS_STORAGE_STATUS_UNATTACHED { - return resource.RetryableError(fmt.Errorf("cbs storage status is %s", *diskInfo.DiskState)) - } - - return nil - }) - - if err != nil { - log.Printf("[CRITAL]%s read cbs status failed, reason:%s\n ", logId, err.Error()) - return err - } - - err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - e := cbsService.DeleteDiskById(ctx, diskId) - if e != nil { - return tccommon.RetryError(e, tccommon.InternalError) - } - - return nil - }) - - if err != nil { - log.Printf("[CRITAL]%s delete cbs failed, reason:%s\n ", logId, err.Error()) - return err - } - - err = resource.Retry(tccommon.ReadRetryTimeout*2, func() *resource.RetryError { - diskInfo, e := cbsService.DescribeDiskById(ctx, diskId) - if e != nil { - return tccommon.RetryError(e, tccommon.InternalError) - } - - if *diskInfo.DiskState != svccbs.CBS_STORAGE_STATUS_TORECYCLE { - return resource.RetryableError(fmt.Errorf("cbs storage status is %s", *diskInfo.DiskState)) - } - - return nil - }) - - if err != nil { - log.Printf("[CRITAL]%s read cbs status failed, reason:%s\n ", logId, err.Error()) - return err - } - } - } + needChange7 := false + mutableArgs7 := []string{"cdh_instance_type"} + for _, v := range mutableArgs7 { + if d.HasChange(v) { + needChange7 = true + break } } - if !forceDelete { - return nil - } - - // exist in recycle, delete again - err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - errRet := cvmService.DeleteInstance(ctx, instanceId) - //when state is terminating, do not delete but check exist - if errRet != nil { - //check InvalidInstanceState.Terminating - ee, ok := errRet.(*sdkErrors.TencentCloudSDKError) - if !ok { - return tccommon.RetryError(errRet) - } - - if ee.Code == "InvalidInstanceState.Terminating" { - return nil - } + if needChange7 { + request7 := cvmv20170312.NewResetInstancesTypeRequest() - return tccommon.RetryError(errRet, "OperationDenied.InstanceOperationInProgress") - } - - return nil - }) + response7 := cvmv20170312.NewResetInstancesTypeResponse() - if err != nil { - return err - } + request7.InstanceIds = []*string{helper.String(instanceId)} - //describe and check not exist - err = resource.Retry(5*tccommon.ReadRetryTimeout, func() *resource.RetryError { - instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) + if v, ok := d.GetOk("cdh_instance_type"); ok { + request7.InstanceType = helper.String(v.(string)) } - if instance == nil { + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmV20170312Client().ResetInstancesTypeWithContext(ctx, request7) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request7.GetAction(), request7.ToJsonString(), result.ToJsonString()) + } return nil + }) + if err != nil { + log.Printf("[CRITAL]%s update instance failed, reason:%+v", logId, err) + return err + } + if err := resourceTencentCloudInstanceUpdatePreHandleResponse7(ctx, response7); err != nil { + return err } - return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState)) - }) - - if err != nil { - return err } - if v, ok := d.GetOk("data_disks"); ok { - dataDisks := v.([]interface{}) - for _, d := range dataDisks { - value := d.(map[string]interface{}) - diskId := value["data_disk_id"].(string) - deleteWithInstance := value["delete_with_instance"].(bool) - if deleteWithInstance && instanceChargeType == CVM_CHARGE_TYPE_POSTPAID { - cbsService := svccbs.NewCbsService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) - err = resource.Retry(tccommon.ReadRetryTimeout*2, func() *resource.RetryError { - diskInfo, e := cbsService.DescribeDiskById(ctx, diskId) - if e != nil { - return tccommon.RetryError(e, tccommon.InternalError) - } - - if *diskInfo.DiskState != svccbs.CBS_STORAGE_STATUS_UNATTACHED { - return resource.RetryableError(fmt.Errorf("cbs storage status is %s", *diskInfo.DiskState)) - } - - return nil - }) - - if err != nil { - log.Printf("[CRITAL]%s delete cbs failed, reason:%s\n ", logId, err.Error()) - return err - } - - err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - e := cbsService.DeleteDiskById(ctx, diskId) - if e != nil { - return tccommon.RetryError(e, tccommon.InternalError) - } - - return nil - }) - - if err != nil { - log.Printf("[CRITAL]%s delete cbs failed, reason:%s\n ", logId, err.Error()) - return err - } - - err = resource.Retry(tccommon.ReadRetryTimeout*2, func() *resource.RetryError { - diskInfo, e := cbsService.DescribeDiskById(ctx, diskId) - if e != nil { - return tccommon.RetryError(e, tccommon.InternalError) - } - - if *diskInfo.DiskState == svccbs.CBS_STORAGE_STATUS_TORECYCLE { - return resource.RetryableError(fmt.Errorf("cbs storage status is %s", *diskInfo.DiskState)) - } - - return nil - }) - - if err != nil { - log.Printf("[CRITAL]%s read cbs status failed, reason:%s\n ", logId, err.Error()) - return err - } - - err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - e := cbsService.DeleteDiskById(ctx, diskId) - if e != nil { - return tccommon.RetryError(e, tccommon.InternalError) - } - - return nil - }) - - if err != nil { - log.Printf("[CRITAL]%s delete cbs failed, reason:%s\n ", logId, err.Error()) - return err - } - err = resource.Retry(tccommon.ReadRetryTimeout*2, func() *resource.RetryError { - diskInfo, e := cbsService.DescribeDiskById(ctx, diskId) - if e != nil { - return tccommon.RetryError(e, tccommon.InternalError) - } - - if diskInfo != nil { - return resource.RetryableError(fmt.Errorf("cbs storage status is %s", *diskInfo.DiskState)) - } - - return nil - }) - - if err != nil { - log.Printf("[CRITAL]%s read cbs status failed, reason:%s\n ", logId, err.Error()) - return err - } - } - - deleteWithInstancePrepaid := value["delete_with_instance_prepaid"].(bool) - if deleteWithInstancePrepaid && instanceChargeType == CVM_CHARGE_TYPE_PREPAID { - cbsService := svccbs.NewCbsService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) - err = resource.Retry(tccommon.ReadRetryTimeout*2, func() *resource.RetryError { - diskInfo, e := cbsService.DescribeDiskById(ctx, diskId) - if e != nil { - return tccommon.RetryError(e, tccommon.InternalError) - } - - if *diskInfo.DiskState != svccbs.CBS_STORAGE_STATUS_TORECYCLE { - return resource.RetryableError(fmt.Errorf("cbs storage status is %s", *diskInfo.DiskState)) - } - - return nil - }) - - if err != nil { - log.Printf("[CRITAL]%s delete cbs failed, reason:%s\n ", logId, err.Error()) - return err - } - - err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - e := cbsService.DeleteDiskById(ctx, diskId) - if e != nil { - return tccommon.RetryError(e, tccommon.InternalError) - } - - return nil - }) - - if err != nil { - log.Printf("[CRITAL]%s delete cbs failed, reason:%s\n ", logId, err.Error()) - return err - } - - err = resource.Retry(tccommon.ReadRetryTimeout*2, func() *resource.RetryError { - diskInfo, e := cbsService.DescribeDiskById(ctx, diskId) - if e != nil { - return tccommon.RetryError(e, tccommon.InternalError) - } - - if diskInfo != nil { - return resource.RetryableError(fmt.Errorf("cbs storage status is %s", *diskInfo.DiskState)) - } - - return nil - }) - - if err != nil { - log.Printf("[CRITAL]%s read cbs status failed, reason:%s\n ", logId, err.Error()) - return err - } - } + needChange8 := false + mutableArgs8 := []string{"vpc_id", "subnet_id"} + for _, v := range mutableArgs8 { + if d.HasChange(v) { + needChange8 = true + break } } - err = waitIpRelease(ctx, vpcService, instance) - if err != nil { - return err - } + if needChange8 { + request8 := cvmv20170312.NewModifyInstancesVpcAttributeRequest() - return nil -} + request8.InstanceIds = []*string{helper.String(instanceId)} -func switchInstance(cvmService *CvmService, ctx context.Context, d *schema.ResourceData, flag bool) (err error) { - instanceId := d.Id() - if flag { - err = cvmService.StartInstance(ctx, instanceId) - if err != nil { - return err + virtualPrivateCloud := cvmv20170312.VirtualPrivateCloud{} + if v, ok := d.GetOk("vpc_id"); ok { + virtualPrivateCloud.VpcId = helper.String(v.(string)) } + if v, ok := d.GetOk("subnet_id"); ok { + virtualPrivateCloud.SubnetId = helper.String(v.(string)) + } + request8.VirtualPrivateCloud = &virtualPrivateCloud - err = resource.Retry(2*tccommon.ReadRetryTimeout, func() *resource.RetryError { - instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) - } - - if instance != nil && *instance.InstanceState == CVM_STATUS_RUNNING { - return nil - } - - return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState)) - }) - - if err != nil { + if err := resourceTencentCloudInstanceUpdatePostFillRequest8(ctx, request8); err != nil { return err } - } else { - stoppedMode := d.Get("stopped_mode").(string) - skipStopApi := false - err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - // when retry polling instance status, stop instance should skipped - if !skipStopApi { - err := cvmService.StopInstance(ctx, instanceId, stoppedMode) - if err != nil { - return resource.NonRetryableError(err) - } - } - - instance, err := cvmService.DescribeInstanceById(ctx, instanceId) - if err != nil { - return resource.NonRetryableError(err) - } - - if instance == nil { - return resource.NonRetryableError(fmt.Errorf("instance %s not found", instanceId)) - } - if instance.LatestOperationState != nil { - operationState := *instance.LatestOperationState - if operationState == "OPERATING" { - skipStopApi = true - return resource.RetryableError(fmt.Errorf("instance %s stop operating, retrying", instanceId)) - } - - if operationState == "FAILED" { - skipStopApi = false - return resource.RetryableError(fmt.Errorf("instance %s stop failed, retrying", instanceId)) - } + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmV20170312Client().ModifyInstancesVpcAttributeWithContext(ctx, request8) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request8.GetAction(), request8.ToJsonString(), result.ToJsonString()) } - return nil }) - if err != nil { + log.Printf("[CRITAL]%s update instance failed, reason:%+v", logId, err) return err } + } - err = resource.Retry(2*tccommon.ReadRetryTimeout, func() *resource.RetryError { - instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) - } - - if instance != nil && *instance.InstanceState == CVM_STATUS_STOPPED { - return nil - } - - return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState)) - }) - - if err != nil { - return err - } + if err := resourceTencentCloudInstanceUpdateOnExit(ctx); err != nil { + return err } - return nil + return resourceTencentCloudInstanceRead(d, meta) } -func waitForOperationFinished(d *schema.ResourceData, meta interface{}, timeout time.Duration, state string, immediately bool) error { +func resourceTencentCloudInstanceDelete(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_instance.delete")() + defer tccommon.InconsistentCheck(d, meta)() + logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() - cvmService := CvmService{client} - instanceId := d.Id() - // We cannot catch LatestOperationState change immediately after modification returns, we must wait for LatestOperationState update to expected. - if !immediately { - time.Sleep(time.Second * 10) - } + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) - err := resource.Retry(timeout, func() *resource.RetryError { - instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) - } + instanceId := d.Id() - if instance == nil { - return resource.NonRetryableError(fmt.Errorf("%s not exists", instanceId)) - } + var ( + request = cvmv20170312.NewTerminateInstancesRequest() + response = cvmv20170312.NewTerminateInstancesResponse() + ) - if instance.LatestOperationState == nil { - return resource.RetryableError(fmt.Errorf("wait for operation update")) - } + request.InstanceIds = []*string{helper.String(instanceId)} - if *instance.LatestOperationState == state { - return resource.RetryableError(fmt.Errorf("waiting for instance %s operation", instanceId)) - } + if err := resourceTencentCloudInstanceDeletePostFillRequest0(ctx, request); err != nil { + return err + } - if *instance.LatestOperationState == CVM_LATEST_OPERATION_STATE_FAILED { - return resource.NonRetryableError(fmt.Errorf("failed operation")) + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmV20170312Client().TerminateInstancesWithContext(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 instance failed, reason:%+v", logId, err) return err } - return nil -} - -func waitIpRelease(ctx context.Context, vpcService vpc.VpcService, instance *cvm.Instance) error { - // wait ip release - if len(instance.PrivateIpAddresses) > 0 { - params := make(map[string]interface{}) - params["VpcId"] = instance.VirtualPrivateCloud.VpcId - params["SubnetId"] = instance.VirtualPrivateCloud.SubnetId - params["IpAddresses"] = instance.PrivateIpAddresses - err := resource.Retry(5*tccommon.ReadRetryTimeout, func() *resource.RetryError { - usedIpAddress, errRet := vpcService.DescribeVpcUsedIpAddressByFilter(ctx, params) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) - } - - if len(usedIpAddress) > 0 { - return resource.RetryableError(fmt.Errorf("wait cvm private ip release...")) - } - - return nil - }) - - if err != nil { - return err - } + if err := resourceTencentCloudInstanceDeletePreHandleResponse0(ctx, response); err != nil { + return err } + _ = response return nil } diff --git a/tencentcloud/services/cvm/resource_tc_instance_extension.go b/tencentcloud/services/cvm/resource_tc_instance_extension.go new file mode 100644 index 0000000000..d4e1d503a7 --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_instance_extension.go @@ -0,0 +1,1183 @@ +package cvm + +import ( + "context" + "encoding/base64" + "fmt" + "log" + "sort" + "strconv" + "strings" + "time" + + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/vpc" + + svccbs "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/cbs" + + svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag" + + sdkErrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" + + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/ratelimit" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" + + "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" +) + +func internetChargeType(k, oldValue, newValue string, d *schema.ResourceData) bool { + stopMode := d.Get("stopped_mode").(string) + if stopMode != CVM_STOP_MODE_STOP_CHARGING || !d.HasChange("running_flag") { + return oldValue == newValue + } + return oldValue == "" || newValue == "" +} + +func keepImageLogin(k, oldValue, newValue string, d *schema.ResourceData) bool { + if newValue == "false" && oldValue == "" || oldValue == "false" && newValue == "" { + return true + } else { + return oldValue == newValue + } +} + +func resourceTencentCloudInstanceCreatePostFillRequest0(ctx context.Context, req *cvm.RunInstancesRequest) error { + d := tccommon.ResourceDataFromContext(ctx) + + if v, ok := d.GetOk("instance_charge_type"); ok { + instanceChargeType := v.(string) + req.InstanceChargeType = &instanceChargeType + if instanceChargeType == CVM_CHARGE_TYPE_PREPAID || instanceChargeType == CVM_CHARGE_TYPE_UNDERWRITE { + req.InstanceChargePrepaid = &cvm.InstanceChargePrepaid{} + if period, ok := d.GetOk("instance_charge_type_prepaid_period"); ok { + periodInt64 := int64(period.(int)) + req.InstanceChargePrepaid.Period = &periodInt64 + } + if renewFlag, ok := d.GetOk("instance_charge_type_prepaid_renew_flag"); ok { + req.InstanceChargePrepaid.RenewFlag = helper.String(renewFlag.(string)) + } + } + if instanceChargeType == CVM_CHARGE_TYPE_SPOTPAID { + spotInstanceType, sitOk := d.GetOk("spot_instance_type") + spotMaxPrice, smpOk := d.GetOk("spot_max_price") + if sitOk || smpOk { + req.InstanceMarketOptions = &cvm.InstanceMarketOptionsRequest{} + req.InstanceMarketOptions.MarketType = helper.String(CVM_MARKET_TYPE_SPOT) + req.InstanceMarketOptions.SpotOptions = &cvm.SpotMarketOptions{} + } + if sitOk { + req.InstanceMarketOptions.SpotOptions.SpotInstanceType = helper.String(strings.ToLower(spotInstanceType.(string))) + } + if smpOk { + req.InstanceMarketOptions.SpotOptions.MaxPrice = helper.String(spotMaxPrice.(string)) + } + } + if instanceChargeType == CVM_CHARGE_TYPE_CDHPAID { + if v, ok := d.GetOk("cdh_instance_type"); ok { + req.InstanceType = helper.String(v.(string)) + } else { + return fmt.Errorf("cdh_instance_type can not be empty when instance_charge_type is %s", instanceChargeType) + } + if v, ok := d.GetOk("cdh_host_id"); ok { + req.Placement.HostIds = append(req.Placement.HostIds, helper.String(v.(string))) + } else { + return fmt.Errorf("cdh_host_id can not be empty when instance_charge_type is %s", instanceChargeType) + } + } + } + + if v, ok := d.GetOk("placement_group_id"); ok { + req.DisasterRecoverGroupIds = []*string{helper.String(v.(string))} + } + + if v, ok := d.GetOk("orderly_security_groups"); ok { + securityGroups := v.([]interface{}) + req.SecurityGroupIds = make([]*string, 0, len(securityGroups)) + for _, securityGroup := range securityGroups { + req.SecurityGroupIds = append(req.SecurityGroupIds, helper.String(securityGroup.(string))) + } + } + + // storage + if v, ok := d.GetOk("data_disks"); ok { + dataDisks := v.([]interface{}) + req.DataDisks = make([]*cvm.DataDisk, 0, len(dataDisks)) + for _, d := range dataDisks { + value := d.(map[string]interface{}) + diskType := value["data_disk_type"].(string) + diskSize := int64(value["data_disk_size"].(int)) + throughputPerformance := int64(value["throughput_performance"].(int)) + dataDisk := cvm.DataDisk{ + DiskType: &diskType, + DiskSize: &diskSize, + ThroughputPerformance: &throughputPerformance, + } + if v, ok := value["data_disk_snapshot_id"]; ok && v != nil { + snapshotId := v.(string) + if snapshotId != "" { + dataDisk.SnapshotId = helper.String(snapshotId) + } + } + if value["data_disk_id"] != "" { + dataDisk.DiskId = helper.String(value["data_disk_id"].(string)) + } + if deleteWithInstance, ok := value["delete_with_instance"]; ok { + deleteWithInstanceBool := deleteWithInstance.(bool) + dataDisk.DeleteWithInstance = &deleteWithInstanceBool + } + + if encrypt, ok := value["encrypt"]; ok { + encryptBool := encrypt.(bool) + dataDisk.Encrypt = &encryptBool + } + req.DataDisks = append(req.DataDisks, &dataDisk) + } + } + + // vpc + if v, ok := d.GetOk("vpc_id"); ok { + req.VirtualPrivateCloud = &cvm.VirtualPrivateCloud{} + req.VirtualPrivateCloud.VpcId = helper.String(v.(string)) + + if v, ok = d.GetOk("subnet_id"); ok { + req.VirtualPrivateCloud.SubnetId = helper.String(v.(string)) + } + + if v, ok = d.GetOk("private_ip"); ok { + req.VirtualPrivateCloud.PrivateIpAddresses = []*string{helper.String(v.(string))} + } + } + + // login + keyIds := d.Get("key_ids").(*schema.Set).List() + if len(keyIds) > 0 { + req.LoginSettings.KeyIds = helper.InterfacesStringsPoint(keyIds) + } else if v, ok := d.GetOk("key_name"); ok { + req.LoginSettings.KeyIds = []*string{helper.String(v.(string))} + } + v := d.Get("keep_image_login").(bool) + if v { + req.LoginSettings.KeepImageLogin = helper.String(CVM_IMAGE_LOGIN) + } else { + req.LoginSettings.KeepImageLogin = helper.String(CVM_IMAGE_LOGIN_NOT) + } + + if v, ok := d.GetOk("user_data_raw"); ok { + userData := base64.StdEncoding.EncodeToString([]byte(v.(string))) + req.UserData = &userData + } + + if v := helper.GetTags(d, "tags"); len(v) > 0 { + tags := make([]*cvm.Tag, 0) + for tagKey, tagValue := range v { + tag := cvm.Tag{ + Key: helper.String(tagKey), + Value: helper.String(tagValue), + } + tags = append(tags, &tag) + } + tagSpecification := cvm.TagSpecification{ + ResourceType: helper.String("instance"), + Tags: tags, + } + req.TagSpecification = append(req.TagSpecification, &tagSpecification) + } + + return nil +} + +func resourceTencentCloudInstanceCreatePreRequest0(ctx context.Context, req *cvm.RunInstancesRequest) *resource.RetryError { + ratelimit.Check("create") + return nil +} + +func resourceTencentCloudInstanceCreateRequestOnError0(ctx context.Context, req *cvm.RunInstancesRequest, e error) *resource.RetryError { + logId := ctx.Value(tccommon.LogIdKey) + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, req.GetAction(), req.ToJsonString(), e.Error()) + + err, ok := e.(*sdkErrors.TencentCloudSDKError) + if ok && tccommon.IsContains(CVM_RETRYABLE_ERROR, err.Code) { + return resource.RetryableError(fmt.Errorf("cvm create error: %s, retrying", err.Error())) + } + return resource.NonRetryableError(e) +} + +func resourceTencentCloudInstanceCreatePostHandleResponse0(ctx context.Context, resp *cvm.RunInstancesResponse) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + + cvmService := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + instanceId := *resp.Response.InstanceIdSet[0] + + err := resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { + instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId) + if errRet != nil { + return tccommon.RetryError(errRet, tccommon.InternalError) + } + if instance != nil && *instance.InstanceState == CVM_STATUS_LAUNCH_FAILED { + //LatestOperationCodeMode + return resource.NonRetryableError(fmt.Errorf("cvm instance %s launch failed, this resource will not be stored to tfstate and will auto removed\n.", *instance.InstanceId)) + } + if instance != nil && *instance.InstanceState == CVM_STATUS_RUNNING { + return nil + } + return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState)) + }) + + if err != nil { + return err + } + + // Wait for the tags attached to the vm since tags attachment it's async while vm creation. + if tags := helper.GetTags(d, "tags"); len(tags) > 0 { + tcClient := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + tagService := svctag.NewTagService(tcClient) + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + actualTags, e := tagService.DescribeResourceTags(ctx, "cvm", "instance", tcClient.Region, instanceId) + if e != nil { + return resource.RetryableError(e) + } + for tagKey, tagValue := range tags { + if v, ok := actualTags[tagKey]; !ok || v != tagValue { + return resource.RetryableError(fmt.Errorf("tag(%s, %s) modification is not completed", tagKey, tagValue)) + } + } + return nil + }) + if err != nil { + return err + } + } + + if !(d.Get("running_flag").(bool)) { + stoppedMode := d.Get("stopped_mode").(string) + err = cvmService.StopInstance(ctx, instanceId, stoppedMode) + if err != nil { + return err + } + + err = resource.Retry(2*tccommon.ReadRetryTimeout, func() *resource.RetryError { + instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId) + if errRet != nil { + return tccommon.RetryError(errRet, tccommon.InternalError) + } + if instance != nil && *instance.InstanceState == CVM_STATUS_STOPPED { + return nil + } + return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState)) + }) + if err != nil { + return err + } + } + + return nil +} + +func resourceTencentCloudInstanceReadRequestOnSuccess0(ctx context.Context, resp *cvm.Instance) *resource.RetryError { + if resp != nil && resp.LatestOperationState != nil && *resp.LatestOperationState == "OPERATING" { + return resource.RetryableError(fmt.Errorf("waiting for instance %s operation", *resp.InstanceId)) + } + return nil +} + +func resourceTencentCloudInstanceReadPreHandleResponse0(ctx context.Context, resp *cvm.Instance) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + instanceId := d.Id() + + if *resp.InstanceState == CVM_STATUS_LAUNCH_FAILED { + d.SetId("") + log.Printf("[CRITAL]instance %s not exist or launch failed", instanceId) + return nil + } + + var errRet error + var cvmImages []string + var response *cvm.DescribeImagesResponse + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + request := cvm.NewDescribeImagesRequest() + response, errRet = client.UseCvmClient().DescribeImages(request) + if errRet != nil { + return tccommon.RetryError(errRet, tccommon.InternalError) + } + if *response.Response.TotalCount > 0 { + for i := range response.Response.ImageSet { + image := response.Response.ImageSet[i] + cvmImages = append(cvmImages, *image.ImageId) + } + } + return nil + }) + if err != nil { + return err + } + + if d.Get("image_id").(string) == "" || resp.ImageId == nil || !tccommon.IsContains(cvmImages, *resp.ImageId) { + _ = d.Set("image_id", resp.ImageId) + } + + return nil +} + +func resourceTencentCloudInstanceReadPostHandleResponse0(ctx context.Context, resp *cvm.Instance) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + cbsService := svccbs.NewCbsService(client) + + instance := resp + + if *instance.InstanceChargeType == CVM_CHARGE_TYPE_CDHPAID { + _ = d.Set("cdh_instance_type", instance.InstanceType) + } + + if _, ok := d.GetOkExists("allocate_public_ip"); !ok { + _ = d.Set("allocate_public_ip", len(instance.PublicIpAddresses) > 0) + } + + tagService := svctag.NewTagService(client) + tags, err := tagService.DescribeResourceTags(ctx, "cvm", "instance", client.Region, d.Id()) + if err != nil { + return err + } + // as attachment add tencentcloud:autoscaling:auto-scaling-group-id tag automatically + // we should remove this tag, otherwise it will cause terraform state change + delete(tags, "tencentcloud:autoscaling:auto-scaling-group-id") + _ = d.Set("tags", tags) + + //set data_disks + var hasDataDisks, isCombineDataDisks bool + dataDiskList := make([]map[string]interface{}, 0, len(instance.DataDisks)) + diskSizeMap := map[string]*uint64{} + diskOrderMap := make(map[string]int) + + if _, ok := d.GetOk("data_disks"); ok { + hasDataDisks = true + } + if len(instance.DataDisks) > 0 { + var diskIds []*string + for i := range instance.DataDisks { + id := instance.DataDisks[i].DiskId + size := instance.DataDisks[i].DiskSize + if id == nil { + continue + } + if strings.HasPrefix(*id, "disk-") { + diskIds = append(diskIds, id) + } else { + diskSizeMap[*id] = helper.Int64Uint64(*size) + } + } + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + disks, err := cbsService.DescribeDiskList(ctx, diskIds) + if err != nil { + return resource.NonRetryableError(err) + } + for i := range disks { + disk := disks[i] + if *disk.DiskState == "EXPANDING" { + return resource.RetryableError(fmt.Errorf("data_disk[%d] is expending", i)) + } + diskSizeMap[*disk.DiskId] = disk.DiskSize + if hasDataDisks { + items := strings.Split(*disk.DiskName, "_") + diskOrder := items[len(items)-1] + diskOrderInt, err := strconv.Atoi(diskOrder) + if err != nil { + isCombineDataDisks = true + continue + } + diskOrderMap[*disk.DiskId] = diskOrderInt + } + } + return nil + }) + if err != nil { + return err + } + } + for _, disk := range instance.DataDisks { + dataDisk := make(map[string]interface{}, 5) + dataDisk["data_disk_id"] = disk.DiskId + if disk.DiskId == nil { + dataDisk["data_disk_size"] = disk.DiskSize + } else if size, ok := diskSizeMap[*disk.DiskId]; ok { + dataDisk["data_disk_size"] = size + } + dataDisk["data_disk_type"] = disk.DiskType + dataDisk["data_disk_snapshot_id"] = disk.SnapshotId + dataDisk["delete_with_instance"] = disk.DeleteWithInstance + dataDisk["encrypt"] = disk.Encrypt + dataDisk["throughput_performance"] = disk.ThroughputPerformance + dataDiskList = append(dataDiskList, dataDisk) + } + if hasDataDisks && !isCombineDataDisks { + sort.SliceStable(dataDiskList, func(idx1, idx2 int) bool { + dataDiskIdIdx1 := *dataDiskList[idx1]["data_disk_id"].(*string) + dataDiskIdIdx2 := *dataDiskList[idx2]["data_disk_id"].(*string) + return diskOrderMap[dataDiskIdIdx1] < diskOrderMap[dataDiskIdIdx2] + }) + } + _ = d.Set("data_disks", dataDiskList) + + if len(instance.PrivateIpAddresses) > 0 { + _ = d.Set("private_ip", instance.PrivateIpAddresses[0]) + } + if len(instance.PublicIpAddresses) > 0 { + _ = d.Set("public_ip", instance.PublicIpAddresses[0]) + } + if len(instance.LoginSettings.KeyIds) > 0 { + _ = d.Set("key_name", instance.LoginSettings.KeyIds[0]) + _ = d.Set("key_ids", instance.LoginSettings.KeyIds) + } else { + _ = d.Set("key_name", "") + _ = d.Set("key_ids", []*string{}) + } + if instance.LoginSettings.KeepImageLogin != nil { + _ = d.Set("keep_image_login", *instance.LoginSettings.KeepImageLogin == CVM_IMAGE_LOGIN) + } + + if *instance.InstanceState == CVM_STATUS_STOPPED { + _ = d.Set("running_flag", false) + } else { + _ = d.Set("running_flag", true) + } + + forceDelete := false + if v, ok := d.GetOkExists("force_delete"); ok { + forceDelete = v.(bool) + _ = d.Set("force_delete", forceDelete) + } + + return nil +} + +func resourceTencentCloudInstanceUpdateOnStart(ctx context.Context) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + cvmService := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + instanceId := d.Id() + + d.Partial(true) + + // Get the latest instance info from actual resource. + instanceInfo, err := cvmService.DescribeInstanceById(ctx, instanceId) + if err != nil { + return err + } + + var ( + periodSet = false + renewFlagSet = false + expectChargeType = CVM_CHARGE_TYPE_POSTPAID + currentChargeType = *instanceInfo.InstanceChargeType + ) + + chargeType, chargeOk := d.GetOk("instance_charge_type") + if chargeOk { + expectChargeType = chargeType.(string) + } + + if d.HasChange("instance_charge_type") && expectChargeType != currentChargeType { + var ( + period = -1 + renewFlag string + ) + + if v, ok := d.GetOk("instance_charge_type_prepaid_period"); ok { + period = v.(int) + } + if v, ok := d.GetOk("instance_charge_type_prepaid_renew_flag"); ok { + renewFlag = v.(string) + } + // change charge type + err := cvmService.ModifyInstanceChargeType(ctx, instanceId, expectChargeType, period, renewFlag) + if err != nil { + return err + } + // query cvm status + err = waitForOperationFinished(d, meta, 5*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) + if err != nil { + return err + } + periodSet = true + renewFlagSet = true + } + + // When instance is prepaid but period was empty and set to 1, skip this case. + op, np := d.GetChange("instance_charge_type_prepaid_period") + if _, ok := op.(int); !ok && np.(int) == 1 { + periodSet = true + } + if d.HasChange("instance_charge_type_prepaid_period") && !periodSet { + chargeType := d.Get("instance_charge_type").(string) + period := d.Get("instance_charge_type_prepaid_period").(int) + renewFlag := "" + + if v, ok := d.GetOk("instance_charge_type_prepaid_renew_flag"); ok { + renewFlag = v.(string) + } + err := cvmService.ModifyInstanceChargeType(ctx, instanceId, chargeType, period, renewFlag) + if err != nil { + return err + } + // query cvm status + err = waitForOperationFinished(d, meta, 5*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) + if err != nil { + return err + } + renewFlagSet = true + } + + if d.HasChange("instance_charge_type_prepaid_renew_flag") && !renewFlagSet { + //renew api + err := cvmService.ModifyRenewParam(ctx, instanceId, d.Get("instance_charge_type_prepaid_renew_flag").(string)) + if err != nil { + return err + } + + //check success + err = waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) + if err != nil { + return err + } + + time.Sleep(tccommon.ReadRetryTimeout) + } + + // Reset Instance + // Keep Login Info + if d.HasChange("image_id") || + d.HasChange("hostname") || + d.HasChange("disable_security_service") || + d.HasChange("disable_monitor_service") || + d.HasChange("keep_image_login") { + + request := cvm.NewResetInstanceRequest() + request.InstanceId = helper.String(d.Id()) + + if v, ok := d.GetOk("image_id"); ok { + request.ImageId = helper.String(v.(string)) + } + if v, ok := d.GetOk("hostname"); ok { + request.HostName = helper.String(v.(string)) + } + + // enhanced service + request.EnhancedService = &cvm.EnhancedService{} + if d.HasChange("disable_security_service") { + v := d.Get("disable_security_service") + securityService := v.(bool) + request.EnhancedService.SecurityService = &cvm.RunSecurityServiceEnabled{ + Enabled: &securityService, + } + } + + if d.HasChange("disable_monitor_service") { + v := d.Get("disable_monitor_service") + monitorService := !(v.(bool)) + request.EnhancedService.MonitorService = &cvm.RunMonitorServiceEnabled{ + Enabled: &monitorService, + } + } + + // Modify or keep login info when instance reset + request.LoginSettings = &cvm.LoginSettings{} + + if v, ok := d.GetOk("password"); ok { + request.LoginSettings.Password = helper.String(v.(string)) + } + + if v, ok := d.GetOk("key_ids"); ok { + request.LoginSettings.KeyIds = helper.InterfacesStringsPoint(v.(*schema.Set).List()) + } else if v, ok := d.GetOk("key_name"); ok { + request.LoginSettings.KeyIds = []*string{helper.String(v.(string))} + } + + if v := d.Get("keep_image_login").(bool); v { + request.LoginSettings.KeepImageLogin = helper.String(CVM_IMAGE_LOGIN) + } else { + request.LoginSettings.KeepImageLogin = helper.String(CVM_IMAGE_LOGIN_NOT) + } + + if err := cvmService.ResetInstance(ctx, request); err != nil { + return err + } + + // Modify Login Info Directly + } else { + if d.HasChange("password") { + err := cvmService.ModifyPassword(ctx, instanceId, d.Get("password").(string)) + if err != nil { + return err + } + err = waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) + if err != nil { + return err + } + } + + if d.HasChange("key_name") { + o, n := d.GetChange("key_name") + oldKeyId := o.(string) + keyId := n.(string) + + if oldKeyId != "" { + err := cvmService.UnbindKeyPair(ctx, []*string{&oldKeyId}, []*string{&instanceId}) + if err != nil { + return err + } + err = waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) + if err != nil { + return err + } + } + + if keyId != "" { + err = cvmService.BindKeyPair(ctx, []*string{&keyId}, instanceId) + if err != nil { + return err + } + err = waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) + if err != nil { + return err + } + } + } + + // support remove old `key_name` to `key_ids`, so do not follow "else" + if d.HasChange("key_ids") { + o, n := d.GetChange("key_ids") + ov := o.(*schema.Set) + + nv := n.(*schema.Set) + + adds := nv.Difference(ov) + removes := ov.Difference(nv) + adds.Remove("") + removes.Remove("") + + if removes.Len() > 0 { + err := cvmService.UnbindKeyPair(ctx, helper.InterfacesStringsPoint(removes.List()), []*string{&instanceId}) + if err != nil { + return err + } + err = waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) + if err != nil { + return err + } + } + if adds.Len() > 0 { + err = cvmService.BindKeyPair(ctx, helper.InterfacesStringsPoint(adds.List()), instanceId) + if err != nil { + return err + } + err = waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) + if err != nil { + return err + } + } + } + } + + if d.HasChange("data_disks") { + o, n := d.GetChange("data_disks") + ov := o.([]interface{}) + nv := n.([]interface{}) + + if len(ov) != len(nv) { + return fmt.Errorf("error: data disk count has changed (%d -> %d) but doesn't support add or remove for now", len(ov), len(nv)) + } + + cbsService := svccbs.NewCbsService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) + + for i := range nv { + sizeKey := fmt.Sprintf("data_disks.%d.data_disk_size", i) + idKey := fmt.Sprintf("data_disks.%d.data_disk_id", i) + if !d.HasChange(sizeKey) { + continue + } + size := d.Get(sizeKey).(int) + diskId := d.Get(idKey).(string) + + err := cbsService.ResizeDisk(ctx, diskId, size) + + if err != nil { + return fmt.Errorf("an error occurred when modifying %s, reason: %s", sizeKey, err.Error()) + } + + } + } + + var flag bool + if d.HasChange("running_flag") { + flag = d.Get("running_flag").(bool) + if err := switchInstance(&cvmService, ctx, d, flag); err != nil { + return err + } + + } + + return nil +} + +func waitForOperationFinished(d *schema.ResourceData, meta interface{}, timeout time.Duration, state string, immediately bool) error { + logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + cvmService := CvmService{client} + instanceId := d.Id() + // We cannot catch LatestOperationState change immediately after modification returns, we must wait for LatestOperationState update to expected. + if !immediately { + time.Sleep(time.Second * 10) + } + + err := resource.Retry(timeout, func() *resource.RetryError { + instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId) + if errRet != nil { + return tccommon.RetryError(errRet, tccommon.InternalError) + } + if instance == nil { + return resource.NonRetryableError(fmt.Errorf("%s not exists", instanceId)) + } + if instance.LatestOperationState == nil { + return resource.RetryableError(fmt.Errorf("wait for operation update")) + } + if *instance.LatestOperationState == state { + return resource.RetryableError(fmt.Errorf("waiting for instance %s operation", instanceId)) + } + if *instance.LatestOperationState == CVM_LATEST_OPERATION_STATE_FAILED { + return resource.NonRetryableError(fmt.Errorf("failed operation")) + } + return nil + }) + if err != nil { + return err + } + return nil +} + +func switchInstance(cvmService *CvmService, ctx context.Context, d *schema.ResourceData, flag bool) (err error) { + instanceId := d.Id() + if flag { + err = cvmService.StartInstance(ctx, instanceId) + if err != nil { + return err + } + err = resource.Retry(2*tccommon.ReadRetryTimeout, func() *resource.RetryError { + instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId) + if errRet != nil { + return tccommon.RetryError(errRet, tccommon.InternalError) + } + if instance != nil && *instance.InstanceState == CVM_STATUS_RUNNING { + return nil + } + return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState)) + }) + if err != nil { + return err + } + } else { + stoppedMode := d.Get("stopped_mode").(string) + skipStopApi := false + err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + // when retry polling instance status, stop instance should skipped + if !skipStopApi { + err := cvmService.StopInstance(ctx, instanceId, stoppedMode) + if err != nil { + return resource.NonRetryableError(err) + } + } + instance, err := cvmService.DescribeInstanceById(ctx, instanceId) + if err != nil { + return resource.NonRetryableError(err) + } + if instance == nil { + return resource.NonRetryableError(fmt.Errorf("instance %s not found", instanceId)) + } + + if instance.LatestOperationState != nil { + operationState := *instance.LatestOperationState + if operationState == "OPERATING" { + skipStopApi = true + return resource.RetryableError(fmt.Errorf("instance %s stop operating, retrying", instanceId)) + } + if operationState == "FAILED" { + skipStopApi = false + return resource.RetryableError(fmt.Errorf("instance %s stop failed, retrying", instanceId)) + } + } + return nil + }) + if err != nil { + return err + } + err = resource.Retry(2*tccommon.ReadRetryTimeout, func() *resource.RetryError { + instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId) + if errRet != nil { + return tccommon.RetryError(errRet, tccommon.InternalError) + } + if instance != nil && *instance.InstanceState == CVM_STATUS_STOPPED { + return nil + } + return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState)) + }) + if err != nil { + return err + } + } + return nil +} + +func resourceTencentCloudInstanceUpdatePreHandleResponse5(ctx context.Context, resp *cvm.ResizeInstanceDisksResponse) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + cvmService := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + instanceId := d.Id() + size := d.Get("system_disk_size").(int) + diskType := d.Get("system_disk_type").(string) + + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + instance, err := cvmService.DescribeInstanceById(ctx, instanceId) + if err != nil { + return resource.NonRetryableError(err) + } + if instance != nil && instance.LatestOperationState != nil { + if *instance.InstanceState == "FAILED" { + return resource.NonRetryableError(fmt.Errorf("instance operation failed")) + } + if *instance.InstanceState == "OPERATING" { + return resource.RetryableError(fmt.Errorf("instance operating")) + } + } + if instance != nil && instance.SystemDisk != nil { + //wait until disk result as expected + if *instance.SystemDisk.DiskType != diskType || int(*instance.SystemDisk.DiskSize) != size { + return resource.RetryableError(fmt.Errorf("waiting for expanding success")) + } + } + return nil + }) + if err != nil { + return err + } + + return nil +} + +func resourceTencentCloudInstanceUpdatePreHandleResponse6(ctx context.Context, resp *cvm.ResetInstancesTypeResponse) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + + err := waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) + if err != nil { + return err + } + + return nil +} + +func resourceTencentCloudInstanceUpdatePreHandleResponse7(ctx context.Context, resp *cvm.ResetInstancesTypeResponse) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + + err := waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) + if err != nil { + return err + } + + return nil +} + +func resourceTencentCloudInstanceUpdatePostFillRequest8(ctx context.Context, req *cvm.ModifyInstancesVpcAttributeRequest) error { + d := tccommon.ResourceDataFromContext(ctx) + + privateIp := d.Get("private_ip").(string) + if privateIp != "" { + req.VirtualPrivateCloud.PrivateIpAddresses = []*string{&privateIp} + } + return nil +} + +func resourceTencentCloudInstanceUpdateOnExit(ctx context.Context) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + cvmService := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + instanceId := d.Id() + + if d.HasChange("tags") { + oldInterface, newInterface := d.GetChange("tags") + replaceTags, deleteTags := svctag.DiffTags(oldInterface.(map[string]interface{}), newInterface.(map[string]interface{})) + tagService := svctag.NewTagService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) + region := meta.(tccommon.ProviderMeta).GetAPIV3Conn().Region + resourceName := tccommon.BuildTagResourceName("cvm", "instance", region, instanceId) + err := tagService.ModifyTags(ctx, resourceName, replaceTags, deleteTags) + if err != nil { + return err + } + //except instance ,system disk and data disk will be tagged + //keep logical consistence with the console + //tag system disk + if systemDiskId, ok := d.GetOk("system_disk_id"); ok { + if systemDiskId.(string) != "" { + resourceName = tccommon.BuildTagResourceName("cvm", "volume", region, systemDiskId.(string)) + if err := tagService.ModifyTags(ctx, resourceName, replaceTags, deleteTags); err != nil { + return err + } + } + } + //tag disk ids + if dataDisks, ok := d.GetOk("data_disks"); ok { + dataDiskList := dataDisks.([]interface{}) + for _, dataDisk := range dataDiskList { + disk := dataDisk.(map[string]interface{}) + dataDiskId := disk["data_disk_id"].(string) + resourceName = tccommon.BuildTagResourceName("cvm", "volume", region, dataDiskId) + if err := tagService.ModifyTags(ctx, resourceName, replaceTags, deleteTags); err != nil { + return err + } + } + } + + } + + if d.HasChange("internet_max_bandwidth_out") { + chargeType := d.Get("internet_charge_type").(string) + bandWidthOut := int64(d.Get("internet_max_bandwidth_out").(int)) + if chargeType != "TRAFFIC_POSTPAID_BY_HOUR" && chargeType != "BANDWIDTH_POSTPAID_BY_HOUR" && chargeType != "BANDWIDTH_PACKAGE" { + return fmt.Errorf("charge type should be one of `TRAFFIC_POSTPAID_BY_HOUR BANDWIDTH_POSTPAID_BY_HOUR BANDWIDTH_PACKAGE` when adjusting internet_max_bandwidth_out") + } + + err := cvmService.ModifyInternetMaxBandwidthOut(ctx, instanceId, chargeType, bandWidthOut) + if err != nil { + return err + } + + err = waitForOperationFinished(d, meta, 2*tccommon.ReadRetryTimeout, CVM_LATEST_OPERATION_STATE_OPERATING, false) + if err != nil { + return err + } + + } + + d.Partial(false) + + return nil +} + +func resourceTencentCloudInstanceDeletePostFillRequest0(ctx context.Context, req *cvm.TerminateInstancesRequest) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + cvmService := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + instanceId := d.Id() + + _, err := cvmService.DescribeInstanceById(ctx, instanceId) + if err != nil { + return err + } + + return nil +} + +func resourceTencentCloudInstanceDeletePreHandleResponse0(ctx context.Context, resp *cvm.TerminateInstancesResponse) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + logId := ctx.Value(tccommon.LogIdKey) + cvmService := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + instanceId := d.Id() + + //check is force delete or not + forceDelete := d.Get("force_delete").(bool) + + //check recycling + notExist := false + + var instance *cvm.Instance + //check exist + err := resource.Retry(5*tccommon.ReadRetryTimeout, func() *resource.RetryError { + instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId) + if errRet != nil { + return tccommon.RetryError(errRet, tccommon.InternalError) + } + if instance == nil { + notExist = true + return nil + } + if *instance.InstanceState == CVM_STATUS_SHUTDOWN && *instance.LatestOperationState != CVM_LATEST_OPERATION_STATE_OPERATING { + //in recycling + return nil + } + return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState)) + }) + if err != nil { + return err + } + + vpcService := vpc.NewVpcService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) + + if notExist { + err := waitIpRelease(ctx, vpcService, instance) + if err != nil { + return err + } + return nil + } + + if !forceDelete { + return nil + } + + // exist in recycle, delete again + err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + errRet := cvmService.DeleteInstance(ctx, instanceId) + //when state is terminating, do not delete but check exist + if errRet != nil { + //check InvalidInstanceState.Terminating + ee, ok := errRet.(*sdkErrors.TencentCloudSDKError) + if !ok { + return tccommon.RetryError(errRet) + } + if ee.Code == "InvalidInstanceState.Terminating" { + return nil + } + return tccommon.RetryError(errRet, "OperationDenied.InstanceOperationInProgress") + } + return nil + }) + if err != nil { + return err + } + + //describe and check not exist + err = resource.Retry(5*tccommon.ReadRetryTimeout, func() *resource.RetryError { + instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId) + if errRet != nil { + return tccommon.RetryError(errRet, tccommon.InternalError) + } + if instance == nil { + return nil + } + return resource.RetryableError(fmt.Errorf("cvm instance status is %s, retry...", *instance.InstanceState)) + }) + if err != nil { + return err + } + if v, ok := d.GetOk("data_disks"); ok { + dataDisks := v.([]interface{}) + for _, d := range dataDisks { + value := d.(map[string]interface{}) + diskId := value["data_disk_id"].(string) + deleteWithInstance := value["delete_with_instance"].(bool) + if deleteWithInstance { + cbsService := svccbs.NewCbsService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) + err := resource.Retry(tccommon.ReadRetryTimeout*2, func() *resource.RetryError { + diskInfo, e := cbsService.DescribeDiskById(ctx, diskId) + if e != nil { + return tccommon.RetryError(e, tccommon.InternalError) + } + if *diskInfo.DiskState != svccbs.CBS_STORAGE_STATUS_UNATTACHED { + return resource.RetryableError(fmt.Errorf("cbs storage status is %s", *diskInfo.DiskState)) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s delete cbs failed, reason:%s\n ", logId, err.Error()) + return err + } + err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + e := cbsService.DeleteDiskById(ctx, diskId) + if e != nil { + return tccommon.RetryError(e, tccommon.InternalError) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s delete cbs failed, reason:%s\n ", logId, err.Error()) + return err + } + err = resource.Retry(tccommon.ReadRetryTimeout*2, func() *resource.RetryError { + diskInfo, e := cbsService.DescribeDiskById(ctx, diskId) + if e != nil { + return tccommon.RetryError(e, tccommon.InternalError) + } + if *diskInfo.DiskState == svccbs.CBS_STORAGE_STATUS_TORECYCLE { + return resource.RetryableError(fmt.Errorf("cbs storage status is %s", *diskInfo.DiskState)) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read cbs status failed, reason:%s\n ", logId, err.Error()) + return err + } + err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + e := cbsService.DeleteDiskById(ctx, diskId) + if e != nil { + return tccommon.RetryError(e, tccommon.InternalError) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s delete cbs failed, reason:%s\n ", logId, err.Error()) + return err + } + err = resource.Retry(tccommon.ReadRetryTimeout*2, func() *resource.RetryError { + diskInfo, e := cbsService.DescribeDiskById(ctx, diskId) + if e != nil { + return tccommon.RetryError(e, tccommon.InternalError) + } + if diskInfo != nil { + return resource.RetryableError(fmt.Errorf("cbs storage status is %s", *diskInfo.DiskState)) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read cbs status failed, reason:%s\n ", logId, err.Error()) + return err + } + } + } + } + + err = waitIpRelease(ctx, vpcService, instance) + if err != nil { + return err + } + + return nil +} + +func waitIpRelease(ctx context.Context, vpcService vpc.VpcService, instance *cvm.Instance) error { + // wait ip release + if instance != nil && len(instance.PrivateIpAddresses) > 0 { + params := make(map[string]interface{}) + params["VpcId"] = instance.VirtualPrivateCloud.VpcId + params["SubnetId"] = instance.VirtualPrivateCloud.SubnetId + params["IpAddresses"] = instance.PrivateIpAddresses + err := resource.Retry(5*tccommon.ReadRetryTimeout, func() *resource.RetryError { + usedIpAddress, errRet := vpcService.DescribeVpcUsedIpAddressByFilter(ctx, params) + if errRet != nil { + return tccommon.RetryError(errRet, tccommon.InternalError) + } + if len(usedIpAddress) > 0 { + return resource.RetryableError(fmt.Errorf("wait cvm private ip release...")) + } + + return nil + }) + if err != nil { + return err + } + } + return nil +} diff --git a/tencentcloud/services/cvm/resource_tc_instance_test.go b/tencentcloud/services/cvm/resource_tc_instance_test.go index 29ec585a5e..f77c9c6c8d 100644 --- a/tencentcloud/services/cvm/resource_tc_instance_test.go +++ b/tencentcloud/services/cvm/resource_tc_instance_test.go @@ -1730,7 +1730,7 @@ data "tencentcloud_instance_types" "default" { filter { name = "instance-family" - values = ["S1"] + values = ["S5"] } cpu_core_count = 2 memory_size = 2 @@ -1758,7 +1758,7 @@ data "tencentcloud_instance_types" "default" { filter { name = "instance-family" - values = ["S1"] + values = ["S5"] } cpu_core_count = 2 memory_size = 2 @@ -2028,7 +2028,7 @@ const testAccTencentCloudInstancePostPaid = ` data "tencentcloud_instance_types" "default" { filter { name = "instance-family" - values = ["S1"] + values = ["S5"] } cpu_core_count = 2 @@ -2052,7 +2052,7 @@ const testAccTencentCloudInstanceBasicToPrepaid = ` data "tencentcloud_instance_types" "default" { filter { name = "instance-family" - values = ["S1"] + values = ["S5"] } cpu_core_count = 2 diff --git a/tencentcloud/services/cvm/resource_tc_key_pair.go b/tencentcloud/services/cvm/resource_tc_key_pair.go index c768504a77..a421adbc86 100644 --- a/tencentcloud/services/cvm/resource_tc_key_pair.go +++ b/tencentcloud/services/cvm/resource_tc_key_pair.go @@ -1,20 +1,18 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( "context" "fmt" "log" - "strings" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" - svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag" - - "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" 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" + svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag" ) func ResourceTencentCloudKeyPair() *schema.Resource { @@ -26,142 +24,67 @@ func ResourceTencentCloudKeyPair() *schema.Resource { Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, - Schema: map[string]*schema.Schema{ "key_name": { Type: schema.TypeString, Required: true, - ValidateFunc: tccommon.ValidateKeyPairName, Description: "The key pair's name. It is the only in one TencentCloud account.", + ValidateFunc: tccommon.ValidateKeyPairName, }, + "public_key": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - StateFunc: func(v interface{}) string { - switch value := v.(type) { - case string: - publicKey := value - split := strings.Split(value, " ") - if len(split) > 2 { - publicKey = strings.Join(split[0:2], " ") - } - return strings.TrimSpace(publicKey) - default: - return "" - } - }, + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, Description: "You can import an existing public key and using TencentCloud key pair to manage it.", + StateFunc: publicKeyStateFunc, }, + "project_id": { Type: schema.TypeInt, Optional: true, - Default: 0, ForceNew: true, + Default: 0, Description: "Specifys to which project the key pair belongs.", }, + "tags": { Type: schema.TypeMap, Optional: true, - Description: "Tags of the key pair.", + Description: "Tag description list.", }, }, } } -func cvmCreateKeyPair(ctx context.Context, d *schema.ResourceData, meta interface{}) (keyId string, err error) { - logId := tccommon.GetLogId(ctx) - request := cvm.NewCreateKeyPairRequest() - response := cvm.NewCreateKeyPairResponse() - request.KeyName = helper.String(d.Get("key_name").(string)) - request.ProjectId = helper.IntInt64(d.Get("project_id").(int)) - - innerErr := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().CreateKeyPair(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 innerErr != nil { - log.Printf("[CRITAL]%s create cvm keyPair by import failed, reason:%+v", logId, err) - err = innerErr - return - } - if response == nil || response.Response == nil || response.Response.KeyPair == nil { - err = fmt.Errorf("Response is nil") - return - } - - keyId = *response.Response.KeyPair.KeyId - return -} - -func cvmCreateKeyPairByImportPublicKey(ctx context.Context, d *schema.ResourceData, meta interface{}) (keyId string, err error) { - logId := tccommon.GetLogId(ctx) - request := cvm.NewImportKeyPairRequest() - response := cvm.NewImportKeyPairResponse() - request.KeyName = helper.String(d.Get("key_name").(string)) - request.ProjectId = helper.IntInt64(d.Get("project_id").(int)) - request.PublicKey = helper.String(d.Get("public_key").(string)) - - innerErr := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ImportKeyPair(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 innerErr != nil { - log.Printf("[CRITAL]%s create cvm keyPair by import failed, reason:%+v", logId, err) - err = innerErr - return - } - if response == nil || response.Response == nil { - err = fmt.Errorf("Response is nil") - return - } - - keyId = *response.Response.KeyId - return -} - func resourceTencentCloudKeyPairCreate(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_key_pair.create")() + defer tccommon.InconsistentCheck(d, meta)() logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + var ( keyId string - err error ) + d.SetId(keyId) - if _, ok := d.GetOk("public_key"); ok { - keyId, err = cvmCreateKeyPairByImportPublicKey(ctx, d, meta) - } else { - keyId, err = cvmCreateKeyPair(ctx, d, meta) - } - if err != nil { + if err := resourceTencentCloudKeyPairCreateOnExit(ctx); err != nil { return err } - d.SetId(keyId) if tags := helper.GetTags(d, "tags"); len(tags) > 0 { - tcClient := meta.(tccommon.ProviderMeta).GetAPIV3Conn() - tagService := svctag.NewTagService(tcClient) - resourceName := tccommon.BuildTagResourceName("cvm", "keypair", tcClient.Region, keyId) + tagService := svctag.NewTagService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) + region := meta.(tccommon.ProviderMeta).GetAPIV3Conn().Region + resourceName := fmt.Sprintf("qcs::cvm:%s:uin/:keypair/%s", region, d.Id()) if err := tagService.ModifyTags(ctx, resourceName, tags, nil); err != nil { return err } } + _ = ctx return resourceTencentCloudKeyPairRead(d, meta) } @@ -170,44 +93,38 @@ func resourceTencentCloudKeyPairRead(d *schema.ResourceData, meta interface{}) e defer tccommon.InconsistentCheck(d, meta)() 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()} keyId := d.Id() - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } - var keyPair *cvm.KeyPair - var errRet error - err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - keyPair, errRet = cvmService.DescribeKeyPairById(ctx, keyId) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) - } - return nil - }) + + respData, err := service.DescribeKeyPairById(ctx, keyId) if err != nil { return err } - if keyPair == nil { + + if respData == nil { d.SetId("") + log.Printf("[WARN]%s resource `key_pair` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) return nil } + if respData.KeyName != nil { + _ = d.Set("key_name", respData.KeyName) + } - _ = d.Set("key_name", keyPair.KeyName) - _ = d.Set("project_id", keyPair.ProjectId) - if keyPair.PublicKey != nil { - publicKey := *keyPair.PublicKey - split := strings.Split(publicKey, " ") - if len(split) > 2 { - publicKey = strings.Join(split[0:2], " ") - } - _ = d.Set("public_key", publicKey) + if respData.ProjectId != nil { + _ = d.Set("project_id", respData.ProjectId) } - client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() - tagService := svctag.NewTagService(client) + if err := resourceTencentCloudKeyPairReadPostHandleResponse0(ctx, respData); err != nil { + return err + } - tags, err := tagService.DescribeResourceTags(ctx, "cvm", "keypair", client.Region, d.Id()) + tcClient := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + tagService := svctag.NewTagService(tcClient) + tags, err := tagService.DescribeResourceTags(ctx, "cvm", "keypair", tcClient.Region, d.Id()) if err != nil { return err } @@ -218,31 +135,55 @@ func resourceTencentCloudKeyPairRead(d *schema.ResourceData, meta interface{}) e func resourceTencentCloudKeyPairUpdate(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_key_pair.update")() + defer tccommon.InconsistentCheck(d, meta)() logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) keyId := d.Id() - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), + + needChange := false + mutableArgs := []string{"key_name"} + for _, v := range mutableArgs { + if d.HasChange(v) { + needChange = true + break + } } - if d.HasChange("key_name") { - keyName := d.Get("key_name").(string) - err := cvmService.ModifyKeyPairName(ctx, keyId, keyName) + if needChange { + request := cvm.NewModifyKeyPairAttributeRequest() + + request.KeyId = helper.String(keyId) + + if v, ok := d.GetOk("key_name"); ok { + request.KeyName = helper.String(v.(string)) + } + + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyKeyPairAttributeWithContext(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 key pair failed, reason:%+v", logId, err) return err } } if d.HasChange("tags") { - oldInterface, newInterface := d.GetChange("tags") - replaceTags, deleteTags := svctag.DiffTags(oldInterface.(map[string]interface{}), newInterface.(map[string]interface{})) - tagService := svctag.NewTagService(meta.(tccommon.ProviderMeta).GetAPIV3Conn()) - region := meta.(tccommon.ProviderMeta).GetAPIV3Conn().Region - resourceName := tccommon.BuildTagResourceName("cvm", "keypair", region, keyId) - err := tagService.ModifyTags(ctx, resourceName, replaceTags, deleteTags) - if err != nil { + ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + tcClient := meta.(tccommon.ProviderMeta).GetAPIV3Conn() + tagService := svctag.NewTagService(tcClient) + oldTags, newTags := d.GetChange("tags") + replaceTags, deleteTags := svctag.DiffTags(oldTags.(map[string]interface{}), newTags.(map[string]interface{})) + resourceName := tccommon.BuildTagResourceName("cvm", "keypair", tcClient.Region, d.Id()) + if err := tagService.ModifyTags(ctx, resourceName, replaceTags, deleteTags); err != nil { return err } } @@ -252,60 +193,42 @@ func resourceTencentCloudKeyPairUpdate(d *schema.ResourceData, meta interface{}) func resourceTencentCloudKeyPairDelete(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_key_pair.delete")() + defer tccommon.InconsistentCheck(d, meta)() logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) keyId := d.Id() - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } - var keyPair *cvm.KeyPair - var errRet error - err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - keyPair, errRet = cvmService.DescribeKeyPairById(ctx, keyId) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) - } - return nil - }) - if err != nil { + var ( + request = cvm.NewDeleteKeyPairsRequest() + response = cvm.NewDeleteKeyPairsResponse() + ) + + request.KeyIds = []*string{helper.String(keyId)} + + if err := resourceTencentCloudKeyPairDeletePostFillRequest0(ctx, request); err != nil { return err } - if keyPair == nil { - d.SetId("") - return nil - } - if len(keyPair.AssociatedInstanceIds) > 0 { - err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - errRet := cvmService.UnbindKeyPair(ctx, []*string{&keyId}, keyPair.AssociatedInstanceIds) - if errRet != nil { - if sdkErr, ok := errRet.(*errors.TencentCloudSDKError); ok { - if sdkErr.Code == CVM_NOT_FOUND_ERROR { - return nil - } - } - return tccommon.RetryError(errRet) + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().DeleteKeyPairsWithContext(ctx, request) + if e != nil { + if err := resourceTencentCloudKeyPairDeleteRequestOnError0(ctx, e); err != nil { + return err } - return nil - }) - if err != nil { - return err - } - } - - err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - errRet := cvmService.DeleteKeyPair(ctx, keyId) - if errRet != nil { - return tccommon.RetryError(errRet, KYE_PAIR_INVALID_ERROR, KEY_PAIR_NOT_SUPPORT_ERROR) + 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 key pair failed, reason:%+v", logId, err) return err } + _ = response return nil } diff --git a/tencentcloud/services/cvm/resource_tc_key_pair_extension.go b/tencentcloud/services/cvm/resource_tc_key_pair_extension.go new file mode 100644 index 0000000000..86dd46c4f9 --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_key_pair_extension.go @@ -0,0 +1,179 @@ +package cvm + +import ( + "context" + "fmt" + "log" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" +) + +func resourceTencentCloudKeyPairReadPostHandleResponse0(ctx context.Context, resp *cvm.KeyPair) error { + d := tccommon.ResourceDataFromContext(ctx) + + if resp.PublicKey != nil { + publicKey := *resp.PublicKey + split := strings.Split(publicKey, " ") + if len(split) > 2 { + publicKey = strings.Join(split[0:2], " ") + } + _ = d.Set("public_key", publicKey) + } + return nil +} + +func resourceTencentCloudKeyPairDeletePostFillRequest0(ctx context.Context, req *cvm.DeleteKeyPairsRequest) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + cvmService := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + keyId := d.Id() + + var keyPair *cvm.KeyPair + var errRet error + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + keyPair, errRet = cvmService.DescribeKeyPairById(ctx, keyId) + if errRet != nil { + return tccommon.RetryError(errRet, tccommon.InternalError) + } + return nil + }) + if err != nil { + return err + } + if keyPair == nil { + d.SetId("") + return nil + } + + if len(keyPair.AssociatedInstanceIds) > 0 { + err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + errRet := cvmService.UnbindKeyPair(ctx, []*string{&keyId}, keyPair.AssociatedInstanceIds) + if errRet != nil { + if sdkErr, ok := errRet.(*errors.TencentCloudSDKError); ok { + if sdkErr.Code == CVM_NOT_FOUND_ERROR { + return nil + } + } + return tccommon.RetryError(errRet) + } + return nil + }) + if err != nil { + return err + } + } + + return nil +} + +func publicKeyStateFunc(v interface{}) string { + switch value := v.(type) { + case string: + publicKey := value + split := strings.Split(value, " ") + if len(split) > 2 { + publicKey = strings.Join(split[0:2], " ") + } + return strings.TrimSpace(publicKey) + default: + return "" + } +} + +func resourceTencentCloudKeyPairDeleteRequestOnError0(ctx context.Context, e error) *resource.RetryError { + return tccommon.RetryError(e, KYE_PAIR_INVALID_ERROR, KEY_PAIR_NOT_SUPPORT_ERROR) +} + +func resourceTencentCloudKeyPairCreateOnExit(ctx context.Context) error { + d := tccommon.ResourceDataFromContext(ctx) + meta := tccommon.ProviderMetaFromContext(ctx) + + var ( + keyId string + err error + ) + if _, ok := d.GetOk("public_key"); ok { + keyId, err = cvmCreateKeyPairByImportPublicKey(ctx, d, meta) + } else { + keyId, err = cvmCreateKeyPair(ctx, d, meta) + } + if err != nil { + return err + } + d.SetId(keyId) + return nil +} + +func cvmCreateKeyPair(ctx context.Context, d *schema.ResourceData, meta interface{}) (keyId string, err error) { + logId := tccommon.GetLogId(ctx) + request := cvm.NewCreateKeyPairRequest() + response := cvm.NewCreateKeyPairResponse() + request.KeyName = helper.String(d.Get("key_name").(string)) + request.ProjectId = helper.IntInt64(d.Get("project_id").(int)) + + innerErr := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().CreateKeyPair(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 innerErr != nil { + log.Printf("[CRITAL]%s create cvm keyPair by import failed, reason:%+v", logId, err) + err = innerErr + return + } + if response == nil || response.Response == nil || response.Response.KeyPair == nil { + err = fmt.Errorf("Response is nil") + return + } + + keyId = *response.Response.KeyPair.KeyId + return +} + +func cvmCreateKeyPairByImportPublicKey(ctx context.Context, d *schema.ResourceData, meta interface{}) (keyId string, err error) { + logId := tccommon.GetLogId(ctx) + request := cvm.NewImportKeyPairRequest() + response := cvm.NewImportKeyPairResponse() + request.KeyName = helper.String(d.Get("key_name").(string)) + request.ProjectId = helper.IntInt64(d.Get("project_id").(int)) + request.PublicKey = helper.String(d.Get("public_key").(string)) + + innerErr := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ImportKeyPair(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 innerErr != nil { + log.Printf("[CRITAL]%s create cvm keyPair by import failed, reason:%+v", logId, err) + err = innerErr + return + } + if response == nil || response.Response == nil { + err = fmt.Errorf("Response is nil") + return + } + + keyId = *response.Response.KeyId + return +} diff --git a/tencentcloud/services/cvm/resource_tc_placement_group.go b/tencentcloud/services/cvm/resource_tc_placement_group.go index 25fac68fbf..f30ba5235d 100644 --- a/tencentcloud/services/cvm/resource_tc_placement_group.go +++ b/tencentcloud/services/cvm/resource_tc_placement_group.go @@ -1,13 +1,16 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( "context" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "log" "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 ResourceTencentCloudPlacementGroup() *schema.Resource { @@ -19,33 +22,34 @@ func ResourceTencentCloudPlacementGroup() *schema.Resource { Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, - Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, Required: true, - ValidateFunc: tccommon.ValidateStringLengthInRange(1, 60), Description: "Name of the placement group, 1-60 characters in length.", + ValidateFunc: tccommon.ValidateStringLengthInRange(1, 60), }, + "type": { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: tccommon.ValidateAllowedStringValue(CVM_PLACEMENT_GROUP_TYPE), Description: "Type of the placement group. Valid values: `HOST`, `SW` and `RACK`.", + ValidateFunc: tccommon.ValidateAllowedStringValue(CVM_PLACEMENT_GROUP_TYPE), }, - // computed "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.", }, + "create_time": { Type: schema.TypeString, Computed: true, @@ -57,27 +61,46 @@ func ResourceTencentCloudPlacementGroup() *schema.Resource { func resourceTencentCloudPlacementGroupCreate(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_placement_group.create")() + defer tccommon.InconsistentCheck(d, meta)() + logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + var ( + disasterRecoverGroupId string + ) + var ( + request = cvm.NewCreateDisasterRecoverGroupRequest() + response = cvm.NewCreateDisasterRecoverGroupResponse() + ) + + if v, ok := d.GetOk("name"); ok { + request.Name = helper.String(v.(string)) + } + + if v, ok := d.GetOk("type"); ok { + request.Type = helper.String(v.(string)) } - placementName := d.Get("name").(string) - placementType := d.Get("type").(string) - var id string - var errRet error + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - id, errRet = cvmService.CreatePlacementGroup(ctx, placementName, placementType) - if errRet != nil { - return tccommon.RetryError(errRet) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().CreateDisasterRecoverGroupWithContext(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 placement group failed, reason:%+v", logId, err) return err } - d.SetId(id) + + disasterRecoverGroupId = *response.Response.DisasterRecoverGroupId + + d.SetId(disasterRecoverGroupId) return resourceTencentCloudPlacementGroupRead(d, meta) } @@ -87,57 +110,85 @@ func resourceTencentCloudPlacementGroupRead(d *schema.ResourceData, meta interfa defer tccommon.InconsistentCheck(d, meta)() logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - placementId := d.Id() - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } - var placement *cvm.DisasterRecoverGroup - var errRet error - err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - placement, errRet = cvmService.DescribePlacementGroupById(ctx, placementId) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) - } - return nil - }) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + disasterRecoverGroupId := d.Id() + + respData, err := service.DescribePlacementGroupById(ctx, disasterRecoverGroupId) if err != nil { return err } - if placement == nil { + + if respData == nil { d.SetId("") + log.Printf("[WARN]%s resource `placement_group` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) return nil } + if respData.Name != nil { + _ = d.Set("name", respData.Name) + } + + if respData.Type != nil { + _ = d.Set("type", respData.Type) + } + + if respData.CvmQuotaTotal != nil { + _ = d.Set("cvm_quota_total", respData.CvmQuotaTotal) + } - _ = d.Set("name", placement.Name) - _ = d.Set("type", placement.Type) - _ = d.Set("cvm_quota_total", placement.CvmQuotaTotal) - _ = d.Set("current_num", placement.CurrentNum) - _ = d.Set("create_time", placement.CreateTime) + if respData.CurrentNum != nil { + _ = d.Set("current_num", respData.CurrentNum) + } + + if respData.CreateTime != nil { + _ = d.Set("create_time", respData.CreateTime) + } return nil } func resourceTencentCloudPlacementGroupUpdate(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_placement_group.update")() + defer tccommon.InconsistentCheck(d, meta)() + logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - placementId := d.Id() - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + disasterRecoverGroupId := d.Id() + + needChange := false + mutableArgs := []string{"name"} + for _, v := range mutableArgs { + if d.HasChange(v) { + needChange = true + break + } } - if d.HasChange("name") { - placementName := d.Get("name").(string) + + if needChange { + request := cvm.NewModifyDisasterRecoverGroupAttributeRequest() + + request.DisasterRecoverGroupId = helper.String(disasterRecoverGroupId) + + if v, ok := d.GetOk("name"); ok { + request.Name = helper.String(v.(string)) + } + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - err := cvmService.ModifyPlacementGroup(ctx, placementId, placementName) - if err != nil { - return tccommon.RetryError(err) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().ModifyDisasterRecoverGroupAttributeWithContext(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 placement group failed, reason:%+v", logId, err) return err } } @@ -147,23 +198,35 @@ func resourceTencentCloudPlacementGroupUpdate(d *schema.ResourceData, meta inter func resourceTencentCloudPlacementGroupDelete(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_placement_group.delete")() + defer tccommon.InconsistentCheck(d, meta)() + logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + disasterRecoverGroupId := d.Id() + + var ( + request = cvm.NewDeleteDisasterRecoverGroupsRequest() + response = cvm.NewDeleteDisasterRecoverGroupsResponse() + ) + + request.DisasterRecoverGroupIds = []*string{helper.String(disasterRecoverGroupId)} - placementId := d.Id() - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - err := cvmService.DeletePlacementGroup(ctx, placementId) - if err != nil { - return tccommon.RetryError(err) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().DeleteDisasterRecoverGroupsWithContext(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 placement group failed, reason:%+v", logId, err) return err } + _ = response return nil } diff --git a/tencentcloud/services/cvm/resource_tc_placement_group_extension.go b/tencentcloud/services/cvm/resource_tc_placement_group_extension.go new file mode 100644 index 0000000000..b417cc5d9f --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_placement_group_extension.go @@ -0,0 +1 @@ +package cvm diff --git a/tencentcloud/services/cvm/resource_tc_reserved_instance.go b/tencentcloud/services/cvm/resource_tc_reserved_instance.go index 9b18443082..e3a9917f90 100644 --- a/tencentcloud/services/cvm/resource_tc_reserved_instance.go +++ b/tencentcloud/services/cvm/resource_tc_reserved_instance.go @@ -1,14 +1,16 @@ +// Code generated by iacg; DO NOT EDIT. package cvm import ( "context" - "fmt" - - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "log" "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 ResourceTencentCloudReservedInstance() *schema.Resource { @@ -20,38 +22,38 @@ func ResourceTencentCloudReservedInstance() *schema.Resource { Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, - Schema: map[string]*schema.Schema{ "config_id": { Type: schema.TypeString, Required: true, Description: "Configuration ID of the reserved instance.", }, + "instance_count": { Type: schema.TypeInt, Required: true, - ValidateFunc: tccommon.ValidateIntegerMin(1), Description: "Number of reserved instances to be purchased.", + ValidateFunc: tccommon.ValidateIntegerMin(1), }, + "reserved_instance_name": { - Type: schema.TypeString, - Optional: true, - Description: `Reserved Instance display name. - - If you do not specify an instance display name, 'Unnamed' is displayed by default. - - Up to 60 characters (including pattern strings) are supported.`, + Type: schema.TypeString, + Optional: true, + Description: "Reserved Instance display name.\n\t\t\t\t- If you do not specify an instance display name, 'Unnamed' is displayed by default.\n\t\t\t\t- Up to 60 characters (including pattern strings) are supported.", }, - // computed "start_time": { Type: schema.TypeString, Computed: true, Description: "Start time of the RI.", }, + "end_time": { Type: schema.TypeString, Computed: true, Description: "Expiry time of the RI.", }, + "status": { Type: schema.TypeString, Computed: true, @@ -63,31 +65,50 @@ func ResourceTencentCloudReservedInstance() *schema.Resource { func resourceTencentCloudReservedInstanceCreate(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_reserved_instance.create")() + defer tccommon.InconsistentCheck(d, meta)() + logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - configId := d.Get("config_id").(string) - count := d.Get("instance_count").(int) - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + var ( + reservedInstanceId string + ) + var ( + request = cvm.NewPurchaseReservedInstancesOfferingRequest() + response = cvm.NewPurchaseReservedInstancesOfferingResponse() + ) + + if v, ok := d.GetOk("config_id"); ok { + request.ReservedInstancesOfferingId = helper.String(v.(string)) + } + + if v, ok := d.GetOkExists("instance_count"); ok { + request.InstanceCount = helper.IntInt64(v.(int)) } - extendParams := make(map[string]interface{}) + if v, ok := d.GetOk("reserved_instance_name"); ok { - extendParams["reserved_instance_name"] = v.(string) + request.ReservedInstanceName = helper.String(v.(string)) } - var instanceId string - var errRet error + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - instanceId, errRet = cvmService.CreateReservedInstance(ctx, configId, int64(count), extendParams) - if errRet != nil { - return tccommon.RetryError(errRet) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseCvmClient().PurchaseReservedInstancesOfferingWithContext(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 reserved instance failed, reason:%+v", logId, err) return err } - d.SetId(instanceId) + + reservedInstanceId = *response.Response.ReservedInstanceId + + d.SetId(reservedInstanceId) return resourceTencentCloudReservedInstanceRead(d, meta) } @@ -97,46 +118,74 @@ func resourceTencentCloudReservedInstanceRead(d *schema.ResourceData, meta inter defer tccommon.InconsistentCheck(d, meta)() logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - id := d.Id() - cvmService := CvmService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } - filter := map[string]string{ - "reserved-instances-id": id, - } - var instances []*cvm.ReservedInstances - var errRet error - err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - instances, errRet = cvmService.DescribeReservedInstanceByFilter(ctx, filter) - if errRet != nil { - return tccommon.RetryError(errRet, tccommon.InternalError) - } - return nil - }) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + service := CvmService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + reservedInstanceId := d.Id() + + respData, err := service.DescribeReservedInstanceById(ctx, reservedInstanceId) if err != nil { return err } - if len(instances) < 1 { + + if respData == nil { d.SetId("") + log.Printf("[WARN]%s resource `reserved_instance` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) return nil } - instance := instances[0] + if respData.InstanceCount != nil { + _ = d.Set("instance_count", respData.InstanceCount) + } + + if respData.StartTime != nil { + _ = d.Set("start_time", respData.StartTime) + } - _ = d.Set("instance_count", instance.InstanceCount) - _ = d.Set("start_time", instance.StartTime) - _ = d.Set("end_time", instance.EndTime) - _ = d.Set("status", instance.State) - _ = d.Set("reserved_instance_name", instance.ReservedInstanceName) + if respData.EndTime != nil { + _ = d.Set("end_time", respData.EndTime) + } + + if respData.State != nil { + _ = d.Set("status", respData.State) + } + + if respData.ReservedInstanceName != nil { + _ = d.Set("reserved_instance_name", respData.ReservedInstanceName) + } return nil } func resourceTencentCloudReservedInstanceUpdate(d *schema.ResourceData, meta interface{}) error { - return fmt.Errorf("reserved instance not allowed to modify") + defer tccommon.LogElapsed("resource.tencentcloud_reserved_instance.update")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + reservedInstanceId := d.Id() + + if err := resourceTencentCloudReservedInstanceUpdateOnStart(ctx); err != nil { + return err + } + + _ = reservedInstanceId + return resourceTencentCloudReservedInstanceRead(d, meta) } func resourceTencentCloudReservedInstanceDelete(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_reserved_instance.delete")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + reservedInstanceId := d.Id() + + _ = reservedInstanceId + _ = ctx return nil } diff --git a/tencentcloud/services/cvm/resource_tc_reserved_instance_extension.go b/tencentcloud/services/cvm/resource_tc_reserved_instance_extension.go new file mode 100644 index 0000000000..d8b9df735f --- /dev/null +++ b/tencentcloud/services/cvm/resource_tc_reserved_instance_extension.go @@ -0,0 +1,10 @@ +package cvm + +import ( + "context" + "fmt" +) + +func resourceTencentCloudReservedInstanceUpdateOnStart(ctx context.Context) error { + return fmt.Errorf("reserved instance not allowed to modify") +} diff --git a/tencentcloud/services/cvm/resource_tc_reserved_instance_test.go b/tencentcloud/services/cvm/resource_tc_reserved_instance_test.go index cd10e3a45a..c5a281f64d 100644 --- a/tencentcloud/services/cvm/resource_tc_reserved_instance_test.go +++ b/tencentcloud/services/cvm/resource_tc_reserved_instance_test.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) -func TestAccTencentCloudReservedInstance(t *testing.T) { +func TestAccTencentCloudNeedFixReservedInstance(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ PreCheck: func() { tcacctest.AccPreCheck(t) }, diff --git a/tencentcloud/services/cvm/tencentcloud_sweeper_test.go b/tencentcloud/services/cvm/resource_test.go similarity index 100% rename from tencentcloud/services/cvm/tencentcloud_sweeper_test.go rename to tencentcloud/services/cvm/resource_test.go diff --git a/tencentcloud/services/cvm/service_tencentcloud_cvm.go b/tencentcloud/services/cvm/service_tencentcloud_cvm.go index 071d5d8f1f..4f61273d86 100644 --- a/tencentcloud/services/cvm/service_tencentcloud_cvm.go +++ b/tencentcloud/services/cvm/service_tencentcloud_cvm.go @@ -9,10 +9,11 @@ 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" - sdkError "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" sdkErrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" @@ -64,28 +65,32 @@ func (me *CvmService) DescribeInstanceSetByIds(ctx context.Context, instanceSetI return } -func (me *CvmService) DescribeInstanceById(ctx context.Context, instanceId string) (instance *cvm.Instance, errRet error) { +func (me *CvmService) DescribeInstanceById(ctx context.Context, instanceId string) (ret *cvm.Instance, errRet error) { logId := tccommon.GetLogId(ctx) + request := cvm.NewDescribeInstancesRequest() - request.InstanceIds = []*string{&instanceId} + 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()) + } + }() - var iacExtInfo connectivity.IacExtInfo - iacExtInfo.InstanceId = instanceId ratelimit.Check(request.GetAction()) - response, err := me.client.UseCvmClient(iacExtInfo).DescribeInstances(request) + + response, err := me.client.UseCvmV20170312Client().DescribeInstances(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()) if len(response.Response.InstanceSet) < 1 { return } - instance = response.Response.InstanceSet[0] + + ret = response.Response.InstanceSet[0] return } @@ -507,34 +512,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 } @@ -572,25 +581,32 @@ func (me *CvmService) DescribeInstancesSellTypeByFilter(ctx context.Context, fil return } -func (me *CvmService) DescribeKeyPairById(ctx context.Context, keyId string) (keyPair *cvm.KeyPair, errRet error) { +func (me *CvmService) DescribeKeyPairById(ctx context.Context, keyId string) (ret *cvm.KeyPair, errRet error) { logId := tccommon.GetLogId(ctx) + request := cvm.NewDescribeKeyPairsRequest() - request.KeyIds = []*string{&keyId} + request.KeyIds = []*string{helper.String(keyId)} + + 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().DescribeKeyPairs(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()) - if len(response.Response.KeyPairSet) > 0 { - keyPair = response.Response.KeyPairSet[0] + if len(response.Response.KeyPairSet) < 1 { + return } + + ret = response.Response.KeyPairSet[0] return } @@ -745,26 +761,32 @@ func (me *CvmService) CreatePlacementGroup(ctx context.Context, placementName, p return } -func (me *CvmService) DescribePlacementGroupById(ctx context.Context, placementId string) (placementGroup *cvm.DisasterRecoverGroup, errRet error) { +func (me *CvmService) DescribePlacementGroupById(ctx context.Context, disasterRecoverGroupId string) (ret *cvm.DisasterRecoverGroup, errRet error) { logId := tccommon.GetLogId(ctx) + request := cvm.NewDescribeDisasterRecoverGroupsRequest() - request.DisasterRecoverGroupIds = []*string{&placementId} + request.DisasterRecoverGroupIds = []*string{helper.String(disasterRecoverGroupId)} + + 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().DescribeDisasterRecoverGroups(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()) if len(response.Response.DisasterRecoverGroupSet) < 1 { return } - placementGroup = response.Response.DisasterRecoverGroupSet[0] + + ret = response.Response.DisasterRecoverGroupSet[0] return } @@ -1073,100 +1095,32 @@ func (me *CvmService) DeleteImage(ctx context.Context, imageId string) error { return nil } -func (me *CvmService) DescribeImageById(ctx context.Context, keyId string, isDelete bool) (image *cvm.Image, has bool, errRet error) { +func (me *CvmService) DescribeImageById(ctx context.Context, imageId string) (ret *cvm.Image, errRet error) { logId := tccommon.GetLogId(ctx) + request := cvm.NewDescribeImagesRequest() - request.ImageIds = []*string{&keyId} + request.ImageIds = []*string{helper.String(imageId)} - var imgRsp *cvm.DescribeImagesResponse - err := resource.Retry(20*tccommon.ReadRetryTimeout, func() *resource.RetryError { - ratelimit.Check(request.GetAction()) - response, err := me.client.UseCvmClient().DescribeImages(request) - if err != nil { - return resource.RetryableError(err) + 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()) } - if response != nil && response.Response != nil { - if len(response.Response.ImageSet) == 0 && !isDelete { - return resource.RetryableError(fmt.Errorf("iamge instance status is processing")) - } - if len(response.Response.ImageSet) > 0 { - if *response.Response.ImageSet[0].ImageState == "CREATEFAILED" { - return resource.NonRetryableError(fmt.Errorf("[CRITAL]%s Create Image is failed", logId)) - } - if *response.Response.ImageSet[0].ImageState != "NORMAL" { - return resource.RetryableError(fmt.Errorf("iamge instance status is processing")) - } - } + }() - imgRsp = response - return nil - } - return resource.NonRetryableError(fmt.Errorf("response is null")) - }) + 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]", - 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 imgRsp == nil { + if len(response.Response.ImageSet) < 1 { return } - if len(imgRsp.Response.ImageSet) > 0 && len(imgRsp.Response.ImageSet[0].SnapshotSet) != 0 { - has = true - image = imgRsp.Response.ImageSet[0] - } - 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 - } - + ret = response.Response.ImageSet[0] return } @@ -1242,11 +1196,11 @@ func (me *CvmService) ResizeInstanceDisks(ctx context.Context, request *cvm.Resi return } -func (me *CvmService) DescribeCvmHpcClusterById(ctx context.Context, hpcClusterId string) (hpcCluster *cvm.HpcClusterInfo, errRet error) { +func (me *CvmService) DescribeCvmHpcClusterById(ctx context.Context, hpcClusterId string) (ret *cvm.HpcClusterInfo, errRet error) { logId := tccommon.GetLogId(ctx) request := cvm.NewDescribeHpcClustersRequest() - request.HpcClusterIds = []*string{&hpcClusterId} + request.HpcClusterIds = []*string{helper.String(hpcClusterId)} defer func() { if errRet != nil { @@ -1260,7 +1214,7 @@ func (me *CvmService) DescribeCvmHpcClusterById(ctx context.Context, hpcClusterI offset uint64 = 0 limit uint64 = 20 ) - instances := make([]*cvm.HpcClusterInfo, 0) + var instances []*cvm.HpcClusterInfo for { request.Offset = &offset request.Limit = &limit @@ -1285,7 +1239,8 @@ func (me *CvmService) DescribeCvmHpcClusterById(ctx context.Context, hpcClusterI if len(instances) < 1 { return } - hpcCluster = instances[0] + + ret = instances[0] return } @@ -1313,11 +1268,11 @@ func (me *CvmService) DeleteCvmHpcClusterById(ctx context.Context, hpcClusterId return } -func (me *CvmService) DescribeCvmLaunchTemplateById(ctx context.Context, launchTemplateId string) (launchTemplate *cvm.LaunchTemplateInfo, errRet error) { +func (me *CvmService) DescribeCvmLaunchTemplateById(ctx context.Context, launchTemplateId string) (ret *cvm.LaunchTemplateInfo, errRet error) { logId := tccommon.GetLogId(ctx) request := cvm.NewDescribeLaunchTemplatesRequest() - request.LaunchTemplateIds = []*string{&launchTemplateId} + request.LaunchTemplateIds = []*string{helper.String(launchTemplateId)} defer func() { if errRet != nil { @@ -1338,7 +1293,7 @@ func (me *CvmService) DescribeCvmLaunchTemplateById(ctx context.Context, launchT return } - launchTemplate = response.Response.LaunchTemplateSet[0] + ret = response.Response.LaunchTemplateSet[0] return } @@ -1434,11 +1389,11 @@ func (me *CvmService) DeleteCvmLaunchTemplateById(ctx context.Context, launchTem return } -func (me *CvmService) DescribeCvmLaunchTemplateVersionById(ctx context.Context, launchTemplateId, launchTemplateVersionNumber string) (launchTemplateVersion *cvm.LaunchTemplateVersionInfo, errRet error) { +func (me *CvmService) DescribeCvmLaunchTemplateVersionById(ctx context.Context, launchTemplateId string, launchTemplateVersionNumber string) (ret *cvm.LaunchTemplateVersionInfo, errRet error) { logId := tccommon.GetLogId(ctx) request := cvm.NewDescribeLaunchTemplateVersionsRequest() - request.LaunchTemplateId = &launchTemplateId + request.LaunchTemplateId = helper.String(launchTemplateId) request.LaunchTemplateVersions = []*uint64{helper.StrToUint64Point(launchTemplateVersionNumber)} defer func() { @@ -1460,7 +1415,7 @@ func (me *CvmService) DescribeCvmLaunchTemplateVersionById(ctx context.Context, return } - launchTemplateVersion = response.Response.LaunchTemplateVersionSet[0] + ret = response.Response.LaunchTemplateVersionSet[0] return } @@ -1498,7 +1453,7 @@ func (me *CvmService) ModifyLaunchTemplateDefaultVersion(ctx context.Context, la ratelimit.Check(request.GetAction()) response, err := me.client.UseCvmClient().ModifyLaunchTemplateDefaultVersion(request) if err != nil { - if sdkErr, ok := err.(*sdkError.TencentCloudSDKError); ok { + if sdkErr, ok := err.(*sdkErrors.TencentCloudSDKError); ok { if sdkErr.Code == "InvalidParameterValue.LaunchTemplateIdVerSetAlready" && strings.Contains(sdkErr.Message, "The specified launch template version had been set to default") { return nil } @@ -1513,7 +1468,7 @@ func (me *CvmService) ModifyLaunchTemplateDefaultVersion(ctx context.Context, la return nil } -func (me *CvmService) DescribeCvmChcHostsByFilter(ctx context.Context, param map[string]interface{}) (chcHosts []*cvm.ChcHost, errRet error) { +func (me *CvmService) DescribeCvmChcHostsByFilter(ctx context.Context, param map[string]interface{}) (ret []*cvm.ChcHost, errRet error) { var ( logId = tccommon.GetLogId(ctx) request = cvm.NewDescribeChcHostsRequest() @@ -1526,10 +1481,10 @@ func (me *CvmService) DescribeCvmChcHostsByFilter(ctx context.Context, param map }() for k, v := range param { - if k == "chc_ids" { - request.ChcIds = helper.Strings(v.([]string)) + if k == "ChcIds" { + request.ChcIds = v.([]*string) } - if k == "filters" { + if k == "Filters" { request.Filters = v.([]*cvm.Filter) } } @@ -1538,7 +1493,7 @@ func (me *CvmService) DescribeCvmChcHostsByFilter(ctx context.Context, param map var ( offset int64 = 0 - limit int64 = 20 + limit int64 = 100 ) for { request.Offset = &offset @@ -1553,7 +1508,7 @@ func (me *CvmService) DescribeCvmChcHostsByFilter(ctx context.Context, param map if response == nil || len(response.Response.ChcHostSet) < 1 { break } - chcHosts = append(chcHosts, response.Response.ChcHostSet...) + ret = append(ret, response.Response.ChcHostSet...) if len(response.Response.ChcHostSet) < int(limit) { break } @@ -1564,7 +1519,7 @@ func (me *CvmService) DescribeCvmChcHostsByFilter(ctx context.Context, param map return } -func (me *CvmService) DescribeCvmChcDeniedActionsByFilter(ctx context.Context, param map[string]interface{}) (chcDeniedActions []*cvm.ChcHostDeniedActions, errRet error) { +func (me *CvmService) DescribeCvmChcDeniedActionsByFilter(ctx context.Context, param map[string]interface{}) (ret []*cvm.ChcHostDeniedActions, errRet error) { var ( logId = tccommon.GetLogId(ctx) request = cvm.NewDescribeChcDeniedActionsRequest() @@ -1577,8 +1532,8 @@ func (me *CvmService) DescribeCvmChcDeniedActionsByFilter(ctx context.Context, p }() for k, v := range param { - if k == "chc_ids" { - request.ChcIds = helper.Strings(v.([]string)) + if k == "ChcIds" { + request.ChcIds = v.([]*string) } } @@ -1591,11 +1546,11 @@ func (me *CvmService) DescribeCvmChcDeniedActionsByFilter(ctx context.Context, p } 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.ChcHostDeniedActionSet) < 1 { + if len(response.Response.ChcHostDeniedActionSet) < 1 { return } - chcDeniedActions = append(chcDeniedActions, response.Response.ChcHostDeniedActionSet...) + ret = response.Response.ChcHostDeniedActionSet return } @@ -1682,7 +1637,7 @@ func (me *CvmService) CvmSyncImagesStateRefreshFunc(imageId string, failStates [ } } -func (me *CvmService) DescribeCvmImageQuotaByFilter(ctx context.Context, param map[string]interface{}) (imageQuota int64, errRet error) { +func (me *CvmService) DescribeCvmImageQuotaByFilter(ctx context.Context, param map[string]interface{}) (ret *cvm.DescribeImageQuotaResponseParams, errRet error) { var ( logId = tccommon.GetLogId(ctx) request = cvm.NewDescribeImageQuotaRequest() @@ -1704,15 +1659,14 @@ func (me *CvmService) DescribeCvmImageQuotaByFilter(ctx context.Context, param m 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 { - errRet = fmt.Errorf("Response is null") return } - imageQuota = *response.Response.ImageNumQuota + ret = response.Response return } -func (me *CvmService) DescribeCvmImageSharePermissionByFilter(ctx context.Context, param map[string]interface{}) (imageSharePermission []*cvm.SharePermission, errRet error) { +func (me *CvmService) DescribeCvmImageSharePermissionByFilter(ctx context.Context, param map[string]interface{}) (ret []*cvm.SharePermission, errRet error) { var ( logId = tccommon.GetLogId(ctx) request = cvm.NewDescribeImageSharePermissionRequest() @@ -1739,11 +1693,11 @@ func (me *CvmService) DescribeCvmImageSharePermissionByFilter(ctx context.Contex } 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 { - errRet = fmt.Errorf("Response is null") + if len(response.Response.SharePermissionSet) < 1 { + return } - imageSharePermission = response.Response.SharePermissionSet + ret = response.Response.SharePermissionSet return } @@ -1776,3 +1730,919 @@ func (me *CvmService) ModifyImageSharePermission(ctx context.Context, imageId, p } return } + +func (me *CvmService) DescribeCvmDisasterRecoverGroupQuotaByFilter(ctx context.Context, param map[string]interface{}) (ret *cvm.DescribeDisasterRecoverGroupQuotaResponseParams, errRet error) { + var ( + logId = tccommon.GetLogId(ctx) + request = cvm.NewDescribeDisasterRecoverGroupQuotaRequest() + ) + + 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().DescribeDisasterRecoverGroupQuota(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) DescribeCvmImportImageOsByFilter(ctx context.Context, param map[string]interface{}) (ret *cvm.DescribeImportImageOsResponseParams, errRet error) { + var ( + logId = tccommon.GetLogId(ctx) + request = cvm.NewDescribeImportImageOsRequest() + ) + + 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().DescribeImportImageOs(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) DescribeCvmChcConfigById(ctx context.Context, chcId string) (ret *cvm.ChcHost, errRet error) { + logId := tccommon.GetLogId(ctx) + + request := cvm.NewDescribeChcHostsRequest() + request.ChcIds = []*string{helper.String(chcId)} + + 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 = 20 + ) + var instances []*cvm.ChcHost + for { + request.Offset = &offset + request.Limit = &limit + response, err := me.client.UseCvmClient().DescribeChcHosts(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.ChcHostSet) < 1 { + break + } + instances = append(instances, response.Response.ChcHostSet...) + if len(response.Response.ChcHostSet) < int(limit) { + break + } + + offset += limit + } + + if len(instances) < 1 { + return + } + + ret = instances[0] + return +} + +func (me *CvmService) DescribeCvmImageSharePermissionById(ctx context.Context, imageId string) (ret *cvm.DescribeImageSharePermissionResponseParams, errRet error) { + logId := tccommon.GetLogId(ctx) + + request := cvm.NewDescribeImageSharePermissionRequest() + request.ImageId = &imageId + + 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().DescribeImageSharePermission(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 *CvmService) DescribeCvmLaunchTemplateById1(ctx context.Context, launchTemplateId string) (ret *cvm.LaunchTemplateVersionInfo, errRet error) { + logId := tccommon.GetLogId(ctx) + + request := cvm.NewDescribeLaunchTemplateVersionsRequest() + request.LaunchTemplateId = helper.String(launchTemplateId) + + 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().DescribeLaunchTemplateVersions(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.LaunchTemplateVersionSet) < 1 { + return + } + + ret = response.Response.LaunchTemplateVersionSet[0] + return +} + +func (me *CvmService) DescribeReservedInstanceById(ctx context.Context, reservedInstanceId string) (ret *cvm.ReservedInstances, errRet error) { + logId := tccommon.GetLogId(ctx) + + request := cvm.NewDescribeReservedInstancesRequest() + filter := &cvm.Filter{ + Name: helper.String("reserved-instances-id"), + Values: []*string{helper.String(reservedInstanceId)}, + } + request.Filters = append(request.Filters, filter) + + 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 = 20 + ) + var instances []*cvm.ReservedInstances + for { + request.Offset = &offset + request.Limit = &limit + response, err := me.client.UseCvmClient().DescribeReservedInstances(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.ReservedInstancesSet) < 1 { + break + } + instances = append(instances, response.Response.ReservedInstancesSet...) + if len(response.Response.ReservedInstancesSet) < int(limit) { + break + } + + offset += limit + } + + if len(instances) < 1 { + return + } + + ret = instances[0] + return +} + +func (me *CvmService) DescribeReservedInstanceConfigsByFilter(ctx context.Context, param map[string]interface{}) (ret []*cvm.ReservedInstancesOffering, errRet error) { + var ( + logId = tccommon.GetLogId(ctx) + request = cvm.NewDescribeReservedInstancesOfferingsRequest() + ) + + 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().DescribeReservedInstancesOfferings(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.ReservedInstancesOfferingsSet) < 1 { + break + } + ret = append(ret, response.Response.ReservedInstancesOfferingsSet...) + if len(response.Response.ReservedInstancesOfferingsSet) < int(limit) { + break + } + + offset += limit + } + + return +} + +func (me *CvmService) DescribeReservedInstancesByFilter(ctx context.Context, param map[string]interface{}) (ret []*cvm.ReservedInstances, errRet error) { + var ( + logId = tccommon.GetLogId(ctx) + request = cvm.NewDescribeReservedInstancesRequest() + ) + + 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().DescribeReservedInstances(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.ReservedInstancesSet) < 1 { + break + } + ret = append(ret, response.Response.ReservedInstancesSet...) + if len(response.Response.ReservedInstancesSet) < int(limit) { + break + } + + offset += limit + } + + return +} + +func (me *CvmService) DescribeCvmInstanceVncUrlByFilter(ctx context.Context, param map[string]interface{}) (ret *cvm.DescribeInstanceVncUrlResponseParams, errRet error) { + var ( + logId = tccommon.GetLogId(ctx) + request = cvm.NewDescribeInstanceVncUrlRequest() + ) + + 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 == "InstanceId" { + request.InstanceId = v.(*string) + } + } + + ratelimit.Check(request.GetAction()) + + response, err := me.client.UseCvmClient().DescribeInstanceVncUrl(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) DescribeEipAddressQuotaByFilter(ctx context.Context, param map[string]interface{}) (ret []*vpc.Quota, errRet error) { + var ( + logId = tccommon.GetLogId(ctx) + request = vpc.NewDescribeAddressQuotaRequest() + ) + + 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().DescribeAddressQuota(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.QuotaSet) < 1 { + return + } + + ret = response.Response.QuotaSet + return +} + +func (me *CvmService) DescribeEipNetworkAccountTypeByFilter(ctx context.Context, param map[string]interface{}) (ret *vpc.DescribeNetworkAccountTypeResponseParams, errRet error) { + var ( + logId = tccommon.GetLogId(ctx) + request = vpc.NewDescribeNetworkAccountTypeRequest() + ) + + 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().DescribeNetworkAccountType(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) DescribeCvmInstancesModificationByFilter(ctx context.Context, param map[string]interface{}) (ret []*cvm.InstanceTypeConfigStatus, errRet error) { + var ( + logId = tccommon.GetLogId(ctx) + request = cvm.NewDescribeInstancesModificationRequest() + ) + + 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 == "InstanceIds" { + request.InstanceIds = v.([]*string) + } + if k == "Filters" { + request.Filters = v.([]*cvm.Filter) + } + } + + ratelimit.Check(request.GetAction()) + + response, err := me.client.UseCvmClient().DescribeInstancesModification(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.InstanceTypeConfigStatusSet) < 1 { + return + } + + ret = response.Response.InstanceTypeConfigStatusSet + return +} + +func (me *CvmService) DescribeCvmLaunchTemplateDefaultVersionById(ctx context.Context, launchTemplateId string) (ret *cvm.LaunchTemplateVersionInfo, errRet error) { + logId := tccommon.GetLogId(ctx) + + request := cvm.NewDescribeLaunchTemplateVersionsRequest() + request.LaunchTemplateId = helper.String(launchTemplateId) + + 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 uint64 = 0 + limit uint64 = 20 + ) + var instances []*cvm.LaunchTemplateVersionInfo + for { + request.Offset = &offset + request.Limit = &limit + response, err := me.client.UseCvmClient().DescribeLaunchTemplateVersions(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.LaunchTemplateVersionSet) < 1 { + break + } + instances = append(instances, response.Response.LaunchTemplateVersionSet...) + if len(response.Response.LaunchTemplateVersionSet) < int(limit) { + break + } + + offset += limit + } + + if len(instances) < 1 { + return + } + + for _, info := range instances { + if info.IsDefaultVersion != nil && *info.IsDefaultVersion == true { + ret = info + break + } + } + return +} + +func NewVpcService(client *connectivity.TencentCloudClient) VpcService { + return VpcService{client: client} +} + +type VpcService struct { + client *connectivity.TencentCloudClient +} + +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 + + 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 *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) 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/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/image.html.markdown b/website/docs/r/image.html.markdown index 5c413cb968..d9d7b594b7 100644 --- a/website/docs/r/image.html.markdown +++ b/website/docs/r/image.html.markdown @@ -33,7 +33,7 @@ The following arguments are supported: * `instance_id` - (Optional, String, ForceNew) Cloud server instance ID. * `snapshot_ids` - (Optional, Set: [`String`], ForceNew) Cloud disk snapshot ID list; creating a mirror based on a snapshot must include a system disk snapshot. It cannot be passed in simultaneously with InstanceId. * `sysprep` - (Optional, Bool) Sysprep function under Windows. When creating a Windows image, you can select true or false to enable or disable the Syspre function. -* `tags` - (Optional, Map) Tags of the image. +* `tags` - (Optional, Map) Tag description list. ## Attributes Reference diff --git a/website/docs/r/instance.html.markdown b/website/docs/r/instance.html.markdown index 9fc943a0d6..9537266f97 100644 --- a/website/docs/r/instance.html.markdown +++ b/website/docs/r/instance.html.markdown @@ -223,15 +223,14 @@ The following arguments are supported: * `cdh_host_id` - (Optional, String, ForceNew) Id of cdh instance. Note: it only works when instance_charge_type is set to `CDHPAID`. * `cdh_instance_type` - (Optional, String) Type of instance created on cdh, the value of this parameter is in the format of CDH_XCXG based on the number of CPU cores and memory capacity. Note: it only works when instance_charge_type is set to `CDHPAID`. * `data_disks` - (Optional, List, ForceNew) Settings for data disks. -* `dedicated_cluster_id` - (Optional, String, ForceNew) Exclusive cluster id. * `disable_api_termination` - (Optional, Bool) Whether the termination protection is enabled. Default is `false`. If set true, which means that this instance can not be deleted by an API action. * `disable_monitor_service` - (Optional, Bool) Disable enhance service for monitor, it is enabled by default. When this options is set, monitor agent won't be installed. Modifying will cause the instance reset. * `disable_security_service` - (Optional, Bool) Disable enhance service for security, it is enabled by default. When this options is set, security agent won't be installed. Modifying will cause the instance reset. * `force_delete` - (Optional, Bool) Indicate whether to force delete the instance. Default is `false`. If set true, the instance will be permanently deleted instead of being moved into the recycle bin. Note: only works for `PREPAID` instance. * `hostname` - (Optional, String) The hostname of the instance. Windows instance: The name should be a combination of 2 to 15 characters comprised of letters (case insensitive), numbers, and hyphens (-). Period (.) is not supported, and the name cannot be a string of pure numbers. Other types (such as Linux) of instances: The name should be a combination of 2 to 60 characters, supporting multiple periods (.). The piece between two periods is composed of letters (case insensitive), numbers, and hyphens (-). Modifying will cause the instance reset. -* `instance_charge_type_prepaid_period` - (Optional, Int) The tenancy (time unit is month) of the prepaid instance, NOTE: it only works when instance_charge_type is set to `PREPAID`. Valid values are `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `24`, `36`, `48`, `60`. +* `instance_charge_type_prepaid_period` - (Optional, Int) The tenancy (time unit is month) of the prepaid instance, NOTE: it only works when instance_charge_type is set to `PREPAID`. Valid values are `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `24`, `36`. * `instance_charge_type_prepaid_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: it only works when instance_charge_type is set to `PREPAID`. -* `instance_charge_type` - (Optional, String) The charge type of instance. Valid values are `PREPAID`, `POSTPAID_BY_HOUR`, `SPOTPAID`, `CDHPAID` and `CDCPAID`. The default is `POSTPAID_BY_HOUR`. Note: TencentCloud International only supports `POSTPAID_BY_HOUR` and `CDHPAID`. `PREPAID` instance may not allow to delete before expired. `SPOTPAID` instance must set `spot_instance_type` and `spot_max_price` at the same time. `CDHPAID` instance must set `cdh_instance_type` and `cdh_host_id`. +* `instance_charge_type` - (Optional, String) The charge type of instance. Valid values are `PREPAID`, `POSTPAID_BY_HOUR`, `SPOTPAID` and `CDHPAID`. The default is `POSTPAID_BY_HOUR`. Note: TencentCloud International only supports `POSTPAID_BY_HOUR` and `CDHPAID`. `PREPAID` instance may not allow to delete before expired. `SPOTPAID` instance must set `spot_instance_type` and `spot_max_price` at the same time. `CDHPAID` instance must set `cdh_instance_type` and `cdh_host_id`. * `instance_count` - (Optional, Int, **Deprecated**) It has been deprecated from version 1.59.18. Use built-in `count` instead. The number of instances to be purchased. Value range:[1,100]; default value: 1. * `instance_name` - (Optional, String) The name of the instance. The max length of instance_name is 60, and default value is `Terraform-CVM-Instance`. * `instance_type` - (Optional, String) The type of the instance. @@ -252,7 +251,6 @@ The following arguments are supported: * `stopped_mode` - (Optional, String) Billing method of a pay-as-you-go instance after shutdown. Available values: `KEEP_CHARGING`,`STOP_CHARGING`. Default `KEEP_CHARGING`. * `subnet_id` - (Optional, String) The ID of a VPC subnet. If you want to create instances in a VPC network, this parameter must be set. * `system_disk_id` - (Optional, String) System disk snapshot ID used to initialize the system disk. When system disk type is `LOCAL_BASIC` and `LOCAL_SSD`, disk id is not supported. -* `system_disk_resize_online` - (Optional, Bool) Resize online. * `system_disk_size` - (Optional, Int) Size of the system disk. unit is GB, Default is 50GB. If modified, the instance may force stop. * `system_disk_type` - (Optional, String) System disk type. For more information on limits of system disk types, see [Storage Overview](https://intl.cloud.tencent.com/document/product/213/4952). Valid values: `LOCAL_BASIC`: local disk, `LOCAL_SSD`: local SSD disk, `CLOUD_BASIC`: cloud disk, `CLOUD_SSD`: cloud SSD disk, `CLOUD_PREMIUM`: Premium Cloud Storage, `CLOUD_BSSD`: Basic SSD, `CLOUD_HSSD`: Enhanced SSD, `CLOUD_TSSD`: Tremendous SSD. NOTE: If modified, the instance may force stop. * `tags` - (Optional, Map) A mapping of tags to assign to the resource. For tag limits, please refer to [Use Limits](https://intl.cloud.tencent.com/document/product/651/13354). @@ -266,7 +264,6 @@ The `data_disks` object supports the following: * `data_disk_type` - (Required, String, ForceNew) Data disk type. For more information about limits on different data disk types, see [Storage Overview](https://intl.cloud.tencent.com/document/product/213/4952). Valid values: LOCAL_BASIC: local disk, LOCAL_SSD: local SSD disk, LOCAL_NVME: local NVME disk, specified in the InstanceType, LOCAL_PRO: local HDD disk, specified in the InstanceType, CLOUD_BASIC: HDD cloud disk, CLOUD_PREMIUM: Premium Cloud Storage, CLOUD_SSD: SSD, CLOUD_HSSD: Enhanced SSD, CLOUD_TSSD: Tremendous SSD, CLOUD_BSSD: Balanced SSD. * `data_disk_id` - (Optional, String) Data disk ID used to initialize the data disk. When data disk type is `LOCAL_BASIC` and `LOCAL_SSD`, disk id is not supported. * `data_disk_snapshot_id` - (Optional, String, ForceNew) Snapshot ID of the data disk. The selected data disk snapshot size must be smaller than the data disk size. -* `delete_with_instance_prepaid` - (Optional, Bool, ForceNew) Decides whether the disk is deleted with instance(only applied to `CLOUD_BASIC`, `CLOUD_SSD` and `CLOUD_PREMIUM` disk with `PREPAID` instance), default is false. * `delete_with_instance` - (Optional, Bool, ForceNew) Decides whether the disk is deleted with instance(only applied to `CLOUD_BASIC`, `CLOUD_SSD` and `CLOUD_PREMIUM` disk with `POSTPAID_BY_HOUR` instance), default is true. * `encrypt` - (Optional, Bool, ForceNew) Decides whether the disk is encrypted. Default is `false`. * `throughput_performance` - (Optional, Int, ForceNew) Add extra performance to the data disk. Only works when disk type is `CLOUD_TSSD` or `CLOUD_HSSD`. diff --git a/website/docs/r/key_pair.html.markdown b/website/docs/r/key_pair.html.markdown index 664d0214fa..26e0e274d3 100644 --- a/website/docs/r/key_pair.html.markdown +++ b/website/docs/r/key_pair.html.markdown @@ -31,7 +31,7 @@ The following arguments are supported: * `key_name` - (Required, String) The key pair's name. It is the only in one TencentCloud account. * `project_id` - (Optional, Int, ForceNew) Specifys to which project the key pair belongs. * `public_key` - (Optional, String, ForceNew) You can import an existing public key and using TencentCloud key pair to manage it. -* `tags` - (Optional, Map) Tags of the key pair. +* `tags` - (Optional, Map) Tag description list. ## Attributes Reference