From 969bf8e8f463ec4007eb955a90526db9786c0e6f Mon Sep 17 00:00:00 2001 From: crab Date: Thu, 9 Jul 2020 11:30:45 +0800 Subject: [PATCH 1/6] datasource images support snapshotSet --- tencentcloud/data_source_tc_images.go | 87 ++++++++++++++++++++++ tencentcloud/data_source_tc_images_test.go | 3 +- tencentcloud/service_tencentcloud_cbs.go | 38 ++++++++++ website/docs/d/images.html.markdown | 5 ++ 4 files changed, 132 insertions(+), 1 deletion(-) diff --git a/tencentcloud/data_source_tc_images.go b/tencentcloud/data_source_tc_images.go index c17348bece..1061de237c 100644 --- a/tencentcloud/data_source_tc_images.go +++ b/tencentcloud/data_source_tc_images.go @@ -21,6 +21,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + cbs "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs/v20170312" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" "github.com/terraform-providers/terraform-provider-tencentcloud/tencentcloud/internal/helper" ) @@ -136,6 +137,35 @@ func dataSourceTencentCloudImages() *schema.Resource { Computed: true, Description: "Whether support cloud-init.", }, + "snapshots": { + Type: schema.TypeSet, + Computed: true, + Description: "List of snapshot details.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + Description: "Snapshot ID.", + }, + "snapshot_name": { + Type: schema.TypeString, + Computed: true, + Description: "Snapshot name, the user-defined snapshot alias.", + }, + "disk_usage": { + Type: schema.TypeString, + Computed: true, + Description: "Type of the cloud disk used to create the snapshot.", + }, + "disk_size": { + Type: schema.TypeInt, + Computed: true, + Description: "Size of the cloud disk used to create the snapshot; unit: GB.", + }, + }, + }, + }, }, }, }, @@ -153,6 +183,10 @@ func dataSourceTencentCloudImagesRead(d *schema.ResourceData, meta interface{}) client: meta.(*TencentCloudClient).apiV3Conn, } + cbsService := CbsService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + var ( imageId string imageType []string @@ -234,6 +268,11 @@ func dataSourceTencentCloudImagesRead(d *schema.ResourceData, meta interface{}) imageList := make([]map[string]interface{}, 0, len(results)) ids := make([]string, 0, len(results)) for _, image := range results { + snapshots, err := imagesReadSnapshotByIds(image, cbsService, ctx) + if err != nil { + return err + } + mapping := map[string]interface{}{ "image_id": image.ImageId, "os_name": image.OsName, @@ -249,6 +288,7 @@ func dataSourceTencentCloudImagesRead(d *schema.ResourceData, meta interface{}) "image_source": image.ImageSource, "sync_percent": image.SyncPercent, "support_cloud_init": image.IsSupportCloudinit, + "snapshots": snapshots, } imageList = append(imageList, mapping) ids = append(ids, *image.ImageId) @@ -270,3 +310,50 @@ func dataSourceTencentCloudImagesRead(d *schema.ResourceData, meta interface{}) return nil } + +func imagesReadSnapshotByIds(image *cvm.Image, cbsService CbsService, ctx context.Context) (snapshotResults []map[string]interface{}, errSnap error) { + if len(image.SnapshotSet) == 0 { + return + } + + snapshotSetMap := map[string]interface{}{} + snapshotByIds := make([]*string, 0, len(image.SnapshotSet)) + for _, snapshot := range image.SnapshotSet { + snapshotByIds = append(snapshotByIds, snapshot.SnapshotId) + } + + var snapshots []*cbs.Snapshot + errSnap = resource.Retry(readRetryTimeout, func() *resource.RetryError { + snapshots, errSnap = cbsService.DescribeSnapshotByIds(ctx, snapshotByIds) + if errSnap != nil { + return retryError(errSnap, InternalError) + } + return nil + }) + if errSnap != nil { + return + } + + for _, snapshot := range snapshots { + snapshotSetMap[*snapshot.SnapshotId] = snapshot + } + + snapshotSet := image.SnapshotSet + snapshotResults = make([]map[string]interface{}, 0, len(snapshotSet)) + if len(snapshotSet) > 0 { + for _, snapshot := range snapshotSet { + snapshotMap := make(map[string]interface{}, 4) + id := snapshot.SnapshotId + snapshotMap["snapshot_id"] = *id + snapshotMap["disk_usage"] = snapshot.DiskUsage + snapshotMap["disk_size"] = snapshot.DiskSize + + if v, ok := snapshotSetMap[*id]; ok { + snapshotMap["snapshot_name"] = v.(*cbs.Snapshot).SnapshotName + } + snapshotResults = append(snapshotResults, snapshotMap) + } + } + + return +} diff --git a/tencentcloud/data_source_tc_images_test.go b/tencentcloud/data_source_tc_images_test.go index fcaa84b02f..ea30e605bd 100644 --- a/tencentcloud/data_source_tc_images_test.go +++ b/tencentcloud/data_source_tc_images_test.go @@ -45,12 +45,13 @@ func TestAccTencentCloudDataSourceImagesBase(t *testing.T) { const testAccTencentCloudDataSourceImagesBase = ` data "tencentcloud_images" "foo" { + result_output_file = "data_source_tc_images_test.txt" } ` const testAccTencentCloudDataSourceImagesBaseWithFilter = ` data "tencentcloud_images" "foo" { - image_type = ["PUBLIC_IMAGE"] + image_type = ["PRIVATE_IMAGE"] } ` diff --git a/tencentcloud/service_tencentcloud_cbs.go b/tencentcloud/service_tencentcloud_cbs.go index 5bd56de94b..e1d8ae6fc7 100644 --- a/tencentcloud/service_tencentcloud_cbs.go +++ b/tencentcloud/service_tencentcloud_cbs.go @@ -226,6 +226,44 @@ func (me *CbsService) DescribeSnapshotById(ctx context.Context, snapshotId strin return } +func (me *CbsService) DescribeSnapshotByIds(ctx context.Context, snapshotIdsParam []*string) (snapshots []*cbs.Snapshot, errRet error) { + logId := getLogId(ctx) + request := cbs.NewDescribeSnapshotsRequest() + if len(snapshotIdsParam) == 0 { + return + } + request.SnapshotIds = snapshotIdsParam + + offset := 0 + pageSize := 100 + for { + request.Offset = helper.IntUint64(offset) + request.Limit = helper.IntUint64(pageSize) + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCbsClient().DescribeSnapshots(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.SnapshotSet) < 1 { + break + } + + snapshots = append(snapshots, response.Response.SnapshotSet...) + + if len(response.Response.SnapshotSet) < pageSize { + break + } + offset += pageSize + } + return +} + func (me *CbsService) DescribeSnapshotsByFilter(ctx context.Context, params map[string]string) (snapshots []*cbs.Snapshot, errRet error) { logId := getLogId(ctx) request := cbs.NewDescribeSnapshotsRequest() diff --git a/website/docs/d/images.html.markdown b/website/docs/d/images.html.markdown index 12190114ea..0646da16cc 100644 --- a/website/docs/d/images.html.markdown +++ b/website/docs/d/images.html.markdown @@ -46,6 +46,11 @@ In addition to all arguments above, the following attributes are exported: * `image_type` - Type of the image. * `os_name` - OS name of the image. * `platform` - Platform of the image. + * `snapshots` - List of snapshot details. + * `disk_size` - Size of the cloud disk used to create the snapshot; unit: GB. + * `disk_usage` - Type of the cloud disk used to create the snapshot. + * `snapshot_id` - Snapshot ID. + * `snapshot_name` - Snapshot name, the user-defined snapshot alias. * `support_cloud_init` - Whether support cloud-init. * `sync_percent` - Sync percent of the image. From 352d5b5773724dac77e79f1d02f48596bc618119 Mon Sep 17 00:00:00 2001 From: crab Date: Thu, 9 Jul 2020 14:03:47 +0800 Subject: [PATCH 2/6] optimize code logic --- tencentcloud/data_source_tc_images.go | 4 ++-- tencentcloud/service_tencentcloud_cbs.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tencentcloud/data_source_tc_images.go b/tencentcloud/data_source_tc_images.go index 1061de237c..8bff25a6c2 100644 --- a/tencentcloud/data_source_tc_images.go +++ b/tencentcloud/data_source_tc_images.go @@ -268,7 +268,7 @@ func dataSourceTencentCloudImagesRead(d *schema.ResourceData, meta interface{}) imageList := make([]map[string]interface{}, 0, len(results)) ids := make([]string, 0, len(results)) for _, image := range results { - snapshots, err := imagesReadSnapshotByIds(image, cbsService, ctx) + snapshots, err := imagesReadSnapshotByIds(ctx, cbsService, image) if err != nil { return err } @@ -311,7 +311,7 @@ func dataSourceTencentCloudImagesRead(d *schema.ResourceData, meta interface{}) return nil } -func imagesReadSnapshotByIds(image *cvm.Image, cbsService CbsService, ctx context.Context) (snapshotResults []map[string]interface{}, errSnap error) { +func imagesReadSnapshotByIds(ctx context.Context, cbsService CbsService, image *cvm.Image) (snapshotResults []map[string]interface{}, errSnap error) { if len(image.SnapshotSet) == 0 { return } diff --git a/tencentcloud/service_tencentcloud_cbs.go b/tencentcloud/service_tencentcloud_cbs.go index e1d8ae6fc7..9ed0c7a488 100644 --- a/tencentcloud/service_tencentcloud_cbs.go +++ b/tencentcloud/service_tencentcloud_cbs.go @@ -250,7 +250,7 @@ func (me *CbsService) DescribeSnapshotByIds(ctx context.Context, snapshotIdsPara log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) - if response == nil || len(response.Response.SnapshotSet) < 1 { + if len(response.Response.SnapshotSet) < 1 { break } From 07f99b53748df785afe58b35d3fabc60dff9721e Mon Sep 17 00:00:00 2001 From: crab Date: Thu, 9 Jul 2020 15:24:00 +0800 Subject: [PATCH 3/6] optimize retry logic --- tencentcloud/data_source_tc_images.go | 9 +-------- tencentcloud/service_tencentcloud_cbs.go | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/tencentcloud/data_source_tc_images.go b/tencentcloud/data_source_tc_images.go index 8bff25a6c2..55ced2032c 100644 --- a/tencentcloud/data_source_tc_images.go +++ b/tencentcloud/data_source_tc_images.go @@ -322,14 +322,7 @@ func imagesReadSnapshotByIds(ctx context.Context, cbsService CbsService, image * snapshotByIds = append(snapshotByIds, snapshot.SnapshotId) } - var snapshots []*cbs.Snapshot - errSnap = resource.Retry(readRetryTimeout, func() *resource.RetryError { - snapshots, errSnap = cbsService.DescribeSnapshotByIds(ctx, snapshotByIds) - if errSnap != nil { - return retryError(errSnap, InternalError) - } - return nil - }) + snapshots, errSnap := cbsService.DescribeSnapshotByIds(ctx, snapshotByIds) if errSnap != nil { return } diff --git a/tencentcloud/service_tencentcloud_cbs.go b/tencentcloud/service_tencentcloud_cbs.go index 9ed0c7a488..c1dbd6bd85 100644 --- a/tencentcloud/service_tencentcloud_cbs.go +++ b/tencentcloud/service_tencentcloud_cbs.go @@ -4,6 +4,7 @@ import ( "context" "log" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" cbs "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs/v20170312" "github.com/terraform-providers/terraform-provider-tencentcloud/tencentcloud/connectivity" "github.com/terraform-providers/terraform-provider-tencentcloud/tencentcloud/internal/helper" @@ -239,8 +240,18 @@ func (me *CbsService) DescribeSnapshotByIds(ctx context.Context, snapshotIdsPara for { request.Offset = helper.IntUint64(offset) request.Limit = helper.IntUint64(pageSize) - ratelimit.Check(request.GetAction()) - response, err := me.client.UseCbsClient().DescribeSnapshots(request) + + var err error + var response *cbs.DescribeSnapshotsResponse + err = resource.Retry(readRetryTimeout, func() *resource.RetryError { + ratelimit.Check(request.GetAction()) + response, err = me.client.UseCbsClient().DescribeSnapshots(request) + if err != nil { + return retryError(err, InternalError) + } + return nil + }) + if err != nil { log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), err.Error()) @@ -255,7 +266,6 @@ func (me *CbsService) DescribeSnapshotByIds(ctx context.Context, snapshotIdsPara } snapshots = append(snapshots, response.Response.SnapshotSet...) - if len(response.Response.SnapshotSet) < pageSize { break } From 2887e9e92a7b5e6e4062915fb255e2caa73e6823 Mon Sep 17 00:00:00 2001 From: crab Date: Thu, 9 Jul 2020 16:05:34 +0800 Subject: [PATCH 4/6] remove unused code --- tencentcloud/data_source_tc_images.go | 34 ++++++++---------------- tencentcloud/service_tencentcloud_cbs.go | 3 --- 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/tencentcloud/data_source_tc_images.go b/tencentcloud/data_source_tc_images.go index 55ced2032c..97459c1548 100644 --- a/tencentcloud/data_source_tc_images.go +++ b/tencentcloud/data_source_tc_images.go @@ -21,7 +21,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - cbs "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs/v20170312" cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" "github.com/terraform-providers/terraform-provider-tencentcloud/tencentcloud/internal/helper" ) @@ -138,7 +137,7 @@ func dataSourceTencentCloudImages() *schema.Resource { Description: "Whether support cloud-init.", }, "snapshots": { - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Description: "List of snapshot details.", Elem: &schema.Resource{ @@ -311,41 +310,30 @@ func dataSourceTencentCloudImagesRead(d *schema.ResourceData, meta interface{}) return nil } -func imagesReadSnapshotByIds(ctx context.Context, cbsService CbsService, image *cvm.Image) (snapshotResults []map[string]interface{}, errSnap error) { +func imagesReadSnapshotByIds(ctx context.Context, cbsService CbsService, image *cvm.Image) (snapshotResults []map[string]interface{}, errRet error) { if len(image.SnapshotSet) == 0 { return } - snapshotSetMap := map[string]interface{}{} snapshotByIds := make([]*string, 0, len(image.SnapshotSet)) for _, snapshot := range image.SnapshotSet { snapshotByIds = append(snapshotByIds, snapshot.SnapshotId) } - snapshots, errSnap := cbsService.DescribeSnapshotByIds(ctx, snapshotByIds) - if errSnap != nil { + snapshots, errRet := cbsService.DescribeSnapshotByIds(ctx, snapshotByIds) + if errRet != nil { return } + snapshotResults = make([]map[string]interface{}, 0, len(snapshots)) for _, snapshot := range snapshots { - snapshotSetMap[*snapshot.SnapshotId] = snapshot - } - - snapshotSet := image.SnapshotSet - snapshotResults = make([]map[string]interface{}, 0, len(snapshotSet)) - if len(snapshotSet) > 0 { - for _, snapshot := range snapshotSet { - snapshotMap := make(map[string]interface{}, 4) - id := snapshot.SnapshotId - snapshotMap["snapshot_id"] = *id - snapshotMap["disk_usage"] = snapshot.DiskUsage - snapshotMap["disk_size"] = snapshot.DiskSize + snapshotMap := make(map[string]interface{}, 4) + snapshotMap["snapshot_id"] = snapshot.SnapshotId + snapshotMap["disk_usage"] = snapshot.DiskUsage + snapshotMap["disk_size"] = snapshot.DiskSize + snapshotMap["snapshot_name"] = snapshot.SnapshotName - if v, ok := snapshotSetMap[*id]; ok { - snapshotMap["snapshot_name"] = v.(*cbs.Snapshot).SnapshotName - } - snapshotResults = append(snapshotResults, snapshotMap) - } + snapshotResults = append(snapshotResults, snapshotMap) } return diff --git a/tencentcloud/service_tencentcloud_cbs.go b/tencentcloud/service_tencentcloud_cbs.go index c1dbd6bd85..f4b5ff6c36 100644 --- a/tencentcloud/service_tencentcloud_cbs.go +++ b/tencentcloud/service_tencentcloud_cbs.go @@ -258,9 +258,6 @@ func (me *CbsService) DescribeSnapshotByIds(ctx context.Context, snapshotIdsPara errRet = err return } - log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", - logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) - if len(response.Response.SnapshotSet) < 1 { break } From 42e32a80369f19f9c6d00177d503d920a781fe72 Mon Sep 17 00:00:00 2001 From: crab Date: Thu, 9 Jul 2020 17:36:52 +0800 Subject: [PATCH 5/6] add changelog --- CHANGELOG.md | 2 ++ tencentcloud/service_tencentcloud_cbs.go | 20 +++++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6b20c58c6..cc8f29e34f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ ## 1.39.0 (Unreleased) ENHANCEMENTS: + +* Data Source: `tencentcloud_images` supports list of snapshots. * Resource: `tencentcloud_kubernetes_cluster_attachment` add new argument `worker_config` to support config with existing instances. ## 1.38.2 (July 03, 2020) diff --git a/tencentcloud/service_tencentcloud_cbs.go b/tencentcloud/service_tencentcloud_cbs.go index f4b5ff6c36..4313d7b4a0 100644 --- a/tencentcloud/service_tencentcloud_cbs.go +++ b/tencentcloud/service_tencentcloud_cbs.go @@ -228,21 +228,23 @@ func (me *CbsService) DescribeSnapshotById(ctx context.Context, snapshotId strin } func (me *CbsService) DescribeSnapshotByIds(ctx context.Context, snapshotIdsParam []*string) (snapshots []*cbs.Snapshot, errRet error) { - logId := getLogId(ctx) - request := cbs.NewDescribeSnapshotsRequest() if len(snapshotIdsParam) == 0 { return } + + var ( + logId = getLogId(ctx) + request = cbs.NewDescribeSnapshotsRequest() + err error + response *cbs.DescribeSnapshotsResponse + offset, pageSize uint64 = 0, 100 + ) request.SnapshotIds = snapshotIdsParam - offset := 0 - pageSize := 100 for { - request.Offset = helper.IntUint64(offset) - request.Limit = helper.IntUint64(pageSize) + request.Offset = &offset + request.Limit = &pageSize - var err error - var response *cbs.DescribeSnapshotsResponse err = resource.Retry(readRetryTimeout, func() *resource.RetryError { ratelimit.Check(request.GetAction()) response, err = me.client.UseCbsClient().DescribeSnapshots(request) @@ -263,7 +265,7 @@ func (me *CbsService) DescribeSnapshotByIds(ctx context.Context, snapshotIdsPara } snapshots = append(snapshots, response.Response.SnapshotSet...) - if len(response.Response.SnapshotSet) < pageSize { + if len(response.Response.SnapshotSet) < int(pageSize) { break } offset += pageSize From 7d1697a712078bc019a11f80d9e3ece833d292b7 Mon Sep 17 00:00:00 2001 From: crab Date: Thu, 9 Jul 2020 18:59:15 +0800 Subject: [PATCH 6/6] optimized code for paging --- tencentcloud/service_tencentcloud_cbs.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/tencentcloud/service_tencentcloud_cbs.go b/tencentcloud/service_tencentcloud_cbs.go index 4313d7b4a0..c032e840a1 100644 --- a/tencentcloud/service_tencentcloud_cbs.go +++ b/tencentcloud/service_tencentcloud_cbs.go @@ -260,9 +260,6 @@ func (me *CbsService) DescribeSnapshotByIds(ctx context.Context, snapshotIdsPara errRet = err return } - if len(response.Response.SnapshotSet) < 1 { - break - } snapshots = append(snapshots, response.Response.SnapshotSet...) if len(response.Response.SnapshotSet) < int(pageSize) {