Skip to content

Commit 061a30f

Browse files
zhengjc2018xiaozhu36
authored andcommitted
update: add support for nat from normal to enhanced
1 parent 6a865c3 commit 061a30f

File tree

6 files changed

+290
-8
lines changed

6 files changed

+290
-8
lines changed

.python-version

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.6.5

alicloud/resource_alicloud_nat_gateway.go

+54-5
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,12 @@ func resourceAliyunNatGateway() *schema.Resource {
5959
"nat_type": {
6060
Type: schema.TypeString,
6161
Optional: true,
62-
ForceNew: true,
6362
ValidateFunc: validation.StringInSlice([]string{"Normal", "Enhanced"}, false),
6463
Default: "Normal",
6564
},
6665
"vswitch_id": {
6766
Type: schema.TypeString,
6867
Optional: true,
69-
ForceNew: true,
7068
},
7169
"bandwidth_package_ids": {
7270
Type: schema.TypeString,
@@ -262,7 +260,6 @@ func resourceAliyunNatGatewayUpdate(d *schema.ResourceData, meta interface{}) er
262260
modifyNatGatewayAttributeRequest.NatGatewayId = natGateway.NatGatewayId
263261

264262
if d.HasChange("name") {
265-
d.SetPartial("name")
266263
var name string
267264
if v, ok := d.GetOk("name"); ok {
268265
name = v.(string)
@@ -272,10 +269,10 @@ func resourceAliyunNatGatewayUpdate(d *schema.ResourceData, meta interface{}) er
272269
modifyNatGatewayAttributeRequest.Name = name
273270

274271
attributeUpdate = true
272+
d.SetPartial("name")
275273
}
276274

277275
if d.HasChange("description") {
278-
d.SetPartial("description")
279276
var description string
280277
if v, ok := d.GetOk("description"); ok {
281278
description = v.(string)
@@ -286,6 +283,7 @@ func resourceAliyunNatGatewayUpdate(d *schema.ResourceData, meta interface{}) er
286283
modifyNatGatewayAttributeRequest.Description = description
287284

288285
attributeUpdate = true
286+
d.SetPartial("description")
289287
}
290288

291289
if attributeUpdate {
@@ -299,7 +297,6 @@ func resourceAliyunNatGatewayUpdate(d *schema.ResourceData, meta interface{}) er
299297
}
300298

301299
if d.HasChange("specification") {
302-
d.SetPartial("specification")
303300
modifyNatGatewaySpecRequest := vpc.CreateModifyNatGatewaySpecRequest()
304301
modifyNatGatewaySpecRequest.RegionId = natGateway.RegionId
305302
modifyNatGatewaySpecRequest.NatGatewayId = natGateway.NatGatewayId
@@ -312,7 +309,59 @@ func resourceAliyunNatGatewayUpdate(d *schema.ResourceData, meta interface{}) er
312309
return WrapErrorf(err, DefaultErrorMsg, d.Id(), modifyNatGatewaySpecRequest.GetActionName(), AlibabaCloudSdkGoERROR)
313310
}
314311
addDebug(modifyNatGatewaySpecRequest.GetActionName(), raw, modifyNatGatewaySpecRequest.RpcRequest, modifyNatGatewaySpecRequest)
312+
d.SetPartial("specification")
315313
}
314+
315+
if d.HasChange("nat_type") {
316+
vv := d.Get("nat_type").(string)
317+
if vv == "Enhanced" {
318+
action := "UpdateNatGatewayNatType"
319+
request := map[string]interface{}{
320+
"RegionId": client.RegionId,
321+
"NatGatewayId": d.Id(),
322+
"NatType": vv,
323+
}
324+
325+
if vswId := d.Get("vswitch_id").(string); vswId != "" {
326+
request["VSwitchId"] = vswId
327+
}
328+
request["ClientToken"] = buildClientToken("UpdateNatGatewayNatType")
329+
330+
conn, err := meta.(*connectivity.AliyunClient).NewVpcClient()
331+
if err != nil {
332+
return WrapError(err)
333+
}
334+
// If the API supports
335+
runtime := util.RuntimeOptions{}
336+
runtime.SetAutoretry(true)
337+
338+
wait := incrementalWait(2*time.Second, 1*time.Second)
339+
err1 := resource.Retry(3*time.Minute, func() *resource.RetryError {
340+
response, err2 := conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2016-04-28"), StringPointer("AK"), nil, request, &runtime)
341+
addDebug(action, response, request)
342+
if err2 != nil {
343+
if IsExpectedErrors(err2, []string{"TaskConflict", "UnknownError", Throttling, "OperationFailed.NatGwRouteInMiddleStatus"}) {
344+
wait()
345+
return resource.RetryableError(err2)
346+
}
347+
return resource.NonRetryableError(err2)
348+
}
349+
addDebug(action, response, request)
350+
return nil
351+
})
352+
if err1 != nil {
353+
return WrapErrorf(err1, DefaultErrorMsg, "alicloud_nat_transform_to_enhanced", action, AlibabaCloudSdkGoERROR)
354+
}
355+
if err3 := vpcService.WaitForNatGatewayTransform(d.Id(), DefaultTimeout*5); err3 != nil {
356+
return WrapError(err3)
357+
}
358+
} else {
359+
return WrapError(Error("You should set natType from Normal to Enhanced"))
360+
}
361+
d.SetPartial("vswitch_id")
362+
d.SetPartial("nat_type")
363+
}
364+
316365
d.Partial(false)
317366
if err := vpcService.WaitForNatGateway(d.Id(), Available, DefaultTimeout); err != nil {
318367
return WrapError(err)

alicloud/resource_alicloud_nat_gateway_test.go

+88
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,56 @@ func TestAccAlicloudNatGatewayEnhanced(t *testing.T) {
246246
})
247247
}
248248

249+
func TestAccAlicloudNatGatewayTransform(t *testing.T) {
250+
var v vpc.NatGateway
251+
resourceId := "alicloud_nat_gateway.main"
252+
ra := resourceAttrInit(resourceId, testAccCheckNatGatewayBasicMap)
253+
serviceFunc := func() interface{} {
254+
return &VpcService{testAccProvider.Meta().(*connectivity.AliyunClient)}
255+
}
256+
rc := resourceCheckInit(resourceId, &v, serviceFunc)
257+
rac := resourceAttrCheckInit(rc, ra)
258+
259+
rand := acctest.RandInt()
260+
testAccCheck := rac.resourceAttrMapUpdateSet()
261+
262+
resource.Test(t, resource.TestCase{
263+
PreCheck: func() {
264+
testAccPreCheck(t)
265+
},
266+
267+
// module name
268+
IDRefreshName: resourceId,
269+
Providers: testAccProviders,
270+
CheckDestroy: testAccCheckNatGatewayDestroy,
271+
Steps: []resource.TestStep{
272+
{
273+
Config: testAccNatGatewayConfig_transform_to_enhanced(rand, "Normal", ""),
274+
Check: resource.ComposeTestCheckFunc(
275+
testAccCheck(map[string]string{
276+
"name": CHECKSET,
277+
}),
278+
),
279+
},
280+
{
281+
ResourceName: resourceId,
282+
ImportState: true,
283+
ImportStateVerify: true,
284+
ImportStateVerifyIgnore: []string{"period"},
285+
},
286+
{
287+
Config: testAccNatGatewayConfig_transform_to_enhanced(rand, "Enhanced", "${alicloud_vswitch.foo1.id}"),
288+
Check: resource.ComposeTestCheckFunc(
289+
testAccCheck(map[string]string{
290+
"nat_type": "Enhanced",
291+
"vswitch_id": CHECKSET,
292+
}),
293+
),
294+
},
295+
},
296+
})
297+
}
298+
249299
func testAccNatGatewayConfigBasic(rand int) string {
250300
return fmt.Sprintf(
251301
`
@@ -466,6 +516,44 @@ resource "alicloud_nat_gateway" "default" {
466516
`, rand)
467517
}
468518

519+
func testAccNatGatewayConfig_transform_to_enhanced(rand int, natType string, vswitchId string) string {
520+
return fmt.Sprintf(
521+
`
522+
variable "name" {
523+
default = "tf-testAccNatGatewayTransformConfig%d"
524+
}
525+
526+
variable "nat_type" {
527+
default = "%s"
528+
}
529+
530+
data "alicloud_enhanced_nat_available_zones" "enhanced" {
531+
}
532+
533+
resource "alicloud_vpc" "foo" {
534+
name = var.name
535+
cidr_block = "10.0.0.0/8"
536+
}
537+
538+
resource "alicloud_vswitch" "foo1" {
539+
depends_on = [alicloud_vpc.foo]
540+
name = var.name
541+
availability_zone = data.alicloud_enhanced_nat_available_zones.enhanced.zones[1].zone_id
542+
cidr_block = "10.10.0.0/20"
543+
vpc_id = alicloud_vpc.foo.id
544+
}
545+
546+
resource "alicloud_nat_gateway" "main" {
547+
depends_on = [alicloud_vpc.foo, alicloud_vswitch.foo1]
548+
vpc_id = alicloud_vpc.foo.id
549+
specification = "Small"
550+
name = var.name
551+
nat_type = var.nat_type
552+
vswitch_id = "%s"
553+
}
554+
`, rand, natType, vswitchId)
555+
}
556+
469557
var testAccCheckNatGatewayBasicMap = map[string]string{
470558
"name": "tf-testAccNatGatewayConfigSpec",
471559
"specification": "Small",

alicloud/service_alicloud_vpc.go

+75
Original file line numberDiff line numberDiff line change
@@ -1347,6 +1347,81 @@ func (s *VpcService) setInstanceSecondaryCidrBlocks(d *schema.ResourceData) erro
13471347
}
13481348
d.SetPartial("secondary_cidr_blocks")
13491349
}
1350+
return nil
1351+
}
1352+
1353+
func (s *VpcService) DescribeNatGatewayTransform(id string) ([]interface{}, error) {
1354+
conn, err := s.client.NewVpcClient()
1355+
if err != nil {
1356+
return nil, WrapError(err)
1357+
}
1358+
1359+
action := "GetNatGatewayConvertStatus"
1360+
request := map[string]interface{}{
1361+
"RegionId": s.client.RegionId,
1362+
"NatGatewayId": id,
1363+
}
1364+
request["ClientToken"] = buildClientToken("GetNatGatewayConvertStatus")
1365+
1366+
runtime := util.RuntimeOptions{}
1367+
runtime.SetAutoretry(true)
1368+
1369+
response, err1 := conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2016-04-28"), StringPointer("AK"), nil, request, &runtime)
1370+
if err1 != nil {
1371+
if IsExpectedErrors(err1, []string{"InvalidVpcID.NotFound", "Forbidden.VpcNotFound"}) {
1372+
return nil, WrapErrorf(err, NotFoundMsg, AlibabaCloudSdkGoERROR)
1373+
}
1374+
return nil, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR)
1375+
}
1376+
addDebug(action, response, request)
1377+
1378+
ob, err2 := jsonpath.Get("$.ConvertSteps", response)
1379+
if err2 != nil {
1380+
return nil, WrapErrorf(err2, FailedGetAttributeMsg, id, "$.ConvertSteps", response)
1381+
}
1382+
1383+
natType, err3 := jsonpath.Get("$.DstNatType", response)
1384+
if err3 != nil {
1385+
return nil, WrapErrorf(err3, FailedGetAttributeMsg, id, "$.DstNatType", response)
1386+
}
13501387

1388+
object := ob.([]interface{})
1389+
if len(object) < 1 || natType.(string) != "Enhanced" {
1390+
return nil, WrapErrorf(Error(GetNotFoundMessage("NAT", id)), NotFoundWithResponse, response)
1391+
}
1392+
return object, nil
1393+
1394+
}
1395+
1396+
func (s *VpcService) WaitForNatGatewayTransform(id string, timeout int64) error {
1397+
deadline := time.Now().Add(time.Duration(timeout) * time.Second)
1398+
for {
1399+
object, err := s.DescribeNatGatewayTransform(id)
1400+
if err != nil {
1401+
if NotFoundError(err) {
1402+
return err
1403+
}
1404+
if IsExpectedErrors(err, []string{"OperationFailed.NatGwRouteInMiddleStatusError"}) {
1405+
return nil
1406+
}
1407+
return err
1408+
}
1409+
1410+
isOk := false
1411+
for _, v := range object {
1412+
val := v.(map[string]interface{})
1413+
if val["StepName"].(string) == "end_success" && val["StepStatus"].(string) == "successful" {
1414+
isOk = true
1415+
break
1416+
}
1417+
}
1418+
if time.Now().After(deadline) {
1419+
return WrapErrorf(err, WaitTimeoutMsg, id, GetFunc(1), timeout, "", "", ProviderERROR)
1420+
}
1421+
if isOk {
1422+
break
1423+
}
1424+
time.Sleep(DefaultIntervalShort * time.Second)
1425+
}
13511426
return nil
13521427
}
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
variable "name" {
2+
default = "nat-transform-to-enhanced"
3+
}
4+
5+
data "alicloud_enhanced_nat_available_zones" "enhanced" {
6+
}
7+
8+
resource "alicloud_vpc" "foo" {
9+
name = var.name
10+
cidr_block = "10.0.0.0/8"
11+
}
12+
13+
resource "alicloud_vswitch" "foo" {
14+
depends_on = [alicloud_vpc.foo]
15+
name = var.name
16+
availability_zone = data.alicloud_enhanced_nat_available_zones.enhanced.zones[0].zone_id
17+
cidr_block = "10.1.0.0/16"
18+
vpc_id = alicloud_vpc.foo.id
19+
}
20+
21+
resource "alicloud_vswitch" "foo1" {
22+
depends_on = [alicloud_vpc.foo]
23+
name = var.name
24+
availability_zone = data.alicloud_enhanced_nat_available_zones.enhanced.zones[1].zone_id
25+
cidr_block = "10.10.0.0/20"
26+
vpc_id = alicloud_vpc.foo.id
27+
}
28+
29+
resource "alicloud_nat_gateway" "main" {
30+
depends_on = [alicloud_vswitch.foo, alicloud_vpc.foo,alicloud_vswitch.foo1]
31+
vpc_id = alicloud_vpc.foo.id
32+
specification = "Small"
33+
name = var.name
34+
nat_type = "Normal"
35+
// vswitch_id = alicloud_vswitch.foo1.id
36+
}

website/docs/r/nat_gateway.html.markdown

+36-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ If you want to add public IP, you can use resource 'alicloud_eip_association' to
1818

1919
-> **NOTE:** From version 1.7.1, this resource has deprecated bandwidth packages.
2020
But, in order to manage stock bandwidth packages, version 1.13.0 re-support configuring 'bandwidth_packages'.
21-
21+
2222

2323
## Example Usage
2424

@@ -56,6 +56,39 @@ resource "alicloud_nat_gateway" "enhanced" {
5656
}
5757
```
5858

59+
- transform nat from Normal to Enhanced
60+
-> **NOTE:** You must set `nat_type` to `Enhanced` and set `vswitch_id`.
61+
```
62+
variable "name" {
63+
default = "nat-transform-to-enhanced"
64+
}
65+
66+
data "alicloud_enhanced_nat_available_zones" "enhanced" {
67+
}
68+
69+
resource "alicloud_vpc" "foo" {
70+
name = var.name
71+
cidr_block = "10.0.0.0/8"
72+
}
73+
74+
resource "alicloud_vswitch" "foo1" {
75+
depends_on = [alicloud_vpc.foo]
76+
name = var.name
77+
availability_zone = data.alicloud_enhanced_nat_available_zones.enhanced.zones[1].zone_id
78+
cidr_block = "10.10.0.0/20"
79+
vpc_id = alicloud_vpc.foo.id
80+
}
81+
82+
resource "alicloud_nat_gateway" "main" {
83+
depends_on = [alicloud_vpc.foo,alicloud_vswitch.foo1]
84+
vpc_id = alicloud_vpc.foo.id
85+
specification = "Small"
86+
name = var.name
87+
nat_type = "Enhanced"
88+
vswitch_id = alicloud_vswitch.foo1.id
89+
}
90+
```
91+
5992
## Argument Reference
6093

6194
The following arguments are supported:
@@ -68,8 +101,8 @@ The following arguments are supported:
68101
* `bandwidth_packages` - (Optional) A list of bandwidth packages for the nat gatway. Only support nat gateway created before 00:00 on November 4, 2017. Available in v1.13.0+ and v1.7.1-.
69102
* `instance_charge_type` - (Optional, ForceNew, Available in 1.45.0+) The billing method of the nat gateway. Valid values are "PrePaid" and "PostPaid". Default to "PostPaid".
70103
* `period` - (Optional, ForceNew, Available in 1.45.0+) The duration that you will buy the resource, in month. It is valid when `instance_charge_type` is `PrePaid`. Default to 1. Valid values: [1-9, 12, 24, 36]. At present, the provider does not support modify "period" and you can do that via web console.
71-
* `nat_type` - (Optional, ForceNew, Available in 1.102.0+) The type of nat gateway. Default to `Normal`. Valid values: [`Normal`, `Enhanced`].
72-
* `vswitch_id` - (Optional, ForceNew, Available in 1.102.0+) The id of VSwitch.
104+
* `nat_type` - (Optional, Available in 1.102.0+) The type of nat gateway. Default to `Normal`. Valid values: [`Normal`, `Enhanced`].
105+
* `vswitch_id` - (Optional, Available in 1.102.0+) The id of VSwitch.
73106

74107
-> **NOTE:** The `Normal` Nat Gateway has been offline and please using `Enhanced` Nat Gateway to get the better performance.
75108

0 commit comments

Comments
 (0)