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 dynamicGroupMetadata in cloud_identity_group #9452

Closed
wants to merge 10 commits into from
Closed
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
81 changes: 80 additions & 1 deletion mmv1/products/cloudidentity/Group.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,17 @@ examples:
test_env_vars:
org_domain: :ORG_DOMAIN
cust_id: :CUST_ID
- !ruby/object:Provider::Terraform::Examples
name: 'cloud_identity_groups_dynamic'
skip_test: true
primary_resource_id: 'cloud_identity_groups_dynamic'
vars:
id_group: 'my-identity-dynamic-group'
test_env_vars:
org_domain: :ORG_DOMAIN
cust_id: :CUST_ID
custom_code: !ruby/object:Provider::Terraform::CustomCode
constants: templates/terraform/constants/cloud_identity_group_dynamic_label.go.erb
post_create: templates/terraform/post_create/set_computed_name.erb
custom_import: templates/terraform/custom_import/cloud_identity_group_import.go.erb
parameters:
Expand Down Expand Up @@ -172,13 +182,82 @@ properties:
- !ruby/object:Api::Type::KeyValuePairs
name: 'labels'
required: true
diff_suppress_func: resourceCloudIdentityGroupDynamicLabelDiffSuppress
description: |
One or more label entries that apply to the Group. Currently supported labels contain a key with an empty value.

Google Groups are the default type of group and have a label with a key of cloudidentity.googleapis.com/groups.discussion_forum and an empty value.

Existing Google Groups can have an additional label with a key of cloudidentity.googleapis.com/groups.security and an empty value added to them. This is an immutable change and the security label cannot be removed once added.

Dynamic groups have a label with a key of cloudidentity.googleapis.com/groups.dynamic.
Dynamic groups have a label with a key of cloudidentity.googleapis.com/groups.dynamic automatically added by the API when creating a group with 'dynamicGroupMetadata'.

Identity-mapped groups for Cloud Search have a label with a key of system/groups/external and an empty value.
- !ruby/object:Api::Type::NestedObject
name: 'dynamicGroupMetadata'
description: |
Dynamic group metadata like queries and status.
properties:
- !ruby/object:Api::Type::Array
name: 'queries'
description: |
Memberships will be the union of all queries. Only one entry with USER resource is currently supported. Customers can create up to 100 dynamic groups.
item_type: !ruby/object:Api::Type::NestedObject
properties:
- !ruby/object:Api::Type::Enum
name: 'resourceType'
required: true
description: |
Resource type for the Dynamic Group Query.
values:
- :USER
- !ruby/object:Api::Type::String
name: 'query'
required: true
description: |
Query that determines the memberships of the dynamic group.
Examples:
* All users with at least one organizations.department of engineering.
```
user.organizations.exists(org, org.department=='engineering')
```
* All users with at least one location that has area of foo and building_id of bar.
```
user.locations.exists(loc, loc.area=='foo' && loc.building_id=='bar')
```
* All users with any variation of the name John Doe (case-insensitive queries add
equalsIgnoreCase() to the value being queried).
```
user.name.value.equalsIgnoreCase('jOhn DoE')
```
**Note:** When using this field, Identity API will add
`"cloudidentity.googleapis.com/groups.dynamic"` to this group's labels.
- !ruby/object:Api::Type::NestedObject
name: 'status'
output: true
description: |
The current status of a dynamic group along with timestamp.
properties:
- !ruby/object:Api::Type::Enum
name: 'status'
output: true
description: |
Status of the dynamic group.
values:
- :UP_TO_DATE
- :UPDATING_MEMBERSHIPS
- :INVALID_QUERY
- :STATUS_UNSPECIFIED
- !ruby/object:Api::Type::Time
name: 'statusTime'
output: true
description: |
The latest time at which the dynamic group is guaranteed to be in
the given status. If status is UP_TO_DATE, the latest time at
which the dynamic group was confirmed to be up-to-date. If status
is UPDATING_MEMBERSHIPS, the time at which dynamic group was
created.

A timestamp in RFC3339 UTC "Zulu" format, with nanosecond
resolution and up to nine fractional digits.
Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const dynamicLabel = "cloudidentity.googleapis.com/groups.dynamic"

// we want to suppress the dynamic label diff
func resourceCloudIdentityGroupDynamicLabelDiffSuppress(k, _, _ string, d *schema.ResourceData) bool {
// For a map, k is path to the element, rather than the map.
// E.g. "node_groups.2.ips.0"
lastDotIndex := strings.LastIndex(k, ".")
if lastDotIndex != -1 {
k = string(k[:lastDotIndex])
}

oldData, newData := d.GetChange(k)
if oldData == nil || newData == nil {
return false
}

m := make(map[string]interface{})
for key, val := range oldData.(map[string]interface{}) {
if key != dynamicLabel {
m[key] = val
}
}
return reflect.DeepEqual(m, newData.(map[string]interface{}))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
resource "google_cloud_identity_group" "<%= ctx[:primary_resource_id] %>" {
display_name = "<%= ctx[:vars]['id_group'] %>"

parent = "customers/<%= ctx[:test_env_vars]['cust_id'] %>"

group_key {
id = "<%= ctx[:vars]['id_group'] %>@<%= ctx[:test_env_vars]['org_domain'] %>"
}

labels = {
"cloudidentity.googleapis.com/groups.discussion_forum" = ""
}

dynamic_group_metadata {
queries {
resource_type = "USER"
query = "user.addresses.exists(ad, ad.locality=='Sunnyvale')"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ resource "google_cloud_identity_group" "cloud_identity_group_basic" {

labels = {
"cloudidentity.googleapis.com/groups.discussion_forum" = ""
"cloudidentity.googleapis.com/groups.security" = ""
"cloudidentity.googleapis.com/groups.security" = ""
}
}
`, context)
Expand Down Expand Up @@ -177,3 +177,87 @@ func testAccCheckCloudIdentityGroupDestroyProducer(t *testing.T) func(s *terrafo
return nil
}
}

func TestAccCloudIdentityGroup_cloudIdentityGroupsDynamicExample(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"org_domain": envvar.GetTestOrgDomainFromEnv(t),
"cust_id": envvar.GetTestCustIdFromEnv(t),
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
CheckDestroy: testAccCheckCloudIdentityGroupDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccCloudIdentityGroup_cloudIdentityGroupsDynamicExample(context),
ExpectNonEmptyPlan: true,
},
{
ResourceName: "google_cloud_identity_group.cloud_identity_groups_dynamic",
ImportState: true,
},
{
Config: testAccCloudIdentityGroup_cloudIdentityGroupsDynamicUpdate(context),
},
{
ResourceName: "google_cloud_identity_group.cloud_identity_groups_dynamic",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccCloudIdentityGroup_cloudIdentityGroupsDynamicExample(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_cloud_identity_group" "cloud_identity_groups_dynamic" {
display_name = "tf-test-my-identity-dynamic-group%{random_suffix}"

parent = "customers/%{cust_id}"

group_key {
id = "tf-test-my-identity-dynamic-group%{random_suffix}@%{org_domain}"
}

labels = {
"cloudidentity.googleapis.com/groups.discussion_forum" = ""
}

dynamic_group_metadata {
queries {
resource_type = "USER"
query = "user.addresses.exists(ad, ad.locality=='Seattle')"
}
}
}
`, context)
}

func testAccCloudIdentityGroup_cloudIdentityGroupsDynamicUpdate(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_cloud_identity_group" "cloud_identity_groups_dynamic" {
display_name = "tf-test-my-identity-dynamic-group%{random_suffix}"

parent = "customers/%{cust_id}"

group_key {
id = "tf-test-my-identity-dynamic-group%{random_suffix}@%{org_domain}"
}

labels = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the automatically added dynamic group label is causing problems here. We may need to either add a DiffSuppressFunc for that label, or add it explicitly to the tests

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, added it to the tests.

"cloudidentity.googleapis.com/groups.discussion_forum" = ""
}

dynamic_group_metadata {
queries {
resource_type = "USER"
query = "user.addresses.exists(ad, ad.locality=='Seattle')"
}
}
}
`, context)
}