-
Notifications
You must be signed in to change notification settings - Fork 163
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(rms): add data source to get the list of RMS resource tags (#5989)
- Loading branch information
1 parent
2717bee
commit 7bcd69c
Showing
4 changed files
with
316 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
--- | ||
subcategory: "Config" | ||
layout: "huaweicloud" | ||
page_title: "HuaweiCloud: huaweicloud_rms_resource_tags" | ||
description: |- | ||
Use this data source to get the list of RMS resource tags. | ||
--- | ||
|
||
# huaweicloud_rms_resource_tags | ||
|
||
Use this data source to get the list of RMS resource tags. | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
variable "resource_type" {} | ||
data "huaweicloud_rms_resource_tags" "test" { | ||
resource_type = var.resource_type | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `region` - (Optional, String) Specifies the region in which to query the resource. | ||
If omitted, the provider-level region will be used. | ||
|
||
* `resource_type` - (Required, String) Specifies the resource type. | ||
The valid value can be **config:policyAssignments**. | ||
|
||
* `resource_id` - (Optional, String) Specifies the resource ID. | ||
|
||
## Attribute Reference | ||
|
||
In addition to all arguments above, the following attributes are exported: | ||
|
||
* `id` - The data source ID. | ||
|
||
* `tags` - The tags. | ||
|
||
The [tags](#tags_struct) structure is documented below. | ||
|
||
<a name="tags_struct"></a> | ||
The `tags` block supports: | ||
|
||
* `key` - The tag key. | ||
|
||
* `values` - The tag values. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
huaweicloud/services/acceptance/rms/data_source_huaweicloud_rms_resource_tags_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package rms | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
|
||
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" | ||
) | ||
|
||
func TestAccDataSourceResourceTags_basic(t *testing.T) { | ||
dataSource := "data.huaweicloud_rms_resource_tags.test" | ||
dc := acceptance.InitDataSourceCheck(dataSource) | ||
name := acceptance.RandomAccResourceName() | ||
baseConfig := testDataSourceResourceTags_base(name) | ||
|
||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { | ||
acceptance.TestAccPreCheck(t) | ||
}, | ||
ProviderFactories: acceptance.TestAccProviderFactories, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testDataSourceResourceTags_basic(baseConfig), | ||
Check: resource.ComposeTestCheckFunc( | ||
dc.CheckResourceExists(), | ||
resource.TestCheckResourceAttrSet(dataSource, "tags.0.key"), | ||
resource.TestCheckResourceAttrSet(dataSource, "tags.0.values.#"), | ||
), | ||
}, | ||
{ | ||
Config: testDataSourceResourceTags_specifiedResource(baseConfig), | ||
Check: resource.ComposeTestCheckFunc( | ||
dc.CheckResourceExists(), | ||
resource.TestCheckResourceAttrSet(dataSource, "tags.0.key"), | ||
resource.TestCheckResourceAttrSet(dataSource, "tags.0.values.#"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testDataSourceResourceTags_basic(baseConfig string) string { | ||
return fmt.Sprintf(` | ||
%[1]s | ||
data "huaweicloud_rms_resource_tags" "test" { | ||
resource_type = "config:policyAssignments" | ||
depends_on = [huaweicloud_rms_policy_assignment.test] | ||
} | ||
`, baseConfig) | ||
} | ||
|
||
func testDataSourceResourceTags_specifiedResource(baseConfig string) string { | ||
return fmt.Sprintf(` | ||
%[1]s | ||
data "huaweicloud_rms_resource_tags" "test" { | ||
resource_type = "config:policyAssignments" | ||
resource_id = huaweicloud_rms_policy_assignment.test.id | ||
} | ||
`, baseConfig) | ||
} | ||
|
||
func testDataSourceResourceTags_base(name string) string { | ||
return fmt.Sprintf(` | ||
data "huaweicloud_rms_policy_definitions" "test" { | ||
name = "regular-matching-of-names" | ||
} | ||
resource "huaweicloud_rms_policy_assignment" "test" { | ||
name = "%[1]s" | ||
description = "A resource name that does not match the regular expression is considered 'non-compliant'." | ||
policy_definition_id = try(data.huaweicloud_rms_policy_definitions.test.definitions[0].id, "") | ||
status = "Disabled" | ||
policy_filter { | ||
region = "%[2]s" | ||
resource_provider = "vpc" | ||
resource_type = "vpcs" | ||
tag_key = "name" | ||
tag_value = "bo" | ||
} | ||
parameters = { | ||
regularExpression = jsonencode("bo-form_") | ||
} | ||
tags = { | ||
foo = "bar" | ||
} | ||
} | ||
`, name, acceptance.HW_REGION_NAME) | ||
} |
169 changes: 169 additions & 0 deletions
169
huaweicloud/services/rms/data_source_huaweicloud_rms_resource_tags.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
package rms | ||
|
||
import ( | ||
"context" | ||
"strings" | ||
|
||
"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/tidwall/gjson" | ||
|
||
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" | ||
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/helper/httphelper" | ||
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/helper/schemas" | ||
) | ||
|
||
func DataSourceResourceTags() *schema.Resource { | ||
return &schema.Resource{ | ||
ReadContext: dataSourceResourceTagsRead, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"region": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Computed: true, | ||
Description: `Specifies the region in which to query the resource. If omitted, the provider-level region will be used.`, | ||
}, | ||
"resource_type": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Description: `Specifies the resource type.`, | ||
}, | ||
"resource_id": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Description: `Specifies the resource ID.`, | ||
}, | ||
"tags": { | ||
Type: schema.TypeList, | ||
Computed: true, | ||
Description: `The tags.`, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"key": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
Description: `The tag key.`, | ||
}, | ||
"values": { | ||
Type: schema.TypeList, | ||
Computed: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
Description: `The tag values.`, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
type TagsDSWrapper struct { | ||
*schemas.ResourceDataWrapper | ||
Config *config.Config | ||
} | ||
|
||
func newTagsDSWrapper(d *schema.ResourceData, meta interface{}) *TagsDSWrapper { | ||
return &TagsDSWrapper{ | ||
ResourceDataWrapper: schemas.NewSchemaWrapper(d), | ||
Config: meta.(*config.Config), | ||
} | ||
} | ||
|
||
func dataSourceResourceTagsRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
wrapper := newTagsDSWrapper(d, meta) | ||
if _, ok := d.GetOk("resource_id"); ok { | ||
lisTagForResRst, err := wrapper.ListTagsForResource() | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
err = wrapper.listTagsToSchema(lisTagForResRst, true) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
} else { | ||
lisTagForResTypRst, err := wrapper.ListTagsForResourceType() | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
err = wrapper.listTagsToSchema(lisTagForResTypRst, false) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
} | ||
|
||
id, err := uuid.GenerateUUID() | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
d.SetId(id) | ||
|
||
return nil | ||
} | ||
|
||
// @API CONFIG GET /v1/resource-manager/{resource_type}/{resource_id}/tags | ||
func (w *TagsDSWrapper) ListTagsForResource() (*gjson.Result, error) { | ||
client, err := w.NewClient(w.Config, "rms") | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
uri := "/v1/resource-manager/{resource_type}/{resource_id}/tags" | ||
uri = strings.ReplaceAll(uri, "{resource_type}", w.Get("resource_type").(string)) | ||
uri = strings.ReplaceAll(uri, "{resource_id}", w.Get("resource_id").(string)) | ||
return httphelper.New(client). | ||
Method("GET"). | ||
URI(uri). | ||
Request(). | ||
Result() | ||
} | ||
|
||
// @API CONFIG GET /v1/resource-manager/{resource_type}/tags | ||
func (w *TagsDSWrapper) ListTagsForResourceType() (*gjson.Result, error) { | ||
client, err := w.NewClient(w.Config, "rms") | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
uri := "/v1/resource-manager/{resource_type}/tags" | ||
uri = strings.ReplaceAll(uri, "{resource_type}", w.Get("resource_type").(string)) | ||
return httphelper.New(client). | ||
Method("GET"). | ||
URI(uri). | ||
OffsetPager("tags", "offset", "limit", 1000). | ||
Request(). | ||
Result() | ||
} | ||
|
||
func (w *TagsDSWrapper) listTagsToSchema(body *gjson.Result, specifiedResourceId bool) error { | ||
d := w.ResourceData | ||
parseTagsFunc := parseResourceTypeTags | ||
if specifiedResourceId { | ||
parseTagsFunc = parseResourceTags | ||
} | ||
mErr := multierror.Append(nil, | ||
d.Set("region", w.Config.GetRegion(w.ResourceData)), | ||
d.Set("tags", schemas.SliceToList(body.Get("tags"), parseTagsFunc)), | ||
) | ||
|
||
return mErr.ErrorOrNil() | ||
} | ||
|
||
func parseResourceTags(tags gjson.Result) any { | ||
rawTag := tags.Get("value").Value().(string) | ||
return map[string]any{ | ||
"key": tags.Get("key").Value(), | ||
"values": []string{rawTag}, | ||
} | ||
} | ||
|
||
func parseResourceTypeTags(tags gjson.Result) any { | ||
return map[string]any{ | ||
"key": tags.Get("key").Value(), | ||
"values": schemas.SliceToStrList(tags.Get("values")), | ||
} | ||
} |