alibabacloudstack/resource_apsarastack_vpngateway_vpnconnection.go (343 lines of code) (raw):

package alibabacloudstack import ( "fmt" "time" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "strings" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" "github.com/aliyun/alibaba-cloud-sdk-go/services/vpc" "github.com/aliyun/terraform-provider-alibabacloudstack/alibabacloudstack/connectivity" "github.com/aliyun/terraform-provider-alibabacloudstack/alibabacloudstack/errmsgs" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func resourceAlibabacloudStackVpnConnection() *schema.Resource { resource := &schema.Resource{ Schema: map[string]*schema.Schema{ "customer_gateway_id": { Type: schema.TypeString, Required: true, ForceNew: true, }, "vpn_gateway_id": { Type: schema.TypeString, Required: true, ForceNew: true, }, "name": { Type: schema.TypeString, Optional: true, Computed:true, ValidateFunc: validation.StringLenBetween(2, 128), Deprecated: "Field 'name' is deprecated and will be removed in a future release. Please use new field 'vpn_connection_name' instead.", ConflictsWith: []string{"vpn_connection_name"}, }, "vpn_connection_name": { Type: schema.TypeString, Optional: true, Computed:true, ValidateFunc: validation.StringLenBetween(2, 128), ConflictsWith: []string{"name"}, }, "local_subnet": { Type: schema.TypeSet, Required: true, Elem: &schema.Schema{ Type: schema.TypeString, ValidateFunc: validateCIDRNetworkAddress, }, MinItems: 1, MaxItems: 10, }, "remote_subnet": { Type: schema.TypeSet, Required: true, Elem: &schema.Schema{ Type: schema.TypeString, ValidateFunc: validateCIDRNetworkAddress, }, MinItems: 1, MaxItems: 10, }, "effect_immediately": { Type: schema.TypeBool, Optional: true, Default: false, }, "ike_config": { Type: schema.TypeList, Optional: true, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "psk": { Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringLenBetween(1, 100), }, "ike_version": { Type: schema.TypeString, Optional: true, Default: IKE_VERSION_1, ValidateFunc: validation.StringInSlice([]string{IKE_VERSION_1, IKE_VERSION_2}, false), }, "ike_mode": { Type: schema.TypeString, Optional: true, Default: IKE_MODE_MAIN, ValidateFunc: validation.StringInSlice([]string{IKE_MODE_MAIN, IKE_MODE_AGGRESSIVE}, false), }, "ike_enc_alg": { Type: schema.TypeString, Optional: true, Default: VPN_ENC_AES, ValidateFunc: validation.StringInSlice([]string{VPN_ENC_AES, VPN_ENC_AES_3DES, VPN_ENC_AES_192, VPN_ENC_AES_256, VPN_ENC_AES_DES}, false), }, "ike_auth_alg": { Type: schema.TypeString, Optional: true, Default: VPN_AUTH_SHA, ValidateFunc: validation.StringInSlice([]string{VPN_AUTH_SHA, VPN_AUTH_MD5, VPN_AUTH_SHA256, VPN_AUTH_SHA386, VPN_AUTH_SHA512}, false), }, "ike_pfs": { Type: schema.TypeString, Optional: true, Default: VPN_PFS_G2, ValidateFunc: validation.StringInSlice([]string{VPN_PFS_G1, VPN_PFS_G2, VPN_PFS_G5, VPN_PFS_G14, VPN_PFS_G24}, false), }, "ike_lifetime": { Type: schema.TypeInt, Optional: true, Default: 86400, ValidateFunc: validation.IntBetween(0, 86400), }, "ike_local_id": { Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringLenBetween(1, 100), }, "ike_remote_id": { Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringLenBetween(1, 100), }, }, }, }, "ipsec_config": { Type: schema.TypeList, Optional: true, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "ipsec_enc_alg": { Type: schema.TypeString, Optional: true, Default: VPN_ENC_AES, ValidateFunc: validation.StringInSlice([]string{VPN_ENC_AES, VPN_ENC_AES_3DES, VPN_ENC_AES_192, VPN_ENC_AES_256, VPN_ENC_AES_DES}, false), }, "ipsec_auth_alg": { Type: schema.TypeString, Optional: true, Default: VPN_AUTH_SHA, ValidateFunc: validation.StringInSlice([]string{VPN_AUTH_SHA, VPN_AUTH_MD5, VPN_AUTH_SHA256, VPN_AUTH_SHA386, VPN_AUTH_SHA512}, false), }, "ipsec_pfs": { Type: schema.TypeString, Optional: true, Default: VPN_PFS_G2, ValidateFunc: validation.StringInSlice([]string{VPN_PFS_G1, VPN_PFS_G2, VPN_PFS_G5, VPN_PFS_G14, VPN_PFS_G24, VPN_PFS_DISABLED}, false), }, "ipsec_lifetime": { Type: schema.TypeInt, Optional: true, ValidateFunc: validation.IntBetween(0, 86400), }, }, }, }, "status": { Type: schema.TypeString, Computed: true, }, }, } setResourceFunc(resource, resourceAlibabacloudStackVpnConnectionCreate, resourceAlibabacloudStackVpnConnectionRead, resourceAlibabacloudStackVpnConnectionUpdate, resourceAlibabacloudStackVpnConnectionDelete) return resource } func resourceAlibabacloudStackVpnConnectionCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) vpnGatewayService := VpnGatewayService{client} request, err := buildAlibabacloudStackVpnConnectionArgs(d, meta) if err != nil { return errmsgs.WrapError(err) } client.InitRpcRequest(*request.RpcRequest) var response *vpc.CreateVpnConnectionResponse var ok bool err = resource.Retry(3*time.Minute, func() *resource.RetryError { args := *request raw, err := client.WithVpcClient(func(vpcClient *vpc.Client) (interface{}, error) { return vpcClient.CreateVpnConnection(&args) }) response, ok = raw.(*vpc.CreateVpnConnectionResponse) if err != nil { if errmsgs.IsExpectedErrors(err, []string{"VpnGateway.Configuring"}) { time.Sleep(10 * time.Second) return resource.RetryableError(err) } errmsg := "" if ok { errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse) } return resource.NonRetryableError(errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, "alibabacloudstack_vpn_connection", request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) return nil }) if err != nil { return errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, "alibabacloudstack_vpn_connection", request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR) } d.SetId(response.VpnConnectionId) if err := vpnGatewayService.WaitForVpnConnection(d.Id(), Null, DefaultTimeoutMedium); err != nil { return errmsgs.WrapError(err) } return nil } func resourceAlibabacloudStackVpnConnectionRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) vpnGatewayService := VpnGatewayService{client} response, err := vpnGatewayService.DescribeVpnConnection(d.Id()) if err != nil { if errmsgs.NotFoundError(err) { d.SetId("") return nil } return errmsgs.WrapError(err) } d.Set("customer_gateway_id", response.CustomerGatewayId) d.Set("vpn_gateway_id", response.VpnGatewayId) connectivity.SetResourceData(d, response.Name, "vpn_connection_name", "name") localSubnet := strings.Split(response.LocalSubnet, ",") d.Set("local_subnet", localSubnet) remoteSubnet := strings.Split(response.RemoteSubnet, ",") d.Set("remote_subnet", remoteSubnet) d.Set("effect_immediately", response.EffectImmediately) d.Set("status", response.Status) if err := d.Set("ike_config", vpnGatewayService.ParseIkeConfig(response.IkeConfig)); err != nil { return errmsgs.WrapError(err) } if err := d.Set("ipsec_config", vpnGatewayService.ParseIpsecConfig(response.IpsecConfig)); err != nil { return errmsgs.WrapError(err) } return nil } func resourceAlibabacloudStackVpnConnectionUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) vpnGatewayService := VpnGatewayService{client} request := vpc.CreateModifyVpnConnectionAttributeRequest() client.InitRpcRequest(*request.RpcRequest) request.VpnConnectionId = d.Id() if d.HasChanges("name", "vpn_connection_name") { request.Name = connectivity.GetResourceData(d, "vpn_connection_name", "name").(string) } request.LocalSubnet = vpnGatewayService.AssembleNetworkSubnetToString(d.Get("local_subnet").(*schema.Set).List()) request.RemoteSubnet = vpnGatewayService.AssembleNetworkSubnetToString(d.Get("remote_subnet").(*schema.Set).List()) /* If not set effect_immediately value, VPN connection will automatically set the value to false*/ if v, ok := d.GetOk("effect_immediately"); ok { request.EffectImmediately = requests.NewBoolean(v.(bool)) } if d.HasChange("ike_config") { ike_config, err := vpnGatewayService.AssembleIkeConfig(d.Get("ike_config").([]interface{})) if err != nil { return errmsgs.WrapError(err) } request.IkeConfig = ike_config } if d.HasChange("ipsec_config") { ipsec_config, err := vpnGatewayService.AssembleIpsecConfig(d.Get("ipsec_config").([]interface{})) if err != nil { return errmsgs.WrapError(err) } request.IpsecConfig = ipsec_config } raw, err := client.WithVpcClient(func(vpcClient *vpc.Client) (interface{}, error) { return vpcClient.ModifyVpnConnectionAttribute(request) }) bresponse, ok := raw.(*responses.CommonResponse) if err != nil { errmsg := "" if ok { errmsg = errmsgs.GetBaseResponseErrorMessage(bresponse.BaseResponse) } return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) return nil } func resourceAlibabacloudStackVpnConnectionDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) vpnGatewayService := VpnGatewayService{client} request := vpc.CreateDeleteVpnConnectionRequest() client.InitRpcRequest(*request.RpcRequest) request.VpnConnectionId = d.Id() err := resource.Retry(5*time.Minute, func() *resource.RetryError { args := *request raw, err := client.WithVpcClient(func(vpcClient *vpc.Client) (interface{}, error) { return vpcClient.DeleteVpnConnection(&args) }) if err != nil { if errmsgs.IsExpectedErrors(err, []string{"VpnGateway.Configuring"}) { time.Sleep(10 * time.Second) return resource.RetryableError(err) } errmsg := "" bresponse, ok := raw.(*responses.CommonResponse) if ok { errmsg = errmsgs.GetBaseResponseErrorMessage(bresponse.BaseResponse) } return resource.NonRetryableError(errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) return nil }) if err != nil { if errmsgs.IsExpectedErrors(err, []string{"InvalidVpnConnectionInstanceId.NotFound"}) { return nil } return errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR) } return errmsgs.WrapError(vpnGatewayService.WaitForVpnConnection(d.Id(), Deleted, DefaultTimeout)) } func buildAlibabacloudStackVpnConnectionArgs(d *schema.ResourceData, meta interface{}) (*vpc.CreateVpnConnectionRequest, error) { client := meta.(*connectivity.AlibabacloudStackClient) vpnGatewayService := VpnGatewayService{client} request := vpc.CreateCreateVpnConnectionRequest() client.InitRpcRequest(*request.RpcRequest) request.CustomerGatewayId = d.Get("customer_gateway_id").(string) request.VpnGatewayId = d.Get("vpn_gateway_id").(string) request.LocalSubnet = vpnGatewayService.AssembleNetworkSubnetToString(d.Get("local_subnet").(*schema.Set).List()) request.RemoteSubnet = vpnGatewayService.AssembleNetworkSubnetToString(d.Get("remote_subnet").(*schema.Set).List()) if v := connectivity.GetResourceData(d, "vpn_connection_name", "name"); v != ""{ request.Name = v.(string) } if v, ok := d.GetOk("effect_immediately"); ok { request.EffectImmediately = requests.NewBoolean(v.(bool)) } if v, ok := d.GetOk("ike_config"); ok { ikeConfig, err := vpnGatewayService.AssembleIkeConfig(v.([]interface{})) if err != nil { return nil, errmsgs.WrapError(err) } request.IkeConfig = ikeConfig } if v, ok := d.GetOk("ipsec_config"); ok { ipsecConfig, err := vpnGatewayService.AssembleIpsecConfig(v.([]interface{})) if err != nil { return nil, fmt.Errorf("wrong ipsec_config: %#v", err) } request.IpsecConfig = ipsecConfig } request.ClientToken = buildClientToken(request.GetActionName()) return request, nil }