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

Promoted (most of) the supported cloud identity resources to GA #7786

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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .changelog/4211.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
```release-note:enhancement
cloud_identity: promoted `google_cloud_identity_group` to GA
```
```release-note:enhancement
cloud_identity: promoted `google_cloud_identity_group_membership` to GA
```
```release-note:enhancement
cloud_identity: promoted data source `google_cloud_identity_groups` to GA
```
```release-note:enhancement
cloud_identity: promoted data source `google_cloud_identity_group_memberships` to GA
```
18 changes: 18 additions & 0 deletions google/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"google.golang.org/api/cloudbilling/v1"
"google.golang.org/api/cloudbuild/v1"
"google.golang.org/api/cloudfunctions/v1"
"google.golang.org/api/cloudidentity/v1"
"google.golang.org/api/cloudiot/v1"
"google.golang.org/api/cloudkms/v1"
"google.golang.org/api/cloudresourcemanager/v1"
Expand Down Expand Up @@ -93,6 +94,7 @@ type Config struct {
CloudAssetBasePath string
CloudBuildBasePath string
CloudFunctionsBasePath string
CloudIdentityBasePath string
CloudIotBasePath string
CloudRunBasePath string
CloudSchedulerBasePath string
Expand Down Expand Up @@ -166,6 +168,7 @@ var BinaryAuthorizationDefaultBasePath = "https://binaryauthorization.googleapis
var CloudAssetDefaultBasePath = "https://cloudasset.googleapis.com/v1/"
var CloudBuildDefaultBasePath = "https://cloudbuild.googleapis.com/v1/"
var CloudFunctionsDefaultBasePath = "https://cloudfunctions.googleapis.com/v1/"
var CloudIdentityDefaultBasePath = "https://cloudidentity.googleapis.com/v1/"
var CloudIotDefaultBasePath = "https://cloudiot.googleapis.com/v1/"
var CloudRunDefaultBasePath = "https://{{location}}-run.googleapis.com/"
var CloudSchedulerDefaultBasePath = "https://cloudscheduler.googleapis.com/v1/"
Expand Down Expand Up @@ -793,6 +796,20 @@ func (c *Config) NewHealthcareClient(userAgent string) *healthcare.Service {
return clientHealthcare
}

func (c *Config) NewCloudIdentityClient(userAgent string) *cloudidentity.Service {
cloudidentityClientBasePath := removeBasePathVersion(c.CloudIdentityBasePath)
log.Printf("[INFO] Instantiating Google Cloud CloudIdentity client for path %s", cloudidentityClientBasePath)
clientCloudIdentity, err := cloudidentity.NewService(c.context, option.WithHTTPClient(c.client))
if err != nil {
log.Printf("[WARN] Error creating client cloud identity: %s", err)
return nil
}
clientCloudIdentity.UserAgent = userAgent
clientCloudIdentity.BasePath = cloudidentityClientBasePath

return clientCloudIdentity
}

func (c *Config) BigTableClientFactory(userAgent string) *BigtableClientFactory {
bigtableClientFactory := &BigtableClientFactory{
UserAgent: userAgent,
Expand Down Expand Up @@ -935,6 +952,7 @@ func ConfigureBasePaths(c *Config) {
c.CloudAssetBasePath = CloudAssetDefaultBasePath
c.CloudBuildBasePath = CloudBuildDefaultBasePath
c.CloudFunctionsBasePath = CloudFunctionsDefaultBasePath
c.CloudIdentityBasePath = CloudIdentityDefaultBasePath
c.CloudIotBasePath = CloudIotDefaultBasePath
c.CloudRunBasePath = CloudRunDefaultBasePath
c.CloudSchedulerBasePath = CloudSchedulerDefaultBasePath
Expand Down
77 changes: 77 additions & 0 deletions google/data_source_cloud_identity_group_memberships.go
Original file line number Diff line number Diff line change
@@ -1 +1,78 @@
package google

import (
"fmt"
"time"

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

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)
userAgent, err := generateUserAgentString(d, config.userAgent)
if err != nil {
return err
}

result := []map[string]interface{}{}
err = config.NewCloudIdentityClient(userAgent).Groups.Memberships.List(d.Get("group").(string)).View("FULL").Pages(config.context, func(resp *cloudidentity.ListMembershipsResponse) error {

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

return nil
})
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("CloudIdentityGroupMemberships %q", d.Id()))
}

if err := d.Set("memberships", result); err != nil {
return fmt.Errorf("Error setting memberships: %s", err)
}
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
}
45 changes: 45 additions & 0 deletions google/data_source_cloud_identity_group_memberships_test.go
Original file line number Diff line number Diff line change
@@ -1 +1,46 @@
package google

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/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: testAccProviders,
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" {
group = google_cloud_identity_group_membership.cloud_identity_group_membership_basic.group
}
`, context)
}
78 changes: 78 additions & 0 deletions google/data_source_cloud_identity_groups.go
Original file line number Diff line number Diff line change
@@ -1 +1,79 @@
package google

import (
"fmt"
"time"

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

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)
userAgent, err := generateUserAgentString(d, config.userAgent)
if err != nil {
return err
}

result := []map[string]interface{}{}
err = config.NewCloudIdentityClient(userAgent).Groups.List().Parent(d.Get("parent").(string)).View("FULL").Pages(config.context, func(resp *cloudidentity.ListGroupsResponse) error {
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),
})
}

return nil
})
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("CloudIdentityGroups %q", d.Id()))
}

if err := d.Set("groups", result); err != nil {
return fmt.Errorf("Error setting groups: %s", err)
}
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}
}
41 changes: 41 additions & 0 deletions google/data_source_cloud_identity_groups_test.go
Original file line number Diff line number Diff line change
@@ -1 +1,42 @@
package google

import (
"regexp"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/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: testAccProviders,
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" {
parent = google_cloud_identity_group.cloud_identity_group_basic.parent
}
`, context)
}
15 changes: 13 additions & 2 deletions google/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,14 @@ func Provider() *schema.Provider {
"GOOGLE_CLOUD_FUNCTIONS_CUSTOM_ENDPOINT",
}, CloudFunctionsDefaultBasePath),
},
"cloud_identity_custom_endpoint": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validateCustomEndpoint,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{
"GOOGLE_CLOUD_IDENTITY_CUSTOM_ENDPOINT",
}, CloudIdentityDefaultBasePath),
},
"cloud_iot_custom_endpoint": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -656,9 +664,9 @@ func Provider() *schema.Provider {
return provider
}

// Generated resources: 167
// Generated resources: 169
// Generated IAM resources: 72
// Total generated resources: 239
// Total generated resources: 241
func ResourceMap() map[string]*schema.Resource {
resourceMap, _ := ResourceMapWithErrors()
return resourceMap
Expand Down Expand Up @@ -706,6 +714,8 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) {
"google_cloudfunctions_function_iam_binding": ResourceIamBinding(CloudFunctionsCloudFunctionIamSchema, CloudFunctionsCloudFunctionIamUpdaterProducer, CloudFunctionsCloudFunctionIdParseFunc),
"google_cloudfunctions_function_iam_member": ResourceIamMember(CloudFunctionsCloudFunctionIamSchema, CloudFunctionsCloudFunctionIamUpdaterProducer, CloudFunctionsCloudFunctionIdParseFunc),
"google_cloudfunctions_function_iam_policy": ResourceIamPolicy(CloudFunctionsCloudFunctionIamSchema, CloudFunctionsCloudFunctionIamUpdaterProducer, CloudFunctionsCloudFunctionIdParseFunc),
"google_cloud_identity_group": resourceCloudIdentityGroup(),
"google_cloud_identity_group_membership": resourceCloudIdentityGroupMembership(),
"google_cloudiot_registry": resourceCloudIotDeviceRegistry(),
"google_cloudiot_device": resourceCloudIotDevice(),
"google_cloud_run_domain_mapping": resourceCloudRunDomainMapping(),
Expand Down Expand Up @@ -1102,6 +1112,7 @@ func providerConfigure(ctx context.Context, d *schema.ResourceData, p *schema.Pr
config.CloudAssetBasePath = d.Get("cloud_asset_custom_endpoint").(string)
config.CloudBuildBasePath = d.Get("cloud_build_custom_endpoint").(string)
config.CloudFunctionsBasePath = d.Get("cloud_functions_custom_endpoint").(string)
config.CloudIdentityBasePath = d.Get("cloud_identity_custom_endpoint").(string)
config.CloudIotBasePath = d.Get("cloud_iot_custom_endpoint").(string)
config.CloudRunBasePath = d.Get("cloud_run_custom_endpoint").(string)
config.CloudSchedulerBasePath = d.Get("cloud_scheduler_custom_endpoint").(string)
Expand Down
18 changes: 18 additions & 0 deletions google/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ var orgEnvVars = []string{
"GOOGLE_ORG",
}

var custIdEnvVars = []string{
"GOOGLE_CUST_ID",
}

var identityUserEnvVars = []string{
"GOOGLE_IDENTITY_USER",
}

var orgEnvDomainVars = []string{
"GOOGLE_ORG_DOMAIN",
}
Expand Down Expand Up @@ -859,6 +867,16 @@ func getTestZoneFromEnv() string {
return multiEnvSearch(zoneEnvVars)
}

func getTestCustIdFromEnv(t *testing.T) string {
skipIfEnvNotSet(t, custIdEnvVars...)
return multiEnvSearch(custIdEnvVars)
}

func getTestIdentityUserFromEnv(t *testing.T) string {
skipIfEnvNotSet(t, identityUserEnvVars...)
return multiEnvSearch(identityUserEnvVars)
}

// Firestore can't be enabled at the same time as Datastore, so we need a new
// project to manage it until we can enable Firestore programmatically.
func getTestFirestoreProjectFromEnv(t *testing.T) string {
Expand Down
Loading