@@ -54,6 +54,7 @@ import (
5454 "github.com/hashicorp/terraform-plugin-sdk/helper/resource"
5555 "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
5656 "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
57+ sdkErrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
5758 vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312"
5859 "github.com/terraform-providers/terraform-provider-tencentcloud/tencentcloud/internal/helper"
5960)
@@ -76,11 +77,22 @@ func resourceTencentCloudVpnConnection() *schema.Resource {
7677 Description : "Name of the VPN connection. The length of character is limited to 1-60." ,
7778 },
7879 "vpc_id" : {
79- Type : schema .TypeString ,
80- Optional : true ,
81- ForceNew : true ,
80+ Type : schema .TypeString ,
81+ Optional : true ,
82+ ForceNew : true ,
83+ DiffSuppressFunc : func (k , old , new string , d * schema.ResourceData ) bool {
84+ if v , ok := d .GetOk ("is_ccn_type" ); ok && v .(bool ) {
85+ return true
86+ }
87+ return old == new
88+ },
8289 Description : "ID of the VPC. Required if vpn gateway is not in `CCN` type, and doesn't make sense for `CCN` vpn gateway." ,
8390 },
91+ "is_ccn_type" : {
92+ Type : schema .TypeBool ,
93+ Computed : true ,
94+ Description : "Indicate whether is ccn type. Modification of this field only impacts force new logic of `vpc_id`. If `is_ccn_type` is true, modification of `vpc_id` will be ignored." ,
95+ },
8496 "customer_gateway_id" : {
8597 Type : schema .TypeString ,
8698 Required : true ,
@@ -99,7 +111,7 @@ func resourceTencentCloudVpnConnection() *schema.Resource {
99111 Description : "Pre-shared key of the VPN connection." ,
100112 },
101113 "security_group_policy" : {
102- Type : schema .TypeList ,
114+ Type : schema .TypeSet ,
103115 Required : true ,
104116 Description : "Security group policy of the VPN connection." ,
105117 Elem : & schema.Resource {
@@ -274,38 +286,21 @@ func resourceTencentCloudVpnConnection() *schema.Resource {
274286func resourceTencentCloudVpnConnectionCreate (d * schema.ResourceData , meta interface {}) error {
275287 defer logElapsed ("resource.tencentcloud_vpn_connection.create" )()
276288
277- logId := getLogId (contextNil )
278- ctx := context .WithValue (context .TODO (), logIdKey , logId )
289+ var (
290+ logId = getLogId (contextNil )
291+ ctx = context .WithValue (context .TODO (), logIdKey , logId )
292+ service = VpcService {client : meta .(* TencentCloudClient ).apiV3Conn }
293+ )
279294
280295 // pre check vpn gateway id
281- requestVpngw := vpc .NewDescribeVpnGatewaysRequest ()
282- requestVpngw .VpnGatewayIds = []* string {helper .String (d .Get ("vpn_gateway_id" ).(string ))}
283- var responseVpngw * vpc.DescribeVpnGatewaysResponse
284- err := resource .Retry (readRetryTimeout , func () * resource.RetryError {
285- result , e := meta .(* TencentCloudClient ).apiV3Conn .UseVpcClient ().DescribeVpnGateways (requestVpngw )
286- if e != nil {
287- ee , ok := e .(* errors.TencentCloudSDKError )
288- if ! ok {
289- return retryError (e )
290- }
291- if ee .Code == VPCNotFound {
292- return nil
293- } else {
294- return retryError (e )
295- }
296- }
297- responseVpngw = result
298- return nil
299- })
296+ has , gateway , err := service .DescribeVpngwById (ctx , d .Get ("vpn_gateway_id" ).(string ))
300297 if err != nil {
301298 return err
302299 }
303- if len ( responseVpngw . Response . VpnGatewaySet ) < 1 {
300+ if ! has {
304301 return fmt .Errorf ("[CRITAL] vpn_gateway_id %s doesn't exist" , d .Get ("vpn_gateway_id" ).(string ))
305302 }
306303
307- gateway := responseVpngw .Response .VpnGatewaySet [0 ]
308-
309304 // create vpn connection
310305 request := vpc .NewCreateVpnConnectionRequest ()
311306 request .VpnConnectionName = helper .String (d .Get ("name" ).(string ))
@@ -315,6 +310,9 @@ func resourceTencentCloudVpnConnectionCreate(d *schema.ResourceData, meta interf
315310 }
316311 request .VpcId = helper .String (d .Get ("vpc_id" ).(string ))
317312 } else {
313+ if _ , ok := d .GetOk ("vpc_id" ); ok {
314+ return fmt .Errorf ("[CRITAL] vpc_id doesn't make sense when vpn gateway is in CCN type" )
315+ }
318316 request .VpcId = helper .String ("" )
319317 }
320318 request .VpnGatewayId = helper .String (d .Get ("vpn_gateway_id" ).(string ))
@@ -323,7 +321,7 @@ func resourceTencentCloudVpnConnectionCreate(d *schema.ResourceData, meta interf
323321
324322 //set up SecurityPolicyDatabases
325323
326- sgps := d .Get ("security_group_policy" ).([] interface {} )
324+ sgps := d .Get ("security_group_policy" ).(* schema. Set ). List ( )
327325 if len (sgps ) < 1 {
328326 return fmt .Errorf ("Para `security_group_policy` should be set at least one." )
329327 }
@@ -516,8 +514,11 @@ func resourceTencentCloudVpnConnectionRead(d *schema.ResourceData, meta interfac
516514 defer logElapsed ("resource.tencentcloud_vpn_connection.read" )()
517515 defer inconsistentCheck (d , meta )()
518516
519- logId := getLogId (contextNil )
520- ctx := context .WithValue (context .TODO (), logIdKey , logId )
517+ var (
518+ logId = getLogId (contextNil )
519+ ctx = context .WithValue (context .TODO (), logIdKey , logId )
520+ service = VpcService {client : meta .(* TencentCloudClient ).apiV3Conn }
521+ )
521522
522523 connectionId := d .Id ()
523524 request := vpc .NewDescribeVpnConnectionsRequest ()
@@ -528,6 +529,10 @@ func resourceTencentCloudVpnConnectionRead(d *schema.ResourceData, meta interfac
528529 if e != nil {
529530 log .Printf ("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n " ,
530531 logId , request .GetAction (), request .ToJsonString (), e .Error ())
532+ ee , ok := e .(* sdkErrors.TencentCloudSDKError )
533+ if ok && ee .Code == VPCNotFound {
534+ return nil
535+ }
531536 return retryError (e )
532537 }
533538
@@ -538,16 +543,31 @@ func resourceTencentCloudVpnConnectionRead(d *schema.ResourceData, meta interfac
538543 log .Printf ("[CRITAL]%s read VPN connection failed, reason:%s\n " , logId , err .Error ())
539544 return err
540545 }
541- if len (response .Response .VpnConnectionSet ) < 1 {
546+ if response == nil || response . Response == nil || len (response .Response .VpnConnectionSet ) < 1 {
542547 d .SetId ("" )
543548 return nil
544549 }
545550
546551 connection := response .Response .VpnConnectionSet [0 ]
547552 _ = d .Set ("name" , * connection .VpnConnectionName )
548- _ = d .Set ("vpc_id" , * connection .VpcId )
549553 _ = d .Set ("create_time" , * connection .CreatedTime )
550554 _ = d .Set ("vpn_gateway_id" , * connection .VpnGatewayId )
555+
556+ // get vpngw type
557+ has , gateway , err := service .DescribeVpngwById (ctx , d .Get ("vpn_gateway_id" ).(string ))
558+ if err != nil {
559+ log .Printf ("[CRITAL]%s read vpn_geteway failed, reason:%s\n " , logId , err .Error ())
560+ return err
561+ }
562+ if ! has {
563+ return fmt .Errorf ("[CRITAL] vpn_gateway_id %s doesn't exist" , d .Get ("vpn_gateway_id" ).(string ))
564+ }
565+
566+ if * gateway .Type != "CCN" {
567+ _ = d .Set ("vpc_id" , * connection .VpcId )
568+ }
569+
570+ _ = d .Set ("is_ccn_type" , * gateway .Type == "CCN" )
551571 _ = d .Set ("customer_gateway_id" , * connection .CustomerGatewayId )
552572 _ = d .Set ("pre_share_key" , * connection .PreShareKey )
553573 //set up SPD
@@ -624,13 +644,13 @@ func resourceTencentCloudVpnConnectionUpdate(d *schema.ResourceData, meta interf
624644
625645 //set up SecurityPolicyDatabases
626646 if d .HasChange ("security_group_policy" ) {
627- sgps := d .Get ("security_group_policy" ).([] interface {} )
647+ sgps := d .Get ("security_group_policy" ).(* schema. Set ). List ( )
628648 if len (sgps ) < 1 {
629649 return fmt .Errorf ("Para `security_group_policy` should be set at least one." )
630650 }
651+ request .SecurityPolicyDatabases = make ([]* vpc.SecurityPolicyDatabase , 0 , len (sgps ))
631652 for _ , v := range sgps {
632653 m := v .(map [string ]interface {})
633- request .SecurityPolicyDatabases = make ([]* vpc.SecurityPolicyDatabase , 0 , len (sgps ))
634654 var sgp vpc.SecurityPolicyDatabase
635655 local := m ["local_cidr_block" ].(string )
636656 sgp .LocalCidrBlock = & local
0 commit comments