From 3d059a8501d5df5607780891df50335569282c4f Mon Sep 17 00:00:00 2001 From: SevenEarth <391613297@qq.com> Date: Sat, 6 May 2023 18:12:27 +0800 Subject: [PATCH 01/10] feat/support-apigw-apidoc & apiapp --- examples/tencentcloud-api-gateway/main.tf | 7 + .../data_source_tc_api_gateway_api_apps.go | 171 ++++++++ ...ata_source_tc_api_gateway_api_apps_test.go | 48 +++ .../data_source_tc_api_gateway_api_docs.go | 115 ++++++ ...ata_source_tc_api_gateway_api_docs_test.go | 33 ++ tencentcloud/extension_api_gateway.go | 6 + tencentcloud/provider.go | 4 + .../resource_tc_api_gateway_api_app.go | 240 +++++++++++ .../resource_tc_api_gateway_api_app_test.go | 120 ++++++ .../resource_tc_api_gateway_api_doc.go | 386 ++++++++++++++++++ .../resource_tc_api_gateway_api_doc_test.go | 122 ++++++ .../service_tencentcloud_api_gateway.go | 224 ++++++++++ 12 files changed, 1476 insertions(+) create mode 100644 tencentcloud/data_source_tc_api_gateway_api_apps.go create mode 100644 tencentcloud/data_source_tc_api_gateway_api_apps_test.go create mode 100644 tencentcloud/data_source_tc_api_gateway_api_docs.go create mode 100644 tencentcloud/data_source_tc_api_gateway_api_docs_test.go create mode 100644 tencentcloud/resource_tc_api_gateway_api_app.go create mode 100644 tencentcloud/resource_tc_api_gateway_api_app_test.go create mode 100644 tencentcloud/resource_tc_api_gateway_api_doc.go create mode 100644 tencentcloud/resource_tc_api_gateway_api_doc_test.go diff --git a/examples/tencentcloud-api-gateway/main.tf b/examples/tencentcloud-api-gateway/main.tf index 6ffde31e3c..17d1dbabc3 100644 --- a/examples/tencentcloud-api-gateway/main.tf +++ b/examples/tencentcloud-api-gateway/main.tf @@ -102,6 +102,13 @@ resource "tencentcloud_api_gateway_strategy_attachment" "test"{ bind_api_id = tencentcloud_api_gateway_api.api.id } +resource "tencentcloud_api_gateway_api_doc" "my_api_doc" { + api_doc_name = "create_doc_test" + service_id = tencentcloud_api_gateway_service_release.service.service_id + environment = "release" + api_ids = [tencentcloud_api_gateway_api.api.id] +} + data "tencentcloud_api_gateway_api_keys" "name" { secret_name = tencentcloud_api_gateway_api_key.test.secret_name } diff --git a/tencentcloud/data_source_tc_api_gateway_api_apps.go b/tencentcloud/data_source_tc_api_gateway_api_apps.go new file mode 100644 index 0000000000..47f984bd27 --- /dev/null +++ b/tencentcloud/data_source_tc_api_gateway_api_apps.go @@ -0,0 +1,171 @@ +/* +Use this data source to query list information of api_gateway api_app + +Example Usage + +```hcl +data "tencentcloud_api_gateway_api_apps" "test" { + api_app_id = ["app-rj8t6zx3"] + api_app_name = ["app_test"] +} +``` +*/ + +package tencentcloud + +import ( + "context" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + apigateway "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/apigateway/v20180808" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" +) + +func dataSourceTencentCloudAPIGatewayAPIApps() *schema.Resource { + return &schema.Resource{ + Read: dataSourceTencentCloudAPIGatewayAPIAppsRead, + Schema: map[string]*schema.Schema{ + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, + + "api_app_id": { + Type: schema.TypeString, + Optional: true, + Description: "Api app ID.", + }, + + "api_app_name": { + Type: schema.TypeString, + Optional: true, + Description: "Api app name.", + }, + + "api_app_list": { + Type: schema.TypeList, + Computed: true, + Description: "List of ApiApp.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "api_app_id": { + Type: schema.TypeString, + Computed: true, + Description: "ApiApp ID.", + }, + "api_app_name": { + Type: schema.TypeString, + Computed: true, + Description: "ApiApp Name.", + }, + "api_app_key": { + Type: schema.TypeString, + Computed: true, + Description: "ApiApp key.", + }, + "api_app_secret": { + Type: schema.TypeString, + Computed: true, + Description: "ApiApp secret.", + }, + "created_time": { + Type: schema.TypeString, + Computed: true, + Description: "ApiApp create time.", + }, + "modified_time": { + Type: schema.TypeString, + Computed: true, + Description: "ApiApp modified time.", + }, + "api_app_desc": { + Type: schema.TypeString, + Computed: true, + Description: "ApiApp description.", + }, + }, + }, + }, + }, + } +} + +func dataSourceTencentCloudAPIGatewayAPIAppsRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("data_source.tencentcloud_api_gateway_api_apps.read")() + defer inconsistentCheck(d, meta)() + + var ( + logId = getLogId(contextNil) + ctx = context.WithValue(context.TODO(), logIdKey, logId) + apiGatewayService = APIGatewayService{client: meta.(*TencentCloudClient).apiV3Conn} + apiAppId, apiAppName string + apiApps []*apigateway.ApiAppInfo + ) + + if v, ok := d.GetOk("api_app_id"); ok { + apiAppId = v.(string) + } + + if v, ok := d.GetOk("api_app_name"); ok { + apiAppName = v.(string) + } + + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + result, e := apiGatewayService.DescribeApiAppList(ctx, apiAppId, apiAppName) + if e != nil { + return retryError(e) + } + apiApps = result + return nil + }) + + if err != nil { + log.Printf("[CRITAL]%s read api_gateway apiApps failed, reason:%+v", logId, err) + return err + } + + apiAppList := []interface{}{} + ids := make([]string, 0, len(apiApps)) + if apiApps != nil { + for _, item := range apiApps { + docMap := map[string]interface{}{} + if item.ApiAppId != nil { + docMap["api_app_id"] = item.ApiAppId + } + if item.ApiAppName != nil { + docMap["api_app_name"] = item.ApiAppName + } + if item.ApiAppKey != nil { + docMap["api_app_key"] = item.ApiAppKey + } + if item.ApiAppSecret != nil { + docMap["api_app_secret"] = item.ApiAppSecret + } + if item.CreatedTime != nil { + docMap["created_time"] = item.CreatedTime + } + if item.ModifiedTime != nil { + docMap["modified_time"] = item.ModifiedTime + } + if item.ApiAppDesc != nil { + docMap["api_app_desc"] = item.ApiAppDesc + } + apiAppList = append(apiAppList, docMap) + ids = append(ids, *item.ApiAppId) + } + _ = d.Set("api_app_list", apiAppList) + } + + d.SetId(helper.DataResourceIdsHash(ids)) + output, ok := d.GetOk("result_output_file") + if ok && output.(string) != "" { + if e := writeToFile(output.(string), apiAppList); e != nil { + return e + } + } + + return nil +} diff --git a/tencentcloud/data_source_tc_api_gateway_api_apps_test.go b/tencentcloud/data_source_tc_api_gateway_api_apps_test.go new file mode 100644 index 0000000000..4a76fa579e --- /dev/null +++ b/tencentcloud/data_source_tc_api_gateway_api_apps_test.go @@ -0,0 +1,48 @@ +package tencentcloud + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +var testAPIGatewayAPIAppsResourceName = "data.tencentcloud_api_gateway_api_apps" + +// go test -i; go test -test.run TestAccTencentAPIGatewayAPIAppsDataSource_basic -v +func TestAccTencentAPIGatewayAPIAppsDataSource_basic(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAPIGatewayAPIAppDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTestAccTencentAPIGatewayAPIApps(), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAPIGatewayAPIAppExists(testAPIGatewayAPIAppResourceName+".test"), + resource.TestCheckResourceAttr(testAPIGatewayAPIAppsResourceName+".test", "api_app_list.#", "1"), + resource.TestCheckResourceAttrSet(testAPIGatewayAPIAppsResourceName+".test", "api_app_list.0.api_app_id"), + resource.TestCheckResourceAttrSet(testAPIGatewayAPIAppsResourceName+".test", "api_app_list.0.api_app_name"), + resource.TestCheckResourceAttrSet(testAPIGatewayAPIAppsResourceName+".test", "api_app_list.0.api_app_key"), + resource.TestCheckResourceAttrSet(testAPIGatewayAPIAppsResourceName+".test", "api_app_list.0.api_app_secret"), + resource.TestCheckResourceAttrSet(testAPIGatewayAPIAppsResourceName+".test", "api_app_list.0.created_time"), + resource.TestCheckResourceAttrSet(testAPIGatewayAPIAppsResourceName+".test", "api_app_list.0.modified_time"), + resource.TestCheckResourceAttrSet(testAPIGatewayAPIAppsResourceName+".test", "api_app_list.0.api_app_desc"), + ), + }, + }, + }) +} + +func testAccTestAccTencentAPIGatewayAPIApps() string { + return ` +resource "tencentcloud_api_gateway_api_app" "test" { + api_app_name = "app_test1" + api_app_desc = "create app desc" +} + +data "tencentcloud_api_gateway_api_apps" "test" { + api_app_id = tencentcloud_api_gateway_api_app.test.id +} +` +} diff --git a/tencentcloud/data_source_tc_api_gateway_api_docs.go b/tencentcloud/data_source_tc_api_gateway_api_docs.go new file mode 100644 index 0000000000..e1cbb2c9ff --- /dev/null +++ b/tencentcloud/data_source_tc_api_gateway_api_docs.go @@ -0,0 +1,115 @@ +/* +Use this data source to query list information of api_gateway api_doc +Example Usage +```hcl +data "tencentcloud_api_gateway_api_docs" "my_api_doc" { +} +``` +*/ + +package tencentcloud + +import ( + "context" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + apigateway "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/apigateway/v20180808" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" +) + +func dataSourceTencentCloudAPIGatewayAPIDocs() *schema.Resource { + return &schema.Resource{ + Read: dataSourceTencentCloudAPIGatewayAPIDocsRead, + Schema: map[string]*schema.Schema{ + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, + + "api_doc_list": { + Type: schema.TypeList, + Computed: true, + Description: "List of ApiDocs.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "api_doc_id": { + Type: schema.TypeString, + Computed: true, + Description: "Api Doc ID.", + }, + "api_doc_name": { + Type: schema.TypeString, + Computed: true, + Description: "Api Doc Name.", + }, + "api_doc_status": { + Type: schema.TypeString, + Computed: true, + Description: "Api Doc Status.", + }, + }, + }, + }, + }, + } +} + +func dataSourceTencentCloudAPIGatewayAPIDocsRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("data_source.tencentcloud_api_gateway_api_docs.read")() + defer inconsistentCheck(d, meta)() + + var ( + logId = getLogId(contextNil) + ctx = context.WithValue(context.TODO(), logIdKey, logId) + apiGatewayService = APIGatewayService{client: meta.(*TencentCloudClient).apiV3Conn} + apiDoc []*apigateway.APIDoc + ) + + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + results, e := apiGatewayService.DescribeApiDocList(ctx) + if e != nil { + return retryError(e) + } + + apiDoc = results + return nil + }) + + if err != nil { + log.Printf("[CRITAL]%s read api_gateway apiDocs failed, reason:%+v", logId, err) + return err + } + + apiDocList := []interface{}{} + ids := make([]string, 0, len(apiDoc)) + if apiDoc != nil { + for _, item := range apiDoc { + docMap := map[string]interface{}{} + if item.ApiDocId != nil { + docMap["api_doc_id"] = item.ApiDocId + } + if item.ApiDocName != nil { + docMap["api_doc_name"] = item.ApiDocName + } + if item.ApiDocStatus != nil { + docMap["api_doc_status"] = item.ApiDocStatus + } + apiDocList = append(apiDocList, docMap) + ids = append(ids, *item.ApiDocId) + } + _ = d.Set("api_doc_list", apiDocList) + } + + d.SetId(helper.DataResourceIdsHash(ids)) + output, ok := d.GetOk("result_output_file") + if ok && output.(string) != "" { + if e := writeToFile(output.(string), apiDocList); e != nil { + return e + } + } + + return nil +} diff --git a/tencentcloud/data_source_tc_api_gateway_api_docs_test.go b/tencentcloud/data_source_tc_api_gateway_api_docs_test.go new file mode 100644 index 0000000000..2511047e54 --- /dev/null +++ b/tencentcloud/data_source_tc_api_gateway_api_docs_test.go @@ -0,0 +1,33 @@ +package tencentcloud + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +var testAPIGatewayAPIDocsResourceName = "data.tencentcloud_api_gateway_api_docs" + +// go test -i; go test -test.run TestAccTencentAPIGatewayAPIDocsDataSource_basic -v +func TestAccTencentAPIGatewayAPIDocsDataSource_basic(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAPIGatewayAPIDocDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTestAccTencentAPIGatewayAPIDocs, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet(testAPIGatewayAPIDocsResourceName+".test", "api_doc_list.#"), + ), + }, + }, + }) +} + +const testAccTestAccTencentAPIGatewayAPIDocs = ` +data "tencentcloud_api_gateway_api_docs" "test" { + +} +` diff --git a/tencentcloud/extension_api_gateway.go b/tencentcloud/extension_api_gateway.go index 6e387daaab..d9b2457641 100644 --- a/tencentcloud/extension_api_gateway.go +++ b/tencentcloud/extension_api_gateway.go @@ -74,6 +74,12 @@ const ( DOMAIN_BIND_SERVICE = "FailedOperation.DomainAlreadyBindService" ) +const ( + API_GATEWAY_API_DOC_STATUS_PROCESSING = "PROCESSING" + API_GATEWAY_API_DOC_STATUS_COMPLETED = "COMPLETED" + API_GATEWAY_API_DOC_STATUS_FAIL = "FAIL" +) + var API_GATEWAY_KEYS = []string{ API_GATEWAY_KEY_ENABLED, API_GATEWAY_KEY_DISABLED, diff --git a/tencentcloud/provider.go b/tencentcloud/provider.go index 2c2a75ed01..70ae838aaa 100644 --- a/tencentcloud/provider.go +++ b/tencentcloud/provider.go @@ -1500,6 +1500,8 @@ func Provider() *schema.Provider { "tencentcloud_tsf_microservice": dataSourceTencentCloudTsfMicroservice(), "tencentcloud_tsf_unit_rules": dataSourceTencentCloudTsfUnitRules(), "tencentcloud_lighthouse_bundle": dataSourceTencentCloudLighthouseBundle(), + "tencentcloud_api_gateway_api_docs": dataSourceTencentCloudAPIGatewayAPIDocs(), + "tencentcloud_api_gateway_api_apps": dataSourceTencentCloudAPIGatewayAPIApps(), }, ResourcesMap: map[string]*schema.Resource{ @@ -1983,6 +1985,8 @@ func Provider() *schema.Provider { "tencentcloud_lighthouse_key_pair": resourceTencentCloudLighthouseKeyPair(), "tencentcloud_lighthouse_snapshot": resourceTencentCloudLighthouseSnapshot(), "tencentcloud_lighthouse_apply_instance_snapshot": resourceTencentCloudLighthouseApplyInstanceSnapshot(), + "tencentcloud_api_gateway_api_doc": resourceTencentCloudAPIGatewayAPIDoc(), + "tencentcloud_api_gateway_api_app": resourceTencentCloudAPIGatewayAPIApp(), }, ConfigureFunc: providerConfigure, diff --git a/tencentcloud/resource_tc_api_gateway_api_app.go b/tencentcloud/resource_tc_api_gateway_api_app.go new file mode 100644 index 0000000000..8210eb96a0 --- /dev/null +++ b/tencentcloud/resource_tc_api_gateway_api_app.go @@ -0,0 +1,240 @@ +/* +Provides a resource to create a APIGateway ApiApp + +Example Usage + +```hcl +resource "tencentcloud_api_gateway_api_app" "my_api_app" { + api_app_name = "app_test1" + api_app_desc = "app desc." +} +``` +*/ + +package tencentcloud + +import ( + "context" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + apiGateway "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/apigateway/v20180808" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" +) + +func resourceTencentCloudAPIGatewayAPIApp() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudAPIGatewayAPIAppCreate, + Read: resourceTencentCloudAPIGatewayAPIAppRead, + Update: resourceTencentCloudAPIGatewayAPIAppUpdate, + Delete: resourceTencentCloudAPIGatewayAPIAppDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "api_app_name": { + Type: schema.TypeString, + Required: true, + Description: "Api app name.", + }, + "api_app_desc": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "App description.", + }, + "api_app_id": { + Type: schema.TypeString, + Computed: true, + Description: "Api app ID.", + }, + "api_app_key": { + Type: schema.TypeString, + Computed: true, + Description: "Api app key.", + }, + "api_app_secret": { + Type: schema.TypeString, + Computed: true, + Description: "Api app secret.", + }, + "created_time": { + Type: schema.TypeString, + Computed: true, + Description: "Api app created time.", + }, + "modified_time": { + Type: schema.TypeString, + Computed: true, + Description: "Api app modified time.", + }, + }, + } +} + +func resourceTencentCloudAPIGatewayAPIAppCreate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_api_gateway_api_app.create")() + defer inconsistentCheck(d, meta)() + + var ( + logId = getLogId(contextNil) + request = apiGateway.NewCreateApiAppRequest() + response *apiGateway.CreateApiAppResponse + apiAppId string + err error + ) + + if v, ok := d.GetOk("api_app_name"); ok { + request.ApiAppName = helper.String(v.(string)) + } + + if v, ok := d.GetOk("api_app_desc"); ok { + request.ApiAppDesc = helper.String(v.(string)) + } + + err = resource.Retry(writeRetryTimeout, func() *resource.RetryError { + result, err := meta.(*TencentCloudClient).apiV3Conn.UseAPIGatewayClient().CreateApiApp(request) + if err != nil { + return retryError(err) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + response = result + return nil + }) + + if err != nil { + log.Printf("[CRITAL]%s create api_app failed, reason:%+v", logId, err) + return err + } + + apiAppId = *response.Response.Result.ApiAppId + d.SetId(apiAppId) + return resourceTencentCloudAPIGatewayAPIAppRead(d, meta) +} + +func resourceTencentCloudAPIGatewayAPIAppRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_api_gateway_api_app.read")() + defer inconsistentCheck(d, meta)() + + var ( + logId = getLogId(contextNil) + ctx = context.WithValue(context.TODO(), logIdKey, logId) + apiGatewayService = APIGatewayService{client: meta.(*TencentCloudClient).apiV3Conn} + apiAppId = d.Id() + apiAppInfo *apiGateway.ApiAppInfos + err error + ) + + err = resource.Retry(writeRetryTimeout, func() *resource.RetryError { + apiAppInfo, err = apiGatewayService.DescribeApiApp(ctx, apiAppId) + if err != nil { + return retryError(err) + } + return nil + }) + + if apiAppInfo == nil { + d.SetId("") + log.Printf("resource `api_app` %s does not exist", apiAppId) + return nil + } + + apiAppData := apiAppInfo.ApiAppSet[0] + if apiAppData.ApiAppId != nil { + _ = d.Set("api_app_id", apiAppData.ApiAppId) + } + + if apiAppData.ApiAppName != nil { + _ = d.Set("api_app_name", apiAppData.ApiAppName) + } + + if apiAppData.ApiAppKey != nil { + _ = d.Set("api_app_key", apiAppData.ApiAppKey) + } + + if apiAppData.ApiAppSecret != nil { + _ = d.Set("api_app_secret", apiAppData.ApiAppSecret) + } + + if apiAppData.CreatedTime != nil { + _ = d.Set("created_time", apiAppData.CreatedTime) + } + + if apiAppData.ModifiedTime != nil { + _ = d.Set("modified_time", apiAppData.ModifiedTime) + } + + if apiAppData.ApiAppDesc != nil { + err = d.Set("api_app_desc", apiAppData.ApiAppDesc) + if err != nil { + return err + } + } + + return nil +} + +func resourceTencentCloudAPIGatewayAPIAppUpdate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_api_gateway_api_app.update")() + defer inconsistentCheck(d, meta)() + + var ( + logId = getLogId(contextNil) + request = apiGateway.NewModifyApiAppRequest() + apiAppId = d.Id() + err error + ) + + request.ApiAppId = &apiAppId + if d.HasChange("api_app_name") { + if v, ok := d.GetOk("api_app_name"); ok { + request.ApiAppName = helper.String(v.(string)) + } + } + + if d.HasChange("api_app_desc") { + if v, ok := d.GetOk("api_app_desc"); ok { + request.ApiAppDesc = helper.String(v.(string)) + } + } + + err = resource.Retry(writeRetryTimeout, func() *resource.RetryError { + result, e := meta.(*TencentCloudClient).apiV3Conn.UseAPIGatewayClient().ModifyApiApp(request) + if e != nil { + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + return nil + }) + + if err != nil { + log.Printf("[CRITAL]%s update api_app failed, reason:%+v", logId, err) + return err + } + + return resourceTencentCloudAPIGatewayAPIAppRead(d, meta) +} + +func resourceTencentCloudAPIGatewayAPIAppDelete(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_api_gateway_api_app.delete")() + defer inconsistentCheck(d, meta)() + + var ( + logId = getLogId(contextNil) + ctx = context.WithValue(context.TODO(), logIdKey, logId) + apiGatewayService = APIGatewayService{client: meta.(*TencentCloudClient).apiV3Conn} + apiAppId = d.Id() + err error + ) + + if err = apiGatewayService.DeleteAPIGatewayAPIAppById(ctx, apiAppId); err != nil { + return err + } + + return nil +} diff --git a/tencentcloud/resource_tc_api_gateway_api_app_test.go b/tencentcloud/resource_tc_api_gateway_api_app_test.go new file mode 100644 index 0000000000..3340444d87 --- /dev/null +++ b/tencentcloud/resource_tc_api_gateway_api_app_test.go @@ -0,0 +1,120 @@ +package tencentcloud + +import ( + "context" + "fmt" + sdkErrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +var testAPIGatewayAPIAppResourceName = "tencentcloud_api_gateway_api_app" +var testAPIGatewayAPIAppResourceKey = testAPIGatewayAPIAppResourceName + ".test" + +// go test -i; go test -test.run TestAccTencentCloudAPIGateWayAPIAppResource_basic -v +func TestAccTencentCloudAPIGateWayAPIAppResource_basic(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAPIGatewayAPIAppDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAPIGatewayAPIApp, + Check: resource.ComposeTestCheckFunc( + testAccCheckAPIGatewayAPIAppExists(testAPIGatewayAPIAppResourceKey), + resource.TestCheckResourceAttrSet(testAPIGatewayAPIAppResourceKey, "api_app_name"), + resource.TestCheckResourceAttr(testAPIGatewayAPIAppResourceKey, "api_app_desc", "app desc"), + ), + }, + { + ResourceName: testAPIGatewayAPIAppResourceKey, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAPIGatewayAPIAppUpdate, + Check: resource.ComposeTestCheckFunc( + testAccCheckAPIGatewayAPIAppExists(testAPIGatewayAPIAppResourceKey), + resource.TestCheckResourceAttr(testAPIGatewayAPIAppResourceKey, "api_app_name", "update_app_name_test"), + resource.TestCheckResourceAttr(testAPIGatewayAPIAppResourceKey, "api_app_desc", "update app desc"), + ), + }, + }, + }) +} + +func testAccCheckAPIGatewayAPIAppDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != testAPIGatewayAPIAppResourceName { + continue + } + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), logIdKey, logId) + + service := APIGatewayService{client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn} + + apiApp, err := service.DescribeApiApp(ctx, rs.Primary.ID) + if err != nil { + if sdkerr, ok := err.(*sdkErrors.TencentCloudSDKError); ok { + if sdkerr.Code == "InvalidParameterValue.InvalidCommandId" { + return nil + } + } + return err + } + + if apiApp != nil { + if *apiApp.TotalCount == 0 { + return nil + } + return fmt.Errorf("api_gateway api_app %s still exists", rs.Primary.ID) + } + } + return nil +} + +func testAccCheckAPIGatewayAPIAppExists(r string) resource.TestCheckFunc { + return func(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), logIdKey, logId) + + rs, ok := s.RootModule().Resources[r] + if !ok { + return fmt.Errorf("resource %s is not found", r) + } + + service := APIGatewayService{client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn} + command, err := service.DescribeApiApp(ctx, rs.Primary.ID) + if err != nil { + if sdkerr, ok := err.(*sdkErrors.TencentCloudSDKError); ok { + if sdkerr.Code == "InvalidParameterValue.InvalidCommandId" { + return nil + } + } + return err + } + + if command == nil { + return fmt.Errorf("api_gateway api_app %s is not found", rs.Primary.ID) + } + + return nil + } +} + +const testAccAPIGatewayAPIApp = ` +resource "tencentcloud_api_gateway_api_app" "test" { + api_app_name = "create_app_test" + api_app_desc = "app desc" +} +` + +const testAccAPIGatewayAPIAppUpdate = ` +resource "tencentcloud_api_gateway_api_app" "test" { + api_app_name = "update_app_name_test" + api_app_desc = "update app desc" +} +` diff --git a/tencentcloud/resource_tc_api_gateway_api_doc.go b/tencentcloud/resource_tc_api_gateway_api_doc.go new file mode 100644 index 0000000000..6ac62e8214 --- /dev/null +++ b/tencentcloud/resource_tc_api_gateway_api_doc.go @@ -0,0 +1,386 @@ +/* +Provides a resource to create a APIGateway ApiDoc + +Example Usage + +```hcl +resource "tencentcloud_api_gateway_api_doc" "my_api_doc" { + api_doc_name = "doc_test1" + service_id = "service_test1" + environment = "release" + api_ids = ["api-test1", "api-test2"] +} +``` +*/ + +package tencentcloud + +import ( + "context" + "fmt" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + apiGateway "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/apigateway/v20180808" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" +) + +func resourceTencentCloudAPIGatewayAPIDoc() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudAPIGatewayAPIDocCreate, + Read: resourceTencentCloudAPIGatewayAPIDocRead, + Update: resourceTencentCloudAPIGatewayAPIDocUpdate, + Delete: resourceTencentCloudAPIGatewayAPIDocDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "api_doc_name": { + Type: schema.TypeString, + Required: true, + Description: "Api Document name.", + }, + "service_id": { + Type: schema.TypeString, + Required: true, + Description: "Service name.", + }, + "environment": { + Type: schema.TypeString, + Required: true, + Description: "Env name.", + }, + "api_ids": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Description: "List of APIs for generating documents.", + }, + "api_doc_id": { + Type: schema.TypeString, + Computed: true, + Description: "Api Document ID.", + }, + "api_count": { + Type: schema.TypeInt, + Computed: true, + Description: "Api Document count.", + }, + "view_count": { + Type: schema.TypeInt, + Computed: true, + Description: "API Document Viewing Times.", + }, + "release_count": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of API document releases.", + }, + "api_doc_uri": { + Type: schema.TypeString, + Computed: true, + Description: "API Document Access URI.", + }, + "share_password": { + Type: schema.TypeString, + Computed: true, + Description: "API Document Sharing Password.", + }, + "api_doc_status": { + Type: schema.TypeString, + Computed: true, + Description: "API Document Build Status.", + }, + "updated_time": { + Type: schema.TypeString, + Computed: true, + Description: "API Document update time.", + }, + "service_name": { + Type: schema.TypeString, + Computed: true, + Description: "API Document service name.", + }, + "api_names": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Description: "List of names for generating documents.", + }, + }, + } +} + +func resourceTencentCloudAPIGatewayAPIDocCreate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_api_gateway_api_doc.create")() + defer inconsistentCheck(d, meta)() + + var ( + logId = getLogId(contextNil) + ctx = context.WithValue(context.TODO(), logIdKey, logId) + apiGatewayService = APIGatewayService{client: meta.(*TencentCloudClient).apiV3Conn} + request = apiGateway.NewCreateAPIDocRequest() + response *apiGateway.CreateAPIDocResponse + apiDocId string + err error + ) + + if v, ok := d.GetOk("api_doc_name"); ok { + request.ApiDocName = helper.String(v.(string)) + } + + if v, ok := d.GetOk("service_id"); ok { + request.ServiceId = helper.String(v.(string)) + } + + if v, ok := d.GetOk("environment"); ok { + request.Environment = helper.String(v.(string)) + } + + if v, ok := d.GetOk("api_ids"); ok { + for _, item := range v.(*schema.Set).List() { + id := helper.String(item.(string)) + request.ApiIds = append(request.ApiIds, id) + } + } + + err = resource.Retry(writeRetryTimeout, func() *resource.RetryError { + result, err := meta.(*TencentCloudClient).apiV3Conn.UseAPIGatewayClient().CreateAPIDoc(request) + if err != nil { + return retryError(err) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + response = result + return nil + }) + + if err != nil { + log.Printf("[CRITAL]%s create api_doc failed, reason:%+v", logId, err) + return err + } + + apiDocId = *response.Response.Result.ApiDocId + + err = resource.Retry(writeRetryTimeout, func() *resource.RetryError { + apiDocInfo, err := apiGatewayService.DescribeApiDoc(ctx, apiDocId) + if err != nil { + return retryError(err) + } + if apiDocInfo == nil { + err = fmt.Errorf("api_doc_id %s not exists", apiDocId) + return resource.NonRetryableError(err) + } + if *apiDocInfo.ApiDocStatus == API_GATEWAY_API_DOC_STATUS_PROCESSING { + return resource.RetryableError(fmt.Errorf("create api_doc task status is %s", API_GATEWAY_API_DOC_STATUS_PROCESSING)) + } + if *apiDocInfo.ApiDocStatus == API_GATEWAY_API_DOC_STATUS_COMPLETED { + return nil + } + if *apiDocInfo.ApiDocStatus == API_GATEWAY_API_DOC_STATUS_FAIL { + return resource.NonRetryableError(fmt.Errorf("create api_doc task status is %s", API_GATEWAY_API_DOC_STATUS_PROCESSING)) + } + err = fmt.Errorf("create api_doc task status is %v, we won't wait for it finish", *apiDocInfo.ApiDocStatus) + return resource.NonRetryableError(err) + }) + + if err != nil { + log.Printf("[CRITAL]%s create api_doc task fail, reason:%s\n ", logId, err.Error()) + return err + } + + d.SetId(apiDocId) + + return resourceTencentCloudAPIGatewayAPIDocRead(d, meta) +} + +func resourceTencentCloudAPIGatewayAPIDocRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_api_gateway_api_doc.read")() + defer inconsistentCheck(d, meta)() + + var ( + logId = getLogId(contextNil) + ctx = context.WithValue(context.TODO(), logIdKey, logId) + apiGatewayService = APIGatewayService{client: meta.(*TencentCloudClient).apiV3Conn} + apiDocId = d.Id() + apiDocInfo *apiGateway.APIDocInfo + err error + ) + + apiDocInfo, err = apiGatewayService.DescribeApiDoc(ctx, apiDocId) + if err != nil { + return err + } + + if apiDocInfo == nil { + d.SetId("") + return nil + } + + if apiDocInfo.ApiDocId != nil { + _ = d.Set("api_doc_id", apiDocInfo.ApiDocId) + } + + if apiDocInfo.ApiDocName != nil { + _ = d.Set("api_doc_name", apiDocInfo.ApiDocName) + } + + if apiDocInfo.ApiCount != nil { + _ = d.Set("api_count", apiDocInfo.ApiCount) + } + + if apiDocInfo.ViewCount != nil { + _ = d.Set("view_count", apiDocInfo.ViewCount) + } + + if apiDocInfo.ReleaseCount != nil { + _ = d.Set("release_count", apiDocInfo.ReleaseCount) + } + + if apiDocInfo.ApiDocUri != nil { + _ = d.Set("api_doc_uri", apiDocInfo.ApiDocUri) + } + + if apiDocInfo.SharePassword != nil { + _ = d.Set("share_password", apiDocInfo.SharePassword) + } + + if apiDocInfo.ApiDocStatus != nil { + _ = d.Set("api_doc_status", apiDocInfo.ApiDocStatus) + } + + if apiDocInfo.UpdatedTime != nil { + _ = d.Set("updated_time", apiDocInfo.UpdatedTime) + } + + if apiDocInfo.ServiceId != nil { + _ = d.Set("service_id", apiDocInfo.ServiceId) + } + + if apiDocInfo.ServiceName != nil { + _ = d.Set("service_name", apiDocInfo.ServiceName) + } + + if apiDocInfo.ApiIds != nil { + apiIdsList := []interface{}{} + for _, id := range apiDocInfo.ApiIds { + apiIdsList = append(apiIdsList, id) + } + _ = d.Set("api_ids", apiIdsList) + } + + if apiDocInfo.ApiNames != nil { + apiNameList := []interface{}{} + for _, name := range apiDocInfo.ApiNames { + apiNameList = append(apiNameList, name) + } + _ = d.Set("api_names", apiNameList) + } + + if apiDocInfo.Environment != nil { + _ = d.Set("environment", apiDocInfo.Environment) + } + + return nil +} + +func resourceTencentCloudAPIGatewayAPIDocUpdate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_api_gateway_api_doc.update")() + defer inconsistentCheck(d, meta)() + + var ( + logId = getLogId(contextNil) + ctx = context.WithValue(context.TODO(), logIdKey, logId) + apiGatewayService = APIGatewayService{client: meta.(*TencentCloudClient).apiV3Conn} + request = apiGateway.NewModifyAPIDocRequest() + apiDocId = d.Id() + err error + ) + + request.ApiDocId = &apiDocId + + if v, ok := d.GetOk("api_doc_name"); ok { + request.ApiDocName = helper.String(v.(string)) + } + + if v, ok := d.GetOk("service_id"); ok { + request.ServiceId = helper.String(v.(string)) + } + + if v, ok := d.GetOk("environment"); ok { + request.Environment = helper.String(v.(string)) + } + + if v, ok := d.GetOk("api_ids"); ok { + for _, item := range v.(*schema.Set).List() { + id := helper.String(item.(string)) + request.ApiIds = append(request.ApiIds, id) + } + } + + err = resource.Retry(writeRetryTimeout, func() *resource.RetryError { + result, e := meta.(*TencentCloudClient).apiV3Conn.UseAPIGatewayClient().ModifyAPIDoc(request) + if e != nil { + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + return nil + }) + + if err != nil { + log.Printf("[CRITAL]%s update api_doc failed, reason:%+v", logId, err) + return err + } + + err = resource.Retry(writeRetryTimeout, func() *resource.RetryError { + apiDocInfo, err := apiGatewayService.DescribeApiDoc(ctx, apiDocId) + if err != nil { + return retryError(err) + } + if apiDocInfo == nil { + err = fmt.Errorf("api_doc_id %s not exists", apiDocId) + return resource.NonRetryableError(err) + } + if *apiDocInfo.ApiDocStatus == API_GATEWAY_API_DOC_STATUS_PROCESSING { + return resource.RetryableError(fmt.Errorf("create api_doc task status is %s", API_GATEWAY_API_DOC_STATUS_PROCESSING)) + } + if *apiDocInfo.ApiDocStatus == API_GATEWAY_API_DOC_STATUS_COMPLETED { + return nil + } + if *apiDocInfo.ApiDocStatus == API_GATEWAY_API_DOC_STATUS_FAIL { + return resource.NonRetryableError(fmt.Errorf("create api_doc task status is %s", API_GATEWAY_API_DOC_STATUS_PROCESSING)) + } + err = fmt.Errorf("create api_doc task status is %v, we won't wait for it finish", *apiDocInfo.ApiDocStatus) + return resource.NonRetryableError(err) + }) + + if err != nil { + log.Printf("[CRITAL]%s update api_doc task fail, reason:%s\n ", logId, err.Error()) + return err + } + + return resourceTencentCloudAPIGatewayAPIDocRead(d, meta) +} + +func resourceTencentCloudAPIGatewayAPIDocDelete(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_api_gateway_api_doc.delete")() + defer inconsistentCheck(d, meta)() + + var ( + logId = getLogId(contextNil) + ctx = context.WithValue(context.TODO(), logIdKey, logId) + apiGatewayService = APIGatewayService{client: meta.(*TencentCloudClient).apiV3Conn} + apiDocId = d.Id() + err error + ) + + if err = apiGatewayService.DeleteAPIGatewayAPIDocById(ctx, apiDocId); err != nil { + return err + } + + return nil +} diff --git a/tencentcloud/resource_tc_api_gateway_api_doc_test.go b/tencentcloud/resource_tc_api_gateway_api_doc_test.go new file mode 100644 index 0000000000..8bc06d632c --- /dev/null +++ b/tencentcloud/resource_tc_api_gateway_api_doc_test.go @@ -0,0 +1,122 @@ +package tencentcloud + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + sdkErrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" +) + +var testAPIGatewayAPIDocResourceName = "tencentcloud_api_gateway_api_doc" +var testAPIGatewayAPIDocResourceKey = testAPIGatewayAPIDocResourceName + ".test" + +// go test -i; go test -test.run TestAccTencentCloudAPIGateWayAPIDocResource_basic -v +func TestAccTencentCloudAPIGateWayAPIDocResource_basic(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAPIGatewayAPIDocDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAPIGatewayAPIDoc, + Check: resource.ComposeTestCheckFunc( + testAccCheckAPIGatewayAPIDocExists(testAPIGatewayAPIDocResourceKey), + resource.TestCheckResourceAttrSet(testAPIGatewayAPIDocResourceKey, "api_doc_name"), + resource.TestCheckResourceAttrSet(testAPIGatewayAPIDocResourceKey, "service_id"), + resource.TestCheckResourceAttrSet(testAPIGatewayAPIDocResourceKey, "environment"), + resource.TestCheckResourceAttrSet(testAPIGatewayAPIDocResourceKey, "api_ids.#"), + ), + }, + { + ResourceName: testAPIGatewayAPIDocResourceKey, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAPIGatewayAPIDocUpdate, + Check: resource.ComposeTestCheckFunc( + testAccCheckAPIGatewayAPIDocExists(testAPIGatewayAPIDocResourceKey), + resource.TestCheckResourceAttr(testAPIGatewayAPIDocResourceKey, "api_doc_name", "update_doc_name_test"), + ), + }, + }, + }) +} + +func testAccCheckAPIGatewayAPIDocDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != testAPIGatewayAPIDocResourceName { + continue + } + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), logIdKey, logId) + + service := APIGatewayService{client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn} + + apiDoc, err := service.DescribeApiDoc(ctx, rs.Primary.ID) + if err != nil { + if sdkerr, ok := err.(*sdkErrors.TencentCloudSDKError); ok { + if sdkerr.Code == "ResourceNotFound.InvalidApiDoc" || sdkerr.Code == "InvalidParameterValue.InvalidCommandId" { + return nil + } + } + return err + } + + if apiDoc != nil { + return fmt.Errorf("api_gateway api_doc %s still exists", rs.Primary.ID) + } + } + return nil +} + +func testAccCheckAPIGatewayAPIDocExists(r string) resource.TestCheckFunc { + return func(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), logIdKey, logId) + + rs, ok := s.RootModule().Resources[r] + if !ok { + return fmt.Errorf("resource %s is not found", r) + } + + service := APIGatewayService{client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn} + command, err := service.DescribeApiDoc(ctx, rs.Primary.ID) + if err != nil { + if sdkerr, ok := err.(*sdkErrors.TencentCloudSDKError); ok { + if sdkerr.Code == "ResourceNotFound.InvalidApiDoc" || sdkerr.Code == "InvalidParameterValue.InvalidCommandId" { + return nil + } + } + return err + } + + if command == nil { + return fmt.Errorf("api_gateway api_doc %s is not found", rs.Primary.ID) + } + + return nil + } +} + +const testAccAPIGatewayAPIDoc = ` +resource "tencentcloud_api_gateway_api_doc" "test" { + api_doc_name = "doc_test1" + service_id = "service-hwd9bmdk" + environment = "release" + api_ids = ["api-p019gpxq"] +} +` + +const testAccAPIGatewayAPIDocUpdate = ` +resource "tencentcloud_api_gateway_api_doc" "test" { + api_doc_name = "update_doc_name_test" + service_id = "service-hwd9bmdk" + environment = "release" + api_ids = ["api-p019gpxq"] +} +` diff --git a/tencentcloud/service_tencentcloud_api_gateway.go b/tencentcloud/service_tencentcloud_api_gateway.go index 1bb1dfb83f..5289d6604a 100644 --- a/tencentcloud/service_tencentcloud_api_gateway.go +++ b/tencentcloud/service_tencentcloud_api_gateway.go @@ -1700,3 +1700,227 @@ func (me *APIGatewayService) DeleteApiGatewayPluginAttachmentById(ctx context.Co return } + +func (me *APIGatewayService) DescribeApiDoc(ctx context.Context, apiDocId string) (apiDoc *apigateway.APIDocInfo, errRet error) { + var ( + logId = getLogId(ctx) + request = apigateway.NewDescribeAPIDocDetailRequest() + ) + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, "query object", request.ToJsonString(), errRet.Error()) + } + }() + + request.ApiDocId = &apiDocId + ratelimit.Check(request.GetAction()) + response, err := me.client.UseAPIGatewayClient().DescribeAPIDocDetail(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 { + return + } + + apiDoc = response.Response.Result + return +} + +func (me *APIGatewayService) DescribeApiDocList(ctx context.Context) (apiDoc []*apigateway.APIDoc, errRet error) { + var ( + logId = getLogId(ctx) + request = apigateway.NewDescribeAPIDocsRequest() + ) + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, "query object", request.ToJsonString(), errRet.Error()) + } + }() + + var offset int64 = 0 + var pageSize int64 = 100 + + for { + request.Offset = &offset + request.Limit = &pageSize + ratelimit.Check(request.GetAction()) + response, err := me.client.UseAPIGatewayClient().DescribeAPIDocs(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 || *response.Response.Result.TotalCount == 0 { + break + } + + apiDoc = append(apiDoc, response.Response.Result.APIDocSet...) + if *response.Response.Result.TotalCount < pageSize { + break + } + + offset += pageSize + } + return +} + +func (me *APIGatewayService) DeleteAPIGatewayAPIDocById(ctx context.Context, apiDocId string) (errRet error) { + logId := getLogId(ctx) + request := apigateway.NewDeleteAPIDocRequest() + request.ApiDocId = &apiDocId + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, "delete object", request.ToJsonString(), errRet.Error()) + } + }() + + ratelimit.Check(request.GetAction()) + response, err := me.client.UseAPIGatewayClient().DeleteAPIDoc(request) + if err != nil { + errRet = err + return + } + + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + return +} + +func (me *APIGatewayService) DescribeApiApp(ctx context.Context, apiAppId string) (apiDoc *apigateway.ApiAppInfos, errRet error) { + var ( + logId = getLogId(ctx) + request = apigateway.NewDescribeApiAppsStatusRequest() + ) + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, "query object", request.ToJsonString(), errRet.Error()) + } + }() + + request.Filters = []*apigateway.Filter{ + &apigateway.Filter{ + Name: helper.String("ApiAppId"), + Values: helper.Strings([]string{apiAppId}), + }, + } + + ratelimit.Check(request.GetAction()) + response, err := me.client.UseAPIGatewayClient().DescribeApiAppsStatus(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 || *response.Response.Result.TotalCount == 0 { + return + } + + apiDoc = response.Response.Result + return +} + +func (me *APIGatewayService) DescribeApiAppList(ctx context.Context, apiAppId, apiAppName string) (apiApp []*apigateway.ApiAppInfo, errRet error) { + var ( + logId = getLogId(ctx) + request = apigateway.NewDescribeApiAppsStatusRequest() + ) + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, "query object", request.ToJsonString(), errRet.Error()) + } + }() + + request.Filters = []*apigateway.Filter{} + if apiAppId != "" { + request.Filters = append(request.Filters, + &apigateway.Filter{ + Name: helper.String("ApiAppId"), + Values: helper.Strings([]string{apiAppId}), + }) + } + + if apiAppName != "" { + request.Filters = append(request.Filters, + &apigateway.Filter{ + Name: helper.String("ApiAppName"), + Values: helper.Strings([]string{apiAppName}), + }) + } + + var offset int64 = 0 + var pageSize int64 = 100 + + for { + request.Offset = &offset + request.Limit = &pageSize + ratelimit.Check(request.GetAction()) + response, err := me.client.UseAPIGatewayClient().DescribeApiAppsStatus(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 || *response.Response.Result.TotalCount == 0 { + break + } + apiApp = append(apiApp, response.Response.Result.ApiAppSet...) + if *response.Response.Result.TotalCount < pageSize { + break + } + offset += pageSize + } + return +} + +func (me *APIGatewayService) DeleteAPIGatewayAPIAppById(ctx context.Context, apiAppId string) (errRet error) { + logId := getLogId(ctx) + request := apigateway.NewDeleteApiAppRequest() + request.ApiAppId = &apiAppId + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, "delete object", request.ToJsonString(), errRet.Error()) + } + }() + + ratelimit.Check(request.GetAction()) + response, err := me.client.UseAPIGatewayClient().DeleteApiApp(request) + if err != nil { + errRet = err + return + } + + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + return +} From c1bbeaa3b6b3670fbbccbf1b69f29edea5bc149d Mon Sep 17 00:00:00 2001 From: SevenEarth <391613297@qq.com> Date: Sat, 6 May 2023 18:28:18 +0800 Subject: [PATCH 02/10] add changelog --- .changelog/1726.txt | 7 +++++++ tencentcloud/resource_tc_api_gateway_api_app_test.go | 3 ++- tencentcloud/service_tencentcloud_api_gateway.go | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 .changelog/1726.txt diff --git a/.changelog/1726.txt b/.changelog/1726.txt new file mode 100644 index 0000000000..30334d8eb7 --- /dev/null +++ b/.changelog/1726.txt @@ -0,0 +1,7 @@ +```release-note:new-data-source +tencentcloud_api_gateway_api_doc +``` + +```release-note:new-data-source +tencentcloud_api_gateway_api_app +``` \ No newline at end of file diff --git a/tencentcloud/resource_tc_api_gateway_api_app_test.go b/tencentcloud/resource_tc_api_gateway_api_app_test.go index 3340444d87..d897220df0 100644 --- a/tencentcloud/resource_tc_api_gateway_api_app_test.go +++ b/tencentcloud/resource_tc_api_gateway_api_app_test.go @@ -3,9 +3,10 @@ package tencentcloud import ( "context" "fmt" - sdkErrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" "testing" + sdkErrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) diff --git a/tencentcloud/service_tencentcloud_api_gateway.go b/tencentcloud/service_tencentcloud_api_gateway.go index 5289d6604a..3856f39223 100644 --- a/tencentcloud/service_tencentcloud_api_gateway.go +++ b/tencentcloud/service_tencentcloud_api_gateway.go @@ -1817,7 +1817,7 @@ func (me *APIGatewayService) DescribeApiApp(ctx context.Context, apiAppId string }() request.Filters = []*apigateway.Filter{ - &apigateway.Filter{ + { Name: helper.String("ApiAppId"), Values: helper.Strings([]string{apiAppId}), }, From d2fe00d89d13ad161b8a1a5ce9e1d061f56c4b8f Mon Sep 17 00:00:00 2001 From: SevenEarth <391613297@qq.com> Date: Sat, 6 May 2023 20:56:28 +0800 Subject: [PATCH 03/10] add --- .changelog/1726.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.changelog/1726.txt b/.changelog/1726.txt index 30334d8eb7..97a16eb074 100644 --- a/.changelog/1726.txt +++ b/.changelog/1726.txt @@ -1,7 +1,15 @@ ```release-note:new-data-source +tencentcloud_api_gateway_api_docs +``` + +```release-note:new-resource tencentcloud_api_gateway_api_doc ``` ```release-note:new-data-source +tencentcloud_api_gateway_api_apps +``` + +```release-note:new-resource tencentcloud_api_gateway_api_app ``` \ No newline at end of file From cd94fcb24b91c3b7e65039100f6de6e6c438357c Mon Sep 17 00:00:00 2001 From: SevenEarth <391613297@qq.com> Date: Mon, 8 May 2023 11:34:42 +0800 Subject: [PATCH 04/10] fix/apigw-custom_domain-bug --- .../resource_tc_api_gateway_custom_domain.go | 18 ++++++++++++++++-- ...source_tc_api_gateway_custom_domain_test.go | 11 ++++++----- .../service_tencentcloud_api_gateway.go | 6 ++++-- .../r/api_gateway_custom_domain.html.markdown | 1 + 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/tencentcloud/resource_tc_api_gateway_custom_domain.go b/tencentcloud/resource_tc_api_gateway_custom_domain.go index 5e57ed89d6..1f80d03fbf 100644 --- a/tencentcloud/resource_tc_api_gateway_custom_domain.go +++ b/tencentcloud/resource_tc_api_gateway_custom_domain.go @@ -83,6 +83,12 @@ func resourceTencentCloudAPIGatewayCustomDomain() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, Description: "Custom domain name path mapping. The data format is: `path#environment`. Optional values for the environment are `test`, `prepub`, and `release`.", }, + "is_forced_https": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Whether to force HTTP requests to jump to HTTPS, default to false. When the parameter is true, the API gateway will redirect all HTTP protocol requests using the custom domain name to the HTTPS protocol for forwarding.", + }, //compute "status": { Type: schema.TypeInt, @@ -106,6 +112,7 @@ func resourceTencentCloudAPIGatewayCustomDomainCreate(d *schema.ResourceData, me netType = d.Get("net_type").(string) defaultDomain = d.Get("default_domain").(string) isDefaultMapping = d.Get("is_default_mapping").(bool) + isForcedHttps = d.Get("is_forced_https").(bool) certificateId string pathMappings []string err error @@ -118,7 +125,7 @@ func resourceTencentCloudAPIGatewayCustomDomainCreate(d *schema.ResourceData, me pathMappings = helper.InterfacesStrings(v.(*schema.Set).List()) } - err = apiGatewayService.BindSubDomainService(ctx, serviceId, subDomain, protocol, netType, defaultDomain, isDefaultMapping, certificateId, pathMappings) + err = apiGatewayService.BindSubDomainService(ctx, serviceId, subDomain, protocol, netType, defaultDomain, isDefaultMapping, certificateId, pathMappings, isForcedHttps) if err != nil { return err } @@ -191,6 +198,7 @@ func resourceTencentCloudAPIGatewayCustomDomainUpdate(d *schema.ResourceData, me protocol string netType string pathMappings []string + isForcedHttps bool hasChange bool ) @@ -230,12 +238,18 @@ func resourceTencentCloudAPIGatewayCustomDomainUpdate(d *schema.ResourceData, me if v, ok := d.GetOk("path_mappings"); ok { pathMappings = helper.InterfacesStrings(v.(*schema.Set).List()) } + if d.HasChange("path_mappings") { hasChange = true } + isForcedHttps = d.Get("is_forced_https").(bool) + if d.HasChange("is_forced_https") { + hasChange = true + } + if hasChange { - err := apiGatewayService.ModifySubDomainService(ctx, serviceId, subDomain, isDefaultMapping, certificateId, protocol, netType, pathMappings) + err := apiGatewayService.ModifySubDomainService(ctx, serviceId, subDomain, isDefaultMapping, certificateId, protocol, netType, pathMappings, isForcedHttps) if err != nil { return err } diff --git a/tencentcloud/resource_tc_api_gateway_custom_domain_test.go b/tencentcloud/resource_tc_api_gateway_custom_domain_test.go index 470f8d6f5e..4bbe98313f 100644 --- a/tencentcloud/resource_tc_api_gateway_custom_domain_test.go +++ b/tencentcloud/resource_tc_api_gateway_custom_domain_test.go @@ -10,7 +10,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) -func TestAccTencentCloudAPIGateWayCustomDomain(t *testing.T) { +// go test -i; go test -test.run TestAccTencentCloudAPIGateWayCustomDomain_basic -v +func TestAccTencentCloudAPIGateWayCustomDomain_basic(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -21,7 +22,7 @@ func TestAccTencentCloudAPIGateWayCustomDomain(t *testing.T) { Config: testAccCustomDomain, Check: resource.ComposeTestCheckFunc( testAccCheckCustomDomainExists("tencentcloud_api_gateway_custom_domain.foo"), - resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "service_id", "service-7lybgojo"), + resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "service_id", "service-hwd9bmdk"), resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "sub_domain", "tic-test.dnsv1.com"), resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "protocol", "http"), resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "net_type", "OUTER"), @@ -34,7 +35,7 @@ func TestAccTencentCloudAPIGateWayCustomDomain(t *testing.T) { Config: testAccCustomDomainUpdate, Check: resource.ComposeTestCheckFunc( testAccCheckCustomDomainExists("tencentcloud_api_gateway_custom_domain.foo"), - resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "service_id", "service-7lybgojo"), + resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "service_id", "service-hwd9bmdk"), resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "sub_domain", "tic-test.dnsv1.com"), resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "protocol", "http"), resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "net_type", "OUTER"), @@ -112,7 +113,7 @@ func testAccCheckCustomDomainExists(n string) resource.TestCheckFunc { const testAccCustomDomain = ` resource "tencentcloud_api_gateway_custom_domain" "foo" { - service_id = "service-7lybgojo" + service_id = "service-hwd9bmdk" sub_domain = "tic-test.dnsv1.com" protocol = "http" net_type = "OUTER" @@ -124,7 +125,7 @@ resource "tencentcloud_api_gateway_custom_domain" "foo" { const testAccCustomDomainUpdate = ` resource "tencentcloud_api_gateway_custom_domain" "foo" { - service_id = "service-7lybgojo" + service_id = "service-hwd9bmdk" sub_domain = "tic-test.dnsv1.com" protocol = "http" net_type = "OUTER" diff --git a/tencentcloud/service_tencentcloud_api_gateway.go b/tencentcloud/service_tencentcloud_api_gateway.go index 3856f39223..aa22d5590b 100644 --- a/tencentcloud/service_tencentcloud_api_gateway.go +++ b/tencentcloud/service_tencentcloud_api_gateway.go @@ -1114,7 +1114,7 @@ func (me *APIGatewayService) ModifyServiceEnvironmentStrategy(ctx context.Contex } func (me *APIGatewayService) BindSubDomainService(ctx context.Context, - serviceId, subDomain, protocol, netType, defaultDomain string, isDefaultMapping bool, certificateId string, pathMappings []string) (errRet error) { + serviceId, subDomain, protocol, netType, defaultDomain string, isDefaultMapping bool, certificateId string, pathMappings []string, isForcedHttps bool) (errRet error) { var ( request = apigateway.NewBindSubDomainRequest() err error @@ -1126,6 +1126,7 @@ func (me *APIGatewayService) BindSubDomainService(ctx context.Context, request.NetType = &netType request.NetSubDomain = &defaultDomain request.IsDefaultMapping = &isDefaultMapping + request.IsForcedHttps = &isForcedHttps if certificateId != "" { request.CertificateId = &certificateId } @@ -1231,7 +1232,7 @@ func (me *APIGatewayService) DescribeServiceSubDomainMappings(ctx context.Contex } func (me *APIGatewayService) ModifySubDomainService(ctx context.Context, - serviceId, subDomain string, isDefaultMapping bool, certificateId, protocol, netType string, pathMappings []string) (errRet error) { + serviceId, subDomain string, isDefaultMapping bool, certificateId, protocol, netType string, pathMappings []string, isForcedHttps bool) (errRet error) { var ( request = apigateway.NewModifySubDomainRequest() response *apigateway.ModifySubDomainResponse @@ -1241,6 +1242,7 @@ func (me *APIGatewayService) ModifySubDomainService(ctx context.Context, request.ServiceId = &serviceId request.SubDomain = &subDomain request.IsDefaultMapping = &isDefaultMapping + request.IsForcedHttps = &isForcedHttps if certificateId != "" { request.CertificateId = &certificateId } diff --git a/website/docs/r/api_gateway_custom_domain.html.markdown b/website/docs/r/api_gateway_custom_domain.html.markdown index 08604db5ca..569e617187 100644 --- a/website/docs/r/api_gateway_custom_domain.html.markdown +++ b/website/docs/r/api_gateway_custom_domain.html.markdown @@ -36,6 +36,7 @@ The following arguments are supported: * `sub_domain` - (Required, String) Custom domain name to be bound. * `certificate_id` - (Optional, String) Unique certificate ID of the custom domain name to be bound. You can choose to upload for the `protocol` attribute value `https` or `http&https`. * `is_default_mapping` - (Optional, Bool) Whether the default path mapping is used. The default value is `true`. When it is `false`, it means custom path mapping. In this case, the `path_mappings` attribute is required. +* `is_forced_https` - (Optional, Bool) Whether to force HTTP requests to jump to HTTPS, default to false. When the parameter is true, the API gateway will redirect all HTTP protocol requests using the custom domain name to the HTTPS protocol for forwarding. * `path_mappings` - (Optional, Set: [`String`]) Custom domain name path mapping. The data format is: `path#environment`. Optional values for the environment are `test`, `prepub`, and `release`. ## Attributes Reference From 8925362395ac210225f225b0fec6395d35845366 Mon Sep 17 00:00:00 2001 From: SevenEarth <391613297@qq.com> Date: Mon, 8 May 2023 14:59:28 +0800 Subject: [PATCH 05/10] fix/apigw-custom_domain-bug --- .../data_source_tc_api_gateway_api_docs_test.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tencentcloud/data_source_tc_api_gateway_api_docs_test.go b/tencentcloud/data_source_tc_api_gateway_api_docs_test.go index 2511047e54..28bc18544f 100644 --- a/tencentcloud/data_source_tc_api_gateway_api_docs_test.go +++ b/tencentcloud/data_source_tc_api_gateway_api_docs_test.go @@ -12,9 +12,9 @@ var testAPIGatewayAPIDocsResourceName = "data.tencentcloud_api_gateway_api_docs" func TestAccTencentAPIGatewayAPIDocsDataSource_basic(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAPIGatewayAPIDocDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + //CheckDestroy: testAccCheckAPIGatewayAPIDocDestroy, Steps: []resource.TestStep{ { Config: testAccTestAccTencentAPIGatewayAPIDocs, @@ -27,7 +27,14 @@ func TestAccTencentAPIGatewayAPIDocsDataSource_basic(t *testing.T) { } const testAccTestAccTencentAPIGatewayAPIDocs = ` +resource "tencentcloud_api_gateway_api_doc" "test" { + api_doc_name = "doc_test1" + service_id = "service-hwd9bmdk" + environment = "release" + api_ids = ["api-p019gpxq"] +} + data "tencentcloud_api_gateway_api_docs" "test" { - + depends_on = [tencentcloud_api_gateway_api_doc.test] } ` From 33072ee67a6f8f69d5475a54d45d368676eba669 Mon Sep 17 00:00:00 2001 From: SevenEarth <391613297@qq.com> Date: Mon, 8 May 2023 15:24:29 +0800 Subject: [PATCH 06/10] fix/apigw-custom_domain-bug --- .../data_source_tc_api_gateway_api_docs_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tencentcloud/data_source_tc_api_gateway_api_docs_test.go b/tencentcloud/data_source_tc_api_gateway_api_docs_test.go index 28bc18544f..5e2e22caa3 100644 --- a/tencentcloud/data_source_tc_api_gateway_api_docs_test.go +++ b/tencentcloud/data_source_tc_api_gateway_api_docs_test.go @@ -12,9 +12,9 @@ var testAPIGatewayAPIDocsResourceName = "data.tencentcloud_api_gateway_api_docs" func TestAccTencentAPIGatewayAPIDocsDataSource_basic(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - //CheckDestroy: testAccCheckAPIGatewayAPIDocDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAPIGatewayAPIDocDestroy, Steps: []resource.TestStep{ { Config: testAccTestAccTencentAPIGatewayAPIDocs, @@ -29,9 +29,9 @@ func TestAccTencentAPIGatewayAPIDocsDataSource_basic(t *testing.T) { const testAccTestAccTencentAPIGatewayAPIDocs = ` resource "tencentcloud_api_gateway_api_doc" "test" { api_doc_name = "doc_test1" - service_id = "service-hwd9bmdk" + service_id = "service-7lybgojo" environment = "release" - api_ids = ["api-p019gpxq"] + api_ids = ["api-2bntitvw"] } data "tencentcloud_api_gateway_api_docs" "test" { From 5324fef36567a8dd119f950ead9f3b3aaf06c6e5 Mon Sep 17 00:00:00 2001 From: SevenEarth <391613297@qq.com> Date: Mon, 8 May 2023 15:26:33 +0800 Subject: [PATCH 07/10] fix/apigw-custom_domain-bug --- tencentcloud/resource_tc_api_gateway_api_doc_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tencentcloud/resource_tc_api_gateway_api_doc_test.go b/tencentcloud/resource_tc_api_gateway_api_doc_test.go index 8bc06d632c..599988ff9e 100644 --- a/tencentcloud/resource_tc_api_gateway_api_doc_test.go +++ b/tencentcloud/resource_tc_api_gateway_api_doc_test.go @@ -115,8 +115,8 @@ resource "tencentcloud_api_gateway_api_doc" "test" { const testAccAPIGatewayAPIDocUpdate = ` resource "tencentcloud_api_gateway_api_doc" "test" { api_doc_name = "update_doc_name_test" - service_id = "service-hwd9bmdk" + service_id = "service-7lybgojo" environment = "release" - api_ids = ["api-p019gpxq"] + api_ids = ["api-2bntitvw"] } ` From 52561b657d9c04052f8ec5943221cb440fa6216d Mon Sep 17 00:00:00 2001 From: SevenEarth <391613297@qq.com> Date: Mon, 8 May 2023 15:27:18 +0800 Subject: [PATCH 08/10] fix/apigw-custom_domain-bug --- tencentcloud/resource_tc_api_gateway_api_doc_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tencentcloud/resource_tc_api_gateway_api_doc_test.go b/tencentcloud/resource_tc_api_gateway_api_doc_test.go index 599988ff9e..bf2025925d 100644 --- a/tencentcloud/resource_tc_api_gateway_api_doc_test.go +++ b/tencentcloud/resource_tc_api_gateway_api_doc_test.go @@ -106,9 +106,9 @@ func testAccCheckAPIGatewayAPIDocExists(r string) resource.TestCheckFunc { const testAccAPIGatewayAPIDoc = ` resource "tencentcloud_api_gateway_api_doc" "test" { api_doc_name = "doc_test1" - service_id = "service-hwd9bmdk" + service_id = "service-7lybgojo" environment = "release" - api_ids = ["api-p019gpxq"] + api_ids = ["api-2bntitvw"] } ` From a10107b19e0c9709fee275f61d2bb52fcbc4c61f Mon Sep 17 00:00:00 2001 From: SevenEarth <391613297@qq.com> Date: Mon, 8 May 2023 15:59:05 +0800 Subject: [PATCH 09/10] fix/apigw-custom_domain-bug --- .../data_source_tc_api_gateway_customer_domains_test.go | 5 +++-- .../resource_tc_api_gateway_custom_domain_test.go | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tencentcloud/data_source_tc_api_gateway_customer_domains_test.go b/tencentcloud/data_source_tc_api_gateway_customer_domains_test.go index b85ed7dc7d..7df4ff445a 100644 --- a/tencentcloud/data_source_tc_api_gateway_customer_domains_test.go +++ b/tencentcloud/data_source_tc_api_gateway_customer_domains_test.go @@ -8,7 +8,8 @@ import ( var testAPIGatewayDomainSourceName = "data.tencentcloud_api_gateway_customer_domains" -func TestAccTencentAPIGatewayCustomerDomain(t *testing.T) { +// go test -i; go test -test.run TestAccTencentAPIGatewayCustomerDomain_basic -v +func TestAccTencentAPIGatewayCustomerDomain_basic(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -34,7 +35,7 @@ func TestAccTencentAPIGatewayCustomerDomain(t *testing.T) { func testAccTestAccTencentAPIGatewayDomain() string { return ` resource "tencentcloud_api_gateway_custom_domain" "foo" { - service_id = "service-ohxqslqe" + service_id = "service-7lybgojo" sub_domain = "tic-test.dnsv1.com" protocol = "http" net_type = "OUTER" diff --git a/tencentcloud/resource_tc_api_gateway_custom_domain_test.go b/tencentcloud/resource_tc_api_gateway_custom_domain_test.go index 4bbe98313f..8db89cfb22 100644 --- a/tencentcloud/resource_tc_api_gateway_custom_domain_test.go +++ b/tencentcloud/resource_tc_api_gateway_custom_domain_test.go @@ -22,7 +22,7 @@ func TestAccTencentCloudAPIGateWayCustomDomain_basic(t *testing.T) { Config: testAccCustomDomain, Check: resource.ComposeTestCheckFunc( testAccCheckCustomDomainExists("tencentcloud_api_gateway_custom_domain.foo"), - resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "service_id", "service-hwd9bmdk"), + resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "service_id", "service-7lybgojo"), resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "sub_domain", "tic-test.dnsv1.com"), resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "protocol", "http"), resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "net_type", "OUTER"), @@ -35,7 +35,7 @@ func TestAccTencentCloudAPIGateWayCustomDomain_basic(t *testing.T) { Config: testAccCustomDomainUpdate, Check: resource.ComposeTestCheckFunc( testAccCheckCustomDomainExists("tencentcloud_api_gateway_custom_domain.foo"), - resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "service_id", "service-hwd9bmdk"), + resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "service_id", "service-7lybgojo"), resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "sub_domain", "tic-test.dnsv1.com"), resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "protocol", "http"), resource.TestCheckResourceAttr("tencentcloud_api_gateway_custom_domain.foo", "net_type", "OUTER"), @@ -113,7 +113,7 @@ func testAccCheckCustomDomainExists(n string) resource.TestCheckFunc { const testAccCustomDomain = ` resource "tencentcloud_api_gateway_custom_domain" "foo" { - service_id = "service-hwd9bmdk" + service_id = "service-7lybgojo" sub_domain = "tic-test.dnsv1.com" protocol = "http" net_type = "OUTER" @@ -125,7 +125,7 @@ resource "tencentcloud_api_gateway_custom_domain" "foo" { const testAccCustomDomainUpdate = ` resource "tencentcloud_api_gateway_custom_domain" "foo" { - service_id = "service-hwd9bmdk" + service_id = "service-7lybgojo" sub_domain = "tic-test.dnsv1.com" protocol = "http" net_type = "OUTER" From 056bd44733849d077c4d1c4bdfa2e10a9e8e802b Mon Sep 17 00:00:00 2001 From: SevenEarth <391613297@qq.com> Date: Mon, 8 May 2023 17:54:43 +0800 Subject: [PATCH 10/10] add --- .changelog/1726.txt | 4 ++ .../data_source_tc_api_gateway_api_apps.go | 1 - .../data_source_tc_api_gateway_api_docs.go | 1 - tencentcloud/provider.go | 4 ++ .../resource_tc_api_gateway_api_app.go | 1 - .../resource_tc_api_gateway_api_doc.go | 1 - .../resource_tc_api_gateway_custom_domain.go | 1 + .../docs/d/api_gateway_api_apps.html.markdown | 44 ++++++++++++++++ .../docs/d/api_gateway_api_docs.html.markdown | 36 +++++++++++++ .../docs/r/api_gateway_api_app.html.markdown | 41 +++++++++++++++ .../docs/r/api_gateway_api_doc.html.markdown | 50 +++++++++++++++++++ website/tencentcloud.erb | 12 +++++ 12 files changed, 192 insertions(+), 4 deletions(-) create mode 100644 website/docs/d/api_gateway_api_apps.html.markdown create mode 100644 website/docs/d/api_gateway_api_docs.html.markdown create mode 100644 website/docs/r/api_gateway_api_app.html.markdown create mode 100644 website/docs/r/api_gateway_api_doc.html.markdown diff --git a/.changelog/1726.txt b/.changelog/1726.txt index 97a16eb074..82ea32c841 100644 --- a/.changelog/1726.txt +++ b/.changelog/1726.txt @@ -12,4 +12,8 @@ tencentcloud_api_gateway_api_apps ```release-note:new-resource tencentcloud_api_gateway_api_app +``` + +```release-note:enhancement +resource/tencentcloud_api_gateway_custom_domain: support add `is_forced_https` params ``` \ No newline at end of file diff --git a/tencentcloud/data_source_tc_api_gateway_api_apps.go b/tencentcloud/data_source_tc_api_gateway_api_apps.go index 47f984bd27..a900338da4 100644 --- a/tencentcloud/data_source_tc_api_gateway_api_apps.go +++ b/tencentcloud/data_source_tc_api_gateway_api_apps.go @@ -10,7 +10,6 @@ data "tencentcloud_api_gateway_api_apps" "test" { } ``` */ - package tencentcloud import ( diff --git a/tencentcloud/data_source_tc_api_gateway_api_docs.go b/tencentcloud/data_source_tc_api_gateway_api_docs.go index e1cbb2c9ff..a9055ff24f 100644 --- a/tencentcloud/data_source_tc_api_gateway_api_docs.go +++ b/tencentcloud/data_source_tc_api_gateway_api_docs.go @@ -6,7 +6,6 @@ data "tencentcloud_api_gateway_api_docs" "my_api_doc" { } ``` */ - package tencentcloud import ( diff --git a/tencentcloud/provider.go b/tencentcloud/provider.go index 70ae838aaa..40b5719187 100644 --- a/tencentcloud/provider.go +++ b/tencentcloud/provider.go @@ -89,6 +89,8 @@ API GateWay tencentcloud_api_gateway_customer_domains tencentcloud_api_gateway_usage_plan_environments tencentcloud_api_gateway_api_keys + tencentcloud_api_gateway_api_docs + tencentcloud_api_gateway_api_apps Resource tencentcloud_api_gateway_api @@ -103,6 +105,8 @@ API GateWay tencentcloud_api_gateway_service_release tencentcloud_api_gateway_plugin tencentcloud_api_gateway_plugin_attachment + tencentcloud_api_gateway_api_doc + tencentcloud_api_gateway_api_app Cloud Audit(Audit) Data Source diff --git a/tencentcloud/resource_tc_api_gateway_api_app.go b/tencentcloud/resource_tc_api_gateway_api_app.go index 8210eb96a0..2712ff23d5 100644 --- a/tencentcloud/resource_tc_api_gateway_api_app.go +++ b/tencentcloud/resource_tc_api_gateway_api_app.go @@ -10,7 +10,6 @@ resource "tencentcloud_api_gateway_api_app" "my_api_app" { } ``` */ - package tencentcloud import ( diff --git a/tencentcloud/resource_tc_api_gateway_api_doc.go b/tencentcloud/resource_tc_api_gateway_api_doc.go index 6ac62e8214..d817672352 100644 --- a/tencentcloud/resource_tc_api_gateway_api_doc.go +++ b/tencentcloud/resource_tc_api_gateway_api_doc.go @@ -12,7 +12,6 @@ resource "tencentcloud_api_gateway_api_doc" "my_api_doc" { } ``` */ - package tencentcloud import ( diff --git a/tencentcloud/resource_tc_api_gateway_custom_domain.go b/tencentcloud/resource_tc_api_gateway_custom_domain.go index 1f80d03fbf..a67a7f512c 100644 --- a/tencentcloud/resource_tc_api_gateway_custom_domain.go +++ b/tencentcloud/resource_tc_api_gateway_custom_domain.go @@ -180,6 +180,7 @@ func resourceTencentCloudAPIGatewayCustomDomainRead(d *schema.ResourceData, meta _ = d.Set("protocol", resultInfo.Protocol) _ = d.Set("net_type", resultInfo.NetType) _ = d.Set("service_id", serviceId) + _ = d.Set("is_forced_https", resultInfo.IsForcedHttps) return nil } diff --git a/website/docs/d/api_gateway_api_apps.html.markdown b/website/docs/d/api_gateway_api_apps.html.markdown new file mode 100644 index 0000000000..70a5a95b8b --- /dev/null +++ b/website/docs/d/api_gateway_api_apps.html.markdown @@ -0,0 +1,44 @@ +--- +subcategory: "API GateWay" +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_api_gateway_api_apps" +sidebar_current: "docs-tencentcloud-datasource-api_gateway_api_apps" +description: |- + Use this data source to query list information of api_gateway api_app +--- + +# tencentcloud_api_gateway_api_apps + +Use this data source to query list information of api_gateway api_app + +## Example Usage + +```hcl +data "tencentcloud_api_gateway_api_apps" "test" { + api_app_id = ["app-rj8t6zx3"] + api_app_name = ["app_test"] +} +``` + +## Argument Reference + +The following arguments are supported: + +* `api_app_id` - (Optional, String) Api app ID. +* `api_app_name` - (Optional, String) Api app name. +* `result_output_file` - (Optional, String) Used to save results. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `api_app_list` - List of ApiApp. + * `api_app_desc` - ApiApp description. + * `api_app_id` - ApiApp ID. + * `api_app_key` - ApiApp key. + * `api_app_name` - ApiApp Name. + * `api_app_secret` - ApiApp secret. + * `created_time` - ApiApp create time. + * `modified_time` - ApiApp modified time. + + diff --git a/website/docs/d/api_gateway_api_docs.html.markdown b/website/docs/d/api_gateway_api_docs.html.markdown new file mode 100644 index 0000000000..f4a3715cf9 --- /dev/null +++ b/website/docs/d/api_gateway_api_docs.html.markdown @@ -0,0 +1,36 @@ +--- +subcategory: "API GateWay" +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_api_gateway_api_docs" +sidebar_current: "docs-tencentcloud-datasource-api_gateway_api_docs" +description: |- + Use this data source to query list information of api_gateway api_doc +--- + +# tencentcloud_api_gateway_api_docs + +Use this data source to query list information of api_gateway api_doc + +## Example Usage + +```hcl +data "tencentcloud_api_gateway_api_docs" "my_api_doc" { +} +``` + +## Argument Reference + +The following arguments are supported: + +* `result_output_file` - (Optional, String) Used to save results. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `api_doc_list` - List of ApiDocs. + * `api_doc_id` - Api Doc ID. + * `api_doc_name` - Api Doc Name. + * `api_doc_status` - Api Doc Status. + + diff --git a/website/docs/r/api_gateway_api_app.html.markdown b/website/docs/r/api_gateway_api_app.html.markdown new file mode 100644 index 0000000000..f205b2a25c --- /dev/null +++ b/website/docs/r/api_gateway_api_app.html.markdown @@ -0,0 +1,41 @@ +--- +subcategory: "API GateWay" +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_api_gateway_api_app" +sidebar_current: "docs-tencentcloud-resource-api_gateway_api_app" +description: |- + Provides a resource to create a APIGateway ApiApp +--- + +# tencentcloud_api_gateway_api_app + +Provides a resource to create a APIGateway ApiApp + +## Example Usage + +```hcl +resource "tencentcloud_api_gateway_api_app" "my_api_app" { + api_app_name = "app_test1" + api_app_desc = "app desc." +} +``` + +## Argument Reference + +The following arguments are supported: + +* `api_app_name` - (Required, String) Api app name. +* `api_app_desc` - (Optional, String) App description. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - ID of the resource. +* `api_app_id` - Api app ID. +* `api_app_key` - Api app key. +* `api_app_secret` - Api app secret. +* `created_time` - Api app created time. +* `modified_time` - Api app modified time. + + diff --git a/website/docs/r/api_gateway_api_doc.html.markdown b/website/docs/r/api_gateway_api_doc.html.markdown new file mode 100644 index 0000000000..10f47ed320 --- /dev/null +++ b/website/docs/r/api_gateway_api_doc.html.markdown @@ -0,0 +1,50 @@ +--- +subcategory: "API GateWay" +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_api_gateway_api_doc" +sidebar_current: "docs-tencentcloud-resource-api_gateway_api_doc" +description: |- + Provides a resource to create a APIGateway ApiDoc +--- + +# tencentcloud_api_gateway_api_doc + +Provides a resource to create a APIGateway ApiDoc + +## Example Usage + +```hcl +resource "tencentcloud_api_gateway_api_doc" "my_api_doc" { + api_doc_name = "doc_test1" + service_id = "service_test1" + environment = "release" + api_ids = ["api-test1", "api-test2"] +} +``` + +## Argument Reference + +The following arguments are supported: + +* `api_doc_name` - (Required, String) Api Document name. +* `api_ids` - (Required, Set: [`String`]) List of APIs for generating documents. +* `environment` - (Required, String) Env name. +* `service_id` - (Required, String) Service name. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - ID of the resource. +* `api_count` - Api Document count. +* `api_doc_id` - Api Document ID. +* `api_doc_status` - API Document Build Status. +* `api_doc_uri` - API Document Access URI. +* `api_names` - List of names for generating documents. +* `release_count` - Number of API document releases. +* `service_name` - API Document service name. +* `share_password` - API Document Sharing Password. +* `updated_time` - API Document update time. +* `view_count` - API Document Viewing Times. + + diff --git a/website/tencentcloud.erb b/website/tencentcloud.erb index 07f104f377..5811bef701 100644 --- a/website/tencentcloud.erb +++ b/website/tencentcloud.erb @@ -30,6 +30,12 @@
  • Data Sources