Skip to content

Commit

Permalink
fix creating multiple route entry bug
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaozhu36 committed Nov 30, 2017
1 parent 1648111 commit 1a10c5a
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 37 deletions.
4 changes: 4 additions & 0 deletions alicloud/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ const (
VpcQuotaExceeded = "QuotaExceeded.Vpc"
// vswitch
VswitcInvalidRegionId = "InvalidRegionId.NotFound"
//vroute entry
IncorrectRouteEntryStatus = "IncorrectRouteEntryStatus"
TaskConflict = "TaskConflict"
RouterEntryForbbiden = "Forbbiden"

// ess
InvalidScalingGroupIdNotFound = "InvalidScalingGroupId.NotFound"
Expand Down
21 changes: 14 additions & 7 deletions alicloud/resource_alicloud_ess_scalinggroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,17 +120,20 @@ func resourceAliyunEssScalingGroupUpdate(d *schema.ResourceData, meta interface{
}

if d.HasChange("min_size") {
args.MinSize = d.Get("min_size").(int)
minsize := d.Get("min_size").(int)
args.MinSize = &minsize
d.SetPartial("min_size")
}

if d.HasChange("max_size") {
args.MaxSize = d.Get("max_size").(int)
maxsize := d.Get("max_size").(int)
args.MaxSize = &maxsize
d.SetPartial("max_size")
}

if d.HasChange("default_cooldown") {
args.DefaultCooldown = d.Get("default_cooldown").(int)
cooldown := d.Get("default_cooldown").(int)
args.DefaultCooldown = &cooldown
d.SetPartial("default_cooldown")
}

Expand All @@ -157,12 +160,16 @@ func resourceAliyunEssScalingGroupDelete(d *schema.ResourceData, meta interface{
func buildAlicloudEssScalingGroupArgs(d *schema.ResourceData, meta interface{}) (*ess.CreateScalingGroupArgs, error) {
client := meta.(*AliyunClient)
args := &ess.CreateScalingGroupArgs{
RegionId: getRegion(d, meta),
MinSize: d.Get("min_size").(int),
MaxSize: d.Get("max_size").(int),
DefaultCooldown: d.Get("default_cooldown").(int),
RegionId: getRegion(d, meta),
}

minsize := d.Get("min_size").(int)
maxsize := d.Get("max_size").(int)
cooldown := d.Get("default_cooldown").(int)
args.MinSize = &minsize
args.MaxSize = &maxsize
args.DefaultCooldown = &cooldown

if v := d.Get("scaling_group_name").(string); v != "" {
args.ScalingGroupName = v
}
Expand Down
9 changes: 8 additions & 1 deletion alicloud/resource_alicloud_router_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ func resourceAlicloudRouterInterfaceCreate(d *schema.ResourceData, meta interfac
}

d.SetId(response.RouterInterfaceId)

if err := conn.WaitForRouterInterfaceAsyn(getRegion(d, meta), d.Id(), ecs.Idle, 300); err != nil {
return fmt.Errorf("WaitForRouterInterface %s got error: %#v", ecs.Idle, err)
}

return resourceAlicloudRouterInterfaceUpdate(d, meta)
}

Expand Down Expand Up @@ -199,7 +204,9 @@ func resourceAlicloudRouterInterfaceDelete(d *schema.ResourceData, meta interfac
return resource.Retry(5*time.Minute, func() *resource.RetryError {
if _, err := conn.DeleteRouterInterface(args); err != nil {
if IsExceptedError(err, RouterInterfaceIncorrectStatus) || IsExceptedError(err, DependencyViolationRouterInterfaceReferedByRouteEntry) {
return resource.RetryableError(fmt.Errorf("Router interface in use - trying again while it is deleted."))
time.Sleep(5 * time.Second)
//e, _ := err.(*common.Error)
return resource.RetryableError(fmt.Errorf("Router interface in use: %#v. Trying again while it is deleted.", err))
}
return resource.NonRetryableError(fmt.Errorf("Error deleting interface %s: %#v", d.Id(), err))
}
Expand Down
13 changes: 6 additions & 7 deletions alicloud/resource_alicloud_vpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,14 @@ func resourceAliyunVpc() *schema.Resource {

func resourceAliyunVpcCreate(d *schema.ResourceData, meta interface{}) error {

args, err := buildAliyunVpcArgs(d, meta)
if err != nil {
return err
}

ecsconn := meta.(*AliyunClient).ecsconn

var vpc *ecs.CreateVpcResponse
err = resource.Retry(3*time.Minute, func() *resource.RetryError {
err := resource.Retry(3*time.Minute, func() *resource.RetryError {
args, err := buildAliyunVpcArgs(d, meta)
if err != nil {
return resource.NonRetryableError(fmt.Errorf("Building CreateVpcArgs got an error: %#v", err))
}
resp, err := ecsconn.CreateVpc(args)
if err != nil {
if IsExceptedError(err, VpcQuotaExceeded) {
Expand All @@ -101,7 +100,7 @@ func resourceAliyunVpcCreate(d *schema.ResourceData, meta interface{}) error {

d.SetId(vpc.VpcId)

err = ecsconn.WaitForVpcAvailable(args.RegionId, vpc.VpcId, 60)
err = ecsconn.WaitForVpcAvailable(getRegion(d, meta), d.Id(), 60)
if err != nil {
return fmt.Errorf("Timeout when WaitForVpcAvailable")
}
Expand Down
43 changes: 43 additions & 0 deletions alicloud/resource_alicloud_vpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,34 @@ func TestAccAlicloudVpc_update(t *testing.T) {
})
}

func TestAccAlicloudVpc_multi(t *testing.T) {
var vpc ecs.VpcSetType

resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckVpcDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccVpcConfigMulti,
Check: resource.ComposeTestCheckFunc(
testAccCheckVpcExists("alicloud_vpc.bar_1", &vpc),
resource.TestCheckResourceAttr(
"alicloud_vpc.bar_1", "cidr_block", "172.16.0.0/12"),
testAccCheckVpcExists("alicloud_vpc.bar_2", &vpc),
resource.TestCheckResourceAttr(
"alicloud_vpc.bar_2", "cidr_block", "192.168.0.0/16"),
testAccCheckVpcExists("alicloud_vpc.bar_3", &vpc),
resource.TestCheckResourceAttr(
"alicloud_vpc.bar_3", "cidr_block", "10.1.0.0/21"),
),
},
},
})
}

func testAccCheckVpcExists(n string, vpc *ecs.VpcSetType) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
Expand Down Expand Up @@ -138,3 +166,18 @@ resource "alicloud_vpc" "foo" {
name = "tf_test_bar"
}
`

const testAccVpcConfigMulti = `
resource "alicloud_vpc" "bar_1" {
cidr_block = "172.16.0.0/12"
name = "tf_test_bar_1"
}
resource "alicloud_vpc" "bar_2" {
cidr_block = "192.168.0.0/16"
name = "tf_test_bar_2"
}
resource "alicloud_vpc" "bar_3" {
cidr_block = "10.1.0.0/21"
name = "tf_test_bar_3"
}
`
44 changes: 32 additions & 12 deletions alicloud/resource_alicloud_vroute_entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,32 @@ func resourceAliyunRouteEntryCreate(d *schema.ResourceData, meta interface{}) er
return fmt.Errorf("Error query route table: %#v", err)
}

if err := conn.WaitForAllRouteEntriesAvailable(table.VRouterId, rtId, defaultTimeout); err != nil {
return fmt.Errorf("WaitFor route entry got error: %#v", err)
}
err = resource.Retry(3*time.Minute, func() *resource.RetryError {

args, err := buildAliyunRouteEntryArgs(d, meta)
if err != nil {
return err
}
err = conn.CreateRouteEntry(args)
if err := conn.WaitForAllRouteEntriesAvailable(table.VRouterId, rtId, defaultTimeout); err != nil {
return resource.NonRetryableError(fmt.Errorf("WaitFor route entry got error: %#v", err))
}

args, err := buildAliyunRouteEntryArgs(d, meta)
if err != nil {
return resource.NonRetryableError(fmt.Errorf("Building CreateRouteEntryArgs got an error: %#v", err))
}
//args.ClientToken = fmt.Sprintf("%s-%d", args.ClientToken, timeNow)

if err := conn.CreateRouteEntry(args); err != nil {
// Route Entry does not support concurrence when creating or deleting it;
// Route Entry does not support creating or deleting within 5 seconds frequently
// It must ensure all the route entries and vswitches' status must be available before creating or deleting route entry.
if IsExceptedError(err, TaskConflict) || IsExceptedError(err, IncorrectRouteEntryStatus) {
time.Sleep(5 * time.Second)
return resource.RetryableError(fmt.Errorf("Vroute entry is still creating -- try again, err:%#v", err))
}
return resource.NonRetryableError(fmt.Errorf("Creating Route entry got an error: %#v", err))
}
return nil
})
if err != nil {
return err
return fmt.Errorf("Create Vroute Entry got an error :%#v", err)
}
// route_table_id:router_id:destination_cidrblock:nexthop_type:nexthop_id

Expand Down Expand Up @@ -118,7 +133,7 @@ func resourceAliyunRouteEntryRead(d *schema.ResourceData, meta interface{}) erro
}

func resourceAliyunRouteEntryDelete(d *schema.ResourceData, meta interface{}) error {
con := meta.(*AliyunClient).ecsconn
conn := meta.(*AliyunClient).ecsconn
args, err := buildAliyunRouteEntryDeleteArgs(d, meta)

if err != nil {
Expand All @@ -144,8 +159,13 @@ func resourceAliyunRouteEntryDelete(d *schema.ResourceData, meta interface{}) er
return resource.RetryableError(fmt.Errorf("Waiting for RouteEntry's status is Available - trying again."))
}

if err := con.DeleteRouteEntry(args); err != nil {
return resource.RetryableError(fmt.Errorf("RouteEntry in use - trying again while it is deleted."))
if err := conn.DeleteRouteEntry(args); err != nil {
if IsExceptedError(err, TaskConflict) || IsExceptedError(err, IncorrectRouteEntryStatus) || IsExceptedError(err, RouterEntryForbbiden) {
// Route Entry does not support creating or deleting within 5 seconds frequently
time.Sleep(5 * time.Second)
return resource.RetryableError(fmt.Errorf("RouteEntry in use - trying again while it is deleted."))
}
return resource.NonRetryableError(fmt.Errorf("Deleting RouteEntry got an error: %#v", err))
}

return nil
Expand Down
4 changes: 3 additions & 1 deletion alicloud/resource_alicloud_vroute_entry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func testAccCheckRouteEntryDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*AliyunClient)

for _, rs := range s.RootModule().Resources {
if rs.Type != "alicloud_route_entry" {
if rs.Type == "alicloud_route_entry" || rs.Type != "alicloud_route_entry" {
continue
}

Expand All @@ -144,6 +144,8 @@ func testAccCheckRouteEntryDestroy(s *terraform.State) error {
}
}

testAccCheckRouterInterfaceDestroy(s)

return nil
}

Expand Down
16 changes: 8 additions & 8 deletions alicloud/resource_alicloud_vswitch.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,12 @@ func resourceAliyunSwitchCreate(d *schema.ResourceData, meta interface{}) error

conn := meta.(*AliyunClient).ecsconn

args, err := buildAliyunSwitchArgs(d, meta)
if err != nil {
return err
}

var vswitchID string
err = resource.Retry(3*time.Minute, func() *resource.RetryError {
var vswitchID, vpcID string
err := resource.Retry(3*time.Minute, func() *resource.RetryError {
args, err := buildAliyunSwitchArgs(d, meta)
if err != nil {
return resource.NonRetryableError(fmt.Errorf("Building CreateVSwitchArgs got an error: %#v", err))
}
vswId, err := conn.CreateVSwitch(args)
if err != nil {
if e, ok := err.(*common.Error); ok && (e.StatusCode == 400 || e.Code == UnknownError) {
Expand All @@ -69,6 +68,7 @@ func resourceAliyunSwitchCreate(d *schema.ResourceData, meta interface{}) error
return resource.NonRetryableError(err)
}
vswitchID = vswId
vpcID = args.VpcId
return nil
})

Expand All @@ -78,7 +78,7 @@ func resourceAliyunSwitchCreate(d *schema.ResourceData, meta interface{}) error

d.SetId(vswitchID)

err = conn.WaitForVSwitchAvailable(args.VpcId, vswitchID, 60)
err = conn.WaitForVSwitchAvailable(vpcID, vswitchID, 300)
if err != nil {
return fmt.Errorf("WaitForVSwitchAvailable got a error: %s", err)
}
Expand Down
59 changes: 59 additions & 0 deletions alicloud/resource_alicloud_vswitch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,37 @@ func TestAccAlicloudVswitch_basic(t *testing.T) {

}

func TestAccAlicloudVswitch_multi(t *testing.T) {
var vsw ecs.VSwitchSetType

resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},

// module name
Providers: testAccProviders,
CheckDestroy: testAccCheckVswitchDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccVswitchMulti,
Check: resource.ComposeTestCheckFunc(
testAccCheckVswitchExists("alicloud_vswitch.foo_0", &vsw),
resource.TestCheckResourceAttr(
"alicloud_vswitch.foo_0", "cidr_block", "172.16.0.0/24"),
testAccCheckVswitchExists("alicloud_vswitch.foo_1", &vsw),
resource.TestCheckResourceAttr(
"alicloud_vswitch.foo_1", "cidr_block", "172.16.1.0/24"),
testAccCheckVswitchExists("alicloud_vswitch.foo_2", &vsw),
resource.TestCheckResourceAttr(
"alicloud_vswitch.foo_2", "cidr_block", "172.16.2.0/24"),
),
},
},
})

}

func testAccCheckVswitchExists(n string, vpc *ecs.VSwitchSetType) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
Expand Down Expand Up @@ -107,3 +138,31 @@ resource "alicloud_vswitch" "foo" {
availability_zone = "${data.alicloud_zones.default.zones.0.id}"
}
`

const testAccVswitchMulti = `
data "alicloud_zones" "default" {
"available_resource_creation"= "VSwitch"
}
resource "alicloud_vpc" "foo" {
name = "tf_test_foo"
cidr_block = "172.16.0.0/12"
}
resource "alicloud_vswitch" "foo_0" {
vpc_id = "${alicloud_vpc.foo.id}"
cidr_block = "172.16.0.0/24"
availability_zone = "${data.alicloud_zones.default.zones.0.id}"
}
resource "alicloud_vswitch" "foo_1" {
vpc_id = "${alicloud_vpc.foo.id}"
cidr_block = "172.16.1.0/24"
availability_zone = "${data.alicloud_zones.default.zones.0.id}"
}
resource "alicloud_vswitch" "foo_2" {
vpc_id = "${alicloud_vpc.foo.id}"
cidr_block = "172.16.2.0/24"
availability_zone = "${data.alicloud_zones.default.zones.0.id}"
}
`
1 change: 0 additions & 1 deletion terraform/examples/alicloud-container-cluster/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ resource "alicloud_container_cluster" "cs_vpc" {
disk_size = "${var.disk_size}"
cidr_block = "${var.cidr_block}"
image_id = "${data.alicloud_images.main.images.0.id}"
// image_id = "m-xx251ll"
vswitch_id = "${alicloud_vswitch.main.id}"
}

0 comments on commit 1a10c5a

Please sign in to comment.