From a335c5639b2d03883e7a6295735ff7383ca7a91e Mon Sep 17 00:00:00 2001 From: oliverpei Date: Mon, 14 Sep 2020 16:40:38 +0800 Subject: [PATCH] fix cvm key_name update error --- CHANGELOG.md | 4 ++ tencentcloud/resource_tc_instance.go | 47 ++++++++++++++++++++++ tencentcloud/resource_tc_instance_test.go | 15 ++++--- tencentcloud/resource_tc_redis_instance.go | 5 ++- tencentcloud/service_tencentcloud_cvm.go | 19 +++++++++ 5 files changed, 83 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c060ec2ab..94ebc625c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ ## 1.42.2 (Unreleased) + +BUG FIXES: +* Resource: `tencentcloud_instance` fix `key_name` update error([#515](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/issues/515)). + ## 1.42.1 (September 10, 2020) BUG FIXES: diff --git a/tencentcloud/resource_tc_instance.go b/tencentcloud/resource_tc_instance.go index d75dde8d76..558fa50d1b 100644 --- a/tencentcloud/resource_tc_instance.go +++ b/tencentcloud/resource_tc_instance.go @@ -716,6 +716,8 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{}) } if len(instance.LoginSettings.KeyIds) > 0 { _ = d.Set("key_name", instance.LoginSettings.KeyIds[0]) + } else { + _ = d.Set("key_name", "") } if *instance.InstanceState == CVM_STATUS_STOPPED { _ = d.Set("running_flag", false) @@ -908,6 +910,51 @@ func resourceTencentCloudInstanceUpdate(d *schema.ResourceData, meta interface{} } } + if d.HasChange("key_name") { + old, new := d.GetChange("key_name") + oldKeyId := old.(string) + keyId := new.(string) + err := cvmService.UnbindKeyPair(ctx, oldKeyId, []*string{&instanceId}) + if err != nil { + return err + } + err = resource.Retry(2*readRetryTimeout, func() *resource.RetryError { + instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId) + if errRet != nil { + return retryError(errRet, InternalError) + } + if instance != nil && *instance.LatestOperationState == CVM_LATEST_OPERATION_STATE_OPERATING { + return resource.RetryableError(fmt.Errorf("cvm instance latest operetion status is %s, retry...", *instance.LatestOperationState)) + } + return nil + }) + if err != nil { + return err + } + + if keyId != "" { + err = cvmService.BindKeyPair(ctx, keyId, instanceId) + if err != nil { + return err + } + time.Sleep(10 * time.Second) + err = resource.Retry(2*readRetryTimeout, func() *resource.RetryError { + instance, errRet := cvmService.DescribeInstanceById(ctx, instanceId) + if errRet != nil { + return retryError(errRet, InternalError) + } + if instance != nil && *instance.LatestOperationState == CVM_LATEST_OPERATION_STATE_OPERATING { + return resource.RetryableError(fmt.Errorf("cvm instance latest operetion status is %s, retry...", *instance.LatestOperationState)) + } + return nil + }) + if err != nil { + return err + } + } + d.SetPartial("key_name") + } + if d.HasChange("vpc_id") || d.HasChange("subnet_id") || d.HasChange("private_ip") { vpcId := d.Get("vpc_id").(string) subnetId := d.Get("subnet_id").(string) diff --git a/tencentcloud/resource_tc_instance_test.go b/tencentcloud/resource_tc_instance_test.go index 12547a26d2..851b69486c 100644 --- a/tencentcloud/resource_tc_instance_test.go +++ b/tencentcloud/resource_tc_instance_test.go @@ -186,7 +186,7 @@ func TestAccTencentCloudInstanceWithKeyPair(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccTencentCloudInstanceWithKeyPair("tf_acc_test_key1"), + Config: testAccTencentCloudInstanceWithKeyPair("key_pair_0"), Check: resource.ComposeTestCheckFunc( testAccCheckTencentCloudDataSourceID(id), testAccCheckTencentCloudInstanceExists(id), @@ -195,7 +195,7 @@ func TestAccTencentCloudInstanceWithKeyPair(t *testing.T) { ), }, { - Config: testAccTencentCloudInstanceWithKeyPair("tf_acc_test_key2"), + Config: testAccTencentCloudInstanceWithKeyPair("key_pair_1"), Check: resource.ComposeTestCheckFunc( testAccCheckTencentCloudDataSourceID(id), testAccCheckTencentCloudInstanceExists(id), @@ -614,17 +614,22 @@ resource "tencentcloud_instance" "foo" { func testAccTencentCloudInstanceWithKeyPair(keyName string) string { return fmt.Sprintf( defaultInstanceVariable+` -resource "tencentcloud_key_pair" "foo" { - key_name = "%s" +resource "tencentcloud_key_pair" "key_pair_0" { + key_name = "key_pair_0" public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDjd8fTnp7Dcuj4mLaQxf9Zs/ORgUL9fQxRCNKkPgP1paTy1I513maMX126i36Lxxl3+FUB52oVbo/FgwlIfX8hyCnv8MCxqnuSDozf1CD0/wRYHcTWAtgHQHBPCC2nJtod6cVC3kB18KeV4U7zsxmwFeBIxojMOOmcOBuh7+trRw==" } +resource "tencentcloud_key_pair" "key_pair_1" { + key_name = "key_pair_1" + public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzwYE6KI8uULEvSNA2k1tlsLtMDe+x1Saw6yL3V1mk9NFws0K2BshYqsnP/BlYiGZv/Nld5xmGoA9LupOcUpyyGGSHZdBrMx1Dz9ajewe7kGowRWwwMAHTlzh9+iqeg/v6P5vW6EwK4hpGWgv06vGs3a8CzfbHu1YRbZAO/ysp3ymdL+vGvw/vzC0T+YwPMisn9wFD5FTlJ+Em6s9PzxqR/41t4YssmCwUV78ZoYL8CyB0emuB8wALvcXbdUVxMxpBEHd5U6ZP5+HPxU2WFbWqiFCuErLIZRuxFw8L/Ot+JOyNnadN1XU4crYDX5cML1i/ExXKVIDoBaLtgAJOpyeP" +} + resource "tencentcloud_instance" "foo" { instance_name = var.instance_name availability_zone = data.tencentcloud_availability_zones.default.zones.0.name image_id = data.tencentcloud_images.default.images.0.image_id instance_type = data.tencentcloud_instance_types.default.instance_types.0.instance_type - key_name = tencentcloud_key_pair.foo.id + key_name = tencentcloud_key_pair.%s.id system_disk_type = "CLOUD_PREMIUM" } `, diff --git a/tencentcloud/resource_tc_redis_instance.go b/tencentcloud/resource_tc_redis_instance.go index ee52ec3e68..0c97645789 100644 --- a/tencentcloud/resource_tc_redis_instance.go +++ b/tencentcloud/resource_tc_redis_instance.go @@ -538,14 +538,15 @@ func resourceTencentCloudRedisInstanceUpdate(d *schema.ResourceData, meta interf if newMemSize < 1 { return fmt.Errorf("redis mem_size value cannot be set to less than 1") } - redisId, err := redisService.UpgradeInstance(ctx, id, int64(newMemSize)) + _, err := redisService.UpgradeInstance(ctx, id, int64(newMemSize)) if err != nil { log.Printf("[CRITAL]%s redis update mem size error, reason:%s\n", logId, err.Error()) + return err } err = resource.Retry(4*readRetryTimeout, func() *resource.RetryError { - _, _, info, err := redisService.CheckRedisOnlineOk(ctx, redisId) + _, _, info, err := redisService.CheckRedisOnlineOk(ctx, id) if info != nil { status := REDIS_STATUS[*info.Status] diff --git a/tencentcloud/service_tencentcloud_cvm.go b/tencentcloud/service_tencentcloud_cvm.go index e0c5924ea5..96fe730eea 100644 --- a/tencentcloud/service_tencentcloud_cvm.go +++ b/tencentcloud/service_tencentcloud_cvm.go @@ -476,6 +476,7 @@ func (me *CvmService) UnbindKeyPair(ctx context.Context, keyId string, instanceI request := cvm.NewDisassociateInstancesKeyPairsRequest() request.KeyIds = []*string{&keyId} request.InstanceIds = instanceIds + request.ForceStop = helper.Bool(true) ratelimit.Check(request.GetAction()) response, err := me.client.UseCvmClient().DisassociateInstancesKeyPairs(request) @@ -490,6 +491,24 @@ func (me *CvmService) UnbindKeyPair(ctx context.Context, keyId string, instanceI return nil } +func (me *CvmService) BindKeyPair(ctx context.Context, keyId, instanceId string) error { + logId := getLogId(ctx) + request := cvm.NewAssociateInstancesKeyPairsRequest() + request.KeyIds = []*string{&keyId} + request.InstanceIds = []*string{&instanceId} + request.ForceStop = helper.Bool(true) + + ratelimit.Check(request.GetAction()) + _, err := me.client.UseCvmClient().AssociateInstancesKeyPairs(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + return err + } + + return nil +} + func (me *CvmService) CreatePlacementGroup(ctx context.Context, placementName, placementType string) (placementId string, errRet error) { logId := getLogId(ctx) request := cvm.NewCreateDisasterRecoverGroupRequest()