Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add cloud identity data sources #2240

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changelog/3714.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
```release-note:new-datasource
`google_cloud_identity_groups`
```
```release-note:new-datasource
`google_cloud_identity_group_memberships`
```
13 changes: 13 additions & 0 deletions google-beta/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"google.golang.org/api/cloudbilling/v1"
"google.golang.org/api/cloudbuild/v1"
"google.golang.org/api/cloudfunctions/v1"
cloudidentity "google.golang.org/api/cloudidentity/v1beta1"
"google.golang.org/api/cloudiot/v1"
"google.golang.org/api/cloudkms/v1"
"google.golang.org/api/cloudresourcemanager/v1"
Expand Down Expand Up @@ -142,6 +143,8 @@ type Config struct {

clientBuild *cloudbuild.Service

clientCloudIdentity *cloudidentity.Service

ComposerBasePath string
clientComposer *composer.Service

Expand Down Expand Up @@ -671,6 +674,16 @@ func (c *Config) LoadAndValidate(ctx context.Context) error {
c.clientHealthcare.UserAgent = userAgent
c.clientHealthcare.BasePath = healthcareClientBasePath

cloudidentityClientBasePath := removeBasePathVersion(c.CloudIdentityBasePath)
log.Printf("[INFO] Instantiating Google Cloud CloudIdentity client for path %s", cloudidentityClientBasePath)

c.clientCloudIdentity, err = cloudidentity.NewService(ctx, option.WithHTTPClient(client))
if err != nil {
return err
}
c.clientCloudIdentity.UserAgent = userAgent
c.clientCloudIdentity.BasePath = cloudidentityClientBasePath

c.Region = GetRegionFromRegionSelfLink(c.Region)

c.requestBatcherServiceUsage = NewRequestBatcher("Service Usage", ctx, c.BatchingConfig)
Expand Down
70 changes: 70 additions & 0 deletions google-beta/data_source_cloud_identity_group_memberships.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package google

import (
"fmt"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
cloudidentity "google.golang.org/api/cloudidentity/v1beta1"
)

func dataSourceGoogleCloudIdentityGroupMemberships() *schema.Resource {
// Generate datasource schema from resource
dsSchema := datasourceSchemaFromResourceSchema(resourceCloudIdentityGroupMembership().Schema)

return &schema.Resource{
Read: dataSourceGoogleCloudIdentityGroupMembershipsRead,

Schema: map[string]*schema.Schema{
"memberships": {
Type: schema.TypeList,
Computed: true,
Description: `List of Cloud Identity group memberships.`,
Elem: &schema.Resource{
Schema: dsSchema,
},
},
"group": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
DiffSuppressFunc: compareSelfLinkOrResourceName,
Description: `The name of the Group to get memberships from.`,
},
},
}
}

func dataSourceGoogleCloudIdentityGroupMembershipsRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

resp, err := config.clientCloudIdentity.Groups.Memberships.List(d.Get("group").(string)).View("FULL").Do()
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("CloudIdentityGroups %q", d.Id()))
}

result := []map[string]interface{}{}
for _, member := range resp.Memberships {
result = append(result, map[string]interface{}{
"name": member.Name,
"roles": flattenCloudIdentityGroupMembershipsRoles(member.Roles),
"member_key": flattenCloudIdentityGroupsEntityKey(member.MemberKey),
"preferred_member_key": flattenCloudIdentityGroupsEntityKey(member.PreferredMemberKey),
})
}

d.Set("memberships", result)
d.SetId(time.Now().UTC().String())
return nil
}

func flattenCloudIdentityGroupMembershipsRoles(roles []*cloudidentity.MembershipRole) []interface{} {
transformed := []interface{}{}

for _, role := range roles {
transformed = append(transformed, map[string]interface{}{
"name": role.Name,
})
}
return transformed
}
48 changes: 48 additions & 0 deletions google-beta/data_source_cloud_identity_group_memberships_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package google

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
)

func TestAccDataSourceCloudIdentityGroupMemberships_basic(t *testing.T) {

context := map[string]interface{}{
"org_domain": getTestOrgDomainFromEnv(t),
"cust_id": getTestCustIdFromEnv(t),
"identity_user": getTestIdentityUserFromEnv(t),
"random_suffix": randString(t, 10),
}

memberId := Nprintf("%{identity_user}@%{org_domain}", context)

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProvidersOiCS,
Steps: []resource.TestStep{
{
Config: testAccCloudIdentityGroupMembershipConfig(context),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.google_cloud_identity_group_memberships.members",
"memberships.#", "1"),
resource.TestCheckResourceAttr("data.google_cloud_identity_group_memberships.members",
"memberships.0.roles.#", "2"),
resource.TestCheckResourceAttr("data.google_cloud_identity_group_memberships.members",
"memberships.0.member_key.0.id", memberId),
),
},
},
})
}

func testAccCloudIdentityGroupMembershipConfig(context map[string]interface{}) string {
return testAccCloudIdentityGroupMembership_cloudIdentityGroupMembershipUserExample(context) + Nprintf(`

data "google_cloud_identity_group_memberships" "members" {
provider = google-beta

group = google_cloud_identity_group_membership.cloud_identity_group_membership_basic.group
}
`, context)
}
71 changes: 71 additions & 0 deletions google-beta/data_source_cloud_identity_groups.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package google

import (
"fmt"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
cloudidentity "google.golang.org/api/cloudidentity/v1beta1"
)

func dataSourceGoogleCloudIdentityGroups() *schema.Resource {
// Generate datasource schema from resource
dsSchema := datasourceSchemaFromResourceSchema(resourceCloudIdentityGroup().Schema)

return &schema.Resource{
Read: dataSourceGoogleCloudIdentityGroupsRead,

Schema: map[string]*schema.Schema{
"groups": {
Type: schema.TypeList,
Computed: true,
Description: `List of Cloud Identity groups.`,
Elem: &schema.Resource{
Schema: dsSchema,
},
},
"parent": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: `The resource name of the entity under which this Group resides in the
Cloud Identity resource hierarchy.

Must be of the form identitysources/{identity_source_id} for external-identity-mapped
groups or customers/{customer_id} for Google Groups.`,
},
},
}
}

func dataSourceGoogleCloudIdentityGroupsRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

resp, err := config.clientCloudIdentity.Groups.List().Parent(d.Get("parent").(string)).View("FULL").Do()
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("CloudIdentityGroups %q", d.Id()))
}

result := []map[string]interface{}{}
for _, group := range resp.Groups {
result = append(result, map[string]interface{}{
"name": group.Name,
"display_name": group.DisplayName,
"labels": group.Labels,
"description": group.Description,
"group_key": flattenCloudIdentityGroupsEntityKey(group.GroupKey),
})
}

d.Set("groups", result)
d.SetId(time.Now().UTC().String())
return nil
}

func flattenCloudIdentityGroupsEntityKey(entityKey *cloudidentity.EntityKey) []interface{} {
transformed := map[string]interface{}{
"id": entityKey.Id,
"namespace": entityKey.Namespace,
}
return []interface{}{transformed}
}
44 changes: 44 additions & 0 deletions google-beta/data_source_cloud_identity_groups_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package google

import (
"regexp"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
)

func TestAccDataSourceCloudIdentityGroups_basic(t *testing.T) {

context := map[string]interface{}{
"org_domain": getTestOrgDomainFromEnv(t),
"cust_id": getTestCustIdFromEnv(t),
"random_suffix": randString(t, 10),
}

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProvidersOiCS,
Steps: []resource.TestStep{
{
Config: testAccCloudIdentityGroupConfig(context),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.google_cloud_identity_groups.groups",
"groups.#"),
resource.TestMatchResourceAttr("data.google_cloud_identity_groups.groups",
"groups.0.name", regexp.MustCompile("^groups/.*$")),
),
},
},
})
}

func testAccCloudIdentityGroupConfig(context map[string]interface{}) string {
return testAccCloudIdentityGroup_cloudIdentityGroupsBasicExample(context) + Nprintf(`

data "google_cloud_identity_groups" "groups" {
provider = google-beta

parent = google_cloud_identity_group.cloud_identity_group_basic.parent
}
`, context)
}
2 changes: 2 additions & 0 deletions google-beta/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,8 @@ func Provider() terraform.ResourceProvider {
"google_client_config": dataSourceGoogleClientConfig(),
"google_client_openid_userinfo": dataSourceGoogleClientOpenIDUserinfo(),
"google_cloudfunctions_function": dataSourceGoogleCloudFunctionsFunction(),
"google_cloud_identity_groups": dataSourceGoogleCloudIdentityGroups(),
"google_cloud_identity_group_memberships": dataSourceGoogleCloudIdentityGroupMemberships(),
"google_composer_image_versions": dataSourceGoogleComposerImageVersions(),
"google_compute_address": dataSourceGoogleComputeAddress(),
"google_compute_backend_service": dataSourceGoogleComputeBackendService(),
Expand Down
74 changes: 74 additions & 0 deletions website/docs/d/cloud_identity_group_membership.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
subcategory: "Cloud Identity"
layout: "google"
page_title: "Google: google_cloud_identity_group_memberships"
sidebar_current: "docs-google-datasource-cloud-identity-group-memberships"
description: |-
Get list of the Cloud Identity Group Memberships within a Group.
---

# google_cloud_identity_group_memberships

Use this data source to get list of the Cloud Identity Group Memberships within a given Group.

https://cloud.google.com/identity/docs/concepts/overview#memberships

## Example Usage

```tf
data "google_cloud_identity_group_memberships" "members" {
group = "groups/123eab45c6defghi"
}
```

## Argument Reference

* `group` - The parent Group resource under which to lookup the Membership names. Must be of the form groups/{group_id}.

## Attributes Reference

In addition to the arguments listed above, the following attributes are exported:

* `memberships` - The list of memberships under the given group. Structure is documented below.

The `memberships` block contains:

* `name` -
The resource name of the Membership, of the form groups/{group_id}/memberships/{membership_id}.

* `roles` - The MembershipRoles that apply to the Membership. Structure is documented below.

* `member_key` -
(Optional)
EntityKey of the member. Structure is documented below.

* `preferred_member_key` -
(Optional)
EntityKey of the member. Structure is documented below.

The `roles` block supports:

* `name` - The name of the MembershipRole. One of OWNER, MANAGER, MEMBER.


The `member_key` block supports:

* `id` - The ID of the entity. For Google-managed entities, the id is the email address of an existing
group or user. For external-identity-mapped entities, the id is a string conforming
to the Identity Source's requirements.

* `namespace` - The namespace in which the entity exists.
If not populated, the EntityKey represents a Google-managed entity
such as a Google user or a Google Group.
If populated, the EntityKey represents an external-identity-mapped group.

The `preferred_member_key` block supports:

* `id` - The ID of the entity. For Google-managed entities, the id is the email address of an existing
group or user. For external-identity-mapped entities, the id is a string conforming
to the Identity Source's requirements.

* `namespace` - The namespace in which the entity exists.
If not populated, the EntityKey represents a Google-managed entity
such as a Google user or a Google Group.
If populated, the EntityKey represents an external-identity-mapped group.