diff --git a/go.mod b/go.mod index 546c645774..1aa1632def 100644 --- a/go.mod +++ b/go.mod @@ -43,10 +43,10 @@ require ( github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/chdfs v1.0.600 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ciam v1.0.695 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ckafka v1.0.1073 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1107 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1132 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cloudaudit v1.0.1033 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cls v1.0.1078 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1130 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1132 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.1128 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cwp v1.0.762 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb v1.0.1111 diff --git a/go.sum b/go.sum index 424111020f..abb581cc62 100644 --- a/go.sum +++ b/go.sum @@ -860,6 +860,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ckafka v1.0.1073 h1:+nT github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ckafka v1.0.1073/go.mod h1:D9xdyB3utAtgGwTExSGxHSVQMfVHEUo/bfaBTxjHkao= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1107 h1:sUiyGfYHzNpHKJx6DlRu1K8xBEGaWlOQT+8W5Ws0v4U= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1107/go.mod h1:L1r6mc7XjFlyLlOVqRvPEhjXneHywnyjyv9EoiGBRvM= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1132 h1:dXKq4d4zTZYV0q1uyf7AJM+u00dd5ndL7lqGfjkmQW0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1132/go.mod h1:nwCB78ZVNC6VC+rd31yxhUeff/Ve7z4+yrL3A2B+/dg= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cloudaudit v1.0.1033 h1:dIr+MVsZeUBiKZELfJh5HRJdI+BI6lCp5pv/2oXekuk= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cloudaudit v1.0.1033/go.mod h1:7oFlNimGSTHFy6JV7W/IZKuJWr+NUjCnGLTvb9MWNrY= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cls v1.0.1078 h1:6yf63sgR2q1ikVedWTXldtrArDHXG01yIdcWSSI5e5Y= @@ -933,6 +935,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1128/go.mod github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1129/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1130 h1:pjtrqJUaidq1fFWwPvBorq7FScq0LXiQ7pZjJZx3Jsc= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1130/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1132 h1:ecdDh9up1kMKSZtEpvRHGF6BsIlfBtdCSBZm3SK5/Xk= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1132/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/controlcenter v1.0.993 h1:WlPgXldQCxt7qi5Xrc6j6zTrsXWzN5BcOGs7Irq7fwQ= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/controlcenter v1.0.993/go.mod h1:Z9U8zNtyuyKhjS0698wqsrG/kLx1TQ5CEixXBwVe7xY= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/csip v1.0.860 h1:F3esKBIT3HW9+7Gt8cVgf8X06VdGIczpgLBUECzSEzU= diff --git a/tencentcloud/services/clb/resource_tc_clb_listener.go b/tencentcloud/services/clb/resource_tc_clb_listener.go index b5f4da9051..a628880a05 100644 --- a/tencentcloud/services/clb/resource_tc_clb_listener.go +++ b/tencentcloud/services/clb/resource_tc_clb_listener.go @@ -281,6 +281,12 @@ func ResourceTencentCloudClbListener() *schema.Resource { Optional: true, Description: "Whether to enable SNAT.", }, + "full_end_ports": { + Type: schema.TypeList, + Optional: true, + Description: "End port of the full port segment listener.", + Elem: &schema.Schema{Type: schema.TypeInt}, + }, //computed "listener_id": { Type: schema.TypeString, @@ -411,6 +417,15 @@ func resourceTencentCloudClbListenerCreate(d *schema.ResourceData, meta interfac request.SnatEnable = helper.Bool(v.(bool)) } + if v, ok := d.GetOk("full_end_ports"); ok { + fullEndPorts := v.([]interface{}) + request.FullEndPorts = make([]*int64, 0, len(fullEndPorts)) + for i := range fullEndPorts { + item := fullEndPorts[i].(int) + request.FullEndPorts = append(request.FullEndPorts, helper.IntInt64(item)) + } + } + var response *clb.CreateListenerResponse err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseClbClient().CreateListener(request) diff --git a/tencentcloud/services/clb/resource_tc_clb_target_group.go b/tencentcloud/services/clb/resource_tc_clb_target_group.go index 27bdf1e826..7144721142 100644 --- a/tencentcloud/services/clb/resource_tc_clb_target_group.go +++ b/tencentcloud/services/clb/resource_tc_clb_target_group.go @@ -2,9 +2,13 @@ package clb import ( "context" + "fmt" + "log" 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" clb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317" ) @@ -36,7 +40,7 @@ func ResourceTencentCloudClbTargetGroup() *schema.Resource { Type: schema.TypeInt, Optional: true, ValidateFunc: tccommon.ValidatePort, - Description: "The default port of target group, add server after can use it.", + Description: "The default port of target group, add server after can use it. If `full_listen_switch` is true, setting this parameter is not supported.", }, "target_group_instances": { Type: schema.TypeList, @@ -72,6 +76,49 @@ func ResourceTencentCloudClbTargetGroup() *schema.Resource { }, }, }, + "type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: tccommon.ValidateAllowedStringValue([]string{"v1", "v2"}), + Description: "Target group type, currently supports v1 (old version target group), v2 (new version target group), defaults to v1 (old version target group).", + }, + "protocol": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: tccommon.ValidateAllowedStringValue([]string{"TCP", "UDP"}), + Description: "Target group backend forwarding protocol. This item is required for the v2 new version target group. Currently supports `TCP`, `UDP`.", + }, + "tags": { + Optional: true, + Type: schema.TypeList, + Description: "Label.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "tag_key": { + Type: schema.TypeString, + Required: true, + Description: "Tag key.", + }, + "tag_value": { + Type: schema.TypeString, + Required: true, + Description: "Tag value.", + }, + }, + }, + }, + "weight": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: tccommon.ValidateIntegerInRange(0, 100), + Description: "Default weights for backend services. Value range [0, 100]. After setting this value, when adding backend services to the target group, if the backend services do not have separate weights set, the default weights here will be used.", + }, + "full_listen_switch": { + Type: schema.TypeBool, + Optional: true, + Description: "Full listening target group identifier, true indicates full listening target group, false indicates not full listening target group.", + }, }, } } @@ -80,40 +127,81 @@ func resourceTencentCloudClbTargetCreate(d *schema.ResourceData, meta interface{ defer tccommon.LogElapsed("resource.tencentcloud_clb_target_group.create")() var ( - logId = tccommon.GetLogId(tccommon.ContextNil) - ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - clbService = ClbService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - vpcId = d.Get("vpc_id").(string) - targetGroupName = d.Get("target_group_name").(string) - port = uint64(d.Get("port").(int)) - insAttachments = make([]*clb.TargetGroupInstance, 0) - targetGroupId string - err error + logId = tccommon.GetLogId(tccommon.ContextNil) + request = clb.NewCreateTargetGroupRequest() + response = clb.NewCreateTargetGroupResponse() ) - if v, ok := d.GetOk("target_group_instances"); ok { - targetGroupInstances := v.([]interface{}) - for _, v1 := range targetGroupInstances { - value := v1.(map[string]interface{}) - bindIP := value["bind_ip"].(string) - port := uint64(value["port"].(int)) - weight := uint64(value["weight"].(int)) - newPort := uint64(value["new_port"].(int)) - tgtGrp := &clb.TargetGroupInstance{ - BindIP: &bindIP, - Port: &port, - Weight: &weight, - NewPort: &newPort, + if v, ok := d.GetOk("target_group_name"); ok { + request.TargetGroupName = helper.String(v.(string)) + } + + if v, ok := d.GetOk("vpc_id"); ok { + request.VpcId = helper.String(v.(string)) + } + + if v, ok := d.GetOkExists("port"); ok { + request.Port = helper.IntUint64(v.(int)) + } + + if v, ok := d.GetOk("type"); ok { + request.Type = helper.String(v.(string)) + } + + if v, ok := d.GetOk("protocol"); ok { + request.Protocol = helper.String(v.(string)) + } + + if v, ok := d.GetOk("tags"); ok { + for _, item := range v.([]interface{}) { + dMap := item.(map[string]interface{}) + clbTags := clb.TagInfo{} + if v, ok := dMap["tag_key"]; ok { + clbTags.TagKey = helper.String(v.(string)) + } + + if v, ok := dMap["tag_value"]; ok { + clbTags.TagValue = helper.String(v.(string)) } - insAttachments = append(insAttachments, tgtGrp) + + request.Tags = append(request.Tags, &clbTags) } } - targetGroupId, err = clbService.CreateTargetGroup(ctx, targetGroupName, vpcId, port, insAttachments) + if v, ok := d.GetOkExists("weight"); ok { + request.Weight = helper.IntUint64(v.(int)) + } + + if v, ok := d.GetOkExists("full_listen_switch"); ok { + request.FullListenSwitch = helper.Bool(v.(bool)) + } + + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseClbClient().CreateTargetGroup(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()) + } + + if result == nil || result.Response == nil { + return resource.NonRetryableError(fmt.Errorf("Create target group failed, Response is nil.")) + } + + response = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s create target group failed, reason:%+v", logId, err) return err } - d.SetId(targetGroupId) + + if response.Response.TargetGroupId == nil { + return fmt.Errorf("TargetGroupId is nil.") + } + + d.SetId(*response.Response.TargetGroupId) return resourceTencentCloudClbTargetRead(d, meta) @@ -124,23 +212,64 @@ func resourceTencentCloudClbTargetRead(d *schema.ResourceData, meta interface{}) defer tccommon.InconsistentCheck(d, meta)() var ( - logId = tccommon.GetLogId(tccommon.ContextNil) - ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - clbService = ClbService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - id = d.Id() + logId = tccommon.GetLogId(tccommon.ContextNil) + ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + clbService = ClbService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + targetGroupId = d.Id() ) + filters := make(map[string]string) - targetGroupInfos, err := clbService.DescribeTargetGroups(ctx, id, filters) + targetGroupInfos, err := clbService.DescribeTargetGroups(ctx, targetGroupId, filters) if err != nil { return err } + if len(targetGroupInfos) < 1 { d.SetId("") return nil } - _ = d.Set("target_group_name", targetGroupInfos[0].TargetGroupName) - _ = d.Set("vpc_id", targetGroupInfos[0].VpcId) - _ = d.Set("port", targetGroupInfos[0].Port) + + if targetGroupInfos[0].TargetGroupName != nil { + _ = d.Set("target_group_name", targetGroupInfos[0].TargetGroupName) + } + + if targetGroupInfos[0].VpcId != nil { + _ = d.Set("vpc_id", targetGroupInfos[0].VpcId) + } + + if targetGroupInfos[0].Port != nil { + _ = d.Set("port", targetGroupInfos[0].Port) + } + + if targetGroupInfos[0].TargetGroupType != nil { + _ = d.Set("type", targetGroupInfos[0].TargetGroupType) + } + + if targetGroupInfos[0].Tag != nil { + tagsList := make([]interface{}, 0, len(targetGroupInfos[0].Tag)) + for _, tags := range targetGroupInfos[0].Tag { + tagsMap := map[string]interface{}{} + if tags.TagKey != nil { + tagsMap["tag_key"] = tags.TagKey + } + + if tags.TagValue != nil { + tagsMap["tag_value"] = tags.TagValue + } + + tagsList = append(tagsList, tagsMap) + } + + _ = d.Set("tags", tagsList) + } + + if targetGroupInfos[0].Weight != nil { + _ = d.Set("weight", targetGroupInfos[0].Weight) + } + + if targetGroupInfos[0].FullListenSwitch != nil { + _ = d.Set("full_listen_switch", targetGroupInfos[0].FullListenSwitch) + } return nil } @@ -150,23 +279,44 @@ func resourceTencentCloudClbTargetUpdate(d *schema.ResourceData, meta interface{ var ( logId = tccommon.GetLogId(tccommon.ContextNil) - ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - clbService = ClbService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} targetGroupId = d.Id() - port uint64 - tgtGroupName string ) - isChanged := false - if d.HasChange("port") || d.HasChange("target_group_name") { - isChanged = true - port = uint64(d.Get("port").(int)) - tgtGroupName = d.Get("target_group_name").(string) + immutableArgs := []string{"type", "protocol", "tags", "full_listen_switch"} + for _, v := range immutableArgs { + if d.HasChange(v) { + return fmt.Errorf("argument `%s` cannot be changed", v) + } } - if isChanged { - err := clbService.ModifyTargetGroup(ctx, targetGroupId, tgtGroupName, port) + if d.HasChange("target_group_name") || d.HasChange("port") || d.HasChange("weight") { + request := clb.NewModifyTargetGroupAttributeRequest() + if v, ok := d.GetOk("target_group_name"); ok { + request.TargetGroupName = helper.String(v.(string)) + } + + if v, ok := d.GetOkExists("port"); ok { + request.Port = helper.IntUint64(v.(int)) + } + + if v, ok := d.GetOkExists("weight"); ok { + request.Weight = helper.IntUint64(v.(int)) + } + + request.TargetGroupId = &targetGroupId + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseClbClient().ModifyTargetGroupAttribute(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 modify target group failed, reason:%+v", logId, err) return err } } @@ -185,9 +335,9 @@ func resourceTencentCloudClbTargetDelete(d *schema.ResourceData, meta interface{ ) err := clbService.DeleteTarget(ctx, targetGroupId) - if err != nil { return err } + return nil } diff --git a/tencentcloud/services/clb/resource_tc_clb_target_group.md b/tencentcloud/services/clb/resource_tc_clb_target_group.md index 4b73493049..5bb0765da4 100644 --- a/tencentcloud/services/clb/resource_tc_clb_target_group.md +++ b/tencentcloud/services/clb/resource_tc_clb_target_group.md @@ -2,10 +2,55 @@ Provides a resource to create a CLB target group. Example Usage +If type is v1 + +```hcl +resource "tencentcloud_clb_target_group" "example" { + target_group_name = "tf-example" + vpc_id = "vpc-jy6pwoy2" + port = 8090 + type = "v1" + + tags { + tag_key = "tagKey" + tag_value = "tagValue" + } +} +``` + +If type is v2 + ```hcl -resource "tencentcloud_clb_target_group" "test"{ - target_group_name = "test" - port = 33 +resource "tencentcloud_clb_target_group" "example" { + target_group_name = "tf-example" + vpc_id = "vpc-jy6pwoy2" + port = 8090 + type = "v2" + protocol = "TCP" + weight = 60 + + tags { + tag_key = "tagKey" + tag_value = "tagValue" + } +} +``` + +Or full_listen_switch is true + +```hcl +resource "tencentcloud_clb_target_group" "example" { + target_group_name = "tf-example" + vpc_id = "vpc-jy6pwoy2" + type = "v2" + protocol = "TCP" + weight = 60 + full_listen_switch = true + + tags { + tag_key = "tagKey" + tag_value = "tagValue" + } } ``` @@ -14,5 +59,5 @@ Import CLB target group can be imported using the id, e.g. ``` -$ terraform import tencentcloud_clb_target_group.test lbtg-3k3io0i0 -``` \ No newline at end of file +$ terraform import tencentcloud_clb_target_group.example lbtg-3k3io0i0 +``` diff --git a/tencentcloud/services/clb/resource_tc_clb_target_group_attachment.go b/tencentcloud/services/clb/resource_tc_clb_target_group_attachment.go index 85d59d957a..4461fd0c1a 100644 --- a/tencentcloud/services/clb/resource_tc_clb_target_group_attachment.go +++ b/tencentcloud/services/clb/resource_tc_clb_target_group_attachment.go @@ -49,6 +49,13 @@ func ResourceTencentCloudClbTargetGroupAttachment() *schema.Resource { ForceNew: true, Description: "ID of the CLB listener rule.", }, + "weight": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + ValidateFunc: tccommon.ValidateIntegerInRange(0, 100), + Description: "Target group weight, range [0, 100]. It only takes effect when binding to the v2 target group. If it does not exist, it defaults to 10.", + }, }, } } @@ -89,6 +96,10 @@ func resourceTencentCloudClbTargetGroupAttachmentCreate(d *schema.ResourceData, locationId = v.(string) } + if v, ok := d.GetOkExists("weight"); ok { + targetGroupAssociation.Weight = helper.IntInt64(v.(int)) + } + //check listenerId checkErr := ListenerIdCheck(listenerId) if checkErr != nil { @@ -195,7 +206,7 @@ func resourceTencentCloudClbTargetGroupAttachmentRead(d *schema.ResourceData, me return fmt.Errorf("CLB target group attachment id is clb_id#listener_id#target_group_id#rule_id(only required for 7 layer CLB)") } - has, err := clbService.DescribeAssociateTargetGroups(ctx, ids) + targetInfo, has, err := clbService.DescribeAssociateTargetGroups(ctx, ids) if err != nil { return err } @@ -212,6 +223,10 @@ func resourceTencentCloudClbTargetGroupAttachmentRead(d *schema.ResourceData, me _ = d.Set("rule_id", ids[3]) } + if targetInfo.Weight != nil { + _ = d.Set("weight", targetInfo.Weight) + } + return nil } diff --git a/tencentcloud/services/clb/resource_tc_clb_target_group_attachment_test.go b/tencentcloud/services/clb/resource_tc_clb_target_group_attachment_test.go index 0de3babf64..e29ac84827 100644 --- a/tencentcloud/services/clb/resource_tc_clb_target_group_attachment_test.go +++ b/tencentcloud/services/clb/resource_tc_clb_target_group_attachment_test.go @@ -125,7 +125,7 @@ func testAccCheckClbTargetGroupAttachmentExists(n string) resource.TestCheckFunc return fmt.Errorf("CLB target group attachment id is clb_id#listener_id#target_group_id#rule_id(only required for 7 layer CLB)") } - has, err := clbService.DescribeAssociateTargetGroups(ctx, ids) + _, has, err := clbService.DescribeAssociateTargetGroups(ctx, ids) if err != nil { return err } diff --git a/tencentcloud/services/clb/resource_tc_clb_target_group_attachments.go b/tencentcloud/services/clb/resource_tc_clb_target_group_attachments.go index e9a18e59ec..4e2ab5beb7 100644 --- a/tencentcloud/services/clb/resource_tc_clb_target_group_attachments.go +++ b/tencentcloud/services/clb/resource_tc_clb_target_group_attachments.go @@ -71,6 +71,13 @@ func ResourceTencentCloudClbTargetGroupAttachments() *schema.Resource { Optional: true, Description: "Forwarding rule ID.", }, + "weight": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + ValidateFunc: tccommon.ValidateIntegerInRange(0, 100), + Description: "Target group weight, range [0, 100]. It only takes effect when binding to the v2 target group. If it does not exist, it defaults to 10.", + }, }, }, }, @@ -269,8 +276,14 @@ func parseParamToRequest(d *schema.ResourceData, param string, id string) (assoc targetGroupAssociation := clb.TargetGroupAssociation{} dMap[param] = id for name := range dMap { - if dMap[name] != nil && dMap[name].(string) != "" { - setString(name, dMap[name].(string), &targetGroupAssociation) + if dMap[name] != nil { + if v, ok := dMap[name].(string); ok && v != "" { + setString(name, v, &targetGroupAssociation) + } + + if v, ok := dMap[name].(int); ok { + setInt(name, v, &targetGroupAssociation) + } } } associations = append(associations, &targetGroupAssociation) @@ -292,6 +305,15 @@ func setString(fieldName string, value string, request *clb.TargetGroupAssociati log.Printf("Invalid field name: %s\n", fieldName) } } + +func setInt(fieldName string, value int, request *clb.TargetGroupAssociation) { + switch fieldName { + case "weight": + request.Weight = helper.IntInt64(value) + default: + log.Printf("Invalid field name: %s\n", fieldName) + } +} func isBindFromClb(id string) bool { re := regexp.MustCompile(`^(.*?)-`) match := re.FindStringSubmatch(id) diff --git a/tencentcloud/services/clb/resource_tc_clb_target_group_instance_attachment.go b/tencentcloud/services/clb/resource_tc_clb_target_group_instance_attachment.go index a01c892579..a967556418 100644 --- a/tencentcloud/services/clb/resource_tc_clb_target_group_instance_attachment.go +++ b/tencentcloud/services/clb/resource_tc_clb_target_group_instance_attachment.go @@ -3,10 +3,11 @@ package clb import ( "context" "fmt" + "log" "strconv" "strings" - "time" + "github.com/pkg/errors" tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" @@ -29,26 +30,26 @@ func ResourceTencentCloudClbTGAttachmentInstance() *schema.Resource { "target_group_id": { Type: schema.TypeString, Required: true, - ValidateFunc: tccommon.ValidateNotEmpty, ForceNew: true, + ValidateFunc: tccommon.ValidateNotEmpty, Description: "Target group ID.", }, "bind_ip": { Type: schema.TypeString, Required: true, - ValidateFunc: tccommon.ValidateNotEmpty, ForceNew: true, + ValidateFunc: tccommon.ValidateNotEmpty, Description: "The Intranet IP of the target group instance.", }, "port": { Type: schema.TypeInt, - Required: true, + Optional: true, ForceNew: true, - Description: "Port of the target group instance.", + Description: "The port of the target group instance, fully listening to the target group does not support passing this field.", }, "weight": { Type: schema.TypeInt, - Required: true, + Optional: true, Description: "The weight of the target group instance.", }, }, @@ -60,21 +61,58 @@ func resourceTencentCloudClbTGAttachmentInstanceCreate(d *schema.ResourceData, m var ( logId = tccommon.GetLogId(tccommon.ContextNil) - ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - clbService = ClbService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} - targetGroupId = d.Get("target_group_id").(string) - bindIp = d.Get("bind_ip").(string) - port = d.Get("port").(int) - weight = d.Get("weight").(int) - err error + request = clb.NewRegisterTargetGroupInstancesRequest() + targetGroupId string + bindIp string + port int ) - err = clbService.RegisterTargetInstances(ctx, targetGroupId, bindIp, uint64(port), uint64(weight)) + if v, ok := d.GetOk("target_group_id"); ok { + request.TargetGroupId = helper.String(v.(string)) + targetGroupId = v.(string) + } + + targetGroupInstances := clb.TargetGroupInstance{} + if v, ok := d.GetOk("bind_ip"); ok { + targetGroupInstances.BindIP = helper.String(v.(string)) + bindIp = v.(string) + } + + if v, ok := d.GetOkExists("port"); ok { + targetGroupInstances.Port = helper.IntUint64(v.(int)) + port = v.(int) + } + + if v, ok := d.GetOkExists("weight"); ok { + targetGroupInstances.Weight = helper.IntUint64(v.(int)) + } + + request.TargetGroupInstances = append(request.TargetGroupInstances, &targetGroupInstances) + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseClbClient().RegisterTargetGroupInstances(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()) + } + + if result == nil || result.Response == nil || result.Response.RequestId == nil { + return resource.NonRetryableError(fmt.Errorf("Register target group instance failed, Response is nil.")) + } + + requestId := *result.Response.RequestId + retryErr := waitForTaskFinish(requestId, meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseClbClient()) + if retryErr != nil { + return resource.NonRetryableError(errors.WithStack(retryErr)) + } + + return nil + }) if err != nil { + log.Printf("[CRITAL]%s register target group instance failed, reason:%+v", logId, err) return err } - time.Sleep(time.Duration(3) * time.Second) d.SetId(strings.Join([]string{targetGroupId, bindIp, strconv.Itoa(port)}, tccommon.FILED_SP)) @@ -91,10 +129,12 @@ func resourceTencentCloudClbTGAttachmentInstanceRead(d *schema.ResourceData, met id = d.Id() targetGroupInstances []*clb.TargetGroupBackend ) + idSplit := strings.Split(id, tccommon.FILED_SP) if len(idSplit) != 3 { return fmt.Errorf("target group instance attachment id is not set") } + targetGroupId := idSplit[0] bindIp := idSplit[1] port, err := strconv.ParseUint(idSplit[2], 0, 64) @@ -110,11 +150,14 @@ func resourceTencentCloudClbTGAttachmentInstanceRead(d *schema.ResourceData, met if err != nil { return tccommon.RetryError(err, tccommon.InternalError) } + return nil }) + if err != nil { return err } + for _, tgInstance := range targetGroupInstances { if *tgInstance.Port == port { _ = d.Set("target_group_id", idSplit[0]) @@ -123,9 +166,11 @@ func resourceTencentCloudClbTGAttachmentInstanceRead(d *schema.ResourceData, met if tgInstance.Weight != nil { _ = d.Set("weight", *tgInstance.Weight) } + return nil } } + d.SetId("") return nil } @@ -142,10 +187,12 @@ func resourceTencentCloudClbTGAttachmentInstanceUpdate(d *schema.ResourceData, m bindIp, targetGroupId string err error ) + idSplit := strings.Split(id, tccommon.FILED_SP) if len(idSplit) != 3 { return fmt.Errorf("target group instance attachment id is not set") } + targetGroupId = idSplit[0] bindIp = idSplit[1] port, err = strconv.Atoi(idSplit[2]) @@ -160,6 +207,7 @@ func resourceTencentCloudClbTGAttachmentInstanceUpdate(d *schema.ResourceData, m return err } } + return resourceTencentCloudClbTGAttachmentInstanceRead(d, meta) } @@ -172,10 +220,12 @@ func resourceTencentCloudClbTGAttachmentInstanceDelete(d *schema.ResourceData, m clbService = ClbService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} id = d.Id() ) + idSplit := strings.Split(id, tccommon.FILED_SP) if len(idSplit) != 3 { return fmt.Errorf("target group instance attachment id is not set") } + targetGroupId := idSplit[0] bindIp := idSplit[1] port, err := strconv.ParseUint(idSplit[2], 0, 64) @@ -184,9 +234,9 @@ func resourceTencentCloudClbTGAttachmentInstanceDelete(d *schema.ResourceData, m } err = clbService.DeregisterTargetInstances(ctx, targetGroupId, bindIp, port) - if err != nil { return err } + return nil } diff --git a/tencentcloud/services/clb/service_tencentcloud_clb.go b/tencentcloud/services/clb/service_tencentcloud_clb.go index a48787736d..48e1035ef2 100644 --- a/tencentcloud/services/clb/service_tencentcloud_clb.go +++ b/tencentcloud/services/clb/service_tencentcloud_clb.go @@ -1481,7 +1481,7 @@ func (me *ClbService) AssociateTargetGroups(ctx context.Context, listenerId, clb return } -func (me *ClbService) DescribeAssociateTargetGroups(ctx context.Context, ids []string) (has bool, err error) { +func (me *ClbService) DescribeAssociateTargetGroups(ctx context.Context, ids []string) (targetInfo *clb.TargetGroupInfo, has bool, err error) { var ( logId = tccommon.GetLogId(ctx) targetInfos []*clb.TargetGroupInfo @@ -1511,15 +1511,17 @@ func (me *ClbService) DescribeAssociateTargetGroups(ctx context.Context, ids []s if *rule.Protocol == CLB_LISTENER_PROTOCOL_TCP || *rule.Protocol == CLB_LISTENER_PROTOCOL_UDP || *rule.Protocol == CLB_LISTENER_PROTOCOL_TCPSSL || *rule.Protocol == CLB_LISTENER_PROTOCOL_QUIC { if originListenerId == ids[1] && originClbId == ids[2] { - return true, nil + targetInfo = info + return targetInfo, true, nil } } else if originListenerId == ids[1] && originClbId == ids[2] && originLocationId == ids[3] { - return true, nil + targetInfo = info + return targetInfo, true, nil } } } - return false, nil + return nil, false, nil } func (me *ClbService) DisassociateTargetGroups(ctx context.Context, targetGroupId, listenerId, clbId, locationId string) (errRet error) { diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317/client.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317/client.go index dc956f4f7d..03f5e346a0 100644 --- a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317/client.go +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317/client.go @@ -1827,7 +1827,7 @@ func NewDeregisterFunctionTargetsResponse() (response *DeregisterFunctionTargets // // // -// - 仅广州、深圳金融、上海、上海金融、北京、成都、中国香港、新加坡、孟买、东京、硅谷地域支持绑定 SCF。 +// - 仅广州、深圳金融、上海、上海金融、北京、成都、中国香港、新加坡、东京、硅谷地域支持绑定 SCF。 // // - 仅标准账户类型支持绑定 SCF,传统账户类型不支持。建议升级为标准账户类型,详情可参见 [账户类型升级说明](https://cloud.tencent.com/document/product/1199/49090)。 // @@ -1868,7 +1868,7 @@ func (c *Client) DeregisterFunctionTargets(request *DeregisterFunctionTargetsReq // // // -// - 仅广州、深圳金融、上海、上海金融、北京、成都、中国香港、新加坡、孟买、东京、硅谷地域支持绑定 SCF。 +// - 仅广州、深圳金融、上海、上海金融、北京、成都、中国香港、新加坡、东京、硅谷地域支持绑定 SCF。 // // - 仅标准账户类型支持绑定 SCF,传统账户类型不支持。建议升级为标准账户类型,详情可参见 [账户类型升级说明](https://cloud.tencent.com/document/product/1199/49090)。 // @@ -5556,7 +5556,7 @@ func NewRegisterFunctionTargetsResponse() (response *RegisterFunctionTargetsResp // // 限制说明: // -// - 仅广州、深圳金融、上海、上海金融、北京、成都、中国香港、新加坡、孟买、东京、硅谷地域支持绑定 SCF。 +// - 仅广州、深圳金融、上海、上海金融、北京、成都、中国香港、新加坡、东京、硅谷地域支持绑定 SCF。 // // - 仅标准账户类型支持绑定 SCF,传统账户类型不支持。建议升级为标准账户类型,详情可参见 [账户类型升级说明](https://cloud.tencent.com/document/product/1199/49090)。 // @@ -5600,7 +5600,7 @@ func (c *Client) RegisterFunctionTargets(request *RegisterFunctionTargetsRequest // // 限制说明: // -// - 仅广州、深圳金融、上海、上海金融、北京、成都、中国香港、新加坡、孟买、东京、硅谷地域支持绑定 SCF。 +// - 仅广州、深圳金融、上海、上海金融、北京、成都、中国香港、新加坡、东京、硅谷地域支持绑定 SCF。 // // - 仅标准账户类型支持绑定 SCF,传统账户类型不支持。建议升级为标准账户类型,详情可参见 [账户类型升级说明](https://cloud.tencent.com/document/product/1199/49090)。 // diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317/models.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317/models.go index 7d319a9fbd..5ceb4bf5ac 100644 --- a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317/models.go +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317/models.go @@ -331,7 +331,7 @@ type Backend struct { // 后端服务的唯一 ID,如 ins-abcd1234 InstanceId *string `json:"InstanceId,omitnil,omitempty" name:"InstanceId"` - // 后端服务的监听端口 + // 后端服务的监听端口,如果是全端口段监听器绑定的全监听目标组场景,此端口返回0,表示无效端口,绑定的后端服务的端口随监听器端口。 Port *int64 `json:"Port,omitnil,omitempty" name:"Port"` // 后端服务的转发权重,取值范围:[0, 100],默认为 10。 @@ -746,6 +746,9 @@ type CertificateInput struct { // 认证类型,UNIDIRECTIONAL:单向认证,MUTUAL:双向认证 SSLMode *string `json:"SSLMode,omitnil,omitempty" name:"SSLMode"` + // 双向认证时,是否开启客户端认证,ON:开启,OPTIONAL:自适应,默认ON。 + SSLVerifyClient *string `json:"SSLVerifyClient,omitnil,omitempty" name:"SSLVerifyClient"` + // 服务端证书的 ID,如果不填写此项则必须上传证书,包括 CertContent,CertKey,CertName。 CertId *string `json:"CertId,omitnil,omitempty" name:"CertId"` @@ -772,6 +775,9 @@ type CertificateOutput struct { // 认证类型,UNIDIRECTIONAL:单向认证,MUTUAL:双向认证 SSLMode *string `json:"SSLMode,omitnil,omitempty" name:"SSLMode"` + // 是否开启客户端证书验证,只在双向认证时生效。 + SSLVerifyClient *string `json:"SSLVerifyClient,omitnil,omitempty" name:"SSLVerifyClient"` + // 服务端证书的ID。 CertId *string `json:"CertId,omitnil,omitempty" name:"CertId"` @@ -1350,12 +1356,8 @@ type CreateListenerRequestParams struct { HealthCheck *HealthCheck `json:"HealthCheck,omitnil,omitempty" name:"HealthCheck"` // 证书相关信息。参数限制如下: - //