Skip to content

Commit 91b3588

Browse files
authored
resourcemanager: adding "google_folders" data source (#10261)
* resourcemanager: adding "folders" data source * docs: updated docs to fix attribute typos * updated google_folders test * fix: updated test to reference correct object
1 parent acd5746 commit 91b3588

File tree

5 files changed

+259
-0
lines changed

5 files changed

+259
-0
lines changed

google/data_source_google_folders.go

+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package google
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
7+
)
8+
9+
func dataSourceGoogleFolders() *schema.Resource {
10+
return &schema.Resource{
11+
Read: dataSourceGoogleFoldersRead,
12+
Schema: map[string]*schema.Schema{
13+
"parent_id": {
14+
Type: schema.TypeString,
15+
Required: true,
16+
},
17+
"folders": {
18+
Type: schema.TypeList,
19+
Computed: true,
20+
Elem: &schema.Resource{
21+
Schema: map[string]*schema.Schema{
22+
"name": {
23+
Type: schema.TypeString,
24+
Computed: true,
25+
},
26+
"parent": {
27+
Type: schema.TypeString,
28+
Computed: true,
29+
},
30+
"display_name": {
31+
Type: schema.TypeString,
32+
Computed: true,
33+
},
34+
"state": {
35+
Type: schema.TypeString,
36+
Computed: true,
37+
},
38+
"create_time": {
39+
Type: schema.TypeString,
40+
Computed: true,
41+
},
42+
"update_time": {
43+
Type: schema.TypeString,
44+
Computed: true,
45+
},
46+
"delete_time": {
47+
Type: schema.TypeString,
48+
Computed: true,
49+
},
50+
"etag": {
51+
Type: schema.TypeString,
52+
Computed: true,
53+
},
54+
},
55+
},
56+
},
57+
},
58+
}
59+
}
60+
61+
func dataSourceGoogleFoldersRead(d *schema.ResourceData, meta interface{}) error {
62+
config := meta.(*Config)
63+
userAgent, err := generateUserAgentString(d, config.userAgent)
64+
if err != nil {
65+
return err
66+
}
67+
68+
params := make(map[string]string)
69+
folders := make([]map[string]interface{}, 0)
70+
71+
for {
72+
params["parent"] = d.Get("parent_id").(string)
73+
url := "https://cloudresourcemanager.googleapis.com/v3/folders"
74+
75+
url, err := addQueryParams(url, params)
76+
if err != nil {
77+
return err
78+
}
79+
80+
res, err := sendRequest(config, "GET", "", url, userAgent, nil)
81+
if err != nil {
82+
return fmt.Errorf("Error retrieving folders: %s", err)
83+
}
84+
85+
pageFolders := flattenDataSourceGoogleFoldersList(res["folders"])
86+
folders = append(folders, pageFolders...)
87+
88+
pToken, ok := res["nextPageToken"]
89+
if ok && pToken != nil && pToken.(string) != "" {
90+
params["pageToken"] = pToken.(string)
91+
} else {
92+
break
93+
}
94+
}
95+
96+
if err := d.Set("folders", folders); err != nil {
97+
return fmt.Errorf("Error retrieving folders: %s", err)
98+
}
99+
100+
d.SetId(d.Get("parent_id").(string))
101+
102+
return nil
103+
}
104+
105+
func flattenDataSourceGoogleFoldersList(v interface{}) []map[string]interface{} {
106+
if v == nil {
107+
return make([]map[string]interface{}, 0)
108+
}
109+
110+
ls := v.([]interface{})
111+
folders := make([]map[string]interface{}, 0, len(ls))
112+
for _, raw := range ls {
113+
f := raw.(map[string]interface{})
114+
115+
var mState, mName, mCreateTime, mUpdateTime, mDeleteTime, mParent, mDisplayName, mEtag interface{}
116+
if fName, ok := f["name"]; ok {
117+
mName = fName
118+
}
119+
if fState, ok := f["state"]; ok {
120+
mState = fState
121+
}
122+
if fCreateTime, ok := f["createTime"]; ok {
123+
mCreateTime = fCreateTime
124+
}
125+
if fUpdateTime, ok := f["updateTime"]; ok {
126+
mUpdateTime = fUpdateTime
127+
}
128+
if fDeleteTime, ok := f["deleteTime"]; ok {
129+
mDeleteTime = fDeleteTime
130+
}
131+
if fParent, ok := f["parent"]; ok {
132+
mParent = fParent
133+
}
134+
if fDisplayName, ok := f["displayName"]; ok {
135+
mDisplayName = fDisplayName
136+
}
137+
if fEtag, ok := f["etag"]; ok {
138+
mEtag = fEtag
139+
}
140+
folders = append(folders, map[string]interface{}{
141+
"name": mName,
142+
"state": mState,
143+
"create_time": mCreateTime,
144+
"update_time": mUpdateTime,
145+
"delete_time": mDeleteTime,
146+
"parent": mParent,
147+
"display_name": mDisplayName,
148+
"etag": mEtag,
149+
})
150+
}
151+
152+
return folders
153+
}
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package google
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
8+
)
9+
10+
func TestAccDataSourceGoogleFolders_basic(t *testing.T) {
11+
t.Parallel()
12+
13+
org := getTestOrgFromEnv(t)
14+
parent := fmt.Sprintf("organizations/%s", org)
15+
displayName := "terraform-test-" + randString(t, 10)
16+
17+
vcrTest(t, resource.TestCase{
18+
PreCheck: func() { testAccPreCheck(t) },
19+
Providers: testAccProviders,
20+
Steps: []resource.TestStep{
21+
{
22+
Config: testAccCheckGoogleFoldersConfig(parent, displayName),
23+
Check: resource.ComposeTestCheckFunc(
24+
resource.TestCheckResourceAttrSet("data.google_folders.root-test", "folders.0.name"),
25+
resource.TestCheckResourceAttrSet("data.google_folders.root-test", "folders.0.display_name"),
26+
resource.TestCheckResourceAttrSet("data.google_folders.root-test", "folders.0.state"),
27+
resource.TestCheckResourceAttrSet("data.google_folders.root-test", "folders.0.parent"),
28+
resource.TestCheckResourceAttrSet("data.google_folders.root-test", "folders.0.create_time"),
29+
resource.TestCheckResourceAttrSet("data.google_folders.root-test", "folders.0.update_time"),
30+
// resource.TestCheckResourceAttrSet("data.google_folders.root-test", "folders.0.delete_time"),
31+
// deleteTime will only be set on a deleted folder
32+
resource.TestCheckResourceAttrSet("data.google_folders.root-test", "folders.0.etag"),
33+
),
34+
},
35+
},
36+
})
37+
}
38+
39+
func testAccCheckGoogleFoldersConfig(parent string, displayName string) string {
40+
return fmt.Sprintf(`
41+
resource "google_folder" "foobar" {
42+
parent = "%s"
43+
display_name = "%s"
44+
}
45+
46+
data "google_folders" "root-test" {
47+
parent_id = "%s"
48+
}
49+
`, parent, displayName, parent)
50+
}

google/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,7 @@ func Provider() *schema.Provider {
761761
"google_kms_secret": dataSourceGoogleKmsSecret(),
762762
"google_kms_secret_ciphertext": dataSourceGoogleKmsSecretCiphertext(),
763763
"google_folder": dataSourceGoogleFolder(),
764+
"google_folders": dataSourceGoogleFolders(),
764765
"google_folder_organization_policy": dataSourceGoogleFolderOrganizationPolicy(),
765766
"google_monitoring_notification_channel": dataSourceMonitoringNotificationChannel(),
766767
"google_monitoring_cluster_istio_service": dataSourceMonitoringServiceClusterIstio(),

website/docs/d/folders.html.markdown

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
subcategory: "Cloud Platform"
3+
layout: "google"
4+
page_title: "Google: google_folders"
5+
sidebar_current: "docs-google-datasource-folders"
6+
description: |-
7+
Retrieve a set of folders based on a parent ID.
8+
---
9+
10+
# google\_folders
11+
12+
Retrieve information about a set of folders based on a parent ID. See the
13+
[REST API](https://cloud.google.com/resource-manager/reference/rest/v3/folders/list)
14+
for more details.
15+
16+
## Example Usage - searching for folders at the root of an org
17+
18+
```hcl
19+
data "google_folders" "my-org-folders" {
20+
parent_id = "organizations/${var.organization_id}"
21+
}
22+
23+
data "google_folder" "first-folder" {
24+
folder = data.google_folders.my-org-folders.folders[0].name
25+
}
26+
```
27+
28+
## Argument Reference
29+
30+
The following arguments are supported:
31+
32+
* `parent_id` - (Required) A string parent as defined in the [REST API](https://cloud.google.com/resource-manager/reference/rest/v3/folders/list#query-parameters).
33+
34+
35+
## Attributes Reference
36+
37+
The following attributes are exported:
38+
39+
* `folders` - A list of projects matching the provided filter. Structure is defined below.
40+
41+
The `folders` block supports:
42+
43+
* `name` - The id of the folder
44+
* `parent` - The parent id of the folder
45+
* `display_name` - The display name of the folder
46+
* `state` - The lifecycle state of the folder
47+
* `create_time` - The timestamp of when the folder was created
48+
* `update_time` - The timestamp of when the folder was last modified
49+
* `delete_time` - The timestamp of when the folder was requested to be deleted (if applicable)
50+
* `etag` - Entity tag identifier of the folder
51+

website/google.erb

+4
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,10 @@
11011101
<a href="/docs/providers/google/d/folder_organization_policy.html">google_folder_organization_policy</a>
11021102
</li>
11031103

1104+
<li>
1105+
<a href="/docs/providers/google/d/folders.html">google_folders</a>
1106+
</li>
1107+
11041108
<li>
11051109
<a href="/docs/providers/google/d/iam_policy.html">google_iam_policy</a>
11061110
</li>

0 commit comments

Comments
 (0)