provider/alicloud: Add the function of replacing ecs instance's system disk (#15048)
* add replacing system disk function for ecs * remove ForceNew of system_disk_size
This commit is contained in:
parent
d6d559a6ab
commit
87562be855
|
@ -1,4 +1,4 @@
|
|||
// Code generated by "stringer -type=countHookAction hook_count_action.go"; DO NOT EDIT.
|
||||
// Code generated by "stringer -type=countHookAction hook_count_action.go"; DO NOT EDIT
|
||||
|
||||
package local
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by "stringer -type=OperationType operation_type.go"; DO NOT EDIT.
|
||||
// Code generated by "stringer -type=OperationType operation_type.go"; DO NOT EDIT
|
||||
|
||||
package backend
|
||||
|
||||
|
|
|
@ -114,7 +114,6 @@ func resourceAliyunInstance() *schema.Resource {
|
|||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ForceNew: true,
|
||||
ValidateFunc: validateIntegerInRange(40, 500),
|
||||
},
|
||||
|
||||
|
@ -365,12 +364,62 @@ func resourceAliyunInstanceUpdate(d *schema.ResourceData, meta interface{}) erro
|
|||
d.SetPartial("tags")
|
||||
}
|
||||
|
||||
imageUpdate := false
|
||||
if d.HasChange("image_id") && !d.IsNewResource() {
|
||||
log.Printf("[DEBUG] Replace instance system disk via changing image_id")
|
||||
replaceSystemArgs := &ecs.ReplaceSystemDiskArgs{
|
||||
InstanceId: d.Id(),
|
||||
ImageId: d.Get("image_id").(string),
|
||||
SystemDisk: ecs.SystemDiskType{
|
||||
Size: d.Get("system_disk_size").(int),
|
||||
},
|
||||
}
|
||||
if v, ok := d.GetOk("status"); ok && v.(string) != "" {
|
||||
if ecs.InstanceStatus(d.Get("status").(string)) == ecs.Running {
|
||||
log.Printf("[DEBUG] StopInstance before change system disk")
|
||||
if err := conn.StopInstance(d.Id(), true); err != nil {
|
||||
return fmt.Errorf("Force Stop Instance got an error: %#v", err)
|
||||
}
|
||||
if err := conn.WaitForInstance(d.Id(), ecs.Stopped, 60); err != nil {
|
||||
return fmt.Errorf("WaitForInstance got error: %#v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
_, err := conn.ReplaceSystemDisk(replaceSystemArgs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Replace system disk got an error: %#v", err)
|
||||
}
|
||||
// Ensure instance's image has been replaced successfully.
|
||||
timeout := ecs.InstanceDefaultTimeout
|
||||
for {
|
||||
instance, errDesc := conn.DescribeInstanceAttribute(d.Id())
|
||||
if errDesc != nil {
|
||||
return fmt.Errorf("Describe instance got an error: %#v", errDesc)
|
||||
}
|
||||
if instance.ImageId == d.Get("image_id") {
|
||||
break
|
||||
}
|
||||
time.Sleep(ecs.DefaultWaitForInterval * time.Second)
|
||||
timeout = timeout - ecs.DefaultWaitForInterval
|
||||
if timeout <= 0 {
|
||||
return common.GetClientErrorFromString("Timeout")
|
||||
}
|
||||
}
|
||||
imageUpdate = true
|
||||
d.SetPartial("system_disk_size")
|
||||
d.SetPartial("image_id")
|
||||
}
|
||||
// Provider doesn't support change 'system_disk_size'separately.
|
||||
if d.HasChange("system_disk_size") && !d.HasChange("image_id") {
|
||||
return fmt.Errorf("Update resource failed. 'system_disk_size' isn't allowed to change separately. You can update it via renewing instance or replacing system disk.")
|
||||
}
|
||||
|
||||
attributeUpdate := false
|
||||
args := &ecs.ModifyInstanceAttributeArgs{
|
||||
InstanceId: d.Id(),
|
||||
}
|
||||
|
||||
if d.HasChange("instance_name") {
|
||||
if d.HasChange("instance_name") && !d.IsNewResource() {
|
||||
log.Printf("[DEBUG] ModifyInstanceAttribute instance_name")
|
||||
d.SetPartial("instance_name")
|
||||
args.InstanceName = d.Get("instance_name").(string)
|
||||
|
@ -378,7 +427,7 @@ func resourceAliyunInstanceUpdate(d *schema.ResourceData, meta interface{}) erro
|
|||
attributeUpdate = true
|
||||
}
|
||||
|
||||
if d.HasChange("description") {
|
||||
if d.HasChange("description") && !d.IsNewResource() {
|
||||
log.Printf("[DEBUG] ModifyInstanceAttribute description")
|
||||
d.SetPartial("description")
|
||||
args.Description = d.Get("description").(string)
|
||||
|
@ -386,7 +435,7 @@ func resourceAliyunInstanceUpdate(d *schema.ResourceData, meta interface{}) erro
|
|||
attributeUpdate = true
|
||||
}
|
||||
|
||||
if d.HasChange("host_name") {
|
||||
if d.HasChange("host_name") && !d.IsNewResource() {
|
||||
log.Printf("[DEBUG] ModifyInstanceAttribute host_name")
|
||||
d.SetPartial("host_name")
|
||||
args.HostName = d.Get("host_name").(string)
|
||||
|
@ -395,7 +444,7 @@ func resourceAliyunInstanceUpdate(d *schema.ResourceData, meta interface{}) erro
|
|||
}
|
||||
|
||||
passwordUpdate := false
|
||||
if d.HasChange("password") {
|
||||
if d.HasChange("password") && !d.IsNewResource() {
|
||||
log.Printf("[DEBUG] ModifyInstanceAttribute password")
|
||||
d.SetPartial("password")
|
||||
args.Password = d.Get("password").(string)
|
||||
|
@ -410,18 +459,27 @@ func resourceAliyunInstanceUpdate(d *schema.ResourceData, meta interface{}) erro
|
|||
}
|
||||
}
|
||||
|
||||
if passwordUpdate {
|
||||
if v, ok := d.GetOk("status"); ok && v.(string) != "" {
|
||||
if ecs.InstanceStatus(d.Get("status").(string)) == ecs.Running {
|
||||
log.Printf("[DEBUG] RebootInstance after change password")
|
||||
if err := conn.RebootInstance(d.Id(), false); err != nil {
|
||||
return fmt.Errorf("RebootInstance got error: %#v", err)
|
||||
}
|
||||
|
||||
if err := conn.WaitForInstance(d.Id(), ecs.Running, defaultTimeout); err != nil {
|
||||
return fmt.Errorf("WaitForInstance got error: %#v", err)
|
||||
}
|
||||
if imageUpdate || passwordUpdate {
|
||||
instance, errDesc := conn.DescribeInstanceAttribute(d.Id())
|
||||
if errDesc != nil {
|
||||
return fmt.Errorf("Describe instance got an error: %#v", errDesc)
|
||||
}
|
||||
if instance.Status != ecs.Running && instance.Status != ecs.Stopped {
|
||||
return fmt.Errorf("ECS instance's status doesn't support to start or reboot operation after replace image_id or update password. The current instance's status is %#v", instance.Status)
|
||||
} else if instance.Status == ecs.Running {
|
||||
log.Printf("[DEBUG] Reboot instance after change image or password")
|
||||
if err := conn.RebootInstance(d.Id(), false); err != nil {
|
||||
return fmt.Errorf("RebootInstance got error: %#v", err)
|
||||
}
|
||||
} else {
|
||||
log.Printf("[DEBUG] Start instance after change image or password")
|
||||
if err := conn.StartInstance(d.Id()); err != nil {
|
||||
return fmt.Errorf("StartInstance got error: %#v", err)
|
||||
}
|
||||
}
|
||||
// Start instance sometimes costs more than 6 minutes when os type is centos.
|
||||
if err := conn.WaitForInstance(d.Id(), ecs.Running, 400); err != nil {
|
||||
return fmt.Errorf("WaitForInstance got error: %#v", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -410,6 +410,39 @@ func TestAccAlicloudInstance_update(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccAlicloudInstanceImage_update(t *testing.T) {
|
||||
var instance ecs.InstanceAttributesType
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() {
|
||||
testAccPreCheck(t)
|
||||
},
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckInstanceDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccCheckInstanceImageOrigin,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckInstanceExists("alicloud_instance.update_image", &instance),
|
||||
resource.TestCheckResourceAttr(
|
||||
"alicloud_instance.update_image",
|
||||
"system_disk_size",
|
||||
"50"),
|
||||
),
|
||||
},
|
||||
resource.TestStep{
|
||||
Config: testAccCheckInstanceImageUpdate,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckInstanceExists("alicloud_instance.update_image", &instance),
|
||||
resource.TestCheckResourceAttr(
|
||||
"alicloud_instance.update_image",
|
||||
"system_disk_size",
|
||||
"60"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccAlicloudInstance_privateIP(t *testing.T) {
|
||||
var instance ecs.InstanceAttributesType
|
||||
|
||||
|
@ -1223,5 +1256,78 @@ resource "alicloud_instance" "foo" {
|
|||
instance_name = "test_foo"
|
||||
io_optimized = "optimized"
|
||||
}
|
||||
|
||||
`
|
||||
const testAccCheckInstanceImageOrigin = `
|
||||
data "alicloud_images" "centos" {
|
||||
most_recent = true
|
||||
owners = "system"
|
||||
name_regex = "^centos_6\\w{1,5}[64]{1}.*"
|
||||
}
|
||||
|
||||
resource "alicloud_vpc" "foo" {
|
||||
name = "tf_test_image"
|
||||
cidr_block = "10.1.0.0/21"
|
||||
}
|
||||
|
||||
resource "alicloud_vswitch" "foo" {
|
||||
vpc_id = "${alicloud_vpc.foo.id}"
|
||||
cidr_block = "10.1.1.0/24"
|
||||
availability_zone = "cn-beijing-a"
|
||||
}
|
||||
|
||||
resource "alicloud_security_group" "tf_test_foo" {
|
||||
name = "tf_test_foo"
|
||||
description = "foo"
|
||||
vpc_id = "${alicloud_vpc.foo.id}"
|
||||
}
|
||||
|
||||
resource "alicloud_instance" "update_image" {
|
||||
image_id = "${data.alicloud_images.centos.images.0.id}"
|
||||
availability_zone = "cn-beijing-a"
|
||||
system_disk_category = "cloud_efficiency"
|
||||
system_disk_size = 50
|
||||
|
||||
instance_type = "ecs.n1.small"
|
||||
internet_charge_type = "PayByBandwidth"
|
||||
instance_name = "update_image"
|
||||
io_optimized = "optimized"
|
||||
password = "Test12345"
|
||||
}
|
||||
`
|
||||
const testAccCheckInstanceImageUpdate = `
|
||||
data "alicloud_images" "ubuntu" {
|
||||
most_recent = true
|
||||
owners = "system"
|
||||
name_regex = "^ubuntu_14\\w{1,5}[64]{1}.*"
|
||||
}
|
||||
|
||||
resource "alicloud_vpc" "foo" {
|
||||
name = "tf_test_image"
|
||||
cidr_block = "10.1.0.0/21"
|
||||
}
|
||||
|
||||
resource "alicloud_vswitch" "foo" {
|
||||
vpc_id = "${alicloud_vpc.foo.id}"
|
||||
cidr_block = "10.1.1.0/24"
|
||||
availability_zone = "cn-beijing-a"
|
||||
}
|
||||
|
||||
resource "alicloud_security_group" "tf_test_foo" {
|
||||
name = "tf_test_foo"
|
||||
description = "foo"
|
||||
vpc_id = "${alicloud_vpc.foo.id}"
|
||||
}
|
||||
|
||||
resource "alicloud_instance" "update_image" {
|
||||
image_id = "${data.alicloud_images.ubuntu.images.0.id}"
|
||||
availability_zone = "cn-beijing-a"
|
||||
system_disk_category = "cloud_efficiency"
|
||||
system_disk_size = 60
|
||||
|
||||
instance_type = "ecs.n1.small"
|
||||
internet_charge_type = "PayByBandwidth"
|
||||
instance_name = "update_image"
|
||||
io_optimized = "optimized"
|
||||
password = "Test12345"
|
||||
}
|
||||
`
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by "stringer -type=ResourceMode -output=resource_mode_string.go resource_mode.go"; DO NOT EDIT.
|
||||
// Code generated by "stringer -type=ResourceMode -output=resource_mode_string.go resource_mode.go"; DO NOT EDIT
|
||||
|
||||
package config
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by "stringer -type=getSource resource_data_get_source.go"; DO NOT EDIT.
|
||||
// Code generated by "stringer -type=getSource resource_data_get_source.go"; DO NOT EDIT
|
||||
|
||||
package schema
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by "stringer -type=ValueType valuetype.go"; DO NOT EDIT.
|
||||
// Code generated by "stringer -type=ValueType valuetype.go"; DO NOT EDIT
|
||||
|
||||
package schema
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by "stringer -type=GraphType context_graph_type.go"; DO NOT EDIT.
|
||||
// Code generated by "stringer -type=GraphType context_graph_type.go"; DO NOT EDIT
|
||||
|
||||
package terraform
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by "stringer -type=InstanceType instancetype.go"; DO NOT EDIT.
|
||||
// Code generated by "stringer -type=InstanceType instancetype.go"; DO NOT EDIT
|
||||
|
||||
package terraform
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by "stringer -type=walkOperation graph_walk_operation.go"; DO NOT EDIT.
|
||||
// Code generated by "stringer -type=walkOperation graph_walk_operation.go"; DO NOT EDIT
|
||||
|
||||
package terraform
|
||||
|
||||
|
|
|
@ -49,3 +49,34 @@ func (client *Client) DescribeInstanceTypesNew(args *DescribeInstanceTypesArgs)
|
|||
return response.InstanceTypes.InstanceType, nil
|
||||
|
||||
}
|
||||
|
||||
type DescribeInstanceTypeFamiliesArgs struct {
|
||||
RegionId common.Region
|
||||
Generation string
|
||||
}
|
||||
|
||||
type InstanceTypeFamilies struct {
|
||||
InstanceTypeFamily []InstanceTypeFamily
|
||||
}
|
||||
|
||||
type InstanceTypeFamily struct {
|
||||
InstanceTypeFamilyId string
|
||||
Generation string
|
||||
}
|
||||
|
||||
type DescribeInstanceTypeFamiliesResponse struct {
|
||||
common.Response
|
||||
|
||||
InstanceTypeFamilies InstanceTypeFamilies
|
||||
}
|
||||
|
||||
func (client *Client) DescribeInstanceTypeFamilies(args *DescribeInstanceTypeFamiliesArgs) (*DescribeInstanceTypeFamiliesResponse, error) {
|
||||
response := &DescribeInstanceTypeFamiliesResponse{}
|
||||
|
||||
err := client.Invoke("DescribeInstanceTypeFamilies", args, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
|
|
@ -336,16 +336,11 @@ func (client *Client) WaitForInstanceAsyn(instanceId string, status InstanceStat
|
|||
instance, err := client.DescribeInstanceAttribute(instanceId)
|
||||
if err != nil {
|
||||
e, _ := err.(*common.Error)
|
||||
if e.ErrorResponse.Code != "InvalidInstanceId.NotFound" {
|
||||
if e.Code != "InvalidInstanceId.NotFound" && e.Code != "Forbidden.InstanceNotFound" {
|
||||
return err
|
||||
}
|
||||
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||
continue
|
||||
}
|
||||
if instance.Status == status {
|
||||
} else if instance != nil && instance.Status == status {
|
||||
//TODO
|
||||
//Sleep one more time for timing issues
|
||||
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||
break
|
||||
}
|
||||
timeout = timeout - DefaultWaitForInterval
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
)
|
||||
|
||||
type CreateKeyPairArgs struct {
|
||||
RegionId common.Region
|
||||
KeyPairName string
|
||||
}
|
||||
|
||||
type CreateKeyPairResponse struct {
|
||||
common.Response
|
||||
KeyPairName string
|
||||
KeyPairFingerPrint string
|
||||
PrivateKeyBody string
|
||||
}
|
||||
|
||||
// CreateKeyPair creates keypair
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/51771.html?spm=5176.doc51775.6.910.cedjfr
|
||||
func (client *Client) CreateKeyPair(args *CreateKeyPairArgs) (resp *CreateKeyPairResponse,err error) {
|
||||
response := CreateKeyPairResponse{}
|
||||
err = client.Invoke("CreateKeyPair", args, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &response, err
|
||||
}
|
||||
|
||||
type ImportKeyPairArgs struct {
|
||||
RegionId common.Region
|
||||
PublicKeyBody string
|
||||
KeyPairName string
|
||||
}
|
||||
|
||||
type ImportKeyPairResponse struct {
|
||||
common.Response
|
||||
KeyPairName string
|
||||
KeyPairFingerPrint string
|
||||
}
|
||||
|
||||
// ImportKeyPair import keypair
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/51774.html?spm=5176.doc51771.6.911.BicQq2
|
||||
func (client *Client) ImportKeyPair(args *ImportKeyPairArgs) (resp *ImportKeyPairResponse,err error) {
|
||||
response := ImportKeyPairResponse{}
|
||||
err = client.Invoke("ImportKeyPair", args, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &response, err
|
||||
}
|
||||
|
||||
type DescribeKeyPairsArgs struct {
|
||||
RegionId common.Region
|
||||
KeyPairFingerPrint string
|
||||
KeyPairName string
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
type KeyPairItemType struct {
|
||||
KeyPairName string
|
||||
KeyPairFingerPrint string
|
||||
}
|
||||
|
||||
type DescribeKeyPairsResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
RegionId common.Region
|
||||
KeyPairs struct {
|
||||
KeyPair []KeyPairItemType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeKeyPairs describe keypairs
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/51773.html?spm=5176.doc51774.6.912.lyE0iX
|
||||
func (client *Client) DescribeKeyPairs(args *DescribeKeyPairsArgs) (KeyPairs []KeyPairItemType, pagination *common.PaginationResult, err error) {
|
||||
response := DescribeKeyPairsResponse{}
|
||||
|
||||
err = client.Invoke("DescribeKeyPairs", args, &response)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return response.KeyPairs.KeyPair, &response.PaginationResult, err
|
||||
}
|
||||
|
||||
type AttachKeyPairArgs struct {
|
||||
RegionId common.Region
|
||||
KeyPairName string
|
||||
InstanceIds string
|
||||
}
|
||||
|
||||
// AttachKeyPair keypars to instances
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/51775.html?spm=5176.doc51773.6.913.igEem4
|
||||
func (client *Client) AttachKeyPair(args *AttachKeyPairArgs) (err error) {
|
||||
response := common.Response{}
|
||||
err = client.Invoke("AttachKeyPair", args, &response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DetachKeyPairArgs struct {
|
||||
RegionId common.Region
|
||||
KeyPairName string
|
||||
InstanceIds string
|
||||
}
|
||||
|
||||
// DetachKeyPair keyparis from instances
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/51776.html?spm=5176.doc51775.6.914.DJ7Gmq
|
||||
func (client *Client) DetachKeyPair(args *DetachKeyPairArgs) (err error) {
|
||||
response := common.Response{}
|
||||
err = client.Invoke("DetachKeyPair", args, &response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DeleteKeyPairsArgs struct {
|
||||
RegionId common.Region
|
||||
KeyPairNames string
|
||||
}
|
||||
|
||||
// DeleteKeyPairs delete keypairs
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/51772.html?spm=5176.doc51776.6.915.Qqcv2Q
|
||||
func (client *Client) DeleteKeyPairs(args *DeleteKeyPairsArgs) (err error) {
|
||||
response := common.Response{}
|
||||
err = client.Invoke("DeleteKeyPairs", args, &response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -345,6 +345,44 @@ func (client *Client) WaitForInstance(instanceId string, status InstanceStatus,
|
|||
return nil
|
||||
}
|
||||
|
||||
// WaitForInstance waits for instance to given status
|
||||
func (client *Client) WaitForInstanceAsyn(instanceId string, status InstanceStatus, timeout int) error {
|
||||
if timeout <= 0 {
|
||||
timeout = InstanceDefaultTimeout
|
||||
}
|
||||
for {
|
||||
args := DescribeDBInstancesArgs{
|
||||
DBInstanceId: instanceId,
|
||||
}
|
||||
|
||||
resp, err := client.DescribeDBInstanceAttribute(&args)
|
||||
if err != nil {
|
||||
e, _ := err.(*common.Error)
|
||||
if e.Code != "InvalidInstanceId.NotFound" && e.Code != "Forbidden.InstanceNotFound" {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if timeout <= 0 {
|
||||
return common.GetClientErrorFromString("Timeout")
|
||||
}
|
||||
|
||||
timeout = timeout - DefaultWaitForInterval
|
||||
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||
if resp != nil {
|
||||
|
||||
if len(resp.Items.DBInstanceAttribute) < 1 {
|
||||
continue
|
||||
}
|
||||
instance := resp.Items.DBInstanceAttribute[0]
|
||||
if instance.DBInstanceStatus == status {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *Client) WaitForAllDatabase(instanceId string, databaseNames []string, status InstanceStatus, timeout int) error {
|
||||
if timeout <= 0 {
|
||||
timeout = InstanceDefaultTimeout
|
||||
|
|
|
@ -472,6 +472,42 @@ func (client *Client) WaitForListener(loadBalancerId string, port int, listenerT
|
|||
return response.Status, nil
|
||||
}
|
||||
|
||||
// WaitForListener waits for listener to given status
|
||||
func (client *Client) WaitForListenerAsyn(loadBalancerId string, port int, listenerType ListenerType, status ListenerStatus, timeout int) error {
|
||||
if timeout <= 0 {
|
||||
timeout = DefaultTimeout
|
||||
}
|
||||
|
||||
args := &CommonLoadBalancerListenerArgs{
|
||||
LoadBalancerId: loadBalancerId,
|
||||
ListenerPort: port,
|
||||
}
|
||||
|
||||
method := fmt.Sprintf("DescribeLoadBalancer%sListenerAttribute", listenerType)
|
||||
response := &DescribeLoadBalancerListenerAttributeResponse{}
|
||||
|
||||
for {
|
||||
err := client.Invoke(method, args, response)
|
||||
e, _ := err.(*common.Error)
|
||||
if e != nil {
|
||||
if e.StatusCode == 404 || e.Code == "InvalidLoadBalancerId.NotFound" {
|
||||
continue
|
||||
}
|
||||
return err
|
||||
} else if response != nil && response.Status == status {
|
||||
//TODO
|
||||
break
|
||||
}
|
||||
timeout = timeout - DefaultWaitForInterval
|
||||
if timeout <= 0 {
|
||||
return common.GetClientErrorFromString("Timeout")
|
||||
}
|
||||
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DescribeListenerAccessControlAttributeResponse struct {
|
||||
common.Response
|
||||
AccessControlStatus AccessControlStatus
|
||||
|
|
|
@ -1324,38 +1324,38 @@
|
|||
{
|
||||
"checksumSHA1": "4YIveqfMA1MH8oX8YMG7rDSl+ms=",
|
||||
"path": "github.com/denverdino/aliyungo/common",
|
||||
"revision": "afcc6903e3f10217da17e315558b3f829718ee04",
|
||||
"revisionTime": "2017-04-13T09:54:00Z"
|
||||
"revision": "812f2752cabdc83e7d410c49f25c2b4b99aa166b",
|
||||
"revisionTime": "2017-05-25T09:14:12Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "WkWWoA5aRYkE2apOEQdAOfn+9cc=",
|
||||
"checksumSHA1": "x4l/zVF/J4ibAH39pNrSvTnFsPI=",
|
||||
"path": "github.com/denverdino/aliyungo/ecs",
|
||||
"revision": "afcc6903e3f10217da17e315558b3f829718ee04",
|
||||
"revisionTime": "2017-04-13T09:54:00Z"
|
||||
"revision": "812f2752cabdc83e7d410c49f25c2b4b99aa166b",
|
||||
"revisionTime": "2017-05-25T09:14:12Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "BgIs8qwCMRM8xL6oLeo2Ki1QwBc=",
|
||||
"path": "github.com/denverdino/aliyungo/ess",
|
||||
"revision": "afcc6903e3f10217da17e315558b3f829718ee04",
|
||||
"revisionTime": "2017-04-13T09:54:00Z"
|
||||
"revision": "812f2752cabdc83e7d410c49f25c2b4b99aa166b",
|
||||
"revisionTime": "2017-05-25T09:14:12Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "riQMe2AR7qkLRkQ/MSr8gQp3zL4=",
|
||||
"checksumSHA1": "XGF+DfnJvqlql64Ygl+eCVxsfVY=",
|
||||
"path": "github.com/denverdino/aliyungo/rds",
|
||||
"revision": "afcc6903e3f10217da17e315558b3f829718ee04",
|
||||
"revisionTime": "2017-04-13T09:54:00Z"
|
||||
"revision": "812f2752cabdc83e7d410c49f25c2b4b99aa166b",
|
||||
"revisionTime": "2017-05-25T09:14:12Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "2g6VZONB51rul5YuSBvngH6u4A0=",
|
||||
"checksumSHA1": "iZftKqx5jdcEaMJNJhrb5QwmMuc=",
|
||||
"path": "github.com/denverdino/aliyungo/slb",
|
||||
"revision": "afcc6903e3f10217da17e315558b3f829718ee04",
|
||||
"revisionTime": "2017-04-13T09:54:00Z"
|
||||
"revision": "812f2752cabdc83e7d410c49f25c2b4b99aa166b",
|
||||
"revisionTime": "2017-05-25T09:14:12Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "piZlmhWPLGxYkXLysTrjcXllO4c=",
|
||||
"path": "github.com/denverdino/aliyungo/util",
|
||||
"revision": "afcc6903e3f10217da17e315558b3f829718ee04",
|
||||
"revisionTime": "2017-04-13T09:54:00Z"
|
||||
"revision": "812f2752cabdc83e7d410c49f25c2b4b99aa166b",
|
||||
"revisionTime": "2017-05-25T09:14:12Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "yDQQpeUxwqB3C+4opweg6znWJQk=",
|
||||
|
|
|
@ -54,7 +54,7 @@ resource "alicloud_slb" "vpc" {
|
|||
|
||||
The following arguments are supported:
|
||||
|
||||
* `image_id` - (Required) The Image to use for the instance.
|
||||
* `image_id` - (Required) The Image to use for the instance. ECS instance's image can be replaced via changing 'image_id'.
|
||||
* `instance_type` - (Required) The type of instance to start.
|
||||
* `io_optimized` - (Required) Valid values are `none`, `optimized`, If `optimized`, the launched ECS instance will be I/O optimized.
|
||||
* `security_groups` - (Optional) A list of security group ids to associate with.
|
||||
|
@ -63,14 +63,14 @@ The following arguments are supported:
|
|||
Terraform will autogenerate a default name is `ECS-Instance`.
|
||||
* `allocate_public_ip` - (Optional) Associate a public ip address with an instance in a VPC or Classic. Boolean value, Default is false.
|
||||
* `system_disk_category` - (Optional) Valid values are `cloud`, `cloud_efficiency`, `cloud_ssd`, For I/O optimized instance type, `cloud_ssd` and `cloud_efficiency` disks are supported. For non I/O Optimized instance type, `cloud` disk are supported.
|
||||
* `system_disk_size` - (Optional) Size of the system disk, value range: 40GB ~ 500GB. Default is 40GB.
|
||||
* `system_disk_size` - (Optional) Size of the system disk, value range: 40GB ~ 500GB. Default is 40GB. ECS instance's system disk can be reset when replacing system disk.
|
||||
* `description` - (Optional) Description of the instance, This description can have a string of 2 to 256 characters, It cannot begin with http:// or https://. Default value is null.
|
||||
* `internet_charge_type` - (Optional) Internet charge type of the instance, Valid values are `PayByBandwidth`, `PayByTraffic`. Default is `PayByBandwidth`.
|
||||
* `internet_max_bandwidth_in` - (Optional) Maximum incoming bandwidth from the public network, measured in Mbps (Mega bit per second). Value range: [1, 200]. If this value is not specified, then automatically sets it to 200 Mbps.
|
||||
* `internet_max_bandwidth_out` - (Optional) Maximum outgoing bandwidth to the public network, measured in Mbps (Mega bit per second). Value range: [0, 100], If this value is not specified, then automatically sets it to 0 Mbps.
|
||||
* `host_name` - (Optional) Host name of the ECS, which is a string of at least two characters. “hostname” cannot start or end with “.” or “-“. In addition, two or more consecutive “.” or “-“ symbols are not allowed. On Windows, the host name can contain a maximum of 15 characters, which can be a combination of uppercase/lowercase letters, numerals, and “-“. The host name cannot contain dots (“.”) or contain only numeric characters.
|
||||
On other OSs such as Linux, the host name can contain a maximum of 30 characters, which can be segments separated by dots (“.”), where each segment can contain uppercase/lowercase letters, numerals, or “_“.
|
||||
* `password` - (Optional) Password to an instance is a string of 8 to 30 characters. It must contain uppercase/lowercase letters and numerals, but cannot contain special symbols.
|
||||
* `password` - (Optional) Password to an instance is a string of 8 to 30 characters. It must contain uppercase/lowercase letters and numerals, but cannot contain special symbols. In order to take effect new password, the instance will be restarted after modifying the password.
|
||||
* `vswitch_id` - (Optional) The virtual switch ID to launch in VPC. If you want to create instances in VPC network, this parameter must be set.
|
||||
* `instance_charge_type` - (Optional) Valid values are `PrePaid`, `PostPaid`, The default is `PostPaid`.
|
||||
* `period` - (Optional) The time that you have bought the resource, in month. Only valid when instance_charge_type is set as `PrePaid`. Value range [1, 12].
|
||||
|
|
Loading…
Reference in New Issue