From 48aed6eec7901cac74422a185c345aaf2ebe38ef Mon Sep 17 00:00:00 2001 From: luxiaohang <deerhang@163.com> Date: Wed, 13 Nov 2024 17:03:48 +0800 Subject: [PATCH] chore(dsc): modify the code style and document description --- docs/resources/dsc_asset_obs.md | 15 +- docs/resources/dsc_instance.md | 42 ++-- huaweicloud/services/acceptance/acceptance.go | 9 + ...resource_huaweicloud_dsc_asset_obs_test.go | 55 ++--- .../resource_huaweicloud_dsc_instance_test.go | 34 ++- .../dsc/resource_huaweicloud_dsc_asset_obs.go | 174 +++++--------- .../dsc/resource_huaweicloud_dsc_instance.go | 222 ++++++++---------- 7 files changed, 233 insertions(+), 318 deletions(-) diff --git a/docs/resources/dsc_asset_obs.md b/docs/resources/dsc_asset_obs.md index 5d8767011b..60371dd6bc 100644 --- a/docs/resources/dsc_asset_obs.md +++ b/docs/resources/dsc_asset_obs.md @@ -2,12 +2,13 @@ subcategory: "Data Security Center (DSC)" layout: "huaweicloud" page_title: "HuaweiCloud: huaweicloud_dsc_asset_obs" -description: "" +description: |- + Manages an OBS asset resource of DSC within HuaweiCloud. --- # huaweicloud_dsc_asset_obs -Manages an OBS asset resource of DSC within HuaweiCloud. +Manages an OBS asset resource of DSC within HuaweiCloud. ## Example Usage @@ -29,13 +30,13 @@ The following arguments are supported: * `region` - (Optional, String, ForceNew) Specifies the region in which to create the resource. If omitted, the provider-level region will be used. Changing this parameter will create a new resource. -* `name` - (Required, String) The name of asset. +* `name` - (Required, String) Specifies the name of asset. -* `bucket_name` - (Required, String, ForceNew) The bucket name. +* `bucket_name` - (Required, String, ForceNew) Specifies the bucket name. Changing this parameter will create a new resource. -* `bucket_policy` - (Required, String, ForceNew) The bucket policy. +* `bucket_policy` - (Required, String, ForceNew) Specifies the bucket policy. Changing this parameter will create a new resource. @@ -47,8 +48,8 @@ In addition to all arguments above, the following attributes are exported: ## Import -The obs asset can be imported using the `id`, e.g. +The OBS asset resource can be imported using the `id`, e.g. ```bash -$ terraform import huaweicloud_dsc_asset_obs.test 0ce123456a00f2591fabc00385ff1234 +$ terraform import huaweicloud_dsc_asset_obs.test <id> ``` diff --git a/docs/resources/dsc_instance.md b/docs/resources/dsc_instance.md index cca93ae9c4..54aca1ea3d 100644 --- a/docs/resources/dsc_instance.md +++ b/docs/resources/dsc_instance.md @@ -2,12 +2,13 @@ subcategory: "Data Security Center (DSC)" layout: "huaweicloud" page_title: "HuaweiCloud: huaweicloud_dsc_instance" -description: "" +description: |- + Manages a DSC instance resource within HuaweiCloud. --- # huaweicloud_dsc_instance -Manages a DSC instance resource within HuaweiCloud. +Manages a DSC instance resource within HuaweiCloud. ## Example Usage @@ -30,46 +31,45 @@ The following arguments are supported: * `region` - (Optional, String, ForceNew) Specifies the region in which to create the resource. If omitted, the provider-level region will be used. Changing this parameter will create a new resource. -* `charging_mode` - (Required, String, ForceNew) Billing mode. - The options are as follows: - + **prePaid**: the yearly/monthly billing mode. +* `charging_mode` - (Required, String, ForceNew) Specifies the billing mode. + Valid value is **prePaid** (the yearly/monthly billing mode). Changing this parameter will create a new resource. -* `period_unit` - (Required, String, ForceNew) The charging period unit. +* `period_unit` - (Required, String, ForceNew) Specifies the charging period unit. Valid values are **month** and **year**. This parameter is mandatory if `charging_mode` is set to **prePaid**. Changing this parameter will create a new resource. -* `period` - (Required, Int, ForceNew) The charging period. +* `period` - (Required, Int, ForceNew) Specifies the charging period. If `period_unit` is set to **month**, the value ranges from `1` to `9`. If `period_unit` is set to **year**, the value ranges from `1` to `3`. This parameter is mandatory if `charging_mode` is set to **prePaid**. Changing this parameter will create a new resource. -* `edition` - (Required, String, ForceNew) The edition of DSC. - By default, it supports 2 databases and 100GB of OBS storage +* `edition` - (Required, String, ForceNew) Specifies the edition of DSC. + By default, it supports `2` databases and `100`GB of OBS storage. The options are as follows: - + **base_standard**: Standard Edition. - It supports **Overview**, **Sensitive Data Identification** and **Data Usage Audit**. - + **base_professional**: Professional Edition. - It supports **Overview**, **Sensitive Data Identification**, **Data Usage Audit**, **Data Masking**, - and **Watermark injection/extraction** + + **base_standard**: Standard Edition. + It supports **Overview**, **Sensitive Data Identification** and **Data Usage Audit**. + + **base_professional**: Professional Edition. + It supports **Overview**, **Sensitive Data Identification**, **Data Usage Audit**, **Data Masking**, + and **Watermark injection/extraction**. Changing this parameter will create a new resource. -* `auto_renew` - (Optional, String, ForceNew) Whether auto renew is enabled. Valid values are **true** and **false**. - Defaults to **false**. +* `auto_renew` - (Optional, String, ForceNew) Specifies whether auto-renew is enabled. Valid values are **true** and **false**. + Defaults to **false**. Changing this parameter will create a new resource. -* `obs_expansion_package` - (Optional, Int, ForceNew) The size of OBS expansion packages. - One expansion package offers 1 TB of OBS storage. +* `obs_expansion_package` - (Optional, Int, ForceNew) Specifies the size of OBS expansion packages. + One expansion package offers `1` TB of OBS storage. Changing this parameter will create a new resource. -* `database_expansion_package` - (Optional, Int, ForceNew) The size of database expansion packages. +* `database_expansion_package` - (Optional, Int, ForceNew) Specifies the size of database expansion packages. One expansion package offers one database. Changing this parameter will create a new resource. @@ -82,8 +82,8 @@ In addition to all arguments above, the following attributes are exported: ## Import -The dsc instance can be imported using the `id`, e.g. +The DSC instance resource can be imported using the `id`, e.g. ```bash -$ terraform import huaweicloud_dsc_instance.test 0ce123456a00f2591fabc00385ff1234 +$ terraform import huaweicloud_dsc_instance.test <id> ``` diff --git a/huaweicloud/services/acceptance/acceptance.go b/huaweicloud/services/acceptance/acceptance.go index 3ea16fcef1..33f39fe105 100644 --- a/huaweicloud/services/acceptance/acceptance.go +++ b/huaweicloud/services/acceptance/acceptance.go @@ -250,6 +250,8 @@ var ( HW_DC_VIRTUAL_INTERFACE_ID = os.Getenv("HW_DC_VIRTUAL_INTERFACE_ID") HW_DC_ENABLE_FLAG = os.Getenv("HW_DC_ENABLE_FLAG") + HW_DSC_INSTANCE_ID = os.Getenv("HW_DSC_INSTANCE_ID") + HW_CES_START_TIME = os.Getenv("HW_CES_START_TIME") HW_CES_END_TIME = os.Getenv("HW_CES_END_TIME") @@ -2534,6 +2536,13 @@ func TestAccPrecheckDcFlag(t *testing.T) { } } +// lintignore:AT003 +func TestAccPrecheckDscInstance(t *testing.T) { + if HW_DSC_INSTANCE_ID == "" { + t.Skip("HW_DSC_INSTANCE_ID must be set for the acceptance test") + } +} + // lintignore:AT003 func TestAccPrecheckTimeStamp(t *testing.T) { if HW_CDN_TIMESTAMP == "" { diff --git a/huaweicloud/services/acceptance/dsc/resource_huaweicloud_dsc_asset_obs_test.go b/huaweicloud/services/acceptance/dsc/resource_huaweicloud_dsc_asset_obs_test.go index a18ea04d3c..6554890797 100644 --- a/huaweicloud/services/acceptance/dsc/resource_huaweicloud_dsc_asset_obs_test.go +++ b/huaweicloud/services/acceptance/dsc/resource_huaweicloud_dsc_asset_obs_test.go @@ -16,40 +16,37 @@ import ( ) func getAssetObsResourceFunc(cfg *config.Config, state *terraform.ResourceState) (interface{}, error) { - region := acceptance.HW_REGION_NAME - // getAssetObs: Query the asset OBS var ( - getAssetObsHttpUrl = "v1/{project_id}/sdg/asset/obs/buckets" - getAssetObsProduct = "dsc" + region = acceptance.HW_REGION_NAME + httpUrl = "v1/{project_id}/sdg/asset/obs/buckets" + product = "dsc" ) - getAssetObsClient, err := cfg.NewServiceClient(getAssetObsProduct, region) + client, err := cfg.NewServiceClient(product, region) if err != nil { - return nil, fmt.Errorf("error creating AssetObs Client: %s", err) + return nil, fmt.Errorf("error creating DSC client: %s", err) } - getAssetObsPath := getAssetObsClient.Endpoint + getAssetObsHttpUrl - getAssetObsPath = strings.ReplaceAll(getAssetObsPath, "{project_id}", getAssetObsClient.ProjectID) - getAssetObsPath += "?added=true" - - getAssetObsOpt := golangsdk.RequestOpts{ + requestPath := client.Endpoint + httpUrl + requestPath = strings.ReplaceAll(requestPath, "{project_id}", client.ProjectID) + requestPath += "?added=true" + requestOpt := golangsdk.RequestOpts{ KeepResponseBody: true, - OkCodes: []int{ - 200, - }, } - getAssetObsResp, err := getAssetObsClient.Request("GET", getAssetObsPath, &getAssetObsOpt) + + resp, err := client.Request("GET", requestPath, &requestOpt) if err != nil { - return nil, fmt.Errorf("error retrieving AssetObs: %s", err) + return nil, fmt.Errorf("error retrieving DSC asset OBS buckets: %s", err) } - getAssetObsRespBody, err := utils.FlattenResponse(getAssetObsResp) + respBody, err := utils.FlattenResponse(resp) if err != nil { - return nil, fmt.Errorf("error retrieving AssetObs: %s", err) + return nil, err } - assetObs := utils.PathSearch(fmt.Sprintf("buckets[?id=='%s']|[0]", state.Primary.ID), getAssetObsRespBody, nil) + expression := fmt.Sprintf("buckets[?id=='%s']|[0]", state.Primary.ID) + assetObs := utils.PathSearch(expression, respBody, nil) if assetObs == nil { - return nil, fmt.Errorf("error retrieving AssetObs: %s", err) + return nil, golangsdk.ErrDefault404{} } return assetObs, nil } @@ -68,7 +65,11 @@ func TestAccAssetObs_basic(t *testing.T) { ) resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acceptance.TestAccPreCheck(t) }, + PreCheck: func() { + acceptance.TestAccPreCheck(t) + // Configure a DSC instance with OBS authorization enabled. + acceptance.TestAccPrecheckDscInstance(t) + }, ProviderFactories: acceptance.TestAccProviderFactories, CheckDestroy: rc.CheckResourceDestroy(), Steps: []resource.TestStep{ @@ -101,26 +102,16 @@ func TestAccAssetObs_basic(t *testing.T) { func testAssetObs_basic(name, obsName string) string { return fmt.Sprintf(` -%s - resource "huaweicloud_obs_bucket" "test" { bucket = "%s" acl = "private" force_destroy = true - - lifecycle { - ignore_changes = [ - logging, - ] - } } resource "huaweicloud_dsc_asset_obs" "test" { name = "%s" bucket_name = huaweicloud_obs_bucket.test.bucket bucket_policy = "private" - - depends_on = [huaweicloud_dsc_instance.test] } -`, testDscInstance_basic(), obsName, name) +`, obsName, name) } diff --git a/huaweicloud/services/acceptance/dsc/resource_huaweicloud_dsc_instance_test.go b/huaweicloud/services/acceptance/dsc/resource_huaweicloud_dsc_instance_test.go index ec0761f15e..d973463a3b 100644 --- a/huaweicloud/services/acceptance/dsc/resource_huaweicloud_dsc_instance_test.go +++ b/huaweicloud/services/acceptance/dsc/resource_huaweicloud_dsc_instance_test.go @@ -16,42 +16,36 @@ import ( ) func getDscInstanceResourceFunc(cfg *config.Config, _ *terraform.ResourceState) (interface{}, error) { - region := acceptance.HW_REGION_NAME - // getDscInstance: Query the DSC instance var ( - getDscInstanceHttpUrl = "v1/{project_id}/period/product/specification" - getDscInstanceProduct = "dsc" + region = acceptance.HW_REGION_NAME + httpUrl = "v1/{project_id}/period/product/specification" + product = "dsc" ) - getDscInstanceClient, err := cfg.NewServiceClient(getDscInstanceProduct, region) + client, err := cfg.NewServiceClient(product, region) if err != nil { return nil, fmt.Errorf("error creating DscInstance Client: %s", err) } - getDscInstancePath := getDscInstanceClient.Endpoint + getDscInstanceHttpUrl - getDscInstancePath = strings.ReplaceAll(getDscInstancePath, "{project_id}", getDscInstanceClient.ProjectID) - - getDscInstanceOpt := golangsdk.RequestOpts{ + requestPath := client.Endpoint + httpUrl + requestPath = strings.ReplaceAll(requestPath, "{project_id}", client.ProjectID) + requestOpt := golangsdk.RequestOpts{ KeepResponseBody: true, - OkCodes: []int{ - 200, - }, } - getDscInstanceResp, err := getDscInstanceClient.Request("GET", getDscInstancePath, &getDscInstanceOpt) + resp, err := client.Request("GET", requestPath, &requestOpt) if err != nil { - return nil, fmt.Errorf("error retrieving DscInstance: %s", err) + return nil, fmt.Errorf("error retrieving DSC instance: %s", err) } - getDscInstanceRespBody, err := utils.FlattenResponse(getDscInstanceResp) + respBody, err := utils.FlattenResponse(resp) if err != nil { - return nil, fmt.Errorf("error retrieving DscInstance: %s", err) + return nil, err } - orderInfo := utils.PathSearch("orderInfo", getDscInstanceRespBody, []interface{}{}) - orders := orderInfo.([]interface{}) + orders := utils.PathSearch("orderInfo", respBody, make([]interface{}, 0)).([]interface{}) if len(orders) == 0 { - return nil, fmt.Errorf("error retrieving DscInstance: %s", err) + return nil, fmt.Errorf("error retrieving DSC instance: %s", err) } - return orderInfo, nil + return orders, nil } func TestAccDscInstance_basic(t *testing.T) { diff --git a/huaweicloud/services/dsc/resource_huaweicloud_dsc_asset_obs.go b/huaweicloud/services/dsc/resource_huaweicloud_dsc_asset_obs.go index 6f976166ae..35cd94b8cf 100644 --- a/huaweicloud/services/dsc/resource_huaweicloud_dsc_asset_obs.go +++ b/huaweicloud/services/dsc/resource_huaweicloud_dsc_asset_obs.go @@ -63,68 +63,54 @@ func ResourceAssetObs() *schema.Resource { } } -func resourceAssetObsCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - cfg := meta.(*config.Config) - region := cfg.GetRegion(d) - - // createAssetObs: create an OBS asset. - var ( - createAssetObsHttpUrl = "v1/{project_id}/sdg/asset/obs/buckets" - createAssetObsProduct = "dsc" - ) - createAssetObsClient, err := cfg.NewServiceClient(createAssetObsProduct, region) - if err != nil { - return diag.Errorf("error creating AssetObs Client: %s", err) - } - - createAssetObsPath := createAssetObsClient.Endpoint + createAssetObsHttpUrl - createAssetObsPath = strings.ReplaceAll(createAssetObsPath, "{project_id}", createAssetObsClient.ProjectID) - - createAssetObsOpt := golangsdk.RequestOpts{ +func queryAssetObsBucket(client *golangsdk.ServiceClient) (interface{}, error) { + requestPath := client.Endpoint + "v1/{project_id}/sdg/asset/obs/buckets" + requestPath = strings.ReplaceAll(requestPath, "{project_id}", client.ProjectID) + requestPath += "?added=true" + requestOpt := golangsdk.RequestOpts{ KeepResponseBody: true, - OkCodes: []int{ - 200, - }, } - createAssetObsOpt.JSONBody = utils.RemoveNil(buildCreateAssetObsBodyParams(d, cfg)) - _, err = createAssetObsClient.Request("POST", createAssetObsPath, &createAssetObsOpt) + resp, err := client.Request("GET", requestPath, &requestOpt) if err != nil { - return diag.Errorf("error creating AssetObs: %s", err) + return nil, err } - // getAssetObs: Query the asset OBS + return utils.FlattenResponse(resp) +} + +func resourceAssetObsCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var ( - getAssetObsHttpUrl = "v1/{project_id}/sdg/asset/obs/buckets" - getAssetObsProduct = "dsc" + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + httpUrl = "v1/{project_id}/sdg/asset/obs/buckets" + product = "dsc" + name = d.Get("name").(string) ) - getAssetObsClient, err := cfg.NewServiceClient(getAssetObsProduct, region) + client, err := cfg.NewServiceClient(product, region) if err != nil { - return diag.Errorf("error creating AssetObs Client: %s", err) + return diag.Errorf("error creating DSC client: %s", err) } - getAssetObsPath := getAssetObsClient.Endpoint + getAssetObsHttpUrl - getAssetObsPath = strings.ReplaceAll(getAssetObsPath, "{project_id}", getAssetObsClient.ProjectID) - getAssetObsPath += "?added=true" - - getAssetObsOpt := golangsdk.RequestOpts{ + requestPath := client.Endpoint + httpUrl + requestPath = strings.ReplaceAll(requestPath, "{project_id}", client.ProjectID) + requestOpt := golangsdk.RequestOpts{ KeepResponseBody: true, - OkCodes: []int{ - 200, - }, + JSONBody: utils.RemoveNil(buildCreateAssetObsBodyParams(d, cfg)), } - getAssetObsResp, err := getAssetObsClient.Request("GET", getAssetObsPath, &getAssetObsOpt) + _, err = client.Request("POST", requestPath, &requestOpt) if err != nil { - return diag.Errorf("error creating AssetObs: %s", err) + return diag.Errorf("error adding DSC asset OBS bucket: %s", err) } - getAssetObsRespBody, err := utils.FlattenResponse(getAssetObsResp) + respBody, err := queryAssetObsBucket(client) if err != nil { - return diag.FromErr(err) + return diag.Errorf("error retrieving DSC asset OBS buckets: %s", err) } - assetObsId := utils.PathSearch(fmt.Sprintf("buckets[?asset_name=='%s']|[0].id", d.Get("name").(string)), getAssetObsRespBody, "").(string) + expression := fmt.Sprintf("buckets[?asset_name=='%s']|[0].id", name) + assetObsId := utils.PathSearch(expression, respBody, "").(string) if assetObsId == "" { - return diag.Errorf("error creating AssetObs: ID is not found in API response") + return diag.Errorf("error adding DSC asset OBS bucket: ID is not found in API response") } d.SetId(assetObsId) @@ -145,44 +131,24 @@ func buildCreateAssetObsBodyParams(d *schema.ResourceData, cfg *config.Config) m } func resourceAssetObsRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - cfg := meta.(*config.Config) - region := cfg.GetRegion(d) - - var mErr *multierror.Error - - // getAssetObs: Query the asset OBS var ( - getAssetObsHttpUrl = "v1/{project_id}/sdg/asset/obs/buckets" - getAssetObsProduct = "dsc" + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + mErr *multierror.Error + product = "dsc" ) - getAssetObsClient, err := cfg.NewServiceClient(getAssetObsProduct, region) - if err != nil { - return diag.Errorf("error creating AssetObs Client: %s", err) - } - - getAssetObsPath := getAssetObsClient.Endpoint + getAssetObsHttpUrl - getAssetObsPath = strings.ReplaceAll(getAssetObsPath, "{project_id}", getAssetObsClient.ProjectID) - getAssetObsPath += "?added=true" - - getAssetObsOpt := golangsdk.RequestOpts{ - KeepResponseBody: true, - OkCodes: []int{ - 200, - }, - } - getAssetObsResp, err := getAssetObsClient.Request("GET", getAssetObsPath, &getAssetObsOpt) - + client, err := cfg.NewServiceClient(product, region) if err != nil { - return common.CheckDeletedDiag(d, err, "error retrieving AssetObs") + return diag.Errorf("error creating DSC client: %s", err) } - getAssetObsRespBody, err := utils.FlattenResponse(getAssetObsResp) + respBody, err := queryAssetObsBucket(client) if err != nil { - return diag.FromErr(err) + return common.CheckDeletedDiag(d, err, "error retrieving DSC asset OBS buckets") } - assetObs := utils.PathSearch(fmt.Sprintf("buckets[?id=='%s']|[0]", d.Id()), getAssetObsRespBody, nil) - + expression := fmt.Sprintf("buckets[?id=='%s']|[0]", d.Id()) + assetObs := utils.PathSearch(expression, respBody, nil) mErr = multierror.Append( mErr, d.Set("region", region), @@ -198,35 +164,26 @@ func resourceAssetObsUpdate(ctx context.Context, d *schema.ResourceData, meta in cfg := meta.(*config.Config) region := cfg.GetRegion(d) - updateAssetObshasChanges := []string{ - "name", - } - - if d.HasChanges(updateAssetObshasChanges...) { - // updateAssetObs: update the OBS asset name. + if d.HasChange("name") { var ( - updateAssetObsHttpUrl = "v1/{project_id}/sdg/asset/{id}/name" - updateAssetObsProduct = "dsc" + httpUrl = "v1/{project_id}/sdg/asset/{id}/name" + product = "dsc" ) - updateAssetObsClient, err := cfg.NewServiceClient(updateAssetObsProduct, region) + client, err := cfg.NewServiceClient(product, region) if err != nil { - return diag.Errorf("error creating AssetObs Client: %s", err) + return diag.Errorf("error creating DSC client: %s", err) } - updateAssetObsPath := updateAssetObsClient.Endpoint + updateAssetObsHttpUrl - updateAssetObsPath = strings.ReplaceAll(updateAssetObsPath, "{project_id}", updateAssetObsClient.ProjectID) - updateAssetObsPath = strings.ReplaceAll(updateAssetObsPath, "{id}", d.Id()) - - updateAssetObsOpt := golangsdk.RequestOpts{ + requestPath := client.Endpoint + httpUrl + requestPath = strings.ReplaceAll(requestPath, "{project_id}", client.ProjectID) + requestPath = strings.ReplaceAll(requestPath, "{id}", d.Id()) + requestOpt := golangsdk.RequestOpts{ KeepResponseBody: true, - OkCodes: []int{ - 200, - }, + JSONBody: utils.RemoveNil(buildUpdateAssetObsBodyParams(d, cfg)), } - updateAssetObsOpt.JSONBody = utils.RemoveNil(buildUpdateAssetObsBodyParams(d, cfg)) - _, err = updateAssetObsClient.Request("PUT", updateAssetObsPath, &updateAssetObsOpt) + _, err = client.Request("PUT", requestPath, &requestOpt) if err != nil { - return diag.Errorf("error updating AssetObs: %s", err) + return diag.Errorf("error updating DSC asset name: %s", err) } } return resourceAssetObsRead(ctx, d, meta) @@ -240,31 +197,26 @@ func buildUpdateAssetObsBodyParams(d *schema.ResourceData, _ *config.Config) map } func resourceAssetObsDelete(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - cfg := meta.(*config.Config) - region := cfg.GetRegion(d) - var ( - deleteAssetObsHttpUrl = "v1/{project_id}/sdg/asset/obs/bucket/{id}" - deleteAssetObsProduct = "dsc" + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + httpUrl = "v1/{project_id}/sdg/asset/obs/bucket/{id}" + product = "dsc" ) - deleteAssetObsClient, err := cfg.NewServiceClient(deleteAssetObsProduct, region) + client, err := cfg.NewServiceClient(product, region) if err != nil { - return diag.Errorf("error creating AssetObs Client: %s", err) + return diag.Errorf("error creating DSC client: %s", err) } - deleteAssetObsPath := deleteAssetObsClient.Endpoint + deleteAssetObsHttpUrl - deleteAssetObsPath = strings.ReplaceAll(deleteAssetObsPath, "{project_id}", deleteAssetObsClient.ProjectID) - deleteAssetObsPath = strings.ReplaceAll(deleteAssetObsPath, "{id}", d.Id()) - - deleteAssetObsOpt := golangsdk.RequestOpts{ + requestPath := client.Endpoint + httpUrl + requestPath = strings.ReplaceAll(requestPath, "{project_id}", client.ProjectID) + requestPath = strings.ReplaceAll(requestPath, "{id}", d.Id()) + requestOpt := golangsdk.RequestOpts{ KeepResponseBody: true, - OkCodes: []int{ - 200, - }, } - _, err = deleteAssetObsClient.Request("DELETE", deleteAssetObsPath, &deleteAssetObsOpt) + _, err = client.Request("DELETE", requestPath, &requestOpt) if err != nil { - return diag.Errorf("error deleting AssetObs: %s", err) + return diag.Errorf("error deleting DSC asset OBS bucket: %s", err) } return nil diff --git a/huaweicloud/services/dsc/resource_huaweicloud_dsc_instance.go b/huaweicloud/services/dsc/resource_huaweicloud_dsc_instance.go index 7b4247d112..ebb2ceff88 100644 --- a/huaweicloud/services/dsc/resource_huaweicloud_dsc_instance.go +++ b/huaweicloud/services/dsc/resource_huaweicloud_dsc_instance.go @@ -16,7 +16,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/chnsz/golangsdk" @@ -74,27 +73,18 @@ func ResourceDscInstance() *schema.Resource { Required: true, ForceNew: true, Description: `The edition of DSC.`, - ValidateFunc: validation.StringInSlice([]string{ - resourceSpecCodeStandardBase, resourceSpecCodeProBase, - }, false), }, "charging_mode": { Type: schema.TypeString, Required: true, ForceNew: true, Description: `Billing mode.`, - ValidateFunc: validation.StringInSlice([]string{ - "prePaid", - }, false), }, "period_unit": { Type: schema.TypeString, Required: true, ForceNew: true, Description: `The charging period unit.`, - ValidateFunc: validation.StringInSlice([]string{ - "month", "year", - }, false), }, "period": { Type: schema.TypeInt, @@ -107,9 +97,6 @@ func ResourceDscInstance() *schema.Resource { Optional: true, ForceNew: true, Description: `Whether auto renew is enabled. Valid values are "true" and "false".`, - ValidateFunc: validation.StringInSlice([]string{ - "true", "false", - }, false), }, "obs_expansion_package": { Type: schema.TypeInt, @@ -129,71 +116,71 @@ func ResourceDscInstance() *schema.Resource { } } -func resourceDscInstanceCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - cfg := meta.(*config.Config) - region := cfg.GetRegion(d) - - // createDscInstance: create a DSC. +func payDscInstanceOrder(cfg *config.Config, d *schema.ResourceData, orderId string) error { var ( - createDscInstanceHttpUrl = "v1/{project_id}/period/order" - createDscInstanceProduct = "dsc" + region = cfg.GetRegion(d) + httpUrl = "v3/orders/customer-orders/pay" + product = "bss" ) - createDscInstanceClient, err := cfg.NewServiceClient(createDscInstanceProduct, region) + client, err := cfg.NewServiceClient(product, region) if err != nil { - return diag.Errorf("error creating DscInstance Client: %s", err) + return fmt.Errorf("error creating BSS client: %s", err) } - createDscInstancePath := createDscInstanceClient.Endpoint + createDscInstanceHttpUrl - createDscInstancePath = strings.ReplaceAll(createDscInstancePath, "{project_id}", createDscInstanceClient.ProjectID) - - createDscInstanceOpt := golangsdk.RequestOpts{ + requestPath := client.Endpoint + httpUrl + requestOpt := golangsdk.RequestOpts{ KeepResponseBody: true, OkCodes: []int{ - 200, + 204, }, + JSONBody: utils.RemoveNil(buildPayOrderBodyParams(orderId)), } - bodyParams, err := buildCreateDscInstanceBodyParams(d, cfg) + _, err = client.Request("POST", requestPath, &requestOpt) if err != nil { - return diag.FromErr(err) + return fmt.Errorf("error paying DSC instance order (%s): %s", orderId, err) } - createDscInstanceOpt.JSONBody = utils.RemoveNil(bodyParams) - createDscInstanceResp, err := createDscInstanceClient.Request("POST", createDscInstancePath, &createDscInstanceOpt) + return nil +} + +func resourceDscInstanceCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var ( + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + httpUrl = "v1/{project_id}/period/order" + product = "dsc" + ) + client, err := cfg.NewServiceClient(product, region) if err != nil { - return diag.Errorf("error creating DscInstance: %s", err) + return diag.Errorf("error creating DSC client: %s", err) } - createDscInstanceRespBody, err := utils.FlattenResponse(createDscInstanceResp) + requestPath := client.Endpoint + httpUrl + requestPath = strings.ReplaceAll(requestPath, "{project_id}", client.ProjectID) + requestOpt := golangsdk.RequestOpts{ + KeepResponseBody: true, + } + bodyParams, err := buildCreateDscInstanceBodyParams(d, cfg) if err != nil { return diag.FromErr(err) } - - orderId := utils.PathSearch("order_id", createDscInstanceRespBody, "").(string) - if orderId == "" { - return diag.Errorf("unable to find the DSC instance ID from the API response") + requestOpt.JSONBody = utils.RemoveNil(bodyParams) + resp, err := client.Request("POST", requestPath, &requestOpt) + if err != nil { + return diag.Errorf("error creating DSC instance: %s", err) } - // auto pay - var ( - payOrderHttpUrl = "v3/orders/customer-orders/pay" - payOrderProduct = "bss" - ) - payOrderClient, err := cfg.NewServiceClient(payOrderProduct, region) + respBody, err := utils.FlattenResponse(resp) if err != nil { - return diag.Errorf("error creating BSS Client: %s", err) + return diag.FromErr(err) } - payOrderPath := payOrderClient.Endpoint + payOrderHttpUrl - - payOrderOpt := golangsdk.RequestOpts{ - KeepResponseBody: true, - OkCodes: []int{ - 204, - }, + orderId := utils.PathSearch("order_id", respBody, "").(string) + if orderId == "" { + return diag.Errorf("error creating DSC instance: ID is not found in API response") } - payOrderOpt.JSONBody = utils.RemoveNil(buildPayOrderBodyParams(orderId)) - _, err = payOrderClient.Request("POST", payOrderPath, &payOrderOpt) - if err != nil { - return diag.Errorf("error pay order=%s: %s", d.Id(), err) + + if err := payDscInstanceOrder(cfg, d, orderId); err != nil { + return diag.FromErr(err) } bssClient, err := cfg.BssV2Client(cfg.GetRegion(d)) @@ -349,33 +336,31 @@ func buildProductInfoMap(products []interface{}) map[string]string { func getOrderProducts(cfg *config.Config, region string, productInfos []map[string]interface{}) ([]interface{}, error) { var ( - getOrderProductsHttpUrl = "v2/bills/ratings/period-resources/subscribe-rate" - getOrderProductsProduct = "bss" + httpUrl = "v2/bills/ratings/period-resources/subscribe-rate" + product = "bss" ) - getOrderProductsClient, err := cfg.NewServiceClient(getOrderProductsProduct, region) + client, err := cfg.NewServiceClient(product, region) if err != nil { - return nil, fmt.Errorf("error creating BSS Client: %s", err) + return nil, fmt.Errorf("error creating BSS client: %s", err) } - getOrderProductsPath := getOrderProductsClient.Endpoint + getOrderProductsHttpUrl - - getOrderProductsOpt := golangsdk.RequestOpts{ + requestPath := client.Endpoint + httpUrl + requestOpt := golangsdk.RequestOpts{ KeepResponseBody: true, + JSONBody: utils.RemoveNil(buildGetProductIdBodyParams(client.ProjectID, productInfos)), } - getOrderProductsOpt.JSONBody = utils.RemoveNil(buildGetProductIdBodyParams(getOrderProductsClient.ProjectID, - productInfos)) - getOrderProductResp, err := getOrderProductsClient.Request("POST", getOrderProductsPath, &getOrderProductsOpt) - + resp, err := client.Request("POST", requestPath, &requestOpt) if err != nil { return nil, fmt.Errorf("error getting DSC order product infos: %s", err) } - getOrderProductRespBody, err := utils.FlattenResponse(getOrderProductResp) + respBody, err := utils.FlattenResponse(resp) if err != nil { return nil, err } - curJson := utils.PathSearch("official_website_rating_result.product_rating_results", - getOrderProductRespBody, make([]interface{}, 0)) + + expression := "official_website_rating_result.product_rating_results" + curJson := utils.PathSearch(expression, respBody, make([]interface{}, 0)) return curJson.([]interface{}), nil } @@ -423,43 +408,35 @@ func buildPayOrderBodyParams(orderId string) map[string]interface{} { } func resourceDscInstanceRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - cfg := meta.(*config.Config) - region := cfg.GetRegion(d) - - var mErr *multierror.Error - - // getDscInstance: Query the DSC instance var ( - getDscInstanceHttpUrl = "v1/{project_id}/period/product/specification" - getDscInstanceProduct = "dsc" + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + mErr *multierror.Error + httpUrl = "v1/{project_id}/period/product/specification" + product = "dsc" ) - getDscInstanceClient, err := cfg.NewServiceClient(getDscInstanceProduct, region) + client, err := cfg.NewServiceClient(product, region) if err != nil { - return diag.Errorf("error creating DscInstance Client: %s", err) + return diag.Errorf("error creating DSC client: %s", err) } - getDscInstancePath := getDscInstanceClient.Endpoint + getDscInstanceHttpUrl - getDscInstancePath = strings.ReplaceAll(getDscInstancePath, "{project_id}", getDscInstanceClient.ProjectID) - - getDscInstanceOpt := golangsdk.RequestOpts{ + requestPath := client.Endpoint + httpUrl + requestPath = strings.ReplaceAll(requestPath, "{project_id}", client.ProjectID) + requestOpt := golangsdk.RequestOpts{ KeepResponseBody: true, - OkCodes: []int{ - 200, - }, } - getDscInstanceResp, err := getDscInstanceClient.Request("GET", getDscInstancePath, &getDscInstanceOpt) - + resp, err := client.Request("GET", requestPath, &requestOpt) if err != nil { - return common.CheckDeletedDiag(d, err, "error retrieving DscInstance") + return common.CheckDeletedDiag(d, err, "error retrieving DSC instance") } - getDscInstanceRespBody, err := utils.FlattenResponse(getDscInstanceResp) + respBody, err := utils.FlattenResponse(resp) if err != nil { return diag.FromErr(err) } - dscOrder := utils.PathSearch("orderInfo[?productInfo.resourceType=='hws.resource.type.dsc.base']", - getDscInstanceRespBody, nil) + expression := "orderInfo[?productInfo.resourceType=='hws.resource.type.dsc.base']" + dscOrder := utils.PathSearch(expression, respBody, nil) if dscOrder == nil { return diag.Errorf("unable to find the base information about the DSC instance from the API response") } @@ -483,68 +460,59 @@ func parsePeriodUnit(periodType interface{}) string { } func resourceDscInstanceDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - cfg := meta.(*config.Config) + var ( + cfg = meta.(*config.Config) + region = cfg.GetRegion(d) + ) if err := common.UnsubscribePrePaidResource(d, cfg, []string{d.Id()}); err != nil { - return diag.Errorf("Error unsubscribing DSC order = %s: %s", d.Id(), err) + return diag.Errorf("error unsubscribing DSC order (%s): %s", d.Id(), err) + } + + client, err := cfg.NewServiceClient("dsc", region) + if err != nil { + return diag.Errorf("error creating DSC client: %s", err) } stateConf := &resource.StateChangeConf{ Pending: []string{"PENDING"}, Target: []string{"COMPLETE"}, - Refresh: waitForBmsInstanceDelete(ctx, d, meta), + Refresh: waitingForDscInstanceDeleted(client), Timeout: d.Timeout(schema.TimeoutDelete), Delay: 20 * time.Second, PollInterval: 10 * time.Second, } - _, err := stateConf.WaitForStateContext(ctx) + _, err = stateConf.WaitForStateContext(ctx) if err != nil { - return diag.Errorf("Error deleting DSC instance: %s", err) + return diag.Errorf("error waiting for DSC instance deletion to complete: %s", err) } return nil } -func waitForBmsInstanceDelete(_ context.Context, d *schema.ResourceData, meta interface{}) resource.StateRefreshFunc { - cfg := meta.(*config.Config) - region := cfg.GetRegion(d) +func waitingForDscInstanceDeleted(client *golangsdk.ServiceClient) resource.StateRefreshFunc { + httpUrl := "v1/{project_id}/period/product/specification" + requestPath := client.Endpoint + httpUrl + requestPath = strings.ReplaceAll(requestPath, "{project_id}", client.ProjectID) + requestOpt := golangsdk.RequestOpts{ + KeepResponseBody: true, + } return func() (interface{}, string, error) { - // getDscInstance: Query the DSC instance - var ( - getDscInstanceHttpUrl = "v1/{project_id}/period/product/specification" - getDscInstanceProduct = "dsc" - ) - getDscInstanceClient, err := cfg.NewServiceClient(getDscInstanceProduct, region) - if err != nil { - return nil, "error", fmt.Errorf("error creating DscInstance Client: %s", err) - } - - getDscInstancePath := getDscInstanceClient.Endpoint + getDscInstanceHttpUrl - getDscInstancePath = strings.ReplaceAll(getDscInstancePath, "{project_id}", getDscInstanceClient.ProjectID) - - getDscInstanceOpt := golangsdk.RequestOpts{ - KeepResponseBody: true, - OkCodes: []int{ - 200, - }, - } - getDscInstanceResp, err := getDscInstanceClient.Request("GET", getDscInstancePath, &getDscInstanceOpt) - + resp, err := client.Request("GET", requestPath, &requestOpt) if err != nil { - return nil, "error", fmt.Errorf("error retrieving DscInstance: %s", err) + return nil, "ERROR", fmt.Errorf("error retrieving DSC instance: %s", err) } - getDscInstanceRespBody, err := utils.FlattenResponse(getDscInstanceResp) + respBody, err := utils.FlattenResponse(resp) if err != nil { - return nil, "error", fmt.Errorf("error retrieving DscInstance: %s", err) + return nil, "ERROR", err } - orderInfo := utils.PathSearch("orderInfo", getDscInstanceRespBody, []interface{}{}) - orders := orderInfo.([]interface{}) + orders := utils.PathSearch("orderInfo", respBody, make([]interface{}, 0)).([]interface{}) if len(orders) == 0 { - return orders, "COMPLETE", nil + return "success_deleted", "COMPLETE", nil } return nil, "PENDING", nil }