From 031c7b6956ab4dfaa8ccd3dde0bf585fd82c76c0 Mon Sep 17 00:00:00 2001 From: Sam Levenick Date: Tue, 30 Nov 2021 15:58:29 -0800 Subject: [PATCH] Upstream folders (#5437) * resourcemanager: adding "folders" data source * resourcemanager: adding "folders" data source * docs: updated docs to fix attribute typos * updated google_folders test * Recommit provider.go change * Fix resource ref * Remove failing check Co-authored-by: Mike Laramie --- .../resources/data_source_google_folders.go | 153 ++++++++++++++++++ .../data_source_google_folders_test.go | 47 ++++++ .../terraform/utils/provider.go.erb | 1 + .../website/docs/d/folders.html.markdown | 51 ++++++ 4 files changed, 252 insertions(+) create mode 100644 mmv1/third_party/terraform/resources/data_source_google_folders.go create mode 100644 mmv1/third_party/terraform/resources/data_source_google_folders_test.go create mode 100644 mmv1/third_party/terraform/website/docs/d/folders.html.markdown diff --git a/mmv1/third_party/terraform/resources/data_source_google_folders.go b/mmv1/third_party/terraform/resources/data_source_google_folders.go new file mode 100644 index 000000000000..cec3124dec2f --- /dev/null +++ b/mmv1/third_party/terraform/resources/data_source_google_folders.go @@ -0,0 +1,153 @@ +package google + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceGoogleFolders() *schema.Resource { + return &schema.Resource{ + Read: dataSourceGoogleFoldersRead, + Schema: map[string]*schema.Schema{ + "parent_id": { + Type: schema.TypeString, + Required: true, + }, + "folders": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "parent": { + Type: schema.TypeString, + Computed: true, + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "state": { + Type: schema.TypeString, + Computed: true, + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + }, + "update_time": { + Type: schema.TypeString, + Computed: true, + }, + "delete_time": { + Type: schema.TypeString, + Computed: true, + }, + "etag": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func dataSourceGoogleFoldersRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + params := make(map[string]string) + folders := make([]map[string]interface{}, 0) + + for { + params["parent"] = d.Get("parent_id").(string) + url := "https://cloudresourcemanager.googleapis.com/v3/folders" + + url, err := addQueryParams(url, params) + if err != nil { + return err + } + + res, err := sendRequest(config, "GET", "", url, userAgent, nil) + if err != nil { + return fmt.Errorf("Error retrieving folders: %s", err) + } + + pageFolders := flattenDataSourceGoogleFoldersList(res["folders"]) + folders = append(folders, pageFolders...) + + pToken, ok := res["nextPageToken"] + if ok && pToken != nil && pToken.(string) != "" { + params["pageToken"] = pToken.(string) + } else { + break + } + } + + if err := d.Set("folders", folders); err != nil { + return fmt.Errorf("Error retrieving folders: %s", err) + } + + d.SetId(d.Get("parent_id").(string)) + + return nil +} + +func flattenDataSourceGoogleFoldersList(v interface{}) []map[string]interface{} { + if v == nil { + return make([]map[string]interface{}, 0) + } + + ls := v.([]interface{}) + folders := make([]map[string]interface{}, 0, len(ls)) + for _, raw := range ls { + f := raw.(map[string]interface{}) + + var mState, mName, mCreateTime, mUpdateTime, mDeleteTime, mParent, mDisplayName, mEtag interface{} + if fName, ok := f["name"]; ok { + mName = fName + } + if fState, ok := f["state"]; ok { + mState = fState + } + if fCreateTime, ok := f["createTime"]; ok { + mCreateTime = fCreateTime + } + if fUpdateTime, ok := f["updateTime"]; ok { + mUpdateTime = fUpdateTime + } + if fDeleteTime, ok := f["deleteTime"]; ok { + mDeleteTime = fDeleteTime + } + if fParent, ok := f["parent"]; ok { + mParent = fParent + } + if fDisplayName, ok := f["displayName"]; ok { + mDisplayName = fDisplayName + } + if fEtag, ok := f["etag"]; ok { + mEtag = fEtag + } + folders = append(folders, map[string]interface{}{ + "name": mName, + "state": mState, + "create_time": mCreateTime, + "update_time": mUpdateTime, + "delete_time": mDeleteTime, + "parent": mParent, + "display_name": mDisplayName, + "etag": mEtag, + }) + } + + return folders +} diff --git a/mmv1/third_party/terraform/resources/data_source_google_folders_test.go b/mmv1/third_party/terraform/resources/data_source_google_folders_test.go new file mode 100644 index 000000000000..9c260c90ba7b --- /dev/null +++ b/mmv1/third_party/terraform/resources/data_source_google_folders_test.go @@ -0,0 +1,47 @@ +package google + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccDataSourceGoogleFolders_basic(t *testing.T) { + t.Parallel() + + org := getTestOrgFromEnv(t) + parent := fmt.Sprintf("organizations/%s", org) + displayName := "terraform-test-" + randString(t, 10) + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCheckGoogleFoldersConfig(parent, displayName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.google_folders.root-test", "folders.0.name"), + resource.TestCheckResourceAttrSet("data.google_folders.root-test", "folders.0.display_name"), + resource.TestCheckResourceAttrSet("data.google_folders.root-test", "folders.0.state"), + resource.TestCheckResourceAttrSet("data.google_folders.root-test", "folders.0.create_time"), + resource.TestCheckResourceAttrSet("data.google_folders.root-test", "folders.0.update_time"), + resource.TestCheckResourceAttrSet("data.google_folders.root-test", "folders.0.etag"), + ), + }, + }, + }) +} + +func testAccCheckGoogleFoldersConfig(parent string, displayName string) string { + return fmt.Sprintf(` +resource "google_folder" "foobar" { + parent = "%s" + display_name = "%s" +} + +data "google_folders" "root-test" { + parent_id = "%s" +} +`, parent, displayName, parent) +} diff --git a/mmv1/third_party/terraform/utils/provider.go.erb b/mmv1/third_party/terraform/utils/provider.go.erb index ac7897fccfa9..8d97b14b82a0 100644 --- a/mmv1/third_party/terraform/utils/provider.go.erb +++ b/mmv1/third_party/terraform/utils/provider.go.erb @@ -268,6 +268,7 @@ func Provider() *schema.Provider { "google_firebase_web_app_config": dataSourceGoogleFirebaseWebappConfig(), <% end -%> "google_folder": dataSourceGoogleFolder(), + "google_folders": dataSourceGoogleFolders(), "google_folder_organization_policy": dataSourceGoogleFolderOrganizationPolicy(), "google_monitoring_notification_channel": dataSourceMonitoringNotificationChannel(), "google_monitoring_cluster_istio_service": dataSourceMonitoringServiceClusterIstio(), diff --git a/mmv1/third_party/terraform/website/docs/d/folders.html.markdown b/mmv1/third_party/terraform/website/docs/d/folders.html.markdown new file mode 100644 index 000000000000..a92909156261 --- /dev/null +++ b/mmv1/third_party/terraform/website/docs/d/folders.html.markdown @@ -0,0 +1,51 @@ +--- +subcategory: "Cloud Platform" +layout: "google" +page_title: "Google: google_folders" +sidebar_current: "docs-google-datasource-folders" +description: |- + Retrieve a set of folders based on a parent ID. +--- + +# google\_folders + +Retrieve information about a set of folders based on a parent ID. See the +[REST API](https://cloud.google.com/resource-manager/reference/rest/v3/folders/list) +for more details. + +## Example Usage - searching for folders at the root of an org + +```hcl +data "google_folders" "my-org-folders" { + parent_id = "organizations/${var.organization_id}" +} + +data "google_folder" "first-folder" { + folder = data.google_folders.my-org-folders.folders[0].name +} +``` + +## Argument Reference + +The following arguments are supported: + +* `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). + + +## Attributes Reference + +The following attributes are exported: + +* `folders` - A list of projects matching the provided filter. Structure is defined below. + +The `folders` block supports: + +* `name` - The id of the folder +* `parent` - The parent id of the folder +* `display_name` - The display name of the folder +* `state` - The lifecycle state of the folder +* `create_time` - The timestamp of when the folder was created +* `update_time` - The timestamp of when the folder was last modified +* `delete_time` - The timestamp of when the folder was requested to be deleted (if applicable) +* `etag` - Entity tag identifier of the folder +