Skip to content

Commit c2c95b6

Browse files
authored
fix: nat dettach ip error (#813)
1 parent ba8e039 commit c2c95b6

File tree

4 files changed

+117
-12
lines changed

4 files changed

+117
-12
lines changed

tencentcloud/resource_tc_eip.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,8 @@ func resourceTencentCloudEipDelete(d *schema.ResourceData, meta interface{}) err
320320

321321
err = resource.Retry(writeRetryTimeout, func() *resource.RetryError {
322322
errRet := vpcService.DeleteEip(ctx, eipId)
323-
if err != nil {
324-
return retryError(errRet)
323+
if errRet != nil {
324+
return retryError(errRet, "DesOperation.MutexTaskRunning")
325325
}
326326
return nil
327327
})

tencentcloud/resource_tc_nat_gateway.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@ func resourceTencentCloudNatGatewayUpdate(d *schema.ResourceData, meta interface
240240
defer logElapsed("resource.tencentcloud_nat_gateway.update")()
241241

242242
logId := getLogId(contextNil)
243+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
244+
vpcService := VpcService{client: meta.(*TencentCloudClient).apiV3Conn}
243245

244246
d.Partial(true)
245247
natGatewayId := d.Id()
@@ -343,10 +345,8 @@ func resourceTencentCloudNatGatewayUpdate(d *schema.ResourceData, meta interface
343345

344346
if len(unassignedRequest.PublicIpAddresses) > 0 {
345347
err := resource.Retry(readRetryTimeout, func() *resource.RetryError {
346-
_, e := meta.(*TencentCloudClient).apiV3Conn.UseVpcClient().DisassociateNatGatewayAddress(unassignedRequest)
348+
e := vpcService.DisassociateNatGatewayAddress(ctx, unassignedRequest)
347349
if e != nil {
348-
log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n",
349-
logId, unassignedRequest.GetAction(), unassignedRequest.ToJsonString(), e.Error())
350350
return retryError(e)
351351
}
352352
return nil
@@ -403,10 +403,8 @@ func resourceTencentCloudNatGatewayUpdate(d *schema.ResourceData, meta interface
403403
unassignedRequest.NatGatewayId = &natGatewayId
404404
unassignedRequest.PublicIpAddresses = []*string{&backUpOldIp}
405405
err := resource.Retry(readRetryTimeout, func() *resource.RetryError {
406-
_, e := meta.(*TencentCloudClient).apiV3Conn.UseVpcClient().DisassociateNatGatewayAddress(unassignedRequest)
406+
e := vpcService.DisassociateNatGatewayAddress(ctx, unassignedRequest)
407407
if e != nil {
408-
log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n",
409-
logId, unassignedRequest.GetAction(), unassignedRequest.ToJsonString(), e.Error())
410408
return retryError(e)
411409
}
412410
return nil
@@ -440,7 +438,6 @@ func resourceTencentCloudNatGatewayUpdate(d *schema.ResourceData, meta interface
440438

441439
}
442440

443-
ctx := context.WithValue(context.TODO(), logIdKey, logId)
444441
if d.HasChange("tags") {
445442

446443
oldValue, newValue := d.GetChange("tags")

tencentcloud/resource_tc_nat_gateway_test.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,6 @@ data "tencentcloud_vpc_instances" "foo" {
145145
# Create EIP
146146
resource "tencentcloud_eip" "eip_dev_dnat" {
147147
name = "terraform_test"
148-
}
149-
resource "tencentcloud_eip" "eip_test_dnat" {
150-
name = "terraform_test"
151148
}
152149
resource "tencentcloud_eip" "new_eip" {
153150
name = "terraform_test"

tencentcloud/service_tencentcloud_vpc.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2025,6 +2025,91 @@ func (me *VpcService) AttachEip(ctx context.Context, eipId, instanceId string) e
20252025
return nil
20262026
}
20272027

2028+
func (me *VpcService) DescribeNatGatewayById(ctx context.Context, natGateWayId string) (natGateWay *vpc.NatGateway, errRet error) {
2029+
logId := getLogId(ctx)
2030+
request := vpc.NewDescribeNatGatewaysRequest()
2031+
request.NatGatewayIds = []*string{&natGateWayId}
2032+
defer func() {
2033+
if errRet != nil {
2034+
log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n",
2035+
logId, request.GetAction(), request.ToJsonString(), errRet.Error())
2036+
}
2037+
}()
2038+
2039+
ratelimit.Check(request.GetAction())
2040+
response, err := me.client.UseVpcClient().DescribeNatGateways(request)
2041+
2042+
if err != nil {
2043+
errRet = err
2044+
return
2045+
}
2046+
2047+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n",
2048+
logId, request.GetAction(), request.ToJsonString(), response.ToJsonString())
2049+
2050+
if len(response.Response.NatGatewaySet) > 0 {
2051+
natGateWay = response.Response.NatGatewaySet[0]
2052+
}
2053+
2054+
return
2055+
}
2056+
2057+
func (me *VpcService) DisassociateNatGatewayAddress(ctx context.Context, request *vpc.DisassociateNatGatewayAddressRequest) (errRet error) {
2058+
logId := getLogId(ctx)
2059+
defer func() {
2060+
if errRet != nil {
2061+
log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n",
2062+
logId, request.GetAction(), request.ToJsonString(), errRet.Error())
2063+
}
2064+
}()
2065+
2066+
// Check if Nat Gateway Ip still associate
2067+
gateway, err := me.DescribeNatGatewayById(ctx, *request.NatGatewayId)
2068+
2069+
if err != nil {
2070+
errRet = err
2071+
return
2072+
}
2073+
2074+
if gateway == nil || len(gateway.PublicIpAddressSet) == 0 {
2075+
return
2076+
}
2077+
2078+
var gatewayAddresses []string
2079+
var candidates []*string
2080+
2081+
for i := range gateway.PublicIpAddressSet {
2082+
addr := gateway.PublicIpAddressSet[i].PublicIpAddress
2083+
gatewayAddresses = append(gatewayAddresses, *addr)
2084+
}
2085+
2086+
for i := range request.PublicIpAddresses {
2087+
addr := request.PublicIpAddresses[i]
2088+
if helper.StringsContain(gatewayAddresses, *addr) {
2089+
candidates = append(candidates, addr)
2090+
}
2091+
}
2092+
2093+
if len(candidates) == 0 {
2094+
return nil
2095+
}
2096+
2097+
request.PublicIpAddresses = candidates
2098+
2099+
ratelimit.Check(request.GetAction())
2100+
response, err := me.client.UseVpcClient().DisassociateNatGatewayAddress(request)
2101+
2102+
if err != nil {
2103+
errRet = err
2104+
return
2105+
}
2106+
2107+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n",
2108+
logId, request.GetAction(), request.ToJsonString(), response.ToJsonString())
2109+
2110+
return
2111+
}
2112+
20282113
func (me *VpcService) UnattachEip(ctx context.Context, eipId string) error {
20292114
eipUnattachLocker.Lock()
20302115
defer eipUnattachLocker.Unlock()
@@ -2038,6 +2123,32 @@ func (me *VpcService) UnattachEip(ctx context.Context, eipId string) error {
20382123
return nil
20392124
}
20402125

2126+
// DisassociateAddress Doesn't support Disassociate NAT Address
2127+
if strings.HasPrefix(*eip.InstanceId, "nat-") {
2128+
request := vpc.NewDisassociateNatGatewayAddressRequest()
2129+
request.NatGatewayId = eip.InstanceId
2130+
request.PublicIpAddresses = []*string{eip.AddressIp}
2131+
err := me.DisassociateNatGatewayAddress(ctx, request)
2132+
if err != nil {
2133+
return err
2134+
}
2135+
2136+
outErr := resource.Retry(readRetryTimeout*3, func() *resource.RetryError {
2137+
eip, err := me.DescribeEipById(ctx, eipId)
2138+
if err != nil {
2139+
return retryError(err)
2140+
}
2141+
if eip != nil && *eip.AddressStatus != EIP_STATUS_UNBIND {
2142+
return resource.RetryableError(fmt.Errorf("eip is still %s", EIP_STATUS_UNBIND))
2143+
}
2144+
return nil
2145+
})
2146+
2147+
if outErr != nil {
2148+
return outErr
2149+
}
2150+
}
2151+
20412152
request := vpc.NewDisassociateAddressRequest()
20422153
request.AddressId = &eipId
20432154
ratelimit.Check(request.GetAction())

0 commit comments

Comments
 (0)