alibabacloudstack/resource_apsarastack_expressconnect_routerinterface.go (341 lines of code) (raw):
package alibabacloudstack
import (
"time"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"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 resourceAlibabacloudStackRouterInterface() *schema.Resource {
resource := &schema.Resource{
Schema: map[string]*schema.Schema{
"opposite_region": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"router_type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{string(VRouter), string(VBR)}, false),
ForceNew: true,
DiffSuppressFunc: routerInterfaceAcceptsideDiffSuppressFunc,
},
"router_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"role": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{string(InitiatingSide), string(AcceptingSide)}, false),
ForceNew: true,
},
"specification": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice(GetAllRouterInterfaceSpec(), false),
DiffSuppressFunc: routerInterfaceAcceptsideDiffSuppressFunc,
},
"name": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringLenBetween(2, 128),
},
"description": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringLenBetween(2, 256),
},
"health_check_source_ip": {
Type: schema.TypeString,
Optional: true,
DiffSuppressFunc: routerInterfaceVBRTypeDiffSuppressFunc,
},
"health_check_target_ip": {
Type: schema.TypeString,
Optional: true,
DiffSuppressFunc: routerInterfaceVBRTypeDiffSuppressFunc,
},
"access_point_id": {
Type: schema.TypeString,
Computed: true,
},
"opposite_access_point_id": {
Type: schema.TypeString,
Optional: true,
},
"opposite_router_type": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"opposite_router_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"opposite_interface_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"opposite_interface_owner_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
},
}
setResourceFunc(resource, resourceAlibabacloudStackRouterInterfaceCreate, resourceAlibabacloudStackRouterInterfaceRead, resourceAlibabacloudStackRouterInterfaceUpdate, resourceAlibabacloudStackRouterInterfaceDelete)
return resource
}
func resourceAlibabacloudStackRouterInterfaceCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AlibabacloudStackClient)
vpcService := VpcService{client}
request, err := buildAlibabacloudStackRouterInterfaceCreateArgs(d, meta)
if err != nil {
return errmsgs.WrapError(err)
}
client.InitRpcRequest(*request.RpcRequest)
raw, err := client.WithVpcClient(func(vpcClient *vpc.Client) (interface{}, error) {
return vpcClient.CreateRouterInterface(request)
})
if err != nil {
errmsg := ""
if raw != nil {
response, ok := raw.(*vpc.CreateRouterInterfaceResponse)
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse)
}
}
return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, "alibabacloudstack_router_interface", request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
response, _ := raw.(*vpc.CreateRouterInterfaceResponse)
d.SetId(response.RouterInterfaceId)
if err := vpcService.WaitForRouterInterface(d.Id(), client.RegionId, Idle, 300); err != nil {
return errmsgs.WrapError(err)
}
return nil
}
func resourceAlibabacloudStackRouterInterfaceUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AlibabacloudStackClient)
d.Partial(true)
request, attributeUpdate, err := buildAlibabacloudStackRouterInterfaceModifyAttrArgs(d, meta)
if err != nil {
return errmsgs.WrapError(err)
}
client.InitRpcRequest(*request.RpcRequest)
if attributeUpdate {
raw, err := client.WithVpcClient(func(vpcClient *vpc.Client) (interface{}, error) {
return vpcClient.ModifyRouterInterfaceAttribute(request)
})
if err != nil {
errmsg := ""
if raw != nil {
response, ok := raw.(*vpc.ModifyRouterInterfaceAttributeResponse)
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse)
}
}
return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
}
if d.HasChange("specification") && !d.IsNewResource() {
request := vpc.CreateModifyRouterInterfaceSpecRequest()
request.RegionId = string(client.Region)
client.InitRpcRequest(*request.RpcRequest)
request.RouterInterfaceId = d.Id()
request.Spec = d.Get("specification").(string)
raw, err := client.WithVpcClient(func(vpcClient *vpc.Client) (interface{}, error) {
return vpcClient.ModifyRouterInterfaceSpec(request)
})
if err != nil {
errmsg := ""
if raw != nil {
response, ok := raw.(*vpc.ModifyRouterInterfaceSpecResponse)
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse)
}
}
return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
}
d.Partial(false)
return nil
}
func resourceAlibabacloudStackRouterInterfaceRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AlibabacloudStackClient)
vpcService := VpcService{client}
object, err := vpcService.DescribeRouterInterface(d.Id(), client.RegionId)
if err != nil {
if errmsgs.NotFoundError(err) {
d.SetId("")
return nil
}
}
d.Set("role", object.Role)
d.Set("specification", object.Spec)
d.Set("name", object.Name)
d.Set("router_id", object.RouterId)
d.Set("router_type", object.RouterType)
d.Set("description", object.Description)
d.Set("access_point_id", object.AccessPointId)
d.Set("opposite_region", object.OppositeRegionId)
d.Set("opposite_router_type", object.OppositeRouterType)
d.Set("opposite_router_id", object.OppositeRouterId)
d.Set("opposite_interface_id", object.OppositeInterfaceId)
d.Set("opposite_interface_owner_id", object.OppositeInterfaceOwnerId)
d.Set("health_check_source_ip", object.HealthCheckSourceIp)
d.Set("health_check_target_ip", object.HealthCheckTargetIp)
return nil
}
func resourceAlibabacloudStackRouterInterfaceDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*connectivity.AlibabacloudStackClient)
vpcService := VpcService{client}
if object, err := vpcService.DescribeRouterInterface(d.Id(), client.RegionId); err != nil {
if errmsgs.NotFoundError(err) {
return nil
}
return errmsgs.WrapError(err)
} else if object.Status == string(Active) {
if err := vpcService.DeactivateRouterInterface(d.Id()); err != nil {
return errmsgs.WrapError(err)
}
}
request := vpc.CreateDeleteRouterInterfaceRequest()
request.RegionId = string(client.Region)
client.InitRpcRequest(*request.RpcRequest)
request.RouterInterfaceId = d.Id()
request.ClientToken = buildClientToken(request.GetActionName())
err := resource.Retry(5*time.Minute, func() *resource.RetryError {
args := *request
raw, err := client.WithVpcClient(func(vpcClient *vpc.Client) (interface{}, error) {
return vpcClient.DeleteRouterInterface(&args)
})
if err != nil {
if errmsgs.IsExpectedErrors(err, []string{"IncorrectStatus", "DependencyViolation.RouterInterfaceReferedByRouteEntry"}) {
time.Sleep(5 * time.Second)
return resource.RetryableError(err)
}
errmsg := ""
if raw != nil {
response, ok := raw.(*vpc.DeleteRouterInterfaceResponse)
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.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{"InvalidInstanceId.NotFound"}) {
return nil
}
errmsgs.WrapErrorf(err, errmsgs.DefaultErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR)
}
return errmsgs.WrapError(vpcService.WaitForRouterInterface(d.Id(), client.RegionId, Deleted, DefaultTimeoutMedium))
}
func buildAlibabacloudStackRouterInterfaceCreateArgs(d *schema.ResourceData, meta interface{}) (*vpc.CreateRouterInterfaceRequest, error) {
client := meta.(*connectivity.AlibabacloudStackClient)
ecsService := EcsService{client}
oppositeRegion := d.Get("opposite_region").(string)
if err := ecsService.JudgeRegionValidation("opposite_region", oppositeRegion); err != nil {
return nil, errmsgs.WrapError(err)
}
request := vpc.CreateCreateRouterInterfaceRequest()
client.InitRpcRequest(*request.RpcRequest)
request.RouterType = d.Get("router_type").(string)
request.RouterId = d.Get("router_id").(string)
request.Role = d.Get("role").(string)
request.Spec = d.Get("specification").(string)
request.OppositeRegionId = oppositeRegion
if request.Role == string(AcceptingSide) {
request.Spec = string(Negative)
request.RouterType = string(VRouter)
} else {
if request.Spec == "" {
return request, errmsgs.WrapError(errmsgs.Error("'specification': required field is not set when role is %s.", InitiatingSide))
}
}
if request.RouterType == string(VBR) {
describeVirtualBorderRoutersRequest := vpc.CreateDescribeVirtualBorderRoutersRequest()
client.InitRpcRequest(*describeVirtualBorderRoutersRequest.RpcRequest)
values := []string{request.RouterId}
filters := []vpc.DescribeVirtualBorderRoutersFilter{{
Key: "VbrId",
Value: &values,
}}
describeVirtualBorderRoutersRequest.Filter = &filters
raw, err := client.WithVpcClient(func(vpcClient *vpc.Client) (interface{}, error) {
return vpcClient.DescribeVirtualBorderRouters(describeVirtualBorderRoutersRequest)
})
if err != nil {
errmsg := ""
if raw != nil {
response, ok := raw.(*vpc.DescribeVirtualBorderRoutersResponse)
if ok {
errmsg = errmsgs.GetBaseResponseErrorMessage(response.BaseResponse)
}
}
return request, errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, "alibabacloudstack_router_interface", request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)
}
addDebug(request.GetActionName(), raw, request.RpcRequest, request)
response, _ := raw.(*vpc.DescribeVirtualBorderRoutersResponse)
if response.TotalCount > 0 {
request.AccessPointId = response.VirtualBorderRouterSet.VirtualBorderRouterType[0].AccessPointId
}
}
request.OppositeInterfaceId = d.Get("opposite_interface_id").(string)
request.OppositeRouterType = d.Get("opposite_router_type").(string)
request.OppositeRouterId = d.Get("opposite_router_id").(string)
request.OppositeInterfaceOwnerId = d.Get("opposite_interface_owner_id").(string)
if request.OppositeInterfaceOwnerId == "" {
owner := request.OppositeInterfaceOwnerId
owner, err := client.AccountId()
if err != nil {
//return errmsgs.WrapError(err.errmsgs.Error()
}
request.OppositeInterfaceOwnerId = owner
}
request.ClientToken = buildClientToken(request.GetActionName())
return request, nil
}
func buildAlibabacloudStackRouterInterfaceModifyAttrArgs(d *schema.ResourceData, meta interface{}) (*vpc.ModifyRouterInterfaceAttributeRequest, bool, error) {
client := meta.(*connectivity.AlibabacloudStackClient)
sourceIp, sourceOk := d.GetOk("health_check_source_ip")
targetIp, targetOk := d.GetOk("health_check_target_ip")
if sourceOk && !targetOk || !sourceOk && targetOk {
return nil, false, errmsgs.WrapError(errmsgs.Error("The 'health_check_source_ip' and 'health_check_target_ip' should be specified or not at one time."))
}
request := vpc.CreateModifyRouterInterfaceAttributeRequest()
client.InitRpcRequest(*request.RpcRequest)
request.RouterInterfaceId = d.Id()
attributeUpdate := false
if d.HasChange("health_check_source_ip") {
request.HealthCheckSourceIp = sourceIp.(string)
request.HealthCheckTargetIp = targetIp.(string)
attributeUpdate = true
}
if d.HasChange("health_check_target_ip") {
request.HealthCheckTargetIp = targetIp.(string)
request.HealthCheckSourceIp = sourceIp.(string)
attributeUpdate = true
}
if d.HasChange("name") {
request.Name = d.Get("name").(string)
attributeUpdate = true
}
if d.HasChange("description") {
request.Description = d.Get("description").(string)
attributeUpdate = true
}
return request, attributeUpdate, nil
}