Skip to content

Commit 07c7236

Browse files
tongyimingmikatong
andauthored
support ddos ip attachment (#1511)
* support ddos ip attachment * add changelog * update Co-authored-by: mikatong <mikatong@tencent.com>
1 parent 6d78b5e commit 07c7236

File tree

9 files changed

+494
-0
lines changed

9 files changed

+494
-0
lines changed

.changelog/1511.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_dayu_ddos_ip_attachment_v2
3+
```

tencentcloud/common.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
)
2626

2727
const FILED_SP = "#"
28+
const COMMA_SP = ","
2829

2930
var contextNil context.Context = nil
3031

tencentcloud/extension_dayu.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,11 @@ const (
173173
DAYU_L7_HEALTH_STATUS_SETTING = 1
174174
DAYU_L7_HEALTH_STATUS_SET_FAIL = 2
175175
)
176+
177+
const DAYU_BOUNDSTATUS_IDLE = "idle"
178+
179+
const RESPONSE_SUCCESS_CODE = "Success"
180+
181+
const BUSINESS_BGP_MULTIP = "bgp-multip"
182+
183+
const ISP_CODE_BGP = 5

tencentcloud/provider.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ Anti-DDoS(DayuV2)
5757
tencentcloud_dayu_l7_rule_v2
5858
tencentcloud_dayu_ddos_policy_v2
5959
tencentcloud_dayu_cc_policy_v2
60+
tencentcloud_dayu_ddos_ip_attachment_v2
6061
6162
Anti-DDoS(Dayu)
6263
Data Source
@@ -1618,6 +1619,7 @@ func Provider() terraform.ResourceProvider {
16181619
"tencentcloud_ci_original_image_protection": resourceTencentCloudCIOriginalImageProtection(),
16191620
"tencentcloud_cynosdb_audit_log_file": resourceTencentCloudCynosdbAuditLogFile(),
16201621
"tencentcloud_cynosdb_security_group": resourceTencentCloudCynosdbSecurityGroup(),
1622+
"tencentcloud_dayu_ddos_ip_attachment_v2": resourceTencentCloudDayuDDosIpAttachmentV2(),
16211623
},
16221624

16231625
ConfigureFunc: providerConfigure,
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
/*
2+
Provides a resource to create a antiddos ip. Only support for bgp-multip.
3+
4+
Example Usage
5+
6+
```hcl
7+
resource "tencentcloud_dayu_ddos_ip_attachment_v2" "boundip" {
8+
id = "bgp-xxxxxx"
9+
bound_ip_list {
10+
ip = "1.1.1.1"
11+
biz_type = "public"
12+
instance_id = "ins-xxx"
13+
device_type = "cvm"
14+
}
15+
}
16+
```
17+
*/
18+
package tencentcloud
19+
20+
import (
21+
"context"
22+
"errors"
23+
"fmt"
24+
"log"
25+
"strings"
26+
27+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
28+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
29+
antiddos "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/antiddos/v20200309"
30+
"github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper"
31+
)
32+
33+
func resourceTencentCloudDayuDDosIpAttachmentV2() *schema.Resource {
34+
return &schema.Resource{
35+
Create: resourceTencentCloudDayuDDosIpAttachmentCreateV2,
36+
Read: resourceTencentCloudDayuDDosIpAttachmentReadV2,
37+
Delete: resourceTencentCloudDayuDDosIpAttachmentDeleteV2,
38+
Schema: map[string]*schema.Schema{
39+
"bgp_instance_id": {
40+
Required: true,
41+
ForceNew: true,
42+
Type: schema.TypeString,
43+
Description: "Anti-DDoS instance ID.",
44+
},
45+
46+
"bound_ip_list": {
47+
Optional: true,
48+
ForceNew: true,
49+
Type: schema.TypeList,
50+
Description: "Array of IPs to bind to the Anti-DDoS instance. For Anti-DDoS Pro Single IP instance, the array contains only one IP. If there are no IPs to bind, it is empty; however, either BoundDevList or UnBoundDevList must not be empty.",
51+
Elem: &schema.Resource{
52+
Schema: map[string]*schema.Schema{
53+
"ip": {
54+
Type: schema.TypeString,
55+
Required: true,
56+
Description: "IP address.",
57+
},
58+
"biz_type": {
59+
Type: schema.TypeString,
60+
Optional: true,
61+
Description: "Category of product that can be bound. Valid values: public (CVM and CLB), bm (BM), eni (ENI), vpngw (VPN gateway), natgw (NAT gateway), waf (WAF), fpc (financial products), gaap (GAAP), and other (hosted IP). This field is required when you perform binding.",
62+
},
63+
"instance_id": {
64+
Type: schema.TypeString,
65+
Optional: true,
66+
Description: "Anti-DDoS instance ID of the IP. This field is required only when the instance is bound to an IP. For example, this field InstanceId will be eni-* if the instance ID is bound to an ENI IP; none if there is no instance to bind to a managed IP.",
67+
},
68+
"device_type": {
69+
Type: schema.TypeString,
70+
Optional: true,
71+
Description: "Sub-product category. Valid values: cvm (CVM), lb (Load balancer), eni (ENI), vpngw (VPN gateway), natgw (NAT gateway), waf (WAF), fpc (financial products), gaap (GAAP), eip (BM EIP) and other (managed IP). This field is required when you perform binding.",
72+
},
73+
},
74+
},
75+
},
76+
},
77+
}
78+
}
79+
80+
func resourceTencentCloudDayuDDosIpAttachmentCreateV2(d *schema.ResourceData, meta interface{}) error {
81+
defer logElapsed("resource.tencentcloud_dayu_ddos_ip_attachment_v2.create")()
82+
defer inconsistentCheck(d, meta)()
83+
84+
logId := getLogId(contextNil)
85+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
86+
87+
service := AntiddosService{client: meta.(*TencentCloudClient).apiV3Conn}
88+
89+
var bgpInstanceId string
90+
boundIps := make([]string, 0)
91+
request := antiddos.NewCreateBoundIPRequest()
92+
93+
request.Business = helper.String(BUSINESS_BGP_MULTIP)
94+
if v, ok := d.GetOk("bgp_instance_id"); ok {
95+
bgpInstanceId = v.(string)
96+
request.Id = helper.String(bgpInstanceId)
97+
}
98+
99+
if v, ok := d.GetOk("bound_ip_list"); ok {
100+
for _, item := range v.([]interface{}) {
101+
dMap := item.(map[string]interface{})
102+
boundIpInfo := antiddos.BoundIpInfo{}
103+
if v, ok := dMap["ip"]; ok {
104+
boundIps = append(boundIps, v.(string))
105+
boundIpInfo.Ip = helper.String(v.(string))
106+
}
107+
if v, ok := dMap["biz_type"]; ok {
108+
boundIpInfo.BizType = helper.String(v.(string))
109+
}
110+
if v, ok := dMap["instance_id"]; ok {
111+
boundIpInfo.InstanceId = helper.String(v.(string))
112+
}
113+
if v, ok := dMap["device_type"]; ok {
114+
boundIpInfo.DeviceType = helper.String(v.(string))
115+
}
116+
boundIpInfo.IspCode = helper.IntUint64(ISP_CODE_BGP)
117+
request.BoundDevList = append(request.BoundDevList, &boundIpInfo)
118+
}
119+
}
120+
121+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
122+
result, e := meta.(*TencentCloudClient).apiV3Conn.UseAntiddosClient().CreateBoundIP(request)
123+
if e != nil {
124+
return retryError(e)
125+
} else {
126+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString())
127+
}
128+
if *result.Response.Success.Code != RESPONSE_SUCCESS_CODE {
129+
return resource.RetryableError(errors.New("request failed"))
130+
}
131+
return nil
132+
})
133+
if err != nil {
134+
log.Printf("[CRITAL]%s create antiddos boundip failed, reason:%+v", logId, err)
135+
return err
136+
}
137+
err = resource.Retry(writeRetryTimeout, func() *resource.RetryError {
138+
boundip, e := service.DescribeAntiddosBoundipById(ctx, bgpInstanceId)
139+
if e != nil {
140+
return retryError(e)
141+
}
142+
if *boundip.BoundStatus == DAYU_BOUNDSTATUS_IDLE {
143+
return nil
144+
}
145+
return resource.RetryableError(errors.New("still building."))
146+
147+
})
148+
if err != nil {
149+
return err
150+
}
151+
152+
d.SetId(bgpInstanceId + FILED_SP + strings.Join(boundIps, COMMA_SP))
153+
154+
return resourceTencentCloudDayuDDosIpAttachmentReadV2(d, meta)
155+
}
156+
157+
func resourceTencentCloudDayuDDosIpAttachmentReadV2(d *schema.ResourceData, meta interface{}) error {
158+
defer logElapsed("resource.tencentcloud_dayu_ddos_ip_attachment_v2.read")()
159+
defer inconsistentCheck(d, meta)()
160+
161+
logId := getLogId(contextNil)
162+
163+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
164+
165+
service := AntiddosService{client: meta.(*TencentCloudClient).apiV3Conn}
166+
167+
idSplit := strings.Split(d.Id(), FILED_SP)
168+
if len(idSplit) != 2 {
169+
return fmt.Errorf("id is broken,%s", d.Id())
170+
}
171+
bgpInstanceId := idSplit[0]
172+
boundIps := idSplit[1]
173+
boundIpMap := make(map[string]bool)
174+
for _, boundIp := range strings.Split(boundIps, COMMA_SP) {
175+
boundIpMap[boundIp] = true
176+
}
177+
178+
boundip, err := service.DescribeAntiddosBoundipById(ctx, bgpInstanceId)
179+
if err != nil {
180+
return err
181+
}
182+
183+
if boundip == nil {
184+
d.SetId("")
185+
log.Printf("resource `AntiddosIp` %s does not exist", d.Id())
186+
return nil
187+
}
188+
_ = d.Set("bgp_instance_id", bgpInstanceId)
189+
boundIpList := make([]map[string]interface{}, 0)
190+
if boundip.EipProductInfos != nil {
191+
boundIpListItem := make(map[string]interface{})
192+
for _, item := range boundip.EipProductInfos {
193+
if _, ok := boundIpMap[*item.Ip]; !ok {
194+
continue
195+
}
196+
boundIpListItem["ip"] = *item.Ip
197+
boundIpListItem["biz_type"] = *item.BizType
198+
boundIpListItem["instance_id"] = *item.InstanceId
199+
boundIpListItem["device_type"] = *item.DeviceType
200+
boundIpList = append(boundIpList, boundIpListItem)
201+
}
202+
}
203+
_ = d.Set("bound_ip_list", boundIpList)
204+
205+
return nil
206+
}
207+
208+
func resourceTencentCloudDayuDDosIpAttachmentDeleteV2(d *schema.ResourceData, meta interface{}) error {
209+
defer logElapsed("resource.tencentcloud_dayu_ddos_ip_attachment_v2.delete")()
210+
defer inconsistentCheck(d, meta)()
211+
212+
logId := getLogId(contextNil)
213+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
214+
215+
service := AntiddosService{client: meta.(*TencentCloudClient).apiV3Conn}
216+
217+
idSplit := strings.Split(d.Id(), FILED_SP)
218+
if len(idSplit) != 2 {
219+
return fmt.Errorf("id is broken,%s", d.Id())
220+
}
221+
bgpInstanceId := idSplit[0]
222+
boundIps := idSplit[1]
223+
224+
request := antiddos.NewCreateBoundIPRequest()
225+
request.Business = helper.String(BUSINESS_BGP_MULTIP)
226+
request.Id = helper.String(bgpInstanceId)
227+
ubBoundDevList := make([]*antiddos.BoundIpInfo, 0)
228+
for _, boundIp := range strings.Split(boundIps, COMMA_SP) {
229+
ubBoundDevList = append(
230+
ubBoundDevList,
231+
&antiddos.BoundIpInfo{
232+
Ip: &boundIp,
233+
},
234+
)
235+
}
236+
request.UnBoundDevList = ubBoundDevList
237+
238+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
239+
result, e := meta.(*TencentCloudClient).apiV3Conn.UseAntiddosClient().CreateBoundIP(request)
240+
if e != nil {
241+
return retryError(e)
242+
} else {
243+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString())
244+
}
245+
if *result.Response.Success.Code != RESPONSE_SUCCESS_CODE {
246+
return resource.RetryableError(errors.New("request failed"))
247+
}
248+
return nil
249+
})
250+
if err != nil {
251+
log.Printf("[CRITAL]%s create antiddos boundip failed, reason:%+v", logId, err)
252+
return err
253+
}
254+
255+
err = resource.Retry(writeRetryTimeout, func() *resource.RetryError {
256+
boundip, e := service.DescribeAntiddosBoundipById(ctx, bgpInstanceId)
257+
if e != nil {
258+
return retryError(e)
259+
}
260+
if *boundip.BoundStatus == DAYU_BOUNDSTATUS_IDLE {
261+
return nil
262+
}
263+
return resource.RetryableError(errors.New("still building."))
264+
265+
})
266+
if err != nil {
267+
return err
268+
}
269+
270+
return nil
271+
}

0 commit comments

Comments
 (0)