Skip to content

Commit 6f4a025

Browse files
authored
feat: clb attachments target group (#2398)
* feat: doc * feat: changelog * fix: golang ci * fix: golang ci * fix: del msg
1 parent 1f5c00f commit 6f4a025

File tree

6 files changed

+438
-0
lines changed

6 files changed

+438
-0
lines changed

.changelog/2398.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:new-resource
2+
tencentcloud_clb_target_group_attachments
3+
```

tencentcloud/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,6 +1850,7 @@ func Provider() *schema.Provider {
18501850
"tencentcloud_cdwpg_instance": resourceTencentCloudCdwpgInstance(),
18511851
"tencentcloud_clickhouse_keyval_config": resourceTencentCloudClickhouseKeyvalConfig(),
18521852
"tencentcloud_clickhouse_xml_config": resourceTencentCloudClickhouseXmlConfig(),
1853+
"tencentcloud_clb_target_group_attachments": resourceTencentCloudClbTargetGroupAttachments(),
18531854
},
18541855

18551856
ConfigureFunc: providerConfigure,
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
package tencentcloud
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log"
7+
"strings"
8+
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
11+
"github.com/pkg/errors"
12+
clb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317"
13+
"github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper"
14+
"github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/ratelimit"
15+
)
16+
17+
func resourceTencentCloudClbTargetGroupAttachments() *schema.Resource {
18+
return &schema.Resource{
19+
Create: resourceTencentCloudClbTargetGroupAttachmentsCreate,
20+
Read: resourceTencentCloudClbTargetGroupAttachmentsRead,
21+
Update: resourceTencentCloudClbTargetGroupAttachmentsUpdate,
22+
Delete: resourceTencentCloudClbTargetGroupAttachmentsDelete,
23+
Importer: &schema.ResourceImporter{
24+
State: schema.ImportStatePassthrough,
25+
},
26+
Schema: map[string]*schema.Schema{
27+
"load_balancer_id": {
28+
Type: schema.TypeString,
29+
Required: true,
30+
Description: "CLB instance ID",
31+
},
32+
"associations": {
33+
Required: true,
34+
Type: schema.TypeSet,
35+
MaxItems: 20,
36+
Description: "Association array, the combination cannot exceed 20",
37+
Elem: &schema.Resource{
38+
Schema: map[string]*schema.Schema{
39+
40+
"listener_id": {
41+
Type: schema.TypeString,
42+
Optional: true,
43+
Description: "Listener ID",
44+
},
45+
"target_group_id": {
46+
Type: schema.TypeString,
47+
Required: true,
48+
Description: "Target group ID",
49+
},
50+
"location_id": {
51+
Type: schema.TypeString,
52+
Optional: true,
53+
Description: "Forwarding rule ID",
54+
},
55+
},
56+
},
57+
},
58+
},
59+
}
60+
}
61+
62+
func resourceTencentCloudClbTargetGroupAttachmentsCreate(d *schema.ResourceData, meta interface{}) error {
63+
defer logElapsed("resource.tencentcloud_clb_target_group_attachments.create")()
64+
defer inconsistentCheck(d, meta)()
65+
66+
logId := getLogId(contextNil)
67+
68+
var (
69+
request = clb.NewAssociateTargetGroupsRequest()
70+
loadBalancerId string
71+
)
72+
if v, ok := d.GetOk("load_balancer_id"); ok {
73+
loadBalancerId = v.(string)
74+
}
75+
if v, ok := d.GetOk("associations"); ok {
76+
for _, item := range v.(*schema.Set).List() {
77+
dMap := item.(map[string]interface{})
78+
targetGroupAssociation := clb.TargetGroupAssociation{}
79+
targetGroupAssociation.LoadBalancerId = helper.String(loadBalancerId)
80+
if v, ok := dMap["listener_id"]; ok {
81+
targetGroupAssociation.ListenerId = helper.String(v.(string))
82+
}
83+
if v, ok := dMap["target_group_id"]; ok {
84+
targetGroupAssociation.TargetGroupId = helper.String(v.(string))
85+
}
86+
if v, ok := dMap["location_id"]; ok {
87+
targetGroupAssociation.LocationId = helper.String(v.(string))
88+
}
89+
request.Associations = append(request.Associations, &targetGroupAssociation)
90+
}
91+
}
92+
93+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
94+
result, e := meta.(*TencentCloudClient).apiV3Conn.UseClbClient().AssociateTargetGroups(request)
95+
if e != nil {
96+
return retryError(e, InternalError)
97+
} else {
98+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n",
99+
logId, request.GetAction(), result.ToJsonString(), result.ToJsonString())
100+
requestId := *result.Response.RequestId
101+
retryErr := waitForTaskFinish(requestId, meta.(*TencentCloudClient).apiV3Conn.UseClbClient())
102+
if retryErr != nil {
103+
return resource.NonRetryableError(errors.WithStack(retryErr))
104+
}
105+
}
106+
return nil
107+
})
108+
if err != nil {
109+
log.Printf("[CRITAL]%s create clb targetGroupAttachments failed, reason:%+v", logId, err)
110+
return err
111+
}
112+
113+
d.SetId(loadBalancerId)
114+
115+
return resourceTencentCloudClbTargetGroupAttachmentsRead(d, meta)
116+
}
117+
118+
func resourceTencentCloudClbTargetGroupAttachmentsRead(d *schema.ResourceData, meta interface{}) error {
119+
defer logElapsed("resource.tencentcloud_clb_target_group_attachments.read")()
120+
defer inconsistentCheck(d, meta)()
121+
122+
logId := getLogId(contextNil)
123+
124+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
125+
126+
service := ClbService{client: meta.(*TencentCloudClient).apiV3Conn}
127+
128+
loadBalancerId := d.Id()
129+
associationsSet := make(map[string]struct{}, 0)
130+
targetGroupList := make([]string, 0)
131+
if v, ok := d.GetOk("associations"); ok {
132+
for _, item := range v.(*schema.Set).List() {
133+
dMap := item.(map[string]interface{})
134+
ids := make([]string, 0)
135+
136+
ids = append(ids, loadBalancerId)
137+
if v, ok := dMap["listener_id"]; ok {
138+
ids = append(ids, v.(string))
139+
} else {
140+
ids = append(ids, "null")
141+
}
142+
143+
if v, ok := dMap["target_group_id"]; ok {
144+
ids = append(ids, v.(string))
145+
targetGroupList = append(targetGroupList, v.(string))
146+
} else {
147+
ids = append(ids, "null")
148+
}
149+
150+
if v, ok := dMap["location_id"]; ok {
151+
ids = append(ids, v.(string))
152+
} else {
153+
ids = append(ids, "null")
154+
}
155+
156+
associationsSet[strings.Join(ids, FILED_SP)] = struct{}{}
157+
}
158+
}
159+
160+
targetGroupAttachments, err := service.DescribeClbTargetGroupAttachmentsById(ctx, targetGroupList, associationsSet)
161+
if err != nil {
162+
return err
163+
}
164+
165+
if len(targetGroupAttachments) < 1 {
166+
d.SetId("")
167+
log.Printf("[WARN]%s resource `ClbTargetGroupAttachments` [%s] not found, please check if it has been deleted.\n", logId, d.Id())
168+
return nil
169+
}
170+
var associationsList []interface{}
171+
172+
for _, attachment := range targetGroupAttachments {
173+
info := strings.Split(attachment, FILED_SP)
174+
if len(info) != 4 {
175+
return fmt.Errorf("id is broken,%s", info)
176+
}
177+
associationsMap := map[string]interface{}{}
178+
_ = d.Set("load_balancer_id", info[0])
179+
180+
associationsMap["listener_id"] = info[1]
181+
182+
associationsMap["target_group_id"] = info[2]
183+
184+
associationsMap["location_id"] = info[3]
185+
186+
associationsList = append(associationsList, associationsMap)
187+
}
188+
189+
_ = d.Set("associations", associationsList)
190+
191+
return nil
192+
}
193+
194+
func resourceTencentCloudClbTargetGroupAttachmentsUpdate(d *schema.ResourceData, meta interface{}) error {
195+
defer logElapsed("resource.tencentcloud_clb_target_group_attachments.update")()
196+
defer inconsistentCheck(d, meta)()
197+
198+
return resourceTencentCloudClbTargetGroupAttachmentsRead(d, meta)
199+
}
200+
201+
func resourceTencentCloudClbTargetGroupAttachmentsDelete(d *schema.ResourceData, meta interface{}) error {
202+
defer logElapsed("resource.tencentcloud_clb_target_group_attachments.delete")()
203+
defer inconsistentCheck(d, meta)()
204+
205+
logId := getLogId(contextNil)
206+
request := clb.NewDisassociateTargetGroupsRequest()
207+
208+
loadBalancerId := d.Id()
209+
if v, ok := d.GetOk("associations"); ok {
210+
for _, item := range v.(*schema.Set).List() {
211+
dMap := item.(map[string]interface{})
212+
targetGroupAssociation := clb.TargetGroupAssociation{}
213+
targetGroupAssociation.LoadBalancerId = helper.String(loadBalancerId)
214+
if v, ok := dMap["listener_id"]; ok {
215+
targetGroupAssociation.ListenerId = helper.String(v.(string))
216+
}
217+
if v, ok := dMap["target_group_id"]; ok {
218+
targetGroupAssociation.TargetGroupId = helper.String(v.(string))
219+
}
220+
if v, ok := dMap["location_id"]; ok {
221+
targetGroupAssociation.LocationId = helper.String(v.(string))
222+
}
223+
request.Associations = append(request.Associations, &targetGroupAssociation)
224+
}
225+
}
226+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
227+
ratelimit.Check(request.GetAction())
228+
result, err := meta.(*TencentCloudClient).apiV3Conn.UseClbClient().DisassociateTargetGroups(request)
229+
if err != nil {
230+
return retryError(err, InternalError)
231+
} else {
232+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n",
233+
logId, request.GetAction(), result.ToJsonString(), result.ToJsonString())
234+
requestId := *result.Response.RequestId
235+
retryErr := waitForTaskFinish(requestId, meta.(*TencentCloudClient).apiV3Conn.UseClbClient())
236+
if retryErr != nil {
237+
return resource.NonRetryableError(errors.WithStack(retryErr))
238+
}
239+
}
240+
return nil
241+
})
242+
243+
if err != nil {
244+
return err
245+
}
246+
247+
return nil
248+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package tencentcloud
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
7+
)
8+
9+
func TestAccTencentCloudClbTargetGroupAttachmentsResource_basic(t *testing.T) {
10+
t.Parallel()
11+
resource.Test(t, resource.TestCase{
12+
PreCheck: func() {
13+
testAccPreCheck(t)
14+
},
15+
Providers: testAccProviders,
16+
Steps: []resource.TestStep{
17+
{
18+
Config: testAccClbTargetGroupAttachments,
19+
Check: resource.ComposeTestCheckFunc(resource.TestCheckResourceAttrSet("tencentcloud_clb_target_group_attachments.target_group_attachments", "id"),
20+
resource.TestCheckResourceAttrSet("tencentcloud_clb_target_group_attachments.target_group_attachments", "load_balancer_id"),
21+
resource.TestCheckResourceAttrSet("tencentcloud_clb_target_group_attachments.target_group_attachments", "associations.#"),
22+
),
23+
},
24+
},
25+
})
26+
}
27+
28+
const testAccClbTargetGroupAttachments = `
29+
30+
resource "tencentcloud_clb_instance" "clb_basic" {
31+
network_type = "OPEN"
32+
clb_name = "tf_test_clb_attach"
33+
vpc_id = "vpc-5kwngvex"
34+
}
35+
36+
resource "tencentcloud_clb_listener" "public_listeners" {
37+
clb_id = tencentcloud_clb_instance.clb_basic.id
38+
# protocol = "HTTPS"
39+
# port = "443"
40+
protocol = "HTTP"
41+
port = "8090"
42+
listener_name = "iac-test-attach-2"
43+
}
44+
45+
resource "tencentcloud_clb_listener_rule" "rule_basic" {
46+
clb_id = tencentcloud_clb_instance.clb_basic.id
47+
listener_id = tencentcloud_clb_listener.public_listeners.listener_id
48+
domain = "abc.com"
49+
url = "/"
50+
session_expire_time = 30
51+
scheduler = "WRR"
52+
target_type = "TARGETGROUP"
53+
}
54+
resource "tencentcloud_clb_listener_rule" "rule_basic2" {
55+
clb_id = tencentcloud_clb_instance.clb_basic.id
56+
listener_id = tencentcloud_clb_listener.public_listeners.listener_id
57+
domain = "baidu.com"
58+
url = "/"
59+
session_expire_time = 30
60+
scheduler = "WRR"
61+
target_type = "TARGETGROUP"
62+
}
63+
resource "tencentcloud_clb_listener_rule" "rule_basic3" {
64+
clb_id = tencentcloud_clb_instance.clb_basic.id
65+
listener_id = tencentcloud_clb_listener.public_listeners.listener_id
66+
domain = "tencent.com"
67+
url = "/"
68+
session_expire_time = 30
69+
scheduler = "WRR"
70+
target_type = "TARGETGROUP"
71+
}
72+
resource "tencentcloud_clb_listener_rule" "rule_basic4" {
73+
clb_id = tencentcloud_clb_instance.clb_basic.id
74+
listener_id = tencentcloud_clb_listener.public_listeners.listener_id
75+
domain = "aws.com"
76+
url = "/"
77+
session_expire_time = 30
78+
scheduler = "WRR"
79+
target_type = "TARGETGROUP"
80+
}
81+
resource "tencentcloud_clb_target_group_attachments" "target_group_attachments" {
82+
load_balancer_id = tencentcloud_clb_instance.clb_basic.id
83+
associations {
84+
listener_id = tencentcloud_clb_listener.public_listeners.listener_id
85+
target_group_id = "lbtg-ln4gk8me"
86+
location_id = tencentcloud_clb_listener_rule.rule_basic.rule_id
87+
}
88+
associations {
89+
listener_id = tencentcloud_clb_listener.public_listeners.listener_id
90+
target_group_id = "lbtg-iv3mdrfy"
91+
location_id = tencentcloud_clb_listener_rule.rule_basic2.rule_id
92+
}
93+
associations {
94+
listener_id = tencentcloud_clb_listener.public_listeners.listener_id
95+
target_group_id = "lbtg-ctz951k0"
96+
location_id = tencentcloud_clb_listener_rule.rule_basic3.rule_id
97+
}
98+
associations {
99+
listener_id = tencentcloud_clb_listener.public_listeners.listener_id
100+
target_group_id = "lbtg-kukb1j9c"
101+
location_id = tencentcloud_clb_listener_rule.rule_basic4.rule_id
102+
}
103+
depends_on = [tencentcloud_clb_listener.public_listeners,
104+
tencentcloud_clb_listener_rule.rule_basic4,
105+
tencentcloud_clb_listener_rule.rule_basic3,
106+
tencentcloud_clb_listener_rule.rule_basic2,
107+
tencentcloud_clb_listener_rule.rule_basic]
108+
}
109+
110+
`

0 commit comments

Comments
 (0)