From b02686b9ebea7ff2381f757ddbc4d862a5df4eda Mon Sep 17 00:00:00 2001 From: lnesci Date: Thu, 5 Apr 2018 20:59:47 -0300 Subject: [PATCH] google folder data source (#1280) * adding google folder data source with get by id, search by fields and lookup organization functionality * removing search functionality * creating folders for each test and updating documentation with default values --- google/data_source_google_folder.go | 108 ++++++++++++++ google/data_source_google_folder_test.go | 161 +++++++++++++++++++++ google/provider.go | 1 + website/docs/d/google_folder.html.markdown | 52 +++++++ website/google.erb | 3 + 5 files changed, 325 insertions(+) create mode 100644 google/data_source_google_folder.go create mode 100644 google/data_source_google_folder_test.go create mode 100644 website/docs/d/google_folder.html.markdown diff --git a/google/data_source_google_folder.go b/google/data_source_google_folder.go new file mode 100644 index 00000000..df634f99 --- /dev/null +++ b/google/data_source_google_folder.go @@ -0,0 +1,108 @@ +package google + +import ( + "fmt" + "strings" + + "github.com/hashicorp/terraform/helper/schema" + + resourceManagerV2Beta1 "google.golang.org/api/cloudresourcemanager/v2beta1" +) + +func dataSourceGoogleFolder() *schema.Resource { + return &schema.Resource{ + Read: dataSourceFolderRead, + Schema: map[string]*schema.Schema{ + "folder": { + Type: schema.TypeString, + Required: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "parent": { + Type: schema.TypeString, + Computed: true, + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + }, + "lifecycle_state": { + Type: schema.TypeString, + Computed: true, + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + }, + "lookup_organization": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "organization": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourceFolderRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + folderName := d.Get("folder").(string) + + folder, err := config.clientResourceManagerV2Beta1.Folders.Get(canonicalFolderName(folderName)).Do() + + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("Folder Not Found : %s", folderName)) + } + + d.SetId(GetResourceNameFromSelfLink(folder.Name)) + d.Set("name", folder.Name) + d.Set("parent", folder.Parent) + d.Set("display_name", folder.DisplayName) + d.Set("lifecycle_state", folder.LifecycleState) + d.Set("create_time", folder.CreateTime) + + if v, ok := d.GetOk("lookup_organization"); ok && v.(bool) { + organization, err := lookupOrganizationName(folder, config) + + if err != nil { + return err + } + + d.Set("organization", organization) + } + + return nil +} + +func canonicalFolderName(ba string) string { + if strings.HasPrefix(ba, "folders/") { + return ba + } + + return "folders/" + ba +} + +func lookupOrganizationName(folder *resourceManagerV2Beta1.Folder, config *Config) (string, error) { + parent := folder.Parent + + if parent == "" || strings.HasPrefix(parent, "organizations/") { + return parent, nil + } else if strings.HasPrefix(parent, "folders/") { + parentFolder, err := config.clientResourceManagerV2Beta1.Folders.Get(parent).Do() + + if err != nil { + return "", fmt.Errorf("Error getting parent folder '%s': %s", parent, err) + } + + return lookupOrganizationName(parentFolder, config) + } else { + return "", fmt.Errorf("Unknown parent type '%s' on folder '%s'", parent, folder.Name) + } +} diff --git a/google/data_source_google_folder_test.go b/google/data_source_google_folder_test.go new file mode 100644 index 00000000..655dfba0 --- /dev/null +++ b/google/data_source_google_folder_test.go @@ -0,0 +1,161 @@ +package google + +import ( + "fmt" + "regexp" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccDataSourceGoogleFolder_byFullName(t *testing.T) { + org := getTestOrgFromEnv(t) + + parent := fmt.Sprintf("organizations/%s", org) + displayName := "terraform-test-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCheckGoogleFolder_byFullNameConfig(parent, displayName), + Check: resource.ComposeTestCheckFunc( + testAccDataSourceGoogleFolderCheck("data.google_folder.folder", "google_folder.foobar"), + ), + }, + }, + }) +} + +func TestAccDataSourceGoogleFolder_byShortName(t *testing.T) { + org := getTestOrgFromEnv(t) + + parent := fmt.Sprintf("organizations/%s", org) + displayName := "terraform-test-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCheckGoogleFolder_byShortNameConfig(parent, displayName), + Check: resource.ComposeTestCheckFunc( + testAccDataSourceGoogleFolderCheck("data.google_folder.folder", "google_folder.foobar"), + ), + }, + }, + }) +} + +func TestAccDataSourceGoogleFolder_lookupOrganization(t *testing.T) { + org := getTestOrgFromEnv(t) + + parent := fmt.Sprintf("organizations/%s", org) + displayName := "terraform-test-" + acctest.RandString(10) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCheckGoogleFolder_lookupOrganizationConfig(parent, displayName), + Check: resource.ComposeTestCheckFunc( + testAccDataSourceGoogleFolderCheck("data.google_folder.folder", "google_folder.foobar"), + resource.TestCheckResourceAttr("data.google_folder.folder", "organization", parent), + ), + }, + }, + }) +} + +func TestAccDataSourceGoogleFolder_byFullNameNotFound(t *testing.T) { + name := "folders/" + acctest.RandString(16) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCheckGoogleFolder_byFullNameNotFoundConfig(name), + ExpectError: regexp.MustCompile("Folder Not Found : " + name), + }, + }, + }) +} + +func testAccDataSourceGoogleFolderCheck(data_source_name string, resource_name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + ds, ok := s.RootModule().Resources[data_source_name] + if !ok { + return fmt.Errorf("root module has no resource called %s", data_source_name) + } + + rs, ok := s.RootModule().Resources[resource_name] + if !ok { + return fmt.Errorf("can't find %s in state", resource_name) + } + + ds_attr := ds.Primary.Attributes + rs_attr := rs.Primary.Attributes + folder_attrs_to_test := []string{"parent", "display_name", "name"} + + for _, attr_to_check := range folder_attrs_to_test { + if ds_attr[attr_to_check] != rs_attr[attr_to_check] { + return fmt.Errorf( + "%s is %s; want %s", + attr_to_check, + ds_attr[attr_to_check], + rs_attr[attr_to_check], + ) + } + } + return nil + } +} + +func testAccCheckGoogleFolder_byFullNameConfig(parent string, displayName string) string { + return fmt.Sprintf(` +resource "google_folder" "foobar" { + parent = "%s" + display_name = "%s" +} + +data "google_folder" "folder" { + folder = "${google_folder.foobar.name}" +}`, parent, displayName) +} + +func testAccCheckGoogleFolder_byShortNameConfig(parent string, displayName string) string { + return fmt.Sprintf(` +resource "google_folder" "foobar" { + parent = "%s" + display_name = "%s" +} + +data "google_folder" "folder" { + folder = "${replace(google_folder.foobar.name, "folders/", "")}" +}`, parent, displayName) +} + +func testAccCheckGoogleFolder_lookupOrganizationConfig(parent string, displayName string) string { + return fmt.Sprintf(` +resource "google_folder" "foobar" { + parent = "%s" + display_name = "%s" +} + +data "google_folder" "folder" { + folder = "${google_folder.foobar.name}" + lookup_organization = true +}`, parent, displayName) +} + +func testAccCheckGoogleFolder_byFullNameNotFoundConfig(name string) string { + return fmt.Sprintf(` +data "google_folder" "folder" { + folder = "%s" +}`, name) +} diff --git a/google/provider.go b/google/provider.go index c823480e..fc767daa 100644 --- a/google/provider.go +++ b/google/provider.go @@ -86,6 +86,7 @@ func Provider() terraform.ResourceProvider { "google_container_registry_image": dataSourceGoogleContainerImage(), "google_iam_policy": dataSourceGoogleIamPolicy(), "google_kms_secret": dataSourceGoogleKmsSecret(), + "google_folder": dataSourceGoogleFolder(), "google_organization": dataSourceGoogleOrganization(), "google_storage_object_signed_url": dataSourceGoogleSignedUrl(), "google_storage_project_service_account": dataSourceGoogleStorageProjectServiceAccount(), diff --git a/website/docs/d/google_folder.html.markdown b/website/docs/d/google_folder.html.markdown new file mode 100644 index 00000000..69146b38 --- /dev/null +++ b/website/docs/d/google_folder.html.markdown @@ -0,0 +1,52 @@ +--- +layout: "google" +page_title: "Google: google_folder" +sidebar_current: "docs-google-datasource-folder" +description: |- + Get information about a Google Cloud Folder. +--- + +# google\_folder + +Use this data source to get information about a Google Cloud Folder. + +```hcl +# Get folder by id +data "google_folder" "my_folder_1" { + folder = "folders/12345" + lookup_organization = true +} + +# Search by fields +data "google_folder" "my_folder_2" { + folder = "folders/23456" +} + +output "my_folder_1_organization" { + value = "${data.google_folder.my_folder_1.organization}" +} + +output "my_folder_2_parent" { + value = "${data.google_folder.my_folder_2.parent}" +} + +``` + +## Argument Reference + +The following arguments are supported: + +* `folder` (Required) - The name of the Folder in the form `{folder_id}` or `folders/{folder_id}`. +* `lookup_organization` (Optional) - `true` to find the organization that the folder belongs, `false` to avoid the lookup. It searches up the tree. (defaults to `false`) + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Folder ID. +* `name` - The resource name of the Folder in the form `folders/{organization_id}`. +* `parent` - The resource name of the parent Folder or Organization. +* `display_name` - The folder's display name. +* `create_time` - Timestamp when the Organization was created. A timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. Example: "2014-10-02T15:01:23.045123456Z". +* `lifecycle_state` - The Folder's current lifecycle state. +* `organization` - If `lookup_organization` is enable, the resource name of the Organization that the folder belongs. diff --git a/website/google.erb b/website/google.erb index d86bd3a1..d08a962f 100644 --- a/website/google.erb +++ b/website/google.erb @@ -95,6 +95,9 @@ > google_organization + > + google_folder + > google_storage_object_signed_url