Skip to content

Commit 3328814

Browse files
authored
feat: support target attach clb (#2454)
* feat: support target attach clb * feat: support target attach clb * feat: support target attach clb * feat: changelog * feat: changelog
1 parent e5ae032 commit 3328814

8 files changed

+431
-94
lines changed

.changelog/2454.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
tencentcloud_clb_target_group_attachments: Support two-way binding of clb and targetGroup
3+
```

tencentcloud/provider.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@ Cloud Load Balancer(CLB)
383383
tencentcloud_clb_target_group
384384
tencentcloud_clb_target_group_instance_attachment
385385
tencentcloud_clb_target_group_attachment
386+
tencentcloud_clb_target_group_attachments
386387
tencentcloud_clb_log_set
387388
tencentcloud_clb_log_topic
388389
tencentcloud_clb_customized_config

tencentcloud/services/clb/resource_tc_clb_target_group_attachments.go

Lines changed: 168 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"log"
7+
"regexp"
78
"strings"
89

910
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
@@ -25,34 +26,44 @@ func ResourceTencentCloudClbTargetGroupAttachments() *schema.Resource {
2526
Importer: &schema.ResourceImporter{
2627
State: schema.ImportStatePassthrough,
2728
},
29+
2830
Schema: map[string]*schema.Schema{
2931
"load_balancer_id": {
3032
Type: schema.TypeString,
31-
Required: true,
32-
Description: "CLB instance ID",
33+
Optional: true,
34+
Description: "CLB instance ID, (load_balancer_id and target_group_id require at least one).",
35+
},
36+
"target_group_id": {
37+
Type: schema.TypeString,
38+
Optional: true,
39+
Description: "Target group ID, (load_balancer_id and target_group_id require at least one).",
3340
},
3441
"associations": {
3542
Required: true,
3643
Type: schema.TypeSet,
3744
MaxItems: 20,
38-
Description: "Association array, the combination cannot exceed 20",
45+
Description: "Association array, the combination cannot exceed 20.",
3946
Elem: &schema.Resource{
4047
Schema: map[string]*schema.Schema{
41-
42-
"listener_id": {
48+
"load_balancer_id": {
4349
Type: schema.TypeString,
4450
Optional: true,
45-
Description: "Listener ID",
51+
Description: "CLB instance ID, when the binding target is target group, load_balancer_id in associations is required.",
4652
},
4753
"target_group_id": {
4854
Type: schema.TypeString,
49-
Required: true,
50-
Description: "Target group ID",
55+
Optional: true,
56+
Description: "Target group ID, when the binding target is clb, the target_group_id in associations is required.",
57+
},
58+
"listener_id": {
59+
Type: schema.TypeString,
60+
Optional: true,
61+
Description: "Listener ID.",
5162
},
5263
"location_id": {
5364
Type: schema.TypeString,
5465
Optional: true,
55-
Description: "Forwarding rule ID",
66+
Description: "Forwarding rule ID.",
5667
},
5768
},
5869
},
@@ -61,36 +72,71 @@ func ResourceTencentCloudClbTargetGroupAttachments() *schema.Resource {
6172
}
6273
}
6374

64-
func resourceTencentCloudClbTargetGroupAttachmentsCreate(d *schema.ResourceData, meta interface{}) error {
65-
defer tccommon.LogElapsed("resource.tencentcloud_clb_target_group_attachments.create")()
66-
defer tccommon.InconsistentCheck(d, meta)()
75+
const ResourcePrefixFromClb = "lb"
6776

68-
logId := tccommon.GetLogId(tccommon.ContextNil)
77+
func checkParam(d *schema.ResourceData) error {
78+
_, clbIdExists := d.GetOk("load_balancer_id")
79+
_, groupIdExists := d.GetOk("target_group_id")
6980

70-
var (
71-
request = clb.NewAssociateTargetGroupsRequest()
72-
loadBalancerId string
73-
)
74-
if v, ok := d.GetOk("load_balancer_id"); ok {
75-
loadBalancerId = v.(string)
81+
if !clbIdExists && !groupIdExists {
82+
return fmt.Errorf("one of load_balancer_id and target_group_id must be specified as the binding target")
7683
}
84+
85+
if clbIdExists && groupIdExists {
86+
return fmt.Errorf("load_balancer_id and target_group_id cannot be used as binding targets at the same time")
87+
}
88+
7789
if v, ok := d.GetOk("associations"); ok {
7890
for _, item := range v.(*schema.Set).List() {
7991
dMap := item.(map[string]interface{})
80-
targetGroupAssociation := clb.TargetGroupAssociation{}
81-
targetGroupAssociation.LoadBalancerId = helper.String(loadBalancerId)
82-
if v, ok := dMap["listener_id"]; ok {
83-
targetGroupAssociation.ListenerId = helper.String(v.(string))
92+
associationsClbExists := false
93+
associationsGroupExists := false
94+
95+
if v, ok := dMap["load_balancer_id"]; ok && v.(string) != "" {
96+
associationsClbExists = true
97+
}
98+
if v, ok := dMap["target_group_id"]; ok && v.(string) != "" {
99+
associationsGroupExists = true
84100
}
85-
if v, ok := dMap["target_group_id"]; ok {
86-
targetGroupAssociation.TargetGroupId = helper.String(v.(string))
101+
102+
if !associationsClbExists && !associationsGroupExists {
103+
return fmt.Errorf("then in associations, load_balancer_id and target_group_id must be filled in one")
104+
}
105+
106+
if clbIdExists && associationsClbExists {
107+
return fmt.Errorf("if the binding target is clb, then in associations, it is expected that " +
108+
"target_group_id exists and load_balancer_id does not exist")
87109
}
88-
if v, ok := dMap["location_id"]; ok {
89-
targetGroupAssociation.LocationId = helper.String(v.(string))
110+
111+
if groupIdExists && associationsGroupExists {
112+
return fmt.Errorf("if the binding target is targetGroup, then in associations, it is expected that " +
113+
"load_balancer_id exists and target_group_id does not exist")
90114
}
91-
request.Associations = append(request.Associations, &targetGroupAssociation)
92115
}
93116
}
117+
return nil
118+
}
119+
func resourceTencentCloudClbTargetGroupAttachmentsCreate(d *schema.ResourceData, meta interface{}) error {
120+
defer tccommon.LogElapsed("resource.tencentcloud_clb_target_group_attachments.create")()
121+
defer tccommon.InconsistentCheck(d, meta)()
122+
123+
logId := tccommon.GetLogId(tccommon.ContextNil)
124+
if err := checkParam(d); err != nil {
125+
return err
126+
}
127+
var (
128+
request = clb.NewAssociateTargetGroupsRequest()
129+
resourceId string
130+
)
131+
if v, ok := d.GetOk("load_balancer_id"); ok && v.(string) != "" {
132+
resourceId = v.(string)
133+
request.Associations = parseParamToRequest(d, "load_balancer_id", resourceId)
134+
}
135+
136+
if v, ok := d.GetOk("target_group_id"); ok && v.(string) != "" {
137+
resourceId = v.(string)
138+
request.Associations = parseParamToRequest(d, "target_group_id", resourceId)
139+
}
94140

95141
err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError {
96142
result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseClbClient().AssociateTargetGroups(request)
@@ -112,7 +158,7 @@ func resourceTencentCloudClbTargetGroupAttachmentsCreate(d *schema.ResourceData,
112158
return err
113159
}
114160

115-
d.SetId(loadBalancerId)
161+
d.SetId(resourceId)
116162

117163
return resourceTencentCloudClbTargetGroupAttachmentsRead(d, meta)
118164
}
@@ -127,38 +173,7 @@ func resourceTencentCloudClbTargetGroupAttachmentsRead(d *schema.ResourceData, m
127173

128174
service := ClbService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()}
129175

130-
loadBalancerId := d.Id()
131-
associationsSet := make(map[string]struct{}, 0)
132-
targetGroupList := make([]string, 0)
133-
if v, ok := d.GetOk("associations"); ok {
134-
for _, item := range v.(*schema.Set).List() {
135-
dMap := item.(map[string]interface{})
136-
ids := make([]string, 0)
137-
138-
ids = append(ids, loadBalancerId)
139-
if v, ok := dMap["listener_id"]; ok {
140-
ids = append(ids, v.(string))
141-
} else {
142-
ids = append(ids, "null")
143-
}
144-
145-
if v, ok := dMap["target_group_id"]; ok {
146-
ids = append(ids, v.(string))
147-
targetGroupList = append(targetGroupList, v.(string))
148-
} else {
149-
ids = append(ids, "null")
150-
}
151-
152-
if v, ok := dMap["location_id"]; ok {
153-
ids = append(ids, v.(string))
154-
} else {
155-
ids = append(ids, "null")
156-
}
157-
158-
associationsSet[strings.Join(ids, tccommon.FILED_SP)] = struct{}{}
159-
}
160-
}
161-
176+
targetGroupList, associationsSet := margeReadRequest(d)
162177
targetGroupAttachments, err := service.DescribeClbTargetGroupAttachmentsById(ctx, targetGroupList, associationsSet)
163178
if err != nil {
164179
return err
@@ -177,12 +192,16 @@ func resourceTencentCloudClbTargetGroupAttachmentsRead(d *schema.ResourceData, m
177192
return fmt.Errorf("id is broken,%s", info)
178193
}
179194
associationsMap := map[string]interface{}{}
180-
_ = d.Set("load_balancer_id", info[0])
181-
182-
associationsMap["listener_id"] = info[1]
195+
if isBindFromClb(d.Id()) {
196+
_ = d.Set("load_balancer_id", info[0])
197+
associationsMap["target_group_id"] = info[1]
183198

184-
associationsMap["target_group_id"] = info[2]
199+
} else {
200+
_ = d.Set("target_group_id", info[1])
201+
associationsMap["load_balancer_id"] = info[0]
202+
}
185203

204+
associationsMap["listener_id"] = info[2]
186205
associationsMap["location_id"] = info[3]
187206

188207
associationsList = append(associationsList, associationsMap)
@@ -206,24 +225,11 @@ func resourceTencentCloudClbTargetGroupAttachmentsDelete(d *schema.ResourceData,
206225

207226
logId := tccommon.GetLogId(tccommon.ContextNil)
208227
request := clb.NewDisassociateTargetGroupsRequest()
209-
210-
loadBalancerId := d.Id()
211-
if v, ok := d.GetOk("associations"); ok {
212-
for _, item := range v.(*schema.Set).List() {
213-
dMap := item.(map[string]interface{})
214-
targetGroupAssociation := clb.TargetGroupAssociation{}
215-
targetGroupAssociation.LoadBalancerId = helper.String(loadBalancerId)
216-
if v, ok := dMap["listener_id"]; ok {
217-
targetGroupAssociation.ListenerId = helper.String(v.(string))
218-
}
219-
if v, ok := dMap["target_group_id"]; ok {
220-
targetGroupAssociation.TargetGroupId = helper.String(v.(string))
221-
}
222-
if v, ok := dMap["location_id"]; ok {
223-
targetGroupAssociation.LocationId = helper.String(v.(string))
224-
}
225-
request.Associations = append(request.Associations, &targetGroupAssociation)
226-
}
228+
id := d.Id()
229+
if isBindFromClb(id) {
230+
request.Associations = parseParamToRequest(d, "load_balancer_id", id)
231+
} else {
232+
request.Associations = parseParamToRequest(d, "target_group_id", id)
227233
}
228234
err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError {
229235
ratelimit.Check(request.GetAction())
@@ -248,3 +254,82 @@ func resourceTencentCloudClbTargetGroupAttachmentsDelete(d *schema.ResourceData,
248254

249255
return nil
250256
}
257+
func parseParamToRequest(d *schema.ResourceData, param string, id string) (associations []*clb.TargetGroupAssociation) {
258+
259+
if v, ok := d.GetOk("associations"); ok {
260+
for _, item := range v.(*schema.Set).List() {
261+
dMap := item.(map[string]interface{})
262+
targetGroupAssociation := clb.TargetGroupAssociation{}
263+
dMap[param] = id
264+
for name := range dMap {
265+
setString(name, dMap[name].(string), &targetGroupAssociation)
266+
}
267+
associations = append(associations, &targetGroupAssociation)
268+
}
269+
}
270+
return associations
271+
}
272+
func setString(fieldName string, value string, request *clb.TargetGroupAssociation) {
273+
switch fieldName {
274+
case "load_balancer_id":
275+
request.LoadBalancerId = helper.String(value)
276+
case "target_group_id":
277+
request.TargetGroupId = helper.String(value)
278+
case "listener_id":
279+
request.ListenerId = helper.String(value)
280+
case "location_id":
281+
request.LocationId = helper.String(value)
282+
default:
283+
log.Printf("Invalid field name: %s\n", fieldName)
284+
}
285+
}
286+
func isBindFromClb(id string) bool {
287+
re := regexp.MustCompile(`^(.*?)-`)
288+
match := re.FindStringSubmatch(id)
289+
290+
if len(match) > 1 {
291+
return match[1] == ResourcePrefixFromClb
292+
}
293+
return false
294+
}
295+
func margeReadRequest(d *schema.ResourceData) ([]string, map[string]struct{}) {
296+
resourceId := d.Id()
297+
298+
associationsSet := make(map[string]struct{})
299+
targetGroupList := make([]string, 0)
300+
if v, ok := d.GetOk("associations"); ok {
301+
for _, item := range v.(*schema.Set).List() {
302+
dMap := item.(map[string]interface{})
303+
ids := make([]string, 0)
304+
305+
processIds(resourceId, dMap, "load_balancer_id", isBindFromClb(resourceId), &ids)
306+
processIds(resourceId, dMap, "target_group_id", isBindFromClb(resourceId), &ids)
307+
processIds(resourceId, dMap, "listener_id", isBindFromClb(resourceId), &ids)
308+
processIds(resourceId, dMap, "location_id", isBindFromClb(resourceId), &ids)
309+
310+
if groupId, ok := dMap["target_group_id"]; ok && groupId.(string) != "" {
311+
targetGroupList = append(targetGroupList, groupId.(string))
312+
}
313+
314+
associationsSet[strings.Join(ids, tccommon.FILED_SP)] = struct{}{}
315+
}
316+
}
317+
if len(targetGroupList) < 1 && !isBindFromClb(resourceId) {
318+
targetGroupList = append(targetGroupList, resourceId)
319+
}
320+
return targetGroupList, associationsSet
321+
}
322+
func processIds(id string, dMap map[string]interface{}, key string, clbFlag bool, ids *[]string) {
323+
if clbFlag && key == "load_balancer_id" {
324+
*ids = append(*ids, id)
325+
} else if !clbFlag && key == "target_group_id" {
326+
*ids = append(*ids, id)
327+
} else {
328+
if v, ok := dMap[key]; ok {
329+
*ids = append(*ids, v.(string))
330+
} else {
331+
*ids = append(*ids, "null")
332+
}
333+
334+
}
335+
}
Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,31 @@
11
Provides a resource to create a clb target_group_attachments
22

3+
This resource supports bidirectional binding (target group binding to the load balancer, load balancer binding to the target group). When choosing either the load balancer or the target group as the binding target, up to 20 combinations can be bound at most.
4+
35
Example Usage
46

7+
Load balancer binding to the target group
8+
59
```hcl
610
resource "tencentcloud_clb_target_group_attachments" "target_group_attachments" {
711
load_balancer_id = "lb-phbx2420"
812
associations {
9-
listener_id = "lbl-m2q6sp9m"
10-
target_group_id = "lbtg-5xunivs0"
11-
location_id = "loc-jjqr0ric"
12-
13+
listener_id = "lbl-m2q6sp9m"
14+
target_group_id = "lbtg-5xunivs0"
15+
location_id = "loc-jjqr0ric"
1316
}
1417
}
18+
1519
```
20+
Target group binding to the load balancer
21+
```hcl
22+
resource "tencentcloud_clb_target_group_attachments" "target_group_attachments" {
23+
target_group_id = "lbtg-5xunivs0"
24+
associations {
25+
listener_id = "lbl-m2q6sp9m"
26+
load_balancer_id = "lb-phbx2420"
27+
location_id = "loc-jjqr0ric"
28+
}
29+
}
1630
31+
```

0 commit comments

Comments
 (0)