diff --git a/docs/data-sources/cdn_billing_option.md b/docs/data-sources/cdn_billing_option.md index 262aff6b9c..7a4be1d62c 100644 --- a/docs/data-sources/cdn_billing_option.md +++ b/docs/data-sources/cdn_billing_option.md @@ -2,12 +2,13 @@ subcategory: Content Delivery Network (CDN) layout: "huaweicloud" page_title: "HuaweiCloud: huaweicloud_cdn_billing_option" -description: "Use this data source to get CDN billing option." +description: |- + Use this data source to get CDN billing option within HuaweiCloud. --- # huaweicloud_cdn_billing_option -Use this data source to get CDN billing option. +Use this data source to get CDN billing option within HuaweiCloud. ## Example Usage diff --git a/huaweicloud/services/acceptance/cdn/data_source_huaweicloud_cdn_billing_option_test.go b/huaweicloud/services/acceptance/cdn/data_source_huaweicloud_cdn_billing_option_test.go index 51ebdf8105..a681dd720a 100644 --- a/huaweicloud/services/acceptance/cdn/data_source_huaweicloud_cdn_billing_option_test.go +++ b/huaweicloud/services/acceptance/cdn/data_source_huaweicloud_cdn_billing_option_test.go @@ -9,7 +9,7 @@ import ( "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" ) -func TestAccDatasourceBillingOption_basic(t *testing.T) { +func TestAccDataSourceBillingOption_basic(t *testing.T) { var ( rName = "data.huaweicloud_cdn_billing_option.test" dc = acceptance.InitDataSourceCheck(rName) @@ -19,11 +19,13 @@ func TestAccDatasourceBillingOption_basic(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acceptance.TestAccPreCheck(t) }, + PreCheck: func() { + acceptance.TestAccPreCheck(t) + }, ProviderFactories: acceptance.TestAccProviderFactories, Steps: []resource.TestStep{ { - Config: testAccDatasourceBillingOption_basic, + Config: testDataSourceBillingOption_basic, Check: resource.ComposeTestCheckFunc( dc.CheckResourceExists(), resource.TestCheckResourceAttrSet(rName, "product_type"), @@ -43,7 +45,7 @@ func TestAccDatasourceBillingOption_basic(t *testing.T) { ), }, { - Config: testAccDatasourceBillingOption_expectError, + Config: testDataSourceBillingOption_expectError, ExpectError: regexp.MustCompile("Your query returned no results. " + "Please change your search criteria and try again."), }, @@ -51,7 +53,7 @@ func TestAccDatasourceBillingOption_basic(t *testing.T) { }) } -const testAccDatasourceBillingOption_basic = ` +const testDataSourceBillingOption_basic = ` data "huaweicloud_cdn_billing_option" "test" { product_type = "base" } @@ -63,7 +65,7 @@ data "huaweicloud_cdn_billing_option" "all_filter" { } ` -const testAccDatasourceBillingOption_expectError = ` +const testDataSourceBillingOption_expectError = ` data "huaweicloud_cdn_billing_option" "test" { product_type = "base" } diff --git a/huaweicloud/services/acceptance/cdn/resource_huaweicloud_cdn_billing_option_test.go b/huaweicloud/services/acceptance/cdn/resource_huaweicloud_cdn_billing_option_test.go index a7c42fc2af..6d809df050 100644 --- a/huaweicloud/services/acceptance/cdn/resource_huaweicloud_cdn_billing_option_test.go +++ b/huaweicloud/services/acceptance/cdn/resource_huaweicloud_cdn_billing_option_test.go @@ -7,40 +7,30 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v2/model" - "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/cdn" ) func getBillingOptionResourceFunc(cfg *config.Config, state *terraform.ResourceState) (interface{}, error) { - region := acceptance.HW_REGION_NAME - hcCdnClient, err := cfg.HcCdnV2Client(region) - if err != nil { - return nil, fmt.Errorf("error creating CDN v2 client: %s", err) - } - - request := model.ShowChargeModesRequest{ - ProductType: state.Primary.Attributes["product_type"], - } - - resp, err := hcCdnClient.ShowChargeModes(&request) + var ( + region = acceptance.HW_REGION_NAME + product = "cdn" + productType = state.Primary.Attributes["product_type"] + ) + client, err := cfg.NewServiceClient(product, region) if err != nil { - return nil, fmt.Errorf("error retrieving CDN billing option: %s", err) - } - - if resp == nil || resp.Result == nil || len(*resp.Result) == 0 { - return nil, fmt.Errorf("error retrieving CDN billing option: Result is not found in API response") + return nil, fmt.Errorf("error creating CDN client: %s", err) } - resultArray := *resp.Result - return resultArray[0], nil + return cdn.GetBillingOptionDetail(client, productType) } func TestAccBillingOption_basic(t *testing.T) { - var obj interface{} - - rName := "huaweicloud_cdn_billing_option.test" + var ( + obj interface{} + rName = "huaweicloud_cdn_billing_option.test" + ) rc := acceptance.InitResourceCheck( rName, @@ -48,9 +38,12 @@ func TestAccBillingOption_basic(t *testing.T) { getBillingOptionResourceFunc, ) + // Avoid CheckDestroy, because there is nothing in the resource destroy method. // lintignore:AT001 resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acceptance.TestAccPreCheck(t) }, + PreCheck: func() { + acceptance.TestAccPreCheck(t) + }, ProviderFactories: acceptance.TestAccProviderFactories, Steps: []resource.TestStep{ { diff --git a/huaweicloud/services/cdn/data_source_huaweicloud_cdn_billing_option.go b/huaweicloud/services/cdn/data_source_huaweicloud_cdn_billing_option.go index 2be5269701..13e75985e4 100644 --- a/huaweicloud/services/cdn/data_source_huaweicloud_cdn_billing_option.go +++ b/huaweicloud/services/cdn/data_source_huaweicloud_cdn_billing_option.go @@ -7,13 +7,14 @@ package cdn import ( "context" + "fmt" "github.com/hashicorp/go-multierror" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v2/model" + "github.com/chnsz/golangsdk" "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils" @@ -22,7 +23,7 @@ import ( // @API CDN GET /v1.0/cdn/charge/charge-modes func DataSourceBillingOption() *schema.Resource { return &schema.Resource{ - ReadContext: dataBillingOptionRead, + ReadContext: dataSourceBillingOptionRead, Schema: map[string]*schema.Schema{ "product_type": { Type: schema.TypeString, @@ -33,7 +34,7 @@ func DataSourceBillingOption() *schema.Resource { Type: schema.TypeString, Optional: true, Computed: true, - Description: `Specifies the service area`, + Description: `Specifies the service area.`, }, "status": { Type: schema.TypeString, @@ -60,30 +61,50 @@ func DataSourceBillingOption() *schema.Resource { } } -func dataBillingOptionRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - cfg := meta.(*config.Config) - region := cfg.GetRegion(d) - hcCdnClient, err := cfg.HcCdnV2Client(region) +func buildDataSourceBillingOptionQueryParams(d *schema.ResourceData) string { + queryParams := fmt.Sprintf("?product_type=%v", d.Get("product_type")) + if v, ok := d.GetOk("service_area"); ok { + queryParams = fmt.Sprintf("%s&service_area=%v", queryParams, v) + } + if v, ok := d.GetOk("status"); ok { + queryParams = fmt.Sprintf("%s&status=%v", queryParams, v) + } + + return queryParams +} + +func dataSourceBillingOptionRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var ( + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + product = "cdn" + mErr *multierror.Error + ) + + client, err := cfg.NewServiceClient(product, region) if err != nil { - return diag.Errorf("error creating CDN v2 client: %s", err) + return diag.Errorf("error creating CDN client: %s", err) } - request := model.ShowChargeModesRequest{ - ProductType: d.Get("product_type").(string), - Status: utils.StringIgnoreEmpty(d.Get("status").(string)), - ServiceArea: utils.StringIgnoreEmpty(d.Get("service_area").(string)), + getPath := client.Endpoint + "v1.0/cdn/charge/charge-modes" + getPath += buildDataSourceBillingOptionQueryParams(d) + getOpt := golangsdk.RequestOpts{ + KeepResponseBody: true, + MoreHeaders: map[string]string{"Content-Type": "application/json"}, } - resp, err := hcCdnClient.ShowChargeModes(&request) + getResp, err := client.Request("GET", getPath, &getOpt) if err != nil { return diag.Errorf("error retrieving CDN billing option: %s", err) } - if resp == nil || resp.Result == nil { - return diag.Errorf("error retrieving CDN billing option: Result is not found in API response") + getRespBody, err := utils.FlattenResponse(getResp) + if err != nil { + return diag.FromErr(err) } - if len(*resp.Result) == 0 { + result := utils.PathSearch("result[0]", getRespBody, nil) + if result == nil { return diag.Errorf("Your query returned no results. Please change your search criteria and try again.") } @@ -91,19 +112,18 @@ func dataBillingOptionRead(_ context.Context, d *schema.ResourceData, meta inter if err != nil { return diag.Errorf("unable to generate ID: %s", err) } + d.SetId(generateUUID) - resultArray := *resp.Result - resultMap := resultArray[0] - var mErr *multierror.Error mErr = multierror.Append( mErr, - d.Set("product_type", resultMap["product_type"]), - d.Set("service_area", resultMap["service_area"]), - d.Set("status", resultMap["status"]), - d.Set("charge_mode", resultMap["charge_mode"]), - d.Set("created_at", flattenTimeStamp(resultMap["create_time"])), - d.Set("effective_time", flattenTimeStamp(resultMap["effective_time"])), + d.Set("product_type", utils.PathSearch("product_type", result, nil)), + d.Set("service_area", utils.PathSearch("service_area", result, nil)), + d.Set("status", utils.PathSearch("status", result, nil)), + d.Set("charge_mode", utils.PathSearch("charge_mode", result, nil)), + d.Set("created_at", flattenCreatedAt(result)), + d.Set("effective_time", flattenEffectiveTime(result)), ) + return diag.FromErr(mErr.ErrorOrNil()) } diff --git a/huaweicloud/services/cdn/resource_huaweicloud_cdn_billing_option.go b/huaweicloud/services/cdn/resource_huaweicloud_cdn_billing_option.go index c2140e635a..d320c521c6 100644 --- a/huaweicloud/services/cdn/resource_huaweicloud_cdn_billing_option.go +++ b/huaweicloud/services/cdn/resource_huaweicloud_cdn_billing_option.go @@ -7,7 +7,6 @@ package cdn import ( "context" - "encoding/json" "fmt" "github.com/hashicorp/go-multierror" @@ -15,8 +14,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - cdnv2 "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v2" - "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v2/model" + "github.com/chnsz/golangsdk" "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils" @@ -71,105 +69,136 @@ func ResourceBillingOption() *schema.Resource { } } +func buildChangeBillingOptionBodyParams(d *schema.ResourceData) interface{} { + return map[string]interface{}{ + "charge_mode": d.Get("charge_mode").(string), + "product_type": d.Get("product_type").(string), + "service_area": d.Get("service_area").(string), + } +} + +func changeBillingOption(client *golangsdk.ServiceClient, d *schema.ResourceData) error { + chargePath := client.Endpoint + "v1.0/cdn/charge/charge-modes" + chargeOpt := golangsdk.RequestOpts{ + KeepResponseBody: true, + MoreHeaders: map[string]string{"Content-Type": "application/json"}, + JSONBody: buildChangeBillingOptionBodyParams(d), + } + _, err := client.Request("PUT", chargePath, &chargeOpt) + + return err +} + func resourceBillingOptionCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - cfg := meta.(*config.Config) - region := cfg.GetRegion(d) - hcCdnClient, err := cfg.HcCdnV2Client(region) + var ( + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + product = "cdn" + ) + + client, err := cfg.NewServiceClient(product, region) if err != nil { - return diag.Errorf("error creating CDN v2 client: %s", err) + return diag.Errorf("error creating CDN client: %s", err) } - if err := changeBillingOption(hcCdnClient, d); err != nil { - return diag.FromErr(err) + if err := changeBillingOption(client, d); err != nil { + return diag.Errorf("error modifying CDN billing option in creation operation: %s", err) } generateUUID, err := uuid.GenerateUUID() if err != nil { return diag.Errorf("unable to generate ID: %s", err) } + d.SetId(generateUUID) return resourceBillingOptionRead(ctx, d, meta) } -func resourceBillingOptionUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - cfg := meta.(*config.Config) - region := cfg.GetRegion(d) - hcCdnClient, err := cfg.HcCdnV2Client(region) - if err != nil { - return diag.Errorf("error creating CDN v2 client: %s", err) - } - - if err := changeBillingOption(hcCdnClient, d); err != nil { - return diag.FromErr(err) - } - - return resourceBillingOptionRead(ctx, d, meta) +func buildBillingOptionQueryParams(productType string) string { + return fmt.Sprintf("?product_type=%v", productType) } -func changeBillingOption(hcCdnClient *cdnv2.CdnClient, d *schema.ResourceData) error { - req := model.SetChargeModesRequest{ - Body: &model.SetChargeModesBody{ - ChargeMode: d.Get("charge_mode").(string), - ProductType: d.Get("product_type").(string), - ServiceArea: d.Get("service_area").(string), - }, +func GetBillingOptionDetail(client *golangsdk.ServiceClient, productType string) (interface{}, error) { + getPath := client.Endpoint + "v1.0/cdn/charge/charge-modes" + getPath += buildBillingOptionQueryParams(productType) + getOpt := golangsdk.RequestOpts{ + KeepResponseBody: true, + MoreHeaders: map[string]string{"Content-Type": "application/json"}, } - _, err := hcCdnClient.SetChargeModes(&req) + + getResp, err := client.Request("GET", getPath, &getOpt) if err != nil { - return fmt.Errorf("error modifying CDN billing options: %s", err) + // The billing model is always valuable and there is no need to pay attention to scenarios where resource does + // not exist. + return nil, fmt.Errorf("error retrieving CDN billing option: %s", err) } - return nil -} -func resourceBillingOptionRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - cfg := meta.(*config.Config) - region := cfg.GetRegion(d) - hcCdnClient, err := cfg.HcCdnV2Client(region) + getRespBody, err := utils.FlattenResponse(getResp) if err != nil { - return diag.Errorf("error creating CDN v2 client: %s", err) + return nil, err } - request := model.ShowChargeModesRequest{ - ProductType: d.Get("product_type").(string), + result := utils.PathSearch("result[0]", getRespBody, nil) + if result == nil { + return nil, fmt.Errorf("error retrieving CDN billing option: result is not found in API response") } - resp, err := hcCdnClient.ShowChargeModes(&request) + return result, nil +} + +func resourceBillingOptionRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var ( + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + product = "cdn" + mErr *multierror.Error + ) + + client, err := cfg.NewServiceClient(product, region) if err != nil { - // The billing model is always valuable and there is no need to pay attention to scenarios where resources do not exist. - return diag.Errorf("error retrieving CDN billing option: %s", err) + return diag.Errorf("error creating CDN client: %s", err) } - if resp == nil || resp.Result == nil || len(*resp.Result) == 0 { - return diag.Errorf("error retrieving CDN billing option: Result is not found in API response") + result, err := GetBillingOptionDetail(client, d.Get("product_type").(string)) + if err != nil { + return diag.FromErr(err) } - var mErr *multierror.Error - resultArray := *resp.Result - resultMap := resultArray[0] - mErr = multierror.Append( mErr, - d.Set("product_type", resultMap["product_type"]), - d.Set("service_area", resultMap["service_area"]), - d.Set("created_at", flattenTimeStamp(resultMap["create_time"])), - d.Set("effective_time", flattenTimeStamp(resultMap["effective_time"])), - d.Set("status", resultMap["status"]), - d.Set("current_charge_mode", resultMap["charge_mode"]), + d.Set("product_type", utils.PathSearch("product_type", result, nil)), + d.Set("service_area", utils.PathSearch("service_area", result, nil)), + d.Set("created_at", flattenCreatedAt(result)), + d.Set("effective_time", flattenEffectiveTime(result)), + d.Set("status", utils.PathSearch("status", result, nil)), + d.Set("current_charge_mode", utils.PathSearch("charge_mode", result, nil)), ) return diag.FromErr(mErr.ErrorOrNil()) } -func flattenTimeStamp(timestamp interface{}) string { - if timestamp == nil { - return "" - } - timeInt64, err := timestamp.(json.Number).Int64() +func flattenEffectiveTime(result interface{}) string { + effectiveTime := utils.PathSearch("effective_time", result, float64(0)).(float64) + return utils.FormatTimeStampRFC3339(int64(effectiveTime)/1000, false) +} + +func resourceBillingOptionUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var ( + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + product = "cdn" + ) + client, err := cfg.NewServiceClient(product, region) if err != nil { - return "" + return diag.Errorf("error creating CDN client: %s", err) + } + + if err := changeBillingOption(client, d); err != nil { + return diag.Errorf("error modifying CDN billing option in update operation: %s", err) } - return utils.FormatTimeStampRFC3339(timeInt64/1000, false) + + return resourceBillingOptionRead(ctx, d, meta) } func resourceBillingOptionDelete(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {