diff --git a/.changelog/2776.txt b/.changelog/2776.txt new file mode 100644 index 0000000000..8b78d1d024 --- /dev/null +++ b/.changelog/2776.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/tencentcloud_clb_attachment: support domain and url params +``` diff --git a/go.mod b/go.mod index 0a622b6dca..fd1da5da2b 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.748 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.961 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.984 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cloudaudit v1.0.544 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cls v1.0.970 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.978 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.984 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.960 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cwp v1.0.762 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb v1.0.692 diff --git a/go.sum b/go.sum index 92d68e89e2..e8eb45796e 100644 --- a/go.sum +++ b/go.sum @@ -864,6 +864,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.960 h1:wiX0lVi github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.960/go.mod h1:ge3NiZB+9eEL6gcnlX2CnyYq3Qvx1AW29aP8d9RiDxE= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.961 h1:H8oPv420A7TtLsrKQv1VYaHHboI6YmYT/kNbgZXfO1Y= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.961/go.mod h1:iEXw9vSSrx7vJ2v+ird8vpjRPmF7kqTa2/VypAs8n64= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.984 h1:uvDvC8ip75yBSUiCOIu4dGv10AKkH7M3qnmOShLZZPQ= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.984/go.mod h1:mqn4vGnC39CHBaniEgnGQqSoVXBnIH8F+O1F5KXhbec= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cloudaudit v1.0.544 h1:ApY6rS7I9otgujOdAFy0+Epno1PNVCQmsOoWQxx724Y= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cloudaudit v1.0.544/go.mod h1:c37rIdL3LrJXYwrfp9c8L4MabTqKIZUe1xvnWhN75oc= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cls v1.0.860 h1:IU20AhNd0fEbgFzTTGB8cdMkUCrgB0FsLd0puC4QDzU= @@ -972,6 +974,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.971 h1:T5zE github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.971/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.978 h1:3piderD6Cl4bt8mnSOROm+My1nHM5jtReECZeAn15oQ= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.978/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.984 h1:QLSx+ibsV68NXKgzofPuo1gxFwYSWk2++rvxZxNjbVo= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.984/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/csip v1.0.860 h1:F3esKBIT3HW9+7Gt8cVgf8X06VdGIczpgLBUECzSEzU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/csip v1.0.860/go.mod h1:NZo1WplQcC314kMlCRUoy8NQju2BnolIJj7NAWgsuhY= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.624 h1:nEZqsoqt1pEoaP9JjkHQy3/H00suCfzlHW1qOm2nYD8= diff --git a/tencentcloud/services/clb/resource_tc_alb_server_attachment.go b/tencentcloud/services/clb/resource_tc_alb_server_attachment.go index e0b3671fbd..bd1704f81d 100644 --- a/tencentcloud/services/clb/resource_tc_alb_server_attachment.go +++ b/tencentcloud/services/clb/resource_tc_alb_server_attachment.go @@ -218,7 +218,7 @@ func resourceTencentCloudAlbServerAttachmentDelete(d *schema.ResourceData, meta client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - e := clbService.DeleteAttachmentById(ctx, clbId, listenerId, locationId, d.Get("backends").(*schema.Set).List()) + e := clbService.DeleteAttachmentById(ctx, clbId, listenerId, locationId, d.Get("backends").(*schema.Set).List(), "", "") if e != nil { return tccommon.RetryError(e) } diff --git a/tencentcloud/services/clb/resource_tc_clb_attachment.go b/tencentcloud/services/clb/resource_tc_clb_attachment.go index a5edc3b685..354256c3ad 100644 --- a/tencentcloud/services/clb/resource_tc_clb_attachment.go +++ b/tencentcloud/services/clb/resource_tc_clb_attachment.go @@ -22,8 +22,8 @@ func ResourceTencentCloudClbServerAttachment() *schema.Resource { return &schema.Resource{ Create: resourceTencentCloudClbServerAttachmentCreate, Read: resourceTencentCloudClbServerAttachmentRead, - Delete: resourceTencentCloudClbServerAttachmentDelete, Update: resourceTencentCloudClbServerAttachmentUpdate, + Delete: resourceTencentCloudClbServerAttachmentDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, @@ -41,10 +41,27 @@ func ResourceTencentCloudClbServerAttachment() *schema.Resource { Description: "ID of the CLB listener.", }, "rule_id": { - Type: schema.TypeString, - ForceNew: true, - Optional: true, - Description: "ID of the CLB listener rule. Only supports listeners of `HTTPS` and `HTTP` protocol.", + Type: schema.TypeString, + ForceNew: true, + Optional: true, + ConflictsWith: []string{"domain", "url"}, + Description: "ID of the CLB listener rule. Only supports listeners of `HTTPS` and `HTTP` protocol.", + }, + "domain": { + Type: schema.TypeString, + ForceNew: true, + Optional: true, + RequiredWith: []string{"url"}, + ConflictsWith: []string{"rule_id"}, + Description: "Domain of the target forwarding rule. Does not take effect when parameter `rule_id` is provided.", + }, + "url": { + Type: schema.TypeString, + ForceNew: true, + Optional: true, + RequiredWith: []string{"domain"}, + ConflictsWith: []string{"rule_id"}, + Description: "URL of the target forwarding rule. Does not take effect when parameter `rule_id` is provided.", }, "protocol_type": { Type: schema.TypeString, @@ -95,28 +112,45 @@ func resourceTencentCloudClbServerAttachmentCreate(d *schema.ResourceData, meta clbActionMu.Lock() defer clbActionMu.Unlock() - logId := tccommon.GetLogId(tccommon.ContextNil) + var ( + logId = tccommon.GetLogId(tccommon.ContextNil) + request = clb.NewRegisterTargetsRequest() + locationId string + domain string + url string + ) + listenerId := d.Get("listener_id").(string) checkErr := ListenerIdCheck(listenerId) if checkErr != nil { return checkErr } + clbId := d.Get("clb_id").(string) - locationId := "" - request := clb.NewRegisterTargetsRequest() request.LoadBalancerId = helper.String(clbId) request.ListenerId = helper.String(listenerId) if v, ok := d.GetOk("rule_id"); ok { locationId = v.(string) - checkErr := RuleIdCheck(locationId) + checkErr = RuleIdCheck(locationId) if checkErr != nil { return checkErr } + if locationId != "" { request.LocationId = helper.String(locationId) } } + if v, ok := d.GetOk("domain"); ok { + request.Domain = helper.String(v.(string)) + domain = v.(string) + } + + if v, ok := d.GetOk("url"); ok { + request.Url = helper.String(v.(string)) + url = v.(string) + } + insList := d.Get("targets").(*schema.Set).List() insLen := len(insList) for count := 0; count < insLen; count += 20 { @@ -127,6 +161,7 @@ func resourceTencentCloudClbServerAttachmentCreate(d *schema.ResourceData, meta if index >= insLen { break } + inst := insList[index].(map[string]interface{}) request.Targets = append(request.Targets, clbNewTarget(inst["instance_id"], inst["eni_ip"], inst["port"], inst["weight"])) } @@ -146,40 +181,244 @@ func resourceTencentCloudClbServerAttachmentCreate(d *schema.ResourceData, meta return resource.NonRetryableError(errors.WithStack(retryErr)) } } + return nil }) + if err != nil { log.Printf("[CRITAL]%s create CLB attachment failed, reason:%+v", logId, err) return err } } - id := fmt.Sprintf("%s#%v#%v", locationId, d.Get("listener_id"), d.Get("clb_id")) + + var id string + if locationId != "" { + id = fmt.Sprintf("%s#%v#%v", locationId, d.Get("listener_id"), d.Get("clb_id")) + } else if domain != "" && url != "" { + id = fmt.Sprintf("%s,%s#%v#%v", domain, url, d.Get("listener_id"), d.Get("clb_id")) + } else { + id = fmt.Sprintf("%s#%v#%v", "", d.Get("listener_id"), d.Get("clb_id")) + } + d.SetId(id) return resourceTencentCloudClbServerAttachmentRead(d, meta) } +func resourceTencentCloudClbServerAttachmentRead(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_clb_attachment.read")() + 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()} + instance *clb.ListenerBackend + locationId string + domain string + url string + ) + + items := strings.Split(d.Id(), "#") + locationIdOrDomainUrl := items[0] + listenerId := items[1] + clbId := items[2] + + if locationIdOrDomainUrl != "" { + if strings.HasPrefix(locationIdOrDomainUrl, "loc-") && !strings.Contains(locationIdOrDomainUrl, ",") { + // get locationId + locationId = locationIdOrDomainUrl + } else { + // get domain & url + domainUrl := strings.Split(locationIdOrDomainUrl, ",") + domain = domainUrl[0] + url = domainUrl[1] + } + } + + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + result, e := clbService.DescribeAttachmentByPara(ctx, clbId, listenerId, locationId) + if e != nil { + return tccommon.RetryError(e) + } + + instance = result + return nil + }) + + if err != nil { + log.Printf("[CRITAL]%s read CLB attachment failed, reason:%+v", logId, err) + return err + } + + //see if read empty + if instance == nil || + (len(instance.Targets) == 0 && locationId == "" && domain == "" && url == "") || + (len(instance.Rules) == 0 && locationId != "") { + d.SetId("") + return nil + } + + _ = d.Set("clb_id", clbId) + _ = d.Set("listener_id", listenerId) + _ = d.Set("protocol_type", instance.Protocol) + + if domain != "" && url != "" { + _ = d.Set("domain", domain) + _ = d.Set("url", url) + } + + var onlineTargets []*clb.Backend + if *instance.Protocol == CLB_LISTENER_PROTOCOL_HTTP || *instance.Protocol == CLB_LISTENER_PROTOCOL_HTTPS { + _ = d.Set("rule_id", locationId) + if len(instance.Rules) > 0 { + for _, loc := range instance.Rules { + if locationId == "" || locationId == *loc.LocationId { + onlineTargets = loc.Targets + } + } + } + // TCP / UDP / TCP_SSL + } else if instance.Targets != nil { + onlineTargets = instance.Targets + } + + targets := make([]interface{}, 0) + for _, onlineTarget := range onlineTargets { + if *onlineTarget.Type == CLB_BACKEND_TYPE_CVM { + target := map[string]interface{}{ + "weight": int(*onlineTarget.Weight), + "port": int(*onlineTarget.Port), + "instance_id": *onlineTarget.InstanceId, + } + + targets = append(targets, target) + } else if *onlineTarget.Type == CLB_BACKEND_TYPE_ENI || *onlineTarget.Type == CLB_BACKEND_TYPE_NAT || *onlineTarget.Type == CLB_BACKEND_TYPE_CCN { + target := map[string]interface{}{ + "weight": int(*onlineTarget.Weight), + "port": int(*onlineTarget.Port), + "eni_ip": *onlineTarget.PrivateIpAddresses[0], + } + + targets = append(targets, target) + } + } + + _ = d.Set("targets", targets) + + err = resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + result, e := clbService.DescribeTargetsByPara(ctx, clbId, listenerId, locationId) + if e != nil { + return tccommon.RetryError(e) + } + + instance = result + return nil + }) + + if err != nil { + log.Printf("[CRITAL]%s read CLB attachment tag failed, reason:%+v", logId, err) + return err + } + + return nil +} + +func resourceTencentCloudClbServerAttachmentUpdate(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_clb_attachment.update")() + + clbActionMu.Lock() + defer clbActionMu.Unlock() + + if d.HasChange("targets") { + o, n := d.GetChange("targets") + os := o.(*schema.Set) + ns := n.(*schema.Set) + add := ns.Difference(os).List() + remove := os.Difference(ns).List() + addLen := len(add) + removeLen := len(remove) + if removeLen > 0 { + for count := 0; count < removeLen; count += 20 { + removeList := make([]interface{}, 0, 20) + for i := 0; i < 20; i++ { + index := count + i + if index >= removeLen { + break + } + + removeList = append(removeList, remove[index]) + } + + err := resourceTencentCloudClbServerAttachmentRemove(d, meta, removeList) + if err != nil { + return err + } + } + } + + if addLen > 0 { + for count := 0; count < addLen; count += 20 { + addList := make([]interface{}, 0, 20) + for i := 0; i < 20; i++ { + index := count + i + if index >= addLen { + break + } + + addList = append(addList, add[index]) + } + + err := resourceTencentCloudClbServerAttachmentAdd(d, meta, addList) + if err != nil { + return err + } + } + } + + return resourceTencentCloudClbServerAttachmentRead(d, meta) + } + + return nil +} + func resourceTencentCloudClbServerAttachmentDelete(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_clb_attachment.delete")() clbActionMu.Lock() defer clbActionMu.Unlock() - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - clbService := ClbService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + var ( + logId = tccommon.GetLogId(tccommon.ContextNil) + ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + clbService = ClbService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + locationId string + domain string + url string + ) attachmentId := d.Id() - items := strings.Split(attachmentId, "#") if len(items) < 3 { return fmt.Errorf("[CHECK][CLB attachment][Delete] check: id %s of resource.tencentcloud_clb_attachment is not match loc-xxx#lbl-xxx#lb-xxx", attachmentId) } - locationId := items[0] + locationIdOrDomainUrl := items[0] listenerId := items[1] clbId := items[2] + if locationIdOrDomainUrl != "" { + if strings.HasPrefix(locationIdOrDomainUrl, "loc-") && !strings.Contains(locationIdOrDomainUrl, ",") { + // get locationId + locationId = locationIdOrDomainUrl + } else { + // get domain & url + domainUrl := strings.Split(locationIdOrDomainUrl, ",") + domain = domainUrl[0] + url = domainUrl[1] + } + } + request := clb.NewDeregisterTargetsRequest() request.ListenerId = &listenerId request.LoadBalancerId = helper.String(clbId) @@ -187,6 +426,11 @@ func resourceTencentCloudClbServerAttachmentDelete(d *schema.ResourceData, meta request.LocationId = helper.String(locationId) } + if domain != "" && url != "" { + request.Domain = helper.String(domain) + request.Url = helper.String(url) + } + //insList := d.Get("targets").(*schema.Set).List() // filter target group which cvm not existed @@ -200,6 +444,7 @@ func resourceTencentCloudClbServerAttachmentDelete(d *schema.ResourceData, meta if index >= insLen { break } + inst := insList[index].(map[string]interface{}) request.Targets = append(request.Targets, clbNewTarget(inst["instance_id"], inst["eni_ip"], inst["port"], inst["weight"])) } @@ -209,13 +454,12 @@ func resourceTencentCloudClbServerAttachmentDelete(d *schema.ResourceData, meta ratelimit.Check(request.GetAction()) result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseClbClient().DeregisterTargets(request) if e != nil { - ee, ok := e.(*sdkErrors.TencentCloudSDKError) if ok && ee.GetCode() == "InvalidParameter" { return nil } - return tccommon.RetryError(e) + return tccommon.RetryError(e) } else { log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) @@ -225,8 +469,10 @@ func resourceTencentCloudClbServerAttachmentDelete(d *schema.ResourceData, meta return resource.NonRetryableError(errors.WithStack(retryErr)) } } + return nil }) + if err != nil { log.Printf("[CRITAL]%s create CLB attachment failed, reason:%+v", logId, err) return err @@ -239,26 +485,34 @@ func resourceTencentCloudClbServerAttachmentDelete(d *schema.ResourceData, meta func resourceTencentCloudClbServerAttachmentRemove(d *schema.ResourceData, meta interface{}, remove []interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_clb_attachment.remove")() - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + var ( + logId = tccommon.GetLogId(tccommon.ContextNil) + ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + clbService = ClbService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + locationId string + domain string + url string + ) + attachmentId := d.Id() items := strings.Split(attachmentId, "#") if len(items) < 3 { return fmt.Errorf("[CHECK][CLB attachment][Remove] check: id %s of resource.tencentcloud_clb_attachment is not match loc-xxx#lbl-xxx#lb-xxx", attachmentId) } - locationId := items[0] + + locationIdOrDomainUrl := items[0] listenerId := items[1] clbId := items[2] - - request := clb.NewDeregisterTargetsRequest() - request.ListenerId = helper.String(listenerId) - request.LoadBalancerId = helper.String(clbId) - if locationId != "" { - request.LocationId = helper.String(locationId) - } - - clbService := ClbService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), + if locationIdOrDomainUrl != "" { + if strings.HasPrefix(locationIdOrDomainUrl, "loc-") && !strings.Contains(locationIdOrDomainUrl, ",") { + // get locationId + locationId = locationIdOrDomainUrl + } else { + // get domain & url + domainUrl := strings.Split(locationIdOrDomainUrl, ",") + domain = domainUrl[0] + url = domainUrl[1] + } } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { @@ -266,13 +520,15 @@ func resourceTencentCloudClbServerAttachmentRemove(d *schema.ResourceData, meta if len(removeCandidates) == 0 { return nil } - e := clbService.DeleteAttachmentById(ctx, clbId, listenerId, locationId, removeCandidates) + + e := clbService.DeleteAttachmentById(ctx, clbId, listenerId, locationId, removeCandidates, domain, url) if e != nil { return tccommon.RetryError(e) } return nil }) + if err != nil { log.Printf("[CRITAL]%s reason[%+v]", logId, err) return err @@ -283,15 +539,17 @@ func resourceTencentCloudClbServerAttachmentRemove(d *schema.ResourceData, meta func resourceTencentCloudClbServerAttachmentAdd(d *schema.ResourceData, meta interface{}, add []interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_clb_attachment.add")() - logId := tccommon.GetLogId(tccommon.ContextNil) + + var ( + logId = tccommon.GetLogId(tccommon.ContextNil) + request = clb.NewRegisterTargetsRequest() + locationId string + ) listenerId := d.Get("listener_id").(string) clbId := d.Get("clb_id").(string) - locationId := "" - request := clb.NewRegisterTargetsRequest() request.LoadBalancerId = helper.String(clbId) request.ListenerId = helper.String(listenerId) - if v, ok := d.GetOk("rule_id"); ok { locationId = v.(string) if locationId != "" { @@ -299,10 +557,19 @@ func resourceTencentCloudClbServerAttachmentAdd(d *schema.ResourceData, meta int } } + if v, ok := d.GetOk("domain"); ok { + request.Domain = helper.String(v.(string)) + } + + if v, ok := d.GetOk("url"); ok { + request.Url = helper.String(v.(string)) + } + for _, v := range add { inst := v.(map[string]interface{}) request.Targets = append(request.Targets, clbNewTarget(inst["instance_id"], inst["eni_ip"], inst["port"], inst["weight"])) } + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { requestId := "" response, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseClbClient().RegisterTargets(request) @@ -317,139 +584,14 @@ func resourceTencentCloudClbServerAttachmentAdd(d *schema.ResourceData, meta int return resource.NonRetryableError(errors.WithStack(retryErr)) } } - return nil - }) - if err != nil { - log.Printf("[CRITAL]%s add CLB attachment failed, reason:%+v", logId, err) - return err - } - return nil -} - -func resourceTencentCloudClbServerAttachmentUpdate(d *schema.ResourceData, meta interface{}) error { - defer tccommon.LogElapsed("resource.tencentcloud_clb_attachment.update")() - - clbActionMu.Lock() - defer clbActionMu.Unlock() - - if d.HasChange("targets") { - o, n := d.GetChange("targets") - os := o.(*schema.Set) - ns := n.(*schema.Set) - add := ns.Difference(os).List() - remove := os.Difference(ns).List() - addLen := len(add) - removeLen := len(remove) - if removeLen > 0 { - for count := 0; count < removeLen; count += 20 { - removeList := make([]interface{}, 0, 20) - for i := 0; i < 20; i++ { - index := count + i - if index >= removeLen { - break - } - removeList = append(removeList, remove[index]) - } - err := resourceTencentCloudClbServerAttachmentRemove(d, meta, removeList) - if err != nil { - return err - } - } - } - if addLen > 0 { - for count := 0; count < addLen; count += 20 { - addList := make([]interface{}, 0, 20) - for i := 0; i < 20; i++ { - index := count + i - if index >= addLen { - break - } - addList = append(addList, add[index]) - } - err := resourceTencentCloudClbServerAttachmentAdd(d, meta, addList) - if err != nil { - return err - } - } - } - return resourceTencentCloudClbServerAttachmentRead(d, meta) - } - - return nil -} - -func resourceTencentCloudClbServerAttachmentRead(d *schema.ResourceData, meta interface{}) error { - defer tccommon.LogElapsed("resource.tencentcloud_clb_attachment.read")() - defer tccommon.InconsistentCheck(d, meta)() - - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - - items := strings.Split(d.Id(), "#") - locationId := items[0] - listenerId := items[1] - clbId := items[2] - clbService := ClbService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } - var instance *clb.ListenerBackend - err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - result, e := clbService.DescribeAttachmentByPara(ctx, clbId, listenerId, locationId) - if e != nil { - return tccommon.RetryError(e) - } - instance = result return nil }) + if err != nil { - log.Printf("[CRITAL]%s read CLB attachment failed, reason:%+v", logId, err) + log.Printf("[CRITAL]%s add CLB attachment failed, reason:%+v", logId, err) return err } - //see if read empty - - if instance == nil || (len(instance.Targets) == 0 && locationId == "") || (len(instance.Rules) == 0 && locationId != "") { - d.SetId("") - return nil - } - - _ = d.Set("clb_id", clbId) - _ = d.Set("listener_id", listenerId) - _ = d.Set("protocol_type", instance.Protocol) - - var onlineTargets []*clb.Backend - if *instance.Protocol == CLB_LISTENER_PROTOCOL_HTTP || *instance.Protocol == CLB_LISTENER_PROTOCOL_HTTPS { - _ = d.Set("rule_id", locationId) - if len(instance.Rules) > 0 { - for _, loc := range instance.Rules { - if locationId == "" || locationId == *loc.LocationId { - onlineTargets = loc.Targets - } - } - } - // TCP / UDP / TCP_SSL - } else if instance.Targets != nil { - onlineTargets = instance.Targets - } - targets := make([]interface{}, 0) - for _, onlineTarget := range onlineTargets { - if *onlineTarget.Type == CLB_BACKEND_TYPE_CVM { - target := map[string]interface{}{ - "weight": int(*onlineTarget.Weight), - "port": int(*onlineTarget.Port), - "instance_id": *onlineTarget.InstanceId, - } - targets = append(targets, target) - } else if *onlineTarget.Type == CLB_BACKEND_TYPE_ENI || *onlineTarget.Type == CLB_BACKEND_TYPE_NAT || *onlineTarget.Type == CLB_BACKEND_TYPE_CCN { - target := map[string]interface{}{ - "weight": int(*onlineTarget.Weight), - "port": int(*onlineTarget.Port), - "eni_ip": *onlineTarget.PrivateIpAddresses[0], - } - targets = append(targets, target) - } - } - _ = d.Set("targets", targets) return nil } @@ -462,6 +604,7 @@ func getRemoveCandidates(ctx context.Context, clbService ClbService, clbId strin if err != nil { return removeCandidates } + existTargetGroups := make([]*clb.Backend, 0) existTargetGroups = append(existTargetGroups, listenerBackend.Targets...) if len(listenerBackend.Rules) > 0 { @@ -484,15 +627,18 @@ func targetGroupContainsInstance(targets []*clb.Backend, instanceId interface{}) if !ok || id == "" { return } + for _, target := range targets { if target.InstanceId == nil { continue } + if id == *target.InstanceId { log.Printf("[WARN] Instance %s applied.", id) return true } } + log.Printf("[WARN] Instance %s not exist, skip deregister.", id) return @@ -504,15 +650,18 @@ func targetGroupContainsEni(targets []*clb.Backend, eniIp interface{}) (contains if !ok || ip == "" { return } + for _, target := range targets { if len(target.PrivateIpAddresses) == 0 || target.PrivateIpAddresses[0] == nil { continue } + if ip == *target.PrivateIpAddresses[0] { log.Printf("[WARN] IP %s applied.", ip) return true } } + log.Printf("[WARN] IP %s not exist, skip deregister.", ip) return diff --git a/tencentcloud/services/clb/resource_tc_clb_attachment.md b/tencentcloud/services/clb/resource_tc_clb_attachment.md index c91e27f799..d4983fc3c4 100644 --- a/tencentcloud/services/clb/resource_tc_clb_attachment.md +++ b/tencentcloud/services/clb/resource_tc_clb_attachment.md @@ -2,12 +2,12 @@ Provides a resource to create a CLB attachment. ~> **NOTE:** This resource is designed to manage the entire set of binding relationships associated with a particular CLB (Cloud Load Balancer). As such, it does not allow the simultaneous use of this resource for the same CLB across different contexts or environments. - Example Usage -Bind a Cvm instance +Bind a Cvm instance by using `rule_id` + ```hcl -resource "tencentcloud_clb_attachment" "foo" { +resource "tencentcloud_clb_attachment" "example" { clb_id = "lb-k2zjp9lv" listener_id = "lbl-hh141sn9" rule_id = "loc-4xxr2cy7" @@ -20,9 +20,27 @@ resource "tencentcloud_clb_attachment" "foo" { } ``` -Bind multiple Cvm instances +Bind a Cvm instance by using `domian` and `url` + ```hcl -resource "tencentcloud_clb_attachment" "foo" { +resource "tencentcloud_clb_attachment" "example" { + clb_id = "lb-k2zjp9lv" + listener_id = "lbl-hh141sn9" + domain = "test.com" + url = "/" + + targets { + instance_id = "ins-1flbqyp8" + port = 80 + weight = 10 + } +} +``` + +Bind multiple Cvm instances by using `rule_id` + +```hcl +resource "tencentcloud_clb_attachment" "example" { clb_id = "lb-k2zjp9lv" listener_id = "lbl-hh141sn9" rule_id = "loc-4xxr2cy7" @@ -41,24 +59,70 @@ resource "tencentcloud_clb_attachment" "foo" { } ``` -Bind backend target is ENI +Bind multiple Cvm instances by using `domian` and `url` + +```hcl +resource "tencentcloud_clb_attachment" "example" { + clb_id = "lb-k2zjp9lv" + listener_id = "lbl-hh141sn9" + domain = "test.com" + url = "/" + + targets { + instance_id = "ins-1flbqyp8" + port = 80 + weight = 10 + } + + targets { + instance_id = "ins-ekloqpa1" + port = 81 + weight = 10 + } +} +``` + +Bind backend target is ENI by using `rule_id` + ```hcl -resource "tencentcloud_clb_attachment" "foo" { +resource "tencentcloud_clb_attachment" "example" { clb_id = "lb-k2zjp9lv" listener_id = "lbl-hh141sn9" rule_id = "loc-4xxr2cy7" + + targets { + eni_ip = "172.16.16.52" + port = 8090 + weight = 50 + } +} +``` + +Bind backend target is ENI by using `domian` and `url` + +```hcl +resource "tencentcloud_clb_attachment" "example" { + clb_id = "lb-k2zjp9lv" + listener_id = "lbl-hh141sn9" + domain = "test.com" + url = "/" targets { - eni_ip = "example-ip" - port = 23 - weight = 50 + eni_ip = "172.16.16.52" + port = 8090 + weight = 50 } } ``` + Import CLB attachment can be imported using the id, e.g. ``` -$ terraform import tencentcloud_clb_attachment.foo loc-4xxr2cy7#lbl-hh141sn9#lb-7a0t6zqb -``` \ No newline at end of file +$ terraform import tencentcloud_clb_attachment.example loc-4xxr2cy7#lbl-hh141sn9#lb-7a0t6zqb + +Or + +$ terraform import tencentcloud_clb_attachment.example test.com,/#lbl-hh141sn9#lb-7a0t6zqb +``` diff --git a/tencentcloud/services/clb/service_tencentcloud_clb.go b/tencentcloud/services/clb/service_tencentcloud_clb.go index 246bb39f44..7ca9af79c2 100644 --- a/tencentcloud/services/clb/service_tencentcloud_clb.go +++ b/tencentcloud/services/clb/service_tencentcloud_clb.go @@ -465,6 +465,59 @@ func (me *ClbService) DescribeAttachmentByPara(ctx context.Context, clbId string return } +func (me *ClbService) DescribeTargetsByPara(ctx context.Context, clbId, listenerId, locationId string) (clbAttachment *clb.ListenerBackend, errRet error) { + logId := tccommon.GetLogId(ctx) + request := clb.NewDescribeTargetsRequest() + request.LoadBalancerId = &clbId + request.ListenerIds = []*string{&listenerId} + ratelimit.Check(request.GetAction()) + response, err := me.client.UseClbClient().DescribeTargets(request) + if err != nil { + return + } + + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + //listener not found, return empty + if len(response.Response.Listeners) < 1 { + return + } + + clbListener := response.Response.Listeners[0] + protocol := clbListener.Protocol + port := clbListener.Port + + aRequest := clb.NewDescribeTargetsRequest() + aRequest.ListenerIds = []*string{&listenerId} + aRequest.LoadBalancerId = &clbId + aRequest.Protocol = protocol + aRequest.Port = port + ratelimit.Check(request.GetAction()) + aResponse, aErr := me.client.UseClbClient().DescribeTargets(aRequest) + + if aErr != nil { + //in case that the lb is not exist, return empty + if e, ok := aErr.(*sdkErrors.TencentCloudSDKError); ok { + if e.GetCode() == "InvalidParameter.LBIdNotFound" { + return + } + } + errRet = errors.WithStack(aErr) + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, aRequest.GetAction(), aRequest.ToJsonString(), aResponse.ToJsonString()) + + if len(aResponse.Response.Listeners) < 1 { + return + } else { + clbAttachment = aResponse.Response.Listeners[0] + } + + return +} + func (me *ClbService) DescribeAttachmentsByFilter(ctx context.Context, params map[string]string) (clbAttachments []*clb.ListenerBackend, errRet error) { logId := tccommon.GetLogId(ctx) //listener filter @@ -541,7 +594,7 @@ func (me *ClbService) DescribeAttachmentsByFilter(ctx context.Context, params ma return } -func (me *ClbService) DeleteAttachmentById(ctx context.Context, clbId string, listenerId string, locationId string, targets []interface{}) error { +func (me *ClbService) DeleteAttachmentById(ctx context.Context, clbId string, listenerId string, locationId string, targets []interface{}, domain string, url string) error { logId := tccommon.GetLogId(ctx) request := clb.NewDeregisterTargetsRequest() request.ListenerId = &listenerId @@ -551,7 +604,12 @@ func (me *ClbService) DeleteAttachmentById(ctx context.Context, clbId string, li request.Targets = append(request.Targets, clbNewTarget(inst["instance_id"], inst["eni_ip"], inst["port"], inst["weight"])) } if locationId != "" { - request.LocationId = &locationId + request.LocationId = helper.String(locationId) + } + + if domain != "" && url != "" { + request.Domain = helper.String(domain) + request.Url = helper.String(url) } ratelimit.Check(request.GetAction()) response, err := me.client.UseClbClient().DeregisterTargets(request) 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 a7499c714e..7a304cff41 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 @@ -4553,6 +4553,8 @@ func NewModifyLoadBalancerAttributesResponse() (response *ModifyLoadBalancerAttr // ModifyLoadBalancerAttributes // 修改负载均衡实例的属性。支持修改负载均衡实例的名称、设置负载均衡的跨域属性。 // +// 注意:非带宽上移用户的 CLB 实例必须加入带宽包才可以设置跨域属性。 +// // 本接口为异步接口,接口返回成功后,需以得到的 RequestID 为入参,调用 DescribeTaskStatus 接口查询本次任务是否成功。 // // 可能返回的错误码: @@ -4577,6 +4579,8 @@ func (c *Client) ModifyLoadBalancerAttributes(request *ModifyLoadBalancerAttribu // ModifyLoadBalancerAttributes // 修改负载均衡实例的属性。支持修改负载均衡实例的名称、设置负载均衡的跨域属性。 // +// 注意:非带宽上移用户的 CLB 实例必须加入带宽包才可以设置跨域属性。 +// // 本接口为异步接口,接口返回成功后,需以得到的 RequestID 为入参,调用 DescribeTaskStatus 接口查询本次任务是否成功。 // // 可能返回的错误码: 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 1083eda3e8..1ac23d7035 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 @@ -1445,6 +1445,9 @@ type CreateLoadBalancerRequestParams struct { // 网络出口 Egress *string `json:"Egress,omitnil,omitempty" name:"Egress"` + + // 负载均衡实例的预付费相关属性 + LBChargePrepaid *LBChargePrepaid `json:"LBChargePrepaid,omitnil,omitempty" name:"LBChargePrepaid"` } type CreateLoadBalancerRequest struct { @@ -1536,6 +1539,9 @@ type CreateLoadBalancerRequest struct { // 网络出口 Egress *string `json:"Egress,omitnil,omitempty" name:"Egress"` + + // 负载均衡实例的预付费相关属性 + LBChargePrepaid *LBChargePrepaid `json:"LBChargePrepaid,omitnil,omitempty" name:"LBChargePrepaid"` } func (r *CreateLoadBalancerRequest) ToJsonString() string { @@ -1577,6 +1583,7 @@ func (r *CreateLoadBalancerRequest) FromJsonString(s string) error { delete(f, "LoadBalancerPassToTarget") delete(f, "DynamicVip") delete(f, "Egress") + delete(f, "LBChargePrepaid") if len(f) > 0 { return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "CreateLoadBalancerRequest has unknown keys!", "") } diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/request.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/request.go index cb33214d0e..4bfc52d0d8 100644 --- a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/request.go +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/request.go @@ -265,7 +265,7 @@ func CompleteCommonParams(request Request, region string, requestClient string) params["Action"] = request.GetAction() params["Timestamp"] = strconv.FormatInt(time.Now().Unix(), 10) params["Nonce"] = strconv.Itoa(rand.Int()) - params["RequestClient"] = "SDK_GO_1.0.978" + params["RequestClient"] = "SDK_GO_1.0.984" if requestClient != "" { params["RequestClient"] += ": " + requestClient } diff --git a/vendor/modules.txt b/vendor/modules.txt index f6d15cf632..800089758b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1151,7 +1151,7 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ciam/v20220331 # github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ckafka v1.0.748 ## explicit; go 1.14 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ckafka/v20190819 -# github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.961 +# github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.984 ## explicit; go 1.14 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317 # github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cloudaudit v1.0.544 @@ -1160,7 +1160,7 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cloudaudit/v20190319 # github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cls v1.0.970 ## explicit; go 1.14 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cls/v20201016 -# github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.978 +# github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.984 ## explicit; go 1.11 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors diff --git a/website/docs/r/clb_attachment.html.markdown b/website/docs/r/clb_attachment.html.markdown index b8eaf50e22..15a03fd6bd 100644 --- a/website/docs/r/clb_attachment.html.markdown +++ b/website/docs/r/clb_attachment.html.markdown @@ -15,10 +15,8 @@ Provides a resource to create a CLB attachment. ## Example Usage -### Bind a Cvm instance - ```hcl -resource "tencentcloud_clb_attachment" "foo" { +resource "tencentcloud_clb_attachment" "example" { clb_id = "lb-k2zjp9lv" listener_id = "lbl-hh141sn9" rule_id = "loc-4xxr2cy7" @@ -31,10 +29,27 @@ resource "tencentcloud_clb_attachment" "foo" { } ``` -### Bind multiple Cvm instances + + +```hcl +resource "tencentcloud_clb_attachment" "example" { + clb_id = "lb-k2zjp9lv" + listener_id = "lbl-hh141sn9" + domain = "test.com" + url = "/" + + targets { + instance_id = "ins-1flbqyp8" + port = 80 + weight = 10 + } +} +``` + + ```hcl -resource "tencentcloud_clb_attachment" "foo" { +resource "tencentcloud_clb_attachment" "example" { clb_id = "lb-k2zjp9lv" listener_id = "lbl-hh141sn9" rule_id = "loc-4xxr2cy7" @@ -53,17 +68,57 @@ resource "tencentcloud_clb_attachment" "foo" { } ``` -### Bind backend target is ENI + ```hcl -resource "tencentcloud_clb_attachment" "foo" { +resource "tencentcloud_clb_attachment" "example" { + clb_id = "lb-k2zjp9lv" + listener_id = "lbl-hh141sn9" + domain = "test.com" + url = "/" + + targets { + instance_id = "ins-1flbqyp8" + port = 80 + weight = 10 + } + + targets { + instance_id = "ins-ekloqpa1" + port = 81 + weight = 10 + } +} +``` + + + +```hcl +resource "tencentcloud_clb_attachment" "example" { clb_id = "lb-k2zjp9lv" listener_id = "lbl-hh141sn9" rule_id = "loc-4xxr2cy7" targets { - eni_ip = "example-ip" - port = 23 + eni_ip = "172.16.16.52" + port = 8090 + weight = 50 + } +} +``` + + + +```hcl +resource "tencentcloud_clb_attachment" "example" { + clb_id = "lb-k2zjp9lv" + listener_id = "lbl-hh141sn9" + domain = "test.com" + url = "/" + + targets { + eni_ip = "172.16.16.52" + port = 8090 weight = 50 } } @@ -76,7 +131,9 @@ The following arguments are supported: * `clb_id` - (Required, String, ForceNew) ID of the CLB. * `listener_id` - (Required, String, ForceNew) ID of the CLB listener. * `targets` - (Required, Set) Information of the backends to be attached. +* `domain` - (Optional, String, ForceNew) Domain of the target forwarding rule. Does not take effect when parameter `rule_id` is provided. * `rule_id` - (Optional, String, ForceNew) ID of the CLB listener rule. Only supports listeners of `HTTPS` and `HTTP` protocol. +* `url` - (Optional, String, ForceNew) URL of the target forwarding rule. Does not take effect when parameter `rule_id` is provided. The `targets` object supports the following: @@ -98,6 +155,10 @@ In addition to all arguments above, the following attributes are exported: CLB attachment can be imported using the id, e.g. ``` -$ terraform import tencentcloud_clb_attachment.foo loc-4xxr2cy7#lbl-hh141sn9#lb-7a0t6zqb +$ terraform import tencentcloud_clb_attachment.example loc-4xxr2cy7#lbl-hh141sn9#lb-7a0t6zqb + +Or + +$ terraform import tencentcloud_clb_attachment.example test.com,/#lbl-hh141sn9#lb-7a0t6zqb ```