alibabacloudstack/resource_apsarastack_vpc_vpc.go (346 lines of code) (raw):

package alibabacloudstack import ( "log" "time" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" "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 resourceAlibabacloudStackVpc() *schema.Resource { resource := &schema.Resource{ Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(10 * time.Minute), Delete: schema.DefaultTimeout(10 * time.Minute), }, Schema: map[string]*schema.Schema{ "cidr_block": { Type: schema.TypeString, Optional: true, Default: "172.16.0.0/12", ValidateFunc: validateCIDRNetworkAddress, ConflictsWith: []string{"enable_ipv6"}, }, "name": { Type: schema.TypeString, Optional: true, Computed: true, Deprecated: "Field 'name' has been deprecated from provider version 1.119.0. New field 'vpc_name' instead.", ConflictsWith: []string{"vpc_name"}, ValidateFunc: validateNormalName, }, "description": { Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringLenBetween(2, 256), }, "router_id": { Type: schema.TypeString, Computed: true, }, "route_table_id": { Type: schema.TypeString, Computed: true, }, "dry_run": { Type: schema.TypeBool, Optional: true, ForceNew: true, }, "enable_ipv6": { Type: schema.TypeBool, Optional: true, ConflictsWith: []string{"cidr_block"}, }, "ipv6_cidr_block": { Type: schema.TypeString, Computed: true, }, "resource_group_id": { Type: schema.TypeString, Optional: true, Computed: true, }, "router_table_id": { Type: schema.TypeString, Computed: true, Deprecated: "Field 'router_table_id' is deprecated and will be removed in a future release. Please use new field 'route_table_id' instead.", }, "secondary_cidr_blocks": { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{ Type: schema.TypeString, }, }, "status": { Type: schema.TypeString, Computed: true, }, "tags": tagsSchema(), "user_cidrs": { Type: schema.TypeList, Optional: true, Elem: &schema.Schema{ Type: schema.TypeString, }, ForceNew: true, }, "vpc_name": { Type: schema.TypeString, Optional: true, Computed: true, ConflictsWith: []string{"name"}, ValidateFunc: validateNormalName, }, }, } setResourceFunc(resource, resourceAlibabacloudStackVpcCreate, resourceAlibabacloudStackVpcRead, resourceAlibabacloudStackVpcUpdate, resourceAlibabacloudStackVpcDelete) return resource } func resourceAlibabacloudStackVpcCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) vpcService := VpcService{client} var response *vpc.CreateVpcResponse request := buildAlibabacloudStackVpcArgs(d, meta) client.InitRpcRequest(*request.RpcRequest) err := resource.Retry(3*time.Minute, func() *resource.RetryError { args := *request raw, err := client.WithVpcClient(func(vpcClient *vpc.Client) (interface{}, error) { return vpcClient.CreateVpc(&args) }) addDebug(request.GetActionName(), raw, request.RpcRequest, request) if err != nil { if errmsgs.IsExpectedErrors(err, []string{"TaskConflict", "UnknownError", errmsgs.Throttling}) { time.Sleep(5 * time.Second) return resource.RetryableError(err) } errmsg := "" bresponse, ok := raw.(*vpc.CreateVpcResponse) if ok { errmsg = errmsgs.GetBaseResponseErrorMessage(bresponse.BaseResponse) } return resource.NonRetryableError(errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, "alibabacloudstack_vpc", request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) response, _ = raw.(*vpc.CreateVpcResponse) return nil }) if err != nil { return err } d.SetId(response.VpcId) stateConf := BuildStateConf([]string{"Pending"}, []string{"Available"}, d.Timeout(schema.TimeoutCreate), 3*time.Second, vpcService.VpcStateRefreshFunc(d.Id(), []string{})) if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id()) } return nil } func resourceAlibabacloudStackVpcRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) vpcService := VpcService{client} object, err := vpcService.DescribeVpc(d.Id()) if err != nil { if errmsgs.NotFoundError(err) { log.Printf("[DEBUG] Resource alibabacloudstack_vpc_vpc vpcService.DescribeVpc Failed!!! %s", err) d.SetId("") return nil } return errmsgs.WrapError(err) } d.Set("cidr_block", object.CidrBlock) d.Set("description", object.Description) d.Set("router_id", object.VRouterId) d.Set("ipv6_cidr_block", object.Ipv6CidrBlock) d.Set("secondary_cidr_blocks", object.SecondaryCidrBlocks.SecondaryCidrBlock) d.Set("status", object.Status) d.Set("resource_group_id", object.ResourceGroupId) if tag := object.Tags.Tag; tag != nil { d.Set("tags", vpcService.tagToMap(tag)) } d.Set("user_cidrs", object.UserCidrs.UserCidr) connectivity.SetResourceData(d, object.VpcName, "vpc_name", "name") request := vpc.CreateDescribeRouteTablesRequest() client.InitRpcRequest(*request.RpcRequest) request.VRouterId = object.VRouterId request.PageNumber = requests.NewInteger(1) request.PageSize = requests.NewInteger(PageSizeLarge) var routeTabls []vpc.RouteTable for { total := 0 err = resource.Retry(6*time.Minute, func() *resource.RetryError { raw, err := client.WithVpcClient(func(vpcClient *vpc.Client) (interface{}, error) { return vpcClient.DescribeRouteTables(request) }) if err != nil { if errmsgs.IsExpectedErrors(err, []string{errmsgs.Throttling}) { time.Sleep(10 * time.Second) return resource.RetryableError(err) } else { errmsg := "" bresponse, ok := raw.(*vpc.DescribeRouteTablesResponse) 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) response, _ := raw.(*vpc.DescribeRouteTablesResponse) routeTabls = append(routeTabls, response.RouteTables.RouteTable...) total = len(response.RouteTables.RouteTable) return nil }) if err != nil { return err } if total < PageSizeLarge { break } if page, err := getNextpageNumber(request.PageNumber); err != nil { return errmsgs.WrapError(err) } else { request.PageNumber = page } } // Generally, the system route table is the last one for i := len(routeTabls) - 1; i >= 0; i-- { if routeTabls[i].RouteTableType == "System" { connectivity.SetResourceData(d, routeTabls[i].RouteTableId, "router_table_id", "route_table_id") break } } return nil } func resourceAlibabacloudStackVpcUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) vpcService := VpcService{client} if err := vpcService.setInstanceSecondaryCidrBlocks(d); err != nil { return errmsgs.WrapError(err) } if d.HasChange("tags") { if err := vpcService.SetResourceTags(d, "vpc"); err != nil { return errmsgs.WrapError(err) } } if d.IsNewResource() { d.Partial(false) return nil } groupRequestUpdate := false groupRequest := vpc.CreateMoveResourceGroupRequest() client.InitRpcRequest(*groupRequest.RpcRequest) groupRequest.ResourceId = d.Id() groupRequest.NewResourceGroupId = d.Get("resource_group_id").(string) groupRequest.ResourceType = "vpc" if !d.IsNewResource() && d.HasChange("resource_group_id") { groupRequestUpdate = true } if groupRequestUpdate { raw, err := client.WithVpcClient(func(vpcClient *vpc.Client) (interface{}, error) { return vpcClient.MoveResourceGroup(groupRequest) }) if err != nil { errmsg := "" bresponse, ok := raw.(*vpc.MoveResourceGroupResponse) if ok { errmsg = errmsgs.GetBaseResponseErrorMessage(bresponse.BaseResponse) } return errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), groupRequest.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg) } addDebug(groupRequest.GetActionName(), raw, groupRequest.RpcRequest, groupRequest) } attributeUpdate := false request := vpc.CreateModifyVpcAttributeRequest() client.InitRpcRequest(*request.RpcRequest) request.VpcId = d.Id() if d.HasChanges("name", "vpc_name") { request.VpcName = connectivity.GetResourceData(d, "vpc_name", "name").(string) attributeUpdate = true } if d.HasChange("description") { request.Description = d.Get("description").(string) attributeUpdate = true } if !d.IsNewResource() && d.HasChange("cidr_block") { request.CidrBlock = d.Get("cidr_block").(string) attributeUpdate = true } enable_ipv6 := d.Get("enable_ipv6").(bool) if attributeUpdate { if enable_ipv6 { request.EnableIPv6 = requests.NewBoolean(d.Get("enable_ipv6").(bool)) } raw, err := client.WithVpcClient(func(vpcClient *vpc.Client) (interface{}, error) { return vpcClient.ModifyVpcAttribute(request) }) if err != nil { errmsg := "" bresponse, ok := raw.(*vpc.ModifyVpcAttributeResponse) 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 resourceAlibabacloudStackVpcDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) vpcService := VpcService{client} request := vpc.CreateDeleteVpcRequest() client.InitRpcRequest(*request.RpcRequest) request.VpcId = d.Id() err := resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { raw, err := client.WithVpcClient(func(vpcClient *vpc.Client) (interface{}, error) { return vpcClient.DeleteVpc(request) }) if err != nil { if errmsgs.IsExpectedErrors(err, []string{"InvalidVpcID.NotFound", "Forbidden.VpcNotFound"}) { return nil } errmsg := "" bresponse, ok := raw.(*vpc.DeleteVpcResponse) if ok { errmsg = errmsgs.GetBaseResponseErrorMessage(bresponse.BaseResponse) } return resource.RetryableError(errmsgs.WrapErrorf(err, errmsgs.RequestV1ErrorMsg, d.Id(), request.GetActionName(), errmsgs.AlibabacloudStackSdkGoERROR, errmsg)) } addDebug(request.GetActionName(), raw, request.RpcRequest, request) return nil }) if err != nil { return err } stateConf := BuildStateConf([]string{"Pending"}, []string{}, d.Timeout(schema.TimeoutDelete), 3*time.Second, vpcService.VpcStateRefreshFunc(d.Id(), []string{})) if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id()) } return nil } func buildAlibabacloudStackVpcArgs(d *schema.ResourceData, meta interface{}) *vpc.CreateVpcRequest { client := meta.(*connectivity.AlibabacloudStackClient) request := vpc.CreateCreateVpcRequest() client.InitRpcRequest(*request.RpcRequest) request.CidrBlock = d.Get("cidr_block").(string) if v := d.Get("description").(string); v != "" { request.Description = v } if v, ok := d.GetOkExists("dry_run"); ok { request.DryRun = requests.NewBoolean(v.(bool)) } request.EnableIpv6 = requests.NewBoolean(d.Get("enable_ipv6").(bool)) if v, ok := d.GetOk("resource_group_id"); ok { request.ResourceGroupId = v.(string) } if v, ok := d.GetOk("user_cidrs"); ok && v != nil { request.UserCidr = convertListToCommaSeparate(v.([]interface{})) } if v, ok := connectivity.GetResourceDataOk(d, "vpc_name", "name"); ok { request.VpcName = v.(string) } return request }