From f754c62cbf5fe6553451f2cc762970a1e4745f18 Mon Sep 17 00:00:00 2001 From: The Magician Date: Fri, 17 Jan 2025 15:39:55 -0800 Subject: [PATCH] Add data source for retrieving all organizations (#12740) (#20965) [upstream:3250f7ce91e2ea62d0450ab92c7e8af2dfbb9aec] Signed-off-by: Modular Magician --- .changelog/12740.txt | 3 + google/provider/provider_mmv1_resources.go | 1 + .../data_source_google_organizations.go | 109 ++++++++++++++++++ .../data_source_google_organizations_test.go | 32 +++++ website/docs/d/organizations.html.markdown | 45 ++++++++ 5 files changed, 190 insertions(+) create mode 100644 .changelog/12740.txt create mode 100644 google/services/resourcemanager/data_source_google_organizations.go create mode 100644 google/services/resourcemanager/data_source_google_organizations_test.go create mode 100644 website/docs/d/organizations.html.markdown diff --git a/.changelog/12740.txt b/.changelog/12740.txt new file mode 100644 index 00000000000..094d1f8f0f3 --- /dev/null +++ b/.changelog/12740.txt @@ -0,0 +1,3 @@ +```release-note:new-datasource +`google_organizations` +``` \ No newline at end of file diff --git a/google/provider/provider_mmv1_resources.go b/google/provider/provider_mmv1_resources.go index 9618b255937..9b337b49088 100644 --- a/google/provider/provider_mmv1_resources.go +++ b/google/provider/provider_mmv1_resources.go @@ -291,6 +291,7 @@ var handwrittenDatasources = map[string]*schema.Resource{ "google_oracle_database_cloud_vm_clusters": oracledatabase.DataSourceOracleDatabaseCloudVmClusters(), "google_oracle_database_cloud_vm_cluster": oracledatabase.DataSourceOracleDatabaseCloudVmCluster(), "google_organization": resourcemanager.DataSourceGoogleOrganization(), + "google_organizations": resourcemanager.DataSourceGoogleOrganizations(), "google_privateca_certificate_authority": privateca.DataSourcePrivatecaCertificateAuthority(), "google_privileged_access_manager_entitlement": privilegedaccessmanager.DataSourceGooglePrivilegedAccessManagerEntitlement(), "google_project": resourcemanager.DataSourceGoogleProject(), diff --git a/google/services/resourcemanager/data_source_google_organizations.go b/google/services/resourcemanager/data_source_google_organizations.go new file mode 100644 index 00000000000..cb1394c776e --- /dev/null +++ b/google/services/resourcemanager/data_source_google_organizations.go @@ -0,0 +1,109 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 +package resourcemanager + +import ( + "context" + "fmt" + "path/filepath" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + + "google.golang.org/api/cloudresourcemanager/v1" +) + +func DataSourceGoogleOrganizations() *schema.Resource { + return &schema.Resource{ + Read: datasourceGoogleOrganizationsRead, + Schema: map[string]*schema.Schema{ + "filter": { + Optional: true, + Type: schema.TypeString, + }, + "organizations": { + Computed: true, + Type: schema.TypeList, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "directory_customer_id": { + Computed: true, + Type: schema.TypeString, + }, + "display_name": { + Computed: true, + Type: schema.TypeString, + }, + "lifecycle_state": { + Computed: true, + Type: schema.TypeString, + }, + "name": { + Computed: true, + Type: schema.TypeString, + }, + "org_id": { + Computed: true, + Type: schema.TypeString, + }, + }, + }, + }, + }, + } +} + +func datasourceGoogleOrganizationsRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + organizations := make([]map[string]interface{}, 0) + + filter := "" + if v, ok := d.GetOk("filter"); ok { + filter = v.(string) + } + + request := config.NewResourceManagerClient(userAgent).Organizations.Search(&cloudresourcemanager.SearchOrganizationsRequest{ + Filter: filter, + }) + + err = request.Pages(context.Background(), func(organizationList *cloudresourcemanager.SearchOrganizationsResponse) error { + for _, organization := range organizationList.Organizations { + directoryCustomerId := "" + if organization.Owner != nil { + directoryCustomerId = organization.Owner.DirectoryCustomerId + } + + organizations = append(organizations, map[string]interface{}{ + "directory_customer_id": directoryCustomerId, + "display_name": organization.DisplayName, + "lifecycle_state": organization.LifecycleState, + "name": organization.Name, + "org_id": filepath.Base(organization.Name), + }) + } + return nil + }) + + if err != nil { + return fmt.Errorf("Error retrieving organizations: %s", err) + } + + if err := d.Set("organizations", organizations); err != nil { + return fmt.Errorf("Error setting organizations: %s", err) + } + + if filter == "" { + filter = "empty_filter" + } + d.SetId(filter) + + return nil +} diff --git a/google/services/resourcemanager/data_source_google_organizations_test.go b/google/services/resourcemanager/data_source_google_organizations_test.go new file mode 100644 index 00000000000..5a8b8d5ef68 --- /dev/null +++ b/google/services/resourcemanager/data_source_google_organizations_test.go @@ -0,0 +1,32 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 +package resourcemanager_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-google/google/acctest" +) + +func TestAccDataSourceGoogleOrganizations_basic(t *testing.T) { + t.Parallel() + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: `data "google_organizations" "test" {}`, + Check: resource.ComposeTestCheckFunc( + // We assume that every principal finds at least one organization and we'll only check set-ness + resource.TestCheckResourceAttrSet("data.google_organizations.test", "organizations.0.directory_customer_id"), + resource.TestCheckResourceAttrSet("data.google_organizations.test", "organizations.0.display_name"), + resource.TestCheckResourceAttrSet("data.google_organizations.test", "organizations.0.lifecycle_state"), + resource.TestCheckResourceAttrSet("data.google_organizations.test", "organizations.0.name"), + resource.TestCheckResourceAttrSet("data.google_organizations.test", "organizations.0.org_id"), + ), + }, + }, + }) +} diff --git a/website/docs/d/organizations.html.markdown b/website/docs/d/organizations.html.markdown new file mode 100644 index 00000000000..e2593be8b8e --- /dev/null +++ b/website/docs/d/organizations.html.markdown @@ -0,0 +1,45 @@ +--- +subcategory: "Cloud Platform" +description: |- + Get all organizations. +--- + + +# google_organizations + +Gets a list of all organizations. +See [the official documentation](https://cloud.google.com/resource-manager/docs/creating-managing-organization) +and [API](https://cloud.google.com/resource-manager/reference/rest/v1/organizations/search). + +## Example Usage + +```hcl +data "google_organizations" "example" { + filter = "domain:example.com" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `filter` - (Optional) An optional query string used to filter the Organizations to return in the response. Filter rules are case-insensitive. Further information can be found in the [REST API](https://cloud.google.com/resource-manager/reference/rest/v1/organizations/search#request-body). + + +## Attributes Reference + +The following attributes are exported: + +* `organizations` - A list of all retrieved organizations. Structure is [defined below](#nested_organizations). + +The `organizations` block supports: + +* `directory_customer_id` - The Google for Work customer ID of the Organization. + +* `display_name` - A human-readable string that refers to the Organization in the Google Cloud console. The string will be set to the primary domain (for example, `"google.com"`) of the G Suite customer that owns the organization. + +* `lifecycle_state` - The Organization's current lifecycle state. + +* `name` - The resource name of the Organization in the form `organizations/{organization_id}`. + +* `org_id` - The Organization ID.