Skip to content

Commit afb8177

Browse files
New Datasource for list Tag Keys and Tag Values (#10209) (#17782)
[upstream:d37b826bffd4ff5310da27f805f254fdec87e0fd] Signed-off-by: Modular Magician <[email protected]>
1 parent ad54367 commit afb8177

8 files changed

+496
-0
lines changed

.changelog/10209.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
```release-note:new-datasource
2+
tags_tag_keys
3+
tags_tag_values
4+
```

google/provider/provider_mmv1_resources.go

+2
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,9 @@ var handwrittenDatasources = map[string]*schema.Resource{
276276
"google_storage_project_service_account": storage.DataSourceGoogleStorageProjectServiceAccount(),
277277
"google_storage_transfer_project_service_account": storagetransfer.DataSourceGoogleStorageTransferProjectServiceAccount(),
278278
"google_tags_tag_key": tags.DataSourceGoogleTagsTagKey(),
279+
"google_tags_tag_keys": tags.DataSourceGoogleTagsTagKeys(),
279280
"google_tags_tag_value": tags.DataSourceGoogleTagsTagValue(),
281+
"google_tags_tag_values": tags.DataSourceGoogleTagsTagValues(),
280282
"google_tpu_tensorflow_versions": tpu.DataSourceTpuTensorflowVersions(),
281283
"google_vpc_access_connector": vpcaccess.DataSourceVPCAccessConnector(),
282284
"google_redis_instance": redis.DataSourceGoogleRedisInstance(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
package tags
4+
5+
import (
6+
"fmt"
7+
8+
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
9+
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
10+
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
12+
)
13+
14+
func DataSourceGoogleTagsTagKeys() *schema.Resource {
15+
return &schema.Resource{
16+
Read: dataSourceGoogleTagsTagKeysRead,
17+
18+
Schema: map[string]*schema.Schema{
19+
"parent": {
20+
Type: schema.TypeString,
21+
Required: true,
22+
},
23+
"keys": {
24+
Type: schema.TypeList,
25+
Computed: true,
26+
Elem: &schema.Resource{
27+
Schema: tpgresource.DatasourceSchemaFromResourceSchema(ResourceTagsTagKey().Schema),
28+
},
29+
},
30+
},
31+
}
32+
}
33+
34+
func dataSourceGoogleTagsTagKeysRead(d *schema.ResourceData, meta interface{}) error {
35+
config := meta.(*transport_tpg.Config)
36+
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
37+
if err != nil {
38+
return err
39+
}
40+
41+
parent := d.Get("parent").(string)
42+
token := ""
43+
44+
tagKeys := make([]map[string]interface{}, 0)
45+
46+
for paginate := true; paginate; {
47+
resp, err := config.NewResourceManagerV3Client(userAgent).TagKeys.List().Parent(parent).PageSize(300).PageToken(token).Do()
48+
if err != nil {
49+
return fmt.Errorf("error reading tag key list: %s", err)
50+
}
51+
52+
for _, tagKey := range resp.TagKeys {
53+
54+
mappedData := map[string]interface{}{
55+
"name": tagKey.Name,
56+
"namespaced_name": tagKey.NamespacedName,
57+
"short_name": tagKey.ShortName,
58+
"parent": tagKey.Parent,
59+
"create_time": tagKey.CreateTime,
60+
"update_time": tagKey.UpdateTime,
61+
"description": tagKey.Description,
62+
"purpose": tagKey.Purpose,
63+
"purpose_data": tagKey.PurposeData,
64+
}
65+
tagKeys = append(tagKeys, mappedData)
66+
}
67+
token = resp.NextPageToken
68+
paginate = token != ""
69+
}
70+
71+
d.SetId(parent)
72+
if err := d.Set("keys", tagKeys); err != nil {
73+
return fmt.Errorf("Error setting tag key name: %s", err)
74+
}
75+
76+
return nil
77+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
package tags_test
4+
5+
import (
6+
"fmt"
7+
"regexp"
8+
"strings"
9+
"testing"
10+
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
12+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
13+
"github.com/hashicorp/terraform-provider-google/google/acctest"
14+
"github.com/hashicorp/terraform-provider-google/google/envvar"
15+
)
16+
17+
func TestAccDataSourceGoogleTagsTagKeys_default(t *testing.T) {
18+
org := envvar.GetTestOrgFromEnv(t)
19+
20+
parent := fmt.Sprintf("organizations/%s", org)
21+
shortName := "tf-test-" + acctest.RandString(t, 10)
22+
23+
acctest.VcrTest(t, resource.TestCase{
24+
PreCheck: func() { acctest.AccTestPreCheck(t) },
25+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
26+
Steps: []resource.TestStep{
27+
{
28+
Config: testAccDataSourceGoogleTagsTagKeysConfig(parent, shortName),
29+
Check: resource.ComposeTestCheckFunc(
30+
testAccDataSourceGoogleTagsTagKeysCheck("data.google_tags_tag_keys.my_tag_keys", "google_tags_tag_key.foobar"),
31+
),
32+
},
33+
},
34+
})
35+
}
36+
37+
func TestAccDataSourceGoogleTagsTagKeys_dot(t *testing.T) {
38+
org := envvar.GetTestOrgFromEnv(t)
39+
40+
parent := fmt.Sprintf("organizations/%s", org)
41+
shortName := "terraform.test." + acctest.RandString(t, 10)
42+
43+
acctest.VcrTest(t, resource.TestCase{
44+
PreCheck: func() { acctest.AccTestPreCheck(t) },
45+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
46+
Steps: []resource.TestStep{
47+
{
48+
Config: testAccDataSourceGoogleTagsTagKeysConfig(parent, shortName),
49+
Check: resource.ComposeTestCheckFunc(
50+
testAccDataSourceGoogleTagsTagKeysCheck("data.google_tags_tag_keys.my_tag_keys", "google_tags_tag_key.foobar"),
51+
),
52+
},
53+
},
54+
})
55+
}
56+
57+
func testAccDataSourceGoogleTagsTagKeysCheck(data_source_name string, resource_name string) resource.TestCheckFunc {
58+
return func(s *terraform.State) error {
59+
ds, ok := s.RootModule().Resources[data_source_name]
60+
if !ok {
61+
return fmt.Errorf("root module has no resource called %s", data_source_name)
62+
}
63+
64+
rs, ok := s.RootModule().Resources[resource_name]
65+
if !ok {
66+
return fmt.Errorf("can't find %s in state", resource_name)
67+
}
68+
69+
ds_attr := ds.Primary.Attributes
70+
rs_attr := rs.Primary.Attributes
71+
tag_key_attrs_to_test := []string{"parent", "short_name", "name", "namespaced_name", "create_time", "update_time", "description"}
72+
re := regexp.MustCompile("[0-9]+")
73+
index := ""
74+
75+
for k := range ds_attr {
76+
ds_a := fmt.Sprintf("keys.%s.%s", re.FindString(k), tag_key_attrs_to_test[1])
77+
if ds_attr[ds_a] == rs_attr[tag_key_attrs_to_test[1]] {
78+
index = re.FindString(k)
79+
break
80+
}
81+
}
82+
83+
for _, attr_to_check := range tag_key_attrs_to_test {
84+
data := ""
85+
if attr_to_check == "name" {
86+
data = strings.Split(ds_attr[fmt.Sprintf("keys.%s.%s", index, attr_to_check)], "/")[1]
87+
} else {
88+
data = ds_attr[fmt.Sprintf("keys.%s.%s", index, attr_to_check)]
89+
}
90+
if data != rs_attr[attr_to_check] {
91+
return fmt.Errorf(
92+
"%s is %s; want %s",
93+
attr_to_check,
94+
data,
95+
rs_attr[attr_to_check],
96+
)
97+
}
98+
}
99+
100+
return nil
101+
}
102+
}
103+
104+
func testAccDataSourceGoogleTagsTagKeysConfig(parent string, shortName string) string {
105+
return fmt.Sprintf(`
106+
resource "google_tags_tag_key" "foobar" {
107+
parent = "%s"
108+
short_name = "%s"
109+
}
110+
111+
data "google_tags_tag_keys" "my_tag_keys" {
112+
parent = google_tags_tag_key.foobar.parent
113+
}
114+
`, parent, shortName)
115+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
package tags
4+
5+
import (
6+
"fmt"
7+
8+
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
9+
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
10+
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
12+
)
13+
14+
func DataSourceGoogleTagsTagValues() *schema.Resource {
15+
return &schema.Resource{
16+
Read: dataSourceGoogleTagsTagValuesRead,
17+
18+
Schema: map[string]*schema.Schema{
19+
"parent": {
20+
Type: schema.TypeString,
21+
Required: true,
22+
},
23+
"values": {
24+
Type: schema.TypeList,
25+
Computed: true,
26+
Elem: &schema.Resource{
27+
Schema: tpgresource.DatasourceSchemaFromResourceSchema(ResourceTagsTagValue().Schema),
28+
},
29+
},
30+
},
31+
}
32+
}
33+
34+
func dataSourceGoogleTagsTagValuesRead(d *schema.ResourceData, meta interface{}) error {
35+
config := meta.(*transport_tpg.Config)
36+
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
37+
if err != nil {
38+
return err
39+
}
40+
41+
parent := d.Get("parent").(string)
42+
token := ""
43+
44+
tagValues := make([]map[string]interface{}, 0)
45+
46+
for paginate := true; paginate; {
47+
resp, err := config.NewResourceManagerV3Client(userAgent).TagValues.List().Parent(parent).PageSize(300).PageToken(token).Do()
48+
if err != nil {
49+
return fmt.Errorf("error reading tag value list: %s", err)
50+
}
51+
52+
for _, tagValue := range resp.TagValues {
53+
mappedData := map[string]interface{}{
54+
"name": tagValue.Name,
55+
"namespaced_name": tagValue.NamespacedName,
56+
"short_name": tagValue.ShortName,
57+
"parent": tagValue.Parent,
58+
"create_time": tagValue.CreateTime,
59+
"update_time": tagValue.UpdateTime,
60+
"description": tagValue.Description,
61+
}
62+
63+
tagValues = append(tagValues, mappedData)
64+
}
65+
token = resp.NextPageToken
66+
paginate = token != ""
67+
}
68+
69+
d.SetId(parent)
70+
71+
if err := d.Set("values", tagValues); err != nil {
72+
return fmt.Errorf("Error setting tag values: %s", err)
73+
}
74+
75+
return nil
76+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
package tags_test
4+
5+
import (
6+
"fmt"
7+
"strings"
8+
"testing"
9+
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
12+
"github.com/hashicorp/terraform-provider-google/google/acctest"
13+
"github.com/hashicorp/terraform-provider-google/google/envvar"
14+
)
15+
16+
func TestAccDataSourceGoogleTagsTagValues_default(t *testing.T) {
17+
org := envvar.GetTestOrgFromEnv(t)
18+
19+
parent := fmt.Sprintf("organizations/%s", org)
20+
keyShortName := "tf-testkey-" + acctest.RandString(t, 10)
21+
shortName := "tf-test-" + acctest.RandString(t, 10)
22+
23+
acctest.VcrTest(t, resource.TestCase{
24+
PreCheck: func() { acctest.AccTestPreCheck(t) },
25+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
26+
Steps: []resource.TestStep{
27+
{
28+
Config: testAccDataSourceGoogleTagsTagValuesConfig(parent, keyShortName, shortName),
29+
Check: resource.ComposeTestCheckFunc(
30+
testAccDataSourceGoogleTagsTagValuesCheck("data.google_tags_tag_values.my_tag_values", "google_tags_tag_value.norfqux"),
31+
),
32+
},
33+
},
34+
})
35+
}
36+
37+
func TestAccDataSourceGoogleTagsTagValues_dot(t *testing.T) {
38+
org := envvar.GetTestOrgFromEnv(t)
39+
40+
parent := fmt.Sprintf("organizations/%s", org)
41+
keyShortName := "tf-testkey-" + acctest.RandString(t, 10)
42+
shortName := "terraform.test." + acctest.RandString(t, 10)
43+
44+
acctest.VcrTest(t, resource.TestCase{
45+
PreCheck: func() { acctest.AccTestPreCheck(t) },
46+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
47+
Steps: []resource.TestStep{
48+
{
49+
Config: testAccDataSourceGoogleTagsTagValuesConfig(parent, keyShortName, shortName),
50+
Check: resource.ComposeTestCheckFunc(
51+
testAccDataSourceGoogleTagsTagValuesCheck("data.google_tags_tag_values.my_tag_values", "google_tags_tag_value.norfqux"),
52+
),
53+
},
54+
},
55+
})
56+
}
57+
58+
func testAccDataSourceGoogleTagsTagValuesCheck(data_source_name string, resource_name string) resource.TestCheckFunc {
59+
return func(s *terraform.State) error {
60+
ds, ok := s.RootModule().Resources[data_source_name]
61+
if !ok {
62+
return fmt.Errorf("root module has no resource called %s", data_source_name)
63+
}
64+
65+
rs, ok := s.RootModule().Resources[resource_name]
66+
if !ok {
67+
return fmt.Errorf("can't find %s in state", resource_name)
68+
}
69+
70+
ds_attr := ds.Primary.Attributes
71+
rs_attr := rs.Primary.Attributes
72+
tag_value_attrs_to_test := []string{"parent", "name", "namespaced_name", "create_time", "update_time", "description"}
73+
74+
for _, attr_to_check := range tag_value_attrs_to_test {
75+
data := ""
76+
if attr_to_check == "name" {
77+
data = strings.Split(ds_attr[fmt.Sprintf("values.0.%s", attr_to_check)], "/")[1]
78+
} else {
79+
data = ds_attr[fmt.Sprintf("values.0.%s", attr_to_check)]
80+
}
81+
if data != rs_attr[attr_to_check] {
82+
return fmt.Errorf(
83+
"%s is %s; want %s",
84+
attr_to_check,
85+
data,
86+
rs_attr[attr_to_check],
87+
)
88+
}
89+
}
90+
91+
return nil
92+
}
93+
}
94+
95+
func testAccDataSourceGoogleTagsTagValuesConfig(parent string, keyShortName string, shortName string) string {
96+
return fmt.Sprintf(`
97+
resource "google_tags_tag_key" "foobar" {
98+
parent = "%s"
99+
short_name = "%s"
100+
}
101+
102+
resource "google_tags_tag_value" "norfqux" {
103+
parent = google_tags_tag_key.foobar.id
104+
short_name = "%s"
105+
}
106+
107+
data "google_tags_tag_values" "my_tag_values" {
108+
parent = google_tags_tag_value.norfqux.parent
109+
}
110+
`, parent, keyShortName, shortName)
111+
}

0 commit comments

Comments
 (0)