From d354b15f4b1faac4bc03efc4ac0e3d48299fad9d Mon Sep 17 00:00:00 2001 From: ttomzhou Date: Wed, 13 Jan 2021 14:58:32 +0800 Subject: [PATCH] fix ccn instance and ccn bandwidth limit --- CHANGELOG.md | 8 ++ .../data_source_tc_ccn_bandwidth_limits.go | 12 +- ...ata_source_tc_ccn_bandwidth_limits_test.go | 61 +++++++- tencentcloud/data_source_tc_ccn_instances.go | 12 ++ .../data_source_tc_ccn_instances_test.go | 4 + tencentcloud/extension_cnn.go | 6 + tencentcloud/resource_tc_ccn.go | 81 ++++++++++- .../resource_tc_ccn_bandwidth_limit.go | 73 ++++++++-- .../resource_tc_ccn_bandwidth_limit_test.go | 133 +++++++++++++++--- tencentcloud/resource_tc_ccn_test.go | 26 ++-- tencentcloud/service_tencentcloud_ccn.go | 108 ++++++++++++-- .../docs/d/ccn_bandwidth_limits.html.markdown | 1 + website/docs/d/ccn_instances.html.markdown | 2 + website/docs/r/ccn.html.markdown | 36 ++++- .../docs/r/ccn_bandwidth_limit.html.markdown | 29 ++++ 15 files changed, 513 insertions(+), 79 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93f68167ca..2043750946 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,14 @@ DEPRECATED: * Resource: `tencentcloud_kubernetes_as_scaling_group` replaced by `tencentcloud_kubernetes_node_pool`. +ENHANCEMENTS: + +* Resource `tencentcloud_ccn` add `charge_type` to support billing mode setting. +* Resource `tencentcloud_ccn` add `bandwidth_limit_type` to support the speed limit type setting. +* Resource `tencentcloud_ccn_bandwidth_limit` add `dst_region` to support destination area restriction setting. +* Data Source `tencentcloud_ccn_instances` add `charge_type` to support billing mode. +* Data Source `tencentcloud_ccn_instances` add `bandwidth_limit_type` to support the speed limit type. +* Data Source `tencentcloud_ccn_bandwidth_limit` add `dst_region` to support destination area restriction. ## 1.51.1 (December 22, 2020) diff --git a/tencentcloud/data_source_tc_ccn_bandwidth_limits.go b/tencentcloud/data_source_tc_ccn_bandwidth_limits.go index 448a7f04cc..2df833b32e 100644 --- a/tencentcloud/data_source_tc_ccn_bandwidth_limits.go +++ b/tencentcloud/data_source_tc_ccn_bandwidth_limits.go @@ -66,6 +66,11 @@ func dataSourceTencentCloudCcnBandwidthLimits() *schema.Resource { Computed: true, Description: "Limitation of bandwidth.", }, + "dst_region": { + Type: schema.TypeString, + Computed: true, + Description: "Destination area restriction.", + }, }, }, }, @@ -85,7 +90,7 @@ func dataSourceTencentCloudCcnBandwidthLimitsRead(d *schema.ResourceData, meta i ccnId = d.Get("ccn_id").(string) ) - var infos, err = service.DescribeCcnRegionBandwidthLimits(ctx, ccnId) + var infos, err = service.GetCcnRegionBandwidthLimits(ctx, ccnId) if err != nil { return err } @@ -94,8 +99,9 @@ func dataSourceTencentCloudCcnBandwidthLimitsRead(d *schema.ResourceData, meta i for _, item := range infos { var infoMap = make(map[string]interface{}) - infoMap["region"] = item.region - infoMap["bandwidth_limit"] = item.limit + infoMap["region"] = item.Region + infoMap["bandwidth_limit"] = item.BandwidthLimit + infoMap["dst_region"] = item.DstRegion infoList = append(infoList, infoMap) } if err := d.Set("limits", infoList); err != nil { diff --git a/tencentcloud/data_source_tc_ccn_bandwidth_limits_test.go b/tencentcloud/data_source_tc_ccn_bandwidth_limits_test.go index cbb0c3a060..b7b2063c8d 100644 --- a/tencentcloud/data_source_tc_ccn_bandwidth_limits_test.go +++ b/tencentcloud/data_source_tc_ccn_bandwidth_limits_test.go @@ -6,27 +6,50 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/resource" ) -func TestAccDataSourceTencentCloudCcnV3BandwidthLimitsBasic(t *testing.T) { +func TestAccDataSourceTencentCloudCcnV3BandwidthLimitsOuter(t *testing.T) { keyName := "data.tencentcloud_ccn_bandwidth_limits.limit" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ { - Config: TestAccDataSourceTencentCloudCcnBandwidthLimits, + Config: TestAccDataSourceTencentCloudCcnOuterBandwidthLimits, Check: resource.ComposeTestCheckFunc( testAccCheckTencentCloudDataSourceID(keyName), resource.TestCheckResourceAttrSet(keyName, "ccn_id"), - resource.TestCheckResourceAttrSet(keyName, "limits.#"), + resource.TestCheckResourceAttr(keyName, "limits.#", "1"), + resource.TestCheckResourceAttr(keyName, "limits.0.region", "ap-shanghai"), + resource.TestCheckResourceAttr(keyName, "limits.0.bandwidth_limit", "500"), ), }, }, }) } -const TestAccDataSourceTencentCloudCcnBandwidthLimits = ` +func TestAccDataSourceTencentCloudCcnV3BandwidthLimitsInter(t *testing.T) { + keyName := "data.tencentcloud_ccn_bandwidth_limits.limit" + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: TestAccDataSourceTencentCloudCcnInterBandwidthLimits, + Check: resource.ComposeTestCheckFunc( + testAccCheckTencentCloudDataSourceID(keyName), + resource.TestCheckResourceAttrSet(keyName, "ccn_id"), + resource.TestCheckResourceAttr(keyName, "limits.#", "1"), + resource.TestCheckResourceAttr(keyName, "limits.0.region", "ap-shanghai"), + resource.TestCheckResourceAttr(keyName, "limits.0.dst_region", "ap-beijing"), + resource.TestCheckResourceAttr(keyName, "limits.0.bandwidth_limit", "500"), + ), + }, + }, + }) +} + +const TestAccDataSourceTencentCloudCcnOuterBandwidthLimits = ` variable "other_region1" { default = "ap-shanghai" } @@ -37,13 +60,41 @@ resource tencentcloud_ccn main { qos = "AG" } +resource tencentcloud_ccn_bandwidth_limit limit1 { + ccn_id = tencentcloud_ccn.main.id + region = var.other_region1 + bandwidth_limit = 500 +} + data tencentcloud_ccn_bandwidth_limits limit { - ccn_id = tencentcloud_ccn.main.id + ccn_id = tencentcloud_ccn_bandwidth_limit.limit1.ccn_id +} +` + +const TestAccDataSourceTencentCloudCcnInterBandwidthLimits = ` +variable "other_region1" { + default = "ap-shanghai" +} + +variable "other_region2" { + default = "ap-beijing" +} + +resource tencentcloud_ccn main { + name = "ci-temp-test-ccn" + description = "ci-temp-test-ccn-des" + qos = "AG" + bandwidth_limit_type = "INTER_REGION_LIMIT" } resource tencentcloud_ccn_bandwidth_limit limit1 { ccn_id = tencentcloud_ccn.main.id region = var.other_region1 + dst_region = var.other_region2 bandwidth_limit = 500 } + +data tencentcloud_ccn_bandwidth_limits limit { + ccn_id = tencentcloud_ccn_bandwidth_limit.limit1.ccn_id +} ` diff --git a/tencentcloud/data_source_tc_ccn_instances.go b/tencentcloud/data_source_tc_ccn_instances.go index fe97bfe5ab..c03e033c22 100644 --- a/tencentcloud/data_source_tc_ccn_instances.go +++ b/tencentcloud/data_source_tc_ccn_instances.go @@ -84,6 +84,16 @@ func dataSourceTencentCloudCcnInstances() *schema.Resource { Computed: true, Description: "States of instance. The available value include 'ISOLATED'(arrears) and 'AVAILABLE'.", }, + "charge_type": { + Type: schema.TypeString, + Computed: true, + Description: "Billing mode.", + }, + "bandwidth_limit_type": { + Type: schema.TypeString, + Computed: true, + Description: "The speed limit type.", + }, "attachment_list": { Type: schema.TypeList, Computed: true, @@ -178,6 +188,8 @@ func dataSourceTencentCloudCcnInstancesRead(d *schema.ResourceData, meta interfa infoMap["qos"] = item.qos infoMap["state"] = strings.ToUpper(item.state) infoMap["create_time"] = item.createTime + infoMap["charge_type"] = item.chargeType + infoMap["bandwidth_limit_type"] = item.bandWithLimitType infoList = append(infoList, infoMap) instances, err := service.DescribeCcnAttachedInstances(ctx, item.ccnId) diff --git a/tencentcloud/data_source_tc_ccn_instances_test.go b/tencentcloud/data_source_tc_ccn_instances_test.go index 1bf463f96f..1183421be4 100644 --- a/tencentcloud/data_source_tc_ccn_instances_test.go +++ b/tencentcloud/data_source_tc_ccn_instances_test.go @@ -25,6 +25,8 @@ func TestAccDataSourceTencentCloudCcnV3InstancesBasic(t *testing.T) { resource.TestCheckResourceAttrSet(keyId, "instance_list.0.ccn_id"), resource.TestCheckResourceAttrSet(keyId, "instance_list.0.qos"), resource.TestCheckResourceAttrSet(keyId, "instance_list.0.state"), + resource.TestCheckResourceAttrSet(keyId, "instance_list.0.charge_type"), + resource.TestCheckResourceAttrSet(keyId, "instance_list.0.bandwidth_limit_type"), resource.TestCheckResourceAttrSet(keyId, "instance_list.0.attachment_list.#"), resource.TestCheckResourceAttrSet(keyId, "instance_list.0.create_time"), @@ -36,6 +38,8 @@ func TestAccDataSourceTencentCloudCcnV3InstancesBasic(t *testing.T) { resource.TestCheckResourceAttrSet(keyName, "instance_list.0.ccn_id"), resource.TestCheckResourceAttrSet(keyName, "instance_list.0.qos"), resource.TestCheckResourceAttrSet(keyName, "instance_list.0.state"), + resource.TestCheckResourceAttrSet(keyId, "instance_list.0.charge_type"), + resource.TestCheckResourceAttrSet(keyId, "instance_list.0.bandwidth_limit_type"), resource.TestCheckResourceAttrSet(keyName, "instance_list.0.attachment_list.#"), resource.TestCheckResourceAttrSet(keyName, "instance_list.0.create_time"), ), diff --git a/tencentcloud/extension_cnn.go b/tencentcloud/extension_cnn.go index 263bd45730..3c89bec444 100644 --- a/tencentcloud/extension_cnn.go +++ b/tencentcloud/extension_cnn.go @@ -8,3 +8,9 @@ const CNN_INSTANCE_TYPE_VPC = "VPC" const CNN_INSTANCE_TYPE_DIRECTCONNECT = "DIRECTCONNECT" const CNN_INSTANCE_TYPE_BMVPC = "BMVPC" const CNN_INSTANCE_TYPE_VPNGW = "VPNGW" + +const PREPAID = "PREPAID" +const POSTPAID = "POSTPAID" + +const OuterRegionLimit = "OUTER_REGION_LIMIT" +const InterRegionLimit = "INTER_REGION_LIMIT" diff --git a/tencentcloud/resource_tc_ccn.go b/tencentcloud/resource_tc_ccn.go index 106de3700b..7d02ddbcc9 100644 --- a/tencentcloud/resource_tc_ccn.go +++ b/tencentcloud/resource_tc_ccn.go @@ -3,11 +3,39 @@ Provides a resource to create a CCN instance. Example Usage +Create a prepaid CCN + +```hcl +resource "tencentcloud_ccn" "main" { + name = "ci-temp-test-ccn" + description = "ci-temp-test-ccn-des" + qos = "AG" + charge_type = "PREPAID" + bandwidth_limit_type = "INTER_REGION_LIMIT" +} +``` + +Create a post-paid regional export speed limit type CCN + +```hcl +resource "tencentcloud_ccn" "main" { + name = "ci-temp-test-ccn" + description = "ci-temp-test-ccn-des" + qos = "AG" + charge_type = "POSTPAID" + bandwidth_limit_type = "OUTER_REGION_LIMIT" +} +``` + +Create a post-paid inter-regional rate limit type CNN + ```hcl resource "tencentcloud_ccn" "main" { - name = "ci-temp-test-ccn" - description = "ci-temp-test-ccn-des" - qos = "AG" + name = "ci-temp-test-ccn" + description = "ci-temp-test-ccn-des" + qos = "AG" + charge_type = "POSTPAID" + bandwidth_limit_type = "INTER_REGION_LIMIT" } ``` @@ -62,6 +90,28 @@ func resourceTencentCloudCcn() *schema.Resource { ValidateFunc: validateAllowedStringValue([]string{CNN_QOS_PT, CNN_QOS_AU, CNN_QOS_AG}), Description: "Service quality of CCN. Valid values: `PT`, `AU`, `AG`. The default is `AU`.", }, + "charge_type": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Default: POSTPAID, + ValidateFunc: validateAllowedStringValue([]string{POSTPAID, PREPAID}), + Description: "Billing mode. Valid values: `PREPAID`, `POSTPAID`. " + + "`PREPAID` means prepaid, which means annual and monthly subscription, " + + "`POSTPAID` means post-payment, which means billing by volume. " + + "The default is `POSTPAID`. The prepaid model only supports inter-regional speed limit, " + + "and the post-paid model supports inter-regional speed limit and regional export speed limit.", + }, + "bandwidth_limit_type": { + Type: schema.TypeString, + Optional: true, + Default: OuterRegionLimit, + ValidateFunc: validateAllowedStringValue([]string{OuterRegionLimit, InterRegionLimit}), + Description: "The speed limit type. Valid values: `INTER_REGION_LIMIT`, `OUTER_REGION_LIMIT`. " + + "`OUTER_REGION_LIMIT` represents the regional export speed limit, " + + "`INTER_REGION_LIMIT` is the inter-regional speed limit. " + + "The default is `OUTER_REGION_LIMIT`.", + }, // Computed values "state": { Type: schema.TypeString, @@ -96,14 +146,16 @@ func resourceTencentCloudCcnCreate(d *schema.ResourceData, meta interface{}) err service := VpcService{client: meta.(*TencentCloudClient).apiV3Conn} var ( - name = d.Get("name").(string) - description = "" - qos = d.Get("qos").(string) + name = d.Get("name").(string) + description = "" + qos = d.Get("qos").(string) + chargeType = d.Get("charge_type").(string) + bandwidthLimitType = d.Get("bandwidth_limit_type").(string) ) if temp, ok := d.GetOk("description"); ok { description = temp.(string) } - info, err := service.CreateCcn(ctx, name, description, qos) + info, err := service.CreateCcn(ctx, name, description, qos, chargeType, bandwidthLimitType) if err != nil { return err } @@ -146,6 +198,8 @@ func resourceTencentCloudCcnRead(d *schema.ResourceData, meta interface{}) error _ = d.Set("state", strings.ToUpper(info.state)) _ = d.Set("instance_count", info.instanceCount) _ = d.Set("create_time", info.createTime) + _ = d.Set("charge_type", info.chargeType) + _ = d.Set("bandwidth_limit_type", info.bandWithLimitType) return nil }) @@ -203,6 +257,19 @@ func resourceTencentCloudCcnUpdate(d *schema.ResourceData, meta interface{}) err d.SetPartial(val) } } + // modify band width limit type + if d.HasChange("bandwidth_limit_type") { + _, news := d.GetChange("bandwidth_limit_type") + if err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + if err := service.ModifyCcnRegionBandwidthLimitsType(ctx, d.Id(), news.(string)); err != nil { + return retryError(err) + } + return nil + }); err != nil { + return err + } + d.SetPartial("bandwidth_limit_type") + } if d.HasChange("tags") { diff --git a/tencentcloud/resource_tc_ccn_bandwidth_limit.go b/tencentcloud/resource_tc_ccn_bandwidth_limit.go index f73f6e942f..a898e10e7f 100644 --- a/tencentcloud/resource_tc_ccn_bandwidth_limit.go +++ b/tencentcloud/resource_tc_ccn_bandwidth_limit.go @@ -3,6 +3,8 @@ Provides a resource to limit CCN bandwidth. Example Usage +Set the upper limit of regional outbound bandwidth + ```hcl variable "other_region1" { default = "ap-shanghai" @@ -20,6 +22,33 @@ resource "tencentcloud_ccn_bandwidth_limit" "limit1" { bandwidth_limit = 500 } ``` + +Set the upper limit between regions + +```hcl +variable "other_region1" { + default = "ap-shanghai" +} + +variable "other_region2" { + default = "ap-nanjing" +} + +resource tencentcloud_ccn main { + name = "ci-temp-test-ccn" + description = "ci-temp-test-ccn-des" + qos = "AG" + bandwidth_limit_type = "INTER_REGION_LIMIT" +} + +resource tencentcloud_ccn_bandwidth_limit limit1 { + ccn_id = tencentcloud_ccn.main.id + region = var.other_region1 + dst_region = var.other_region2 + bandwidth_limit = 100 +} +``` + */ package tencentcloud @@ -57,6 +86,13 @@ func resourceTencentCloudCcnBandwidthLimit() *schema.Resource { Computed: true, Description: "Limitation of bandwidth.", }, + "dst_region": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "Destination area restriction. If the `CCN` rate limit type is `OUTER_REGION_LIMIT`, " + + "this value does not need to be set.", + }, }, } } @@ -81,13 +117,19 @@ func resourceTencentCloudCcnBandwidthLimitCreate(d *schema.ResourceData, meta in if has == 0 { return fmt.Errorf("ccn[%s] doesn't exist", ccnId) } - id := fmt.Sprintf("%s#%s", ccnId, region) - - if limitTemp, ok := d.GetOk("bandwidth_limit"); ok { - if err := service.SetCcnRegionBandwidthLimits(ctx, ccnId, region, int64(limitTemp.(int))); err != nil { - return err - } + var ( + dstRegion string + limit int64 + ) + if v, ok := d.GetOkExists("dst_region"); ok { + dstRegion = v.(string) + } + if v, ok := d.GetOk("bandwidth_limit"); ok { + limit = int64(v.(int)) + } + if err := service.SetCcnRegionBandwidthLimits(ctx, ccnId, region, dstRegion, limit); err != nil { + return err } d.SetId(id) @@ -113,13 +155,16 @@ func resourceTencentCloudCcnBandwidthLimitUpdate(d *schema.ResourceData, meta in if has == 0 { return fmt.Errorf("ccn[%s] doesn't exist", ccnId) } - - if limitTemp, ok := d.GetOk("bandwidth_limit"); ok { - if err := service.SetCcnRegionBandwidthLimits(ctx, ccnId, region, int64(limitTemp.(int))); err != nil { + if d.HasChange("bandwidth_limit") { + var limitTemp int64 + if v, ok := d.GetOk("bandwidth_limit"); ok { + limitTemp = int64(v.(int)) + } + _, dstRegion := d.GetChange("dst_region") + if err := service.SetCcnRegionBandwidthLimits(ctx, ccnId, region, dstRegion.(string), limitTemp); err != nil { return err } } - return resourceTencentCloudCcnBandwidthLimitRead(d, meta) } @@ -135,10 +180,12 @@ func resourceTencentCloudCcnBandwidthLimitRead(d *schema.ResourceData, meta inte var ( ccnId = d.Get("ccn_id").(string) region = d.Get("region").(string) + dstRegion = d.Get("dst_region").(string) onlineHas = true + info CcnBasicInfo ) err := resource.Retry(readRetryTimeout, func() *resource.RetryError { - _, has, e := service.DescribeCcn(ctx, ccnId) + infoTmp, has, e := service.DescribeCcn(ctx, ccnId) if e != nil { return retryError(e) } @@ -148,6 +195,7 @@ func resourceTencentCloudCcnBandwidthLimitRead(d *schema.ResourceData, meta inte onlineHas = false return nil } + info = infoTmp return nil }) if err != nil { @@ -157,11 +205,12 @@ func resourceTencentCloudCcnBandwidthLimitRead(d *schema.ResourceData, meta inte return nil } err = resource.Retry(readRetryTimeout, func() *resource.RetryError { - bandwidth, e := service.DescribeCcnRegionBandwidthLimit(ctx, ccnId, region) + bandwidth, e := service.GetCcnRegionBandwidthLimit(ctx, ccnId, region, dstRegion, info.bandWithLimitType) if e != nil { return retryError(e) } _ = d.Set("bandwidth_limit", bandwidth) + _ = d.Set("dst_region", dstRegion) return nil }) if err != nil { diff --git a/tencentcloud/resource_tc_ccn_bandwidth_limit_test.go b/tencentcloud/resource_tc_ccn_bandwidth_limit_test.go index 299c018e92..d52cbf8da9 100644 --- a/tencentcloud/resource_tc_ccn_bandwidth_limit_test.go +++ b/tencentcloud/resource_tc_ccn_bandwidth_limit_test.go @@ -9,27 +9,60 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/terraform" ) -func TestAccTencentCloudCcnV3BandwidthLimitBasic(t *testing.T) { +const keyNameLimit1 = "tencentcloud_ccn_bandwidth_limit.limit1" - keyNameLimit1 := "tencentcloud_ccn_bandwidth_limit.limit1" - keyNameLimit2 := "tencentcloud_ccn_bandwidth_limit.limit2" +func TestAccTencentCloudCcnV3BandwidthLimitOuter(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckCcnBandwidthLimitDestroy, Steps: []resource.TestStep{ { - Config: testAccCcnBandwidthLimitConfig, + Config: testAccCcnOuterBandwidthLimitConfig, Check: resource.ComposeTestCheckFunc( testAccCheckCcnBandwidthLimitExists(keyNameLimit1), - testAccCheckCcnBandwidthLimitExists(keyNameLimit2), resource.TestCheckResourceAttrSet(keyNameLimit1, "ccn_id"), resource.TestCheckResourceAttrSet(keyNameLimit1, "region"), resource.TestCheckResourceAttr(keyNameLimit1, "bandwidth_limit", "500"), + ), + }, + { + Config: testAccCcnOuterBandwidthLimitConfigUpdate, + Check: resource.ComposeTestCheckFunc( + testAccCheckCcnBandwidthLimitExists(keyNameLimit1), + resource.TestCheckResourceAttrSet(keyNameLimit1, "ccn_id"), + resource.TestCheckResourceAttrSet(keyNameLimit1, "region"), + resource.TestCheckResourceAttr(keyNameLimit1, "bandwidth_limit", "100"), + ), + }, + }, + }) +} - resource.TestCheckResourceAttrSet(keyNameLimit2, "ccn_id"), - resource.TestCheckResourceAttrSet(keyNameLimit2, "region"), - resource.TestCheckResourceAttrSet(keyNameLimit2, "bandwidth_limit"), +func TestAccTencentCloudCcnV3BandwidthLimitInter(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCcnBandwidthLimitDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCcnInterBandwidthLimitConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckCcnBandwidthLimitExists(keyNameLimit1), + resource.TestCheckResourceAttrSet(keyNameLimit1, "ccn_id"), + resource.TestCheckResourceAttrSet(keyNameLimit1, "region"), + resource.TestCheckResourceAttr(keyNameLimit1, "dst_region", "ap-beijing"), + resource.TestCheckResourceAttr(keyNameLimit1, "bandwidth_limit", "500"), + ), + }, + { + Config: testAccCcnInterBandwidthLimitConfigUpdate, + Check: resource.ComposeTestCheckFunc( + testAccCheckCcnBandwidthLimitExists(keyNameLimit1), + resource.TestCheckResourceAttrSet(keyNameLimit1, "ccn_id"), + resource.TestCheckResourceAttrSet(keyNameLimit1, "region"), + resource.TestCheckResourceAttr(keyNameLimit1, "dst_region", "ap-nanjing"), + resource.TestCheckResourceAttr(keyNameLimit1, "bandwidth_limit", "100"), ), }, }, @@ -51,45 +84,101 @@ func testAccCheckCcnBandwidthLimitExists(r string) resource.TestCheckFunc { } service := VpcService{client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn} - - bandwidth, err := service.DescribeCcnRegionBandwidthLimit(ctx, - rs.Primary.Attributes["ccn_id"], - rs.Primary.Attributes["region"]) + ccnID := rs.Primary.Attributes["ccn_id"] + info, has, err := service.DescribeCcn(ctx, ccnID) + if err != nil { + return err + } + if has == 0 { + return fmt.Errorf("ccn instance not exists") + } + bandwidth, err := service.GetCcnRegionBandwidthLimit(ctx, + ccnID, + rs.Primary.Attributes["region"], + rs.Primary.Attributes["dst_region"], + info.bandWithLimitType) if err != nil { return err } if fmt.Sprintf("%d", bandwidth) != rs.Primary.Attributes["bandwidth_limit"] { - return fmt.Errorf("ccn attachment not exists.") + return fmt.Errorf("ccn attachment not exists") } return nil } } -const testAccCcnBandwidthLimitConfig = ` +const ccnOuterBase = ` +resource tencentcloud_ccn main { + name = "ci-temp-test-ccn" + description = "ci-temp-test-ccn-des" + qos = "AG" +}` + +const testAccCcnOuterBandwidthLimitConfig = ccnOuterBase + ` +variable "other_region1" { + default = "ap-shanghai" +} + +resource tencentcloud_ccn_bandwidth_limit limit1 { + ccn_id = tencentcloud_ccn.main.id + region = var.other_region1 + bandwidth_limit = 500 +} +` + +const testAccCcnOuterBandwidthLimitConfigUpdate = ccnOuterBase + ` variable "other_region1" { default = "ap-shanghai" } -variable "other_region2" { - default = "ap-beijing" +resource tencentcloud_ccn_bandwidth_limit limit1 { + ccn_id = tencentcloud_ccn.main.id + region = var.other_region1 + bandwidth_limit = 100 } +` +const ccnInterBase = ` resource tencentcloud_ccn main { - name = "ci-temp-test-ccn" - description = "ci-temp-test-ccn-des" - qos = "AG" + name = "ci-temp-test-ccn" + description = "ci-temp-test-ccn-des" + qos = "AG" + bandwidth_limit_type = "INTER_REGION_LIMIT" +} +` + +const testAccCcnInterBandwidthLimitConfig = ccnInterBase + ` +variable "other_region1" { + default = "ap-shanghai" +} + +variable "other_region2" { + default = "ap-beijing" } resource tencentcloud_ccn_bandwidth_limit limit1 { ccn_id = tencentcloud_ccn.main.id region = var.other_region1 + dst_region = var.other_region2 bandwidth_limit = 500 } +` + +const testAccCcnInterBandwidthLimitConfigUpdate = ccnInterBase + ` +variable "other_region1" { + default = "ap-shanghai" +} + +variable "other_region2" { + default = "ap-nanjing" +} -resource tencentcloud_ccn_bandwidth_limit limit2 { - ccn_id = tencentcloud_ccn.main.id - region = var.other_region2 +resource tencentcloud_ccn_bandwidth_limit limit1 { + ccn_id = tencentcloud_ccn.main.id + region = var.other_region1 + dst_region = var.other_region2 + bandwidth_limit = 100 } ` diff --git a/tencentcloud/resource_tc_ccn_test.go b/tencentcloud/resource_tc_ccn_test.go index 7d688d57c0..2edfa14dd5 100644 --- a/tencentcloud/resource_tc_ccn_test.go +++ b/tencentcloud/resource_tc_ccn_test.go @@ -24,7 +24,6 @@ func TestAccTencentCloudCcnV3Basic(t *testing.T) { resource.TestCheckResourceAttr(keyName, "name", "ci-temp-test-ccn"), resource.TestCheckResourceAttr(keyName, "description", "ci-temp-test-ccn-des"), resource.TestCheckResourceAttr(keyName, "instance_count", "0"), - resource.TestCheckResourceAttr(keyName, "qos", "AG"), resource.TestCheckResourceAttrSet(keyName, "state"), resource.TestCheckResourceAttrSet(keyName, "create_time"), @@ -78,7 +77,6 @@ func TestAccTencentCloudCcnV3Update(t *testing.T) { resource.TestCheckResourceAttr(keyName, "name", "ci-temp-test-ccn"), resource.TestCheckResourceAttr(keyName, "description", "ci-temp-test-ccn-des"), resource.TestCheckResourceAttr(keyName, "instance_count", "0"), - resource.TestCheckResourceAttr(keyName, "qos", "AG"), resource.TestCheckResourceAttrSet(keyName, "state"), resource.TestCheckResourceAttrSet(keyName, "create_time"), @@ -87,12 +85,10 @@ func TestAccTencentCloudCcnV3Update(t *testing.T) { { Config: testAccCcnConfigUpdate, Check: resource.ComposeTestCheckFunc( - testAccCheckCcnExists(keyName), resource.TestCheckResourceAttr(keyName, "name", "ci-temp-test-ccn-update"), resource.TestCheckResourceAttr(keyName, "description", "ci-temp-test-ccn-des-update"), resource.TestCheckResourceAttr(keyName, "instance_count", "0"), - resource.TestCheckResourceAttr(keyName, "qos", "AG"), resource.TestCheckResourceAttrSet(keyName, "state"), resource.TestCheckResourceAttrSet(keyName, "create_time"), @@ -147,14 +143,6 @@ func testAccCheckCcnDestroy(s *terraform.State) error { return nil } -const testAccCcnConfig = ` -resource tencentcloud_ccn main { - name = "ci-temp-test-ccn" - description = "ci-temp-test-ccn-des" - qos = "AG" -} -` - func testAccCcn_multiTags(value string) string { return fmt.Sprintf( ` @@ -169,10 +157,18 @@ resource tencentcloud_ccn main { `, value) } +const testAccCcnConfig = ` +resource tencentcloud_ccn main { + name = "ci-temp-test-ccn" + description = "ci-temp-test-ccn-des" + qos = "AG" +} +` + const testAccCcnConfigUpdate = ` resource tencentcloud_ccn main { - name = "ci-temp-test-ccn-update" - description = "ci-temp-test-ccn-des-update" - qos = "AG" + name = "ci-temp-test-ccn-update" + description = "ci-temp-test-ccn-des-update" + qos = "AG" } ` diff --git a/tencentcloud/service_tencentcloud_ccn.go b/tencentcloud/service_tencentcloud_ccn.go index e1a334d22f..7198ecf0c4 100644 --- a/tencentcloud/service_tencentcloud_ccn.go +++ b/tencentcloud/service_tencentcloud_ccn.go @@ -13,13 +13,15 @@ import ( //Ccn basic information type CcnBasicInfo struct { - ccnId string - name string - description string - state string - qos string - instanceCount int64 - createTime string + ccnId string + name string + description string + state string + qos string + chargeType string + bandWithLimitType string + instanceCount int64 + createTime string } type CcnAttachedInstanceInfo struct { @@ -126,11 +128,12 @@ getMoreData: basicInfo.ccnId = *item.CcnId basicInfo.name = *item.CcnName basicInfo.createTime = *item.CreateTime - basicInfo.description = *item.CcnDescription basicInfo.instanceCount = int64(*item.InstanceCount) basicInfo.qos = *item.QosLevel basicInfo.state = *item.State + basicInfo.chargeType = *item.InstanceChargeType + basicInfo.bandWithLimitType = *item.BandwidthLimitType if has[basicInfo.ccnId] { errRet = fmt.Errorf("get repeated ccn_id[%s] when doing DescribeCcns", basicInfo.ccnId) @@ -189,7 +192,8 @@ func (me *VpcService) DescribeCcnRegionBandwidthLimits(ctx context.Context, ccnI return } -func (me *VpcService) CreateCcn(ctx context.Context, name, description, qos string) (basicInfo CcnBasicInfo, errRet error) { +func (me *VpcService) CreateCcn(ctx context.Context, name, description, + qos, chargeType, bandWithLimitType string) (basicInfo CcnBasicInfo, errRet error) { logId := getLogId(ctx) request := vpc.NewCreateCcnRequest() @@ -197,6 +201,8 @@ func (me *VpcService) CreateCcn(ctx context.Context, name, description, qos stri request.CcnName = &name request.CcnDescription = &description request.QosLevel = &qos + request.InstanceChargeType = &chargeType + request.BandwidthLimitType = &bandWithLimitType ratelimit.Check(request.GetAction()) response, err := me.client.UseVpcClient().CreateCcn(request) @@ -530,7 +536,8 @@ func (me *VpcService) DetachCcnInstances(ctx context.Context, ccnId, instanceReg } -func (me *VpcService) DescribeCcnRegionBandwidthLimit(ctx context.Context, ccnId, region string) (bandwidth int64, errRet error) { +func (me *VpcService) DescribeCcnRegionBandwidthLimit(ctx context.Context, ccnId, + region string) (bandwidth int64, errRet error) { infos, err := me.DescribeCcnRegionBandwidthLimits(ctx, ccnId) if err != nil { @@ -546,17 +553,83 @@ func (me *VpcService) DescribeCcnRegionBandwidthLimit(ctx context.Context, ccnId return } -func (me *VpcService) SetCcnRegionBandwidthLimits(ctx context.Context, ccnId, region string, bandwidth int64) (errRet error) { +func (me *VpcService) GetCcnRegionBandwidthLimit(ctx context.Context, ccnId, + region, dstRegion, limitType string) (int64, error) { + infos, err := me.GetCcnRegionBandwidthLimits(ctx, ccnId) + if err != nil { + return 0, err + } + for _, v := range infos { + if v.Region != nil { + switch limitType { + case OuterRegionLimit: + if *v.Region == region { + return int64(*v.BandwidthLimit), nil + } + case InterRegionLimit: + if v.DstRegion != nil && *v.DstRegion == dstRegion && *v.Region == region { + return int64(*v.BandwidthLimit), nil + } + default: + return 0, fmt.Errorf("unknown type of band with limit type") + } + } + } + return 0, nil +} + +func (me *VpcService) GetCcnRegionBandwidthLimits(ctx context.Context, + ccnID string) (infos []vpc.CcnRegionBandwidthLimit, errRet error) { + var ( + request = vpc.NewGetCcnRegionBandwidthLimitsRequest() + response *vpc.GetCcnRegionBandwidthLimitsResponse + err error + limit uint64 = 100 + offset uint64 = 0 + ) + request.CcnId = &ccnID + request.Limit = &limit + request.Offset = &offset + + ratelimit.Check(request.GetAction()) + for { + response, err = me.client.UseVpcClient().GetCcnRegionBandwidthLimits(request) + if err != nil { + errRet = err + return + } + if response.Response == nil || response.Response.CcnBandwidthSet == nil { + errRet = fmt.Errorf("TencentCloud SDK %s return empty response", request.GetAction()) + return + } + + for _, item := range response.Response.CcnBandwidthSet { + if item.CcnRegionBandwidthLimit != nil { + infos = append(infos, *item.CcnRegionBandwidthLimit) + } + } + if len(response.Response.CcnBandwidthSet) < int(limit) { + break + } + offset += limit + } + return +} + +func (me *VpcService) SetCcnRegionBandwidthLimits(ctx context.Context, ccnId, region, dstRegion string, + bandwidth int64) (errRet error) { logId := getLogId(ctx) request := vpc.NewSetCcnRegionBandwidthLimitsRequest() request.CcnId = &ccnId var uint64bandwidth = uint64(bandwidth) - var ccnRegionBandwidthLimit vpc.CcnRegionBandwidthLimit ccnRegionBandwidthLimit.BandwidthLimit = &uint64bandwidth ccnRegionBandwidthLimit.Region = ®ion + if dstRegion != "" { + ccnRegionBandwidthLimit.DstRegion = &dstRegion + } request.CcnRegionBandwidthLimits = []*vpc.CcnRegionBandwidthLimit{&ccnRegionBandwidthLimit} ratelimit.Check(request.GetAction()) @@ -588,3 +661,14 @@ func (me *VpcService) SetCcnRegionBandwidthLimits(ctx context.Context, ccnId, re response.ToJsonString()) return } + +func (me *VpcService) ModifyCcnRegionBandwidthLimitsType(ctx context.Context, ccnID, limitType string) error { + request := vpc.NewModifyCcnRegionBandwidthLimitsTypeRequest() + request.CcnId = &ccnID + request.BandwidthLimitType = &limitType + _, err := me.client.UseVpcClient().ModifyCcnRegionBandwidthLimitsType(request) + if err != nil { + return err + } + return nil +} diff --git a/website/docs/d/ccn_bandwidth_limits.html.markdown b/website/docs/d/ccn_bandwidth_limits.html.markdown index 79932f47b6..e7ebca1896 100644 --- a/website/docs/d/ccn_bandwidth_limits.html.markdown +++ b/website/docs/d/ccn_bandwidth_limits.html.markdown @@ -48,6 +48,7 @@ In addition to all arguments above, the following attributes are exported: * `limits` - The bandwidth limits of regions: * `bandwidth_limit` - Limitation of bandwidth. + * `dst_region` - Destination area restriction. * `region` - Limitation of region. diff --git a/website/docs/d/ccn_instances.html.markdown b/website/docs/d/ccn_instances.html.markdown index 42ee97ff37..d4fbb0628a 100644 --- a/website/docs/d/ccn_instances.html.markdown +++ b/website/docs/d/ccn_instances.html.markdown @@ -49,7 +49,9 @@ In addition to all arguments above, the following attributes are exported: * `instance_region` - The region that the instance locates at. * `instance_type` - Type of attached instance network, and available values include VPC, DIRECTCONNECT, BMVPC and VPNGW. * `state` - States of instance is attached, and available values include PENDING, ACTIVE, EXPIRED, REJECTED, DELETED, FAILED(asynchronous forced disassociation after 2 hours), ATTACHING, DETACHING and DETACHFAILED(asynchronous forced disassociation after 2 hours). + * `bandwidth_limit_type` - The speed limit type. * `ccn_id` - ID of the CCN. + * `charge_type` - Billing mode. * `create_time` - Creation time of resource. * `description` - Description of the CCN. * `name` - Name of the CCN. diff --git a/website/docs/r/ccn.html.markdown b/website/docs/r/ccn.html.markdown index b085cc237a..0a5bb95439 100644 --- a/website/docs/r/ccn.html.markdown +++ b/website/docs/r/ccn.html.markdown @@ -13,11 +13,39 @@ Provides a resource to create a CCN instance. ## Example Usage +Create a prepaid CCN + +```hcl +resource "tencentcloud_ccn" "main" { + name = "ci-temp-test-ccn" + description = "ci-temp-test-ccn-des" + qos = "AG" + charge_type = "PREPAID" + bandwidth_limit_type = "INTER_REGION_LIMIT" +} +``` + +Create a post-paid regional export speed limit type CCN + +```hcl +resource "tencentcloud_ccn" "main" { + name = "ci-temp-test-ccn" + description = "ci-temp-test-ccn-des" + qos = "AG" + charge_type = "POSTPAID" + bandwidth_limit_type = "OUTER_REGION_LIMIT" +} +``` + +Create a post-paid inter-regional rate limit type CNN + ```hcl resource "tencentcloud_ccn" "main" { - name = "ci-temp-test-ccn" - description = "ci-temp-test-ccn-des" - qos = "AG" + name = "ci-temp-test-ccn" + description = "ci-temp-test-ccn-des" + qos = "AG" + charge_type = "POSTPAID" + bandwidth_limit_type = "INTER_REGION_LIMIT" } ``` @@ -26,6 +54,8 @@ resource "tencentcloud_ccn" "main" { The following arguments are supported: * `name` - (Required) Name of the CCN to be queried, and maximum length does not exceed 60 bytes. +* `bandwidth_limit_type` - (Optional) The speed limit type. Valid values: `INTER_REGION_LIMIT`, `OUTER_REGION_LIMIT`. `OUTER_REGION_LIMIT` represents the regional export speed limit, `INTER_REGION_LIMIT` is the inter-regional speed limit. The default is `OUTER_REGION_LIMIT`. +* `charge_type` - (Optional, ForceNew) Billing mode. Valid values: `PREPAID`, `POSTPAID`. `PREPAID` means prepaid, which means annual and monthly subscription, `POSTPAID` means post-payment, which means billing by volume. The default is `POSTPAID`. The prepaid model only supports inter-regional speed limit, and the post-paid model supports inter-regional speed limit and regional export speed limit. * `description` - (Optional) Description of CCN, and maximum length does not exceed 100 bytes. * `qos` - (Optional, ForceNew) Service quality of CCN. Valid values: `PT`, `AU`, `AG`. The default is `AU`. * `tags` - (Optional) Instance tag. diff --git a/website/docs/r/ccn_bandwidth_limit.html.markdown b/website/docs/r/ccn_bandwidth_limit.html.markdown index a3fdcd139c..bdfe7fe221 100644 --- a/website/docs/r/ccn_bandwidth_limit.html.markdown +++ b/website/docs/r/ccn_bandwidth_limit.html.markdown @@ -13,6 +13,8 @@ Provides a resource to limit CCN bandwidth. ## Example Usage +Set the upper limit of regional outbound bandwidth + ```hcl variable "other_region1" { default = "ap-shanghai" @@ -31,6 +33,32 @@ resource "tencentcloud_ccn_bandwidth_limit" "limit1" { } ``` +Set the upper limit between regions + +```hcl +variable "other_region1" { + default = "ap-shanghai" +} + +variable "other_region2" { + default = "ap-nanjing" +} + +resource tencentcloud_ccn main { + name = "ci-temp-test-ccn" + description = "ci-temp-test-ccn-des" + qos = "AG" + bandwidth_limit_type = "INTER_REGION_LIMIT" +} + +resource tencentcloud_ccn_bandwidth_limit limit1 { + ccn_id = tencentcloud_ccn.main.id + region = var.other_region1 + dst_region = var.other_region2 + bandwidth_limit = 100 +} +``` + ## Argument Reference The following arguments are supported: @@ -38,6 +66,7 @@ The following arguments are supported: * `ccn_id` - (Required, ForceNew) ID of the CCN. * `region` - (Required, ForceNew) Limitation of region. * `bandwidth_limit` - (Optional) Limitation of bandwidth. +* `dst_region` - (Optional, ForceNew) Destination area restriction. If the `CCN` rate limit type is `OUTER_REGION_LIMIT`, this value does not need to be set. ## Attributes Reference