Skip to content

Commit e599942

Browse files
add expiryDetail to google_cloud_identity_group_membership (#9427) (#16643)
[upstream:08dfecd2300850889a16251595a0bbca320b73a6] Signed-off-by: Modular Magician <[email protected]>
1 parent 67b0850 commit e599942

File tree

4 files changed

+189
-42
lines changed

4 files changed

+189
-42
lines changed

.changelog/9427.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
cloudidentity: added `expiry_detail` field to `google_cloud_identity_group_membership` resource
3+
```

google/services/cloudidentity/resource_cloud_identity_group_membership.go

+166-41
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,27 @@ func cloudidentityGroupMembershipRolesSchema() *schema.Resource {
138138
ValidateFunc: verify.ValidateEnum([]string{"OWNER", "MANAGER", "MEMBER"}),
139139
Description: `The name of the MembershipRole. Must be one of OWNER, MANAGER, MEMBER. Possible values: ["OWNER", "MANAGER", "MEMBER"]`,
140140
},
141+
"expiry_detail": {
142+
Type: schema.TypeList,
143+
Optional: true,
144+
Description: `The MembershipRole expiry details, only supported for MEMBER role.
145+
Other roles cannot be accompanied with MEMBER role having expiry.`,
146+
MaxItems: 1,
147+
Elem: &schema.Resource{
148+
Schema: map[string]*schema.Schema{
149+
"expire_time": {
150+
Type: schema.TypeString,
151+
Required: true,
152+
Description: `The time at which the MembershipRole will expire.
153+
154+
A timestamp in RFC3339 UTC "Zulu" format, with nanosecond
155+
resolution and up to nine fractional digits.
156+
157+
Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".`,
158+
},
159+
},
160+
},
161+
},
141162
},
142163
}
143164
}
@@ -286,20 +307,6 @@ func resourceCloudIdentityGroupMembershipUpdate(d *schema.ResourceData, meta int
286307
d.Partial(true)
287308

288309
if d.HasChange("roles") {
289-
obj := make(map[string]interface{})
290-
291-
rolesProp, err := expandCloudIdentityGroupMembershipRoles(d.Get("roles"), d, config)
292-
if err != nil {
293-
return err
294-
} else if v, ok := d.GetOkExists("roles"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, rolesProp)) {
295-
obj["roles"] = rolesProp
296-
}
297-
298-
obj, err = resourceCloudIdentityGroupMembershipUpdateEncoder(d, meta, obj)
299-
if err != nil {
300-
return err
301-
}
302-
303310
url, err := tpgresource.ReplaceVars(d, config, "{{CloudIdentityBasePath}}{{name}}:modifyMembershipRoles")
304311
if err != nil {
305312
return err
@@ -310,21 +317,106 @@ func resourceCloudIdentityGroupMembershipUpdate(d *schema.ResourceData, meta int
310317
billingProject = bp
311318
}
312319

313-
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
314-
Config: config,
315-
Method: "POST",
316-
Project: billingProject,
317-
RawURL: url,
318-
UserAgent: userAgent,
319-
Body: obj,
320-
Timeout: d.Timeout(schema.TimeoutUpdate),
321-
})
322-
if err != nil {
323-
return fmt.Errorf("Error updating GroupMembership %q: %s", d.Id(), err)
324-
} else {
325-
log.Printf("[DEBUG] Finished updating GroupMembership %q: %#v", d.Id(), res)
320+
// Return object for modifyMembershipRoles (we build request object from scratch, without using `obj`)
321+
b, a := d.GetChange("roles")
322+
before := b.(*schema.Set)
323+
after := a.(*schema.Set)
324+
325+
ignoreUpdateR := make(map[string]struct{})
326+
addRoleList := after.Difference(before).List()
327+
removeRoleList := before.Difference(after).List()
328+
329+
var updateRolesParams []map[string]interface{}
330+
for _, addR := range addRoleList {
331+
ar := addR.(map[string]interface{})["name"].(string)
332+
ae := addR.(map[string]interface{})["expiry_detail"].([]interface{})
333+
for _, removeR := range removeRoleList {
334+
if ar == removeR.(map[string]interface{})["name"].(string) {
335+
ignoreUpdateR[ar] = struct{}{}
336+
var updateR map[string]interface{}
337+
if len(ae) == 0 {
338+
updateR = map[string]interface{}{"name": ar}
339+
} else {
340+
updateR = map[string]interface{}{"name": ar, "expiry_detail": ae[0]}
341+
}
342+
updateP := map[string]interface{}{"field_mask": "expiryDetail.expire_time", "membership_role": updateR}
343+
updateRolesParams = append(updateRolesParams, updateP)
344+
}
345+
}
346+
}
347+
348+
var addRoles []map[string]interface{}
349+
for _, r := range addRoleList {
350+
name := r.(map[string]interface{})["name"].(string)
351+
if _, ignore := ignoreUpdateR[name]; ignore {
352+
continue
353+
}
354+
expiryDetail := r.(map[string]interface{})["expiry_detail"].([]interface{})
355+
if len(expiryDetail) == 0 {
356+
addRoles = append(addRoles, map[string]interface{}{"name": name})
357+
} else {
358+
addRoles = append(addRoles, map[string]interface{}{"name": name, "expiry_detail": expiryDetail[0]})
359+
}
360+
}
361+
var removeRoles []string
362+
for _, r := range removeRoleList {
363+
name := r.(map[string]interface{})["name"].(string)
364+
if _, ignore := ignoreUpdateR[name]; ignore {
365+
continue
366+
}
367+
removeRoles = append(removeRoles, name)
326368
}
327369

370+
// ref: https://cloud.google.com/identity/docs/reference/rest/v1/groups.memberships/modifyMembershipRoles#request-body
371+
// Only single operation per request is allowed.
372+
if len(removeRoles) > 0 {
373+
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
374+
Config: config,
375+
Method: "POST",
376+
Project: billingProject,
377+
RawURL: url,
378+
UserAgent: userAgent,
379+
Body: map[string]interface{}{"removeRoles": removeRoles},
380+
Timeout: d.Timeout(schema.TimeoutUpdate),
381+
})
382+
if err != nil {
383+
return fmt.Errorf("Error removing GroupMembership %q: %s", d.Id(), err)
384+
} else {
385+
log.Printf("[DEBUG] Finished removing GroupMembership %q: %#v", d.Id(), res)
386+
}
387+
}
388+
if len(updateRolesParams) > 0 {
389+
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
390+
Config: config,
391+
Method: "POST",
392+
Project: billingProject,
393+
RawURL: url,
394+
UserAgent: userAgent,
395+
Body: map[string]interface{}{"updateRolesParams": updateRolesParams},
396+
Timeout: d.Timeout(schema.TimeoutUpdate),
397+
})
398+
if err != nil {
399+
return fmt.Errorf("Error updating GroupMembership %q: %s", d.Id(), err)
400+
} else {
401+
log.Printf("[DEBUG] Finished updating GroupMembership %q: %#v", d.Id(), res)
402+
}
403+
}
404+
if len(addRoles) > 0 {
405+
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
406+
Config: config,
407+
Method: "POST",
408+
Project: billingProject,
409+
RawURL: url,
410+
UserAgent: userAgent,
411+
Body: map[string]interface{}{"addRoles": addRoles},
412+
Timeout: d.Timeout(schema.TimeoutUpdate),
413+
})
414+
if err != nil {
415+
return fmt.Errorf("Error adding GroupMembership %q: %s", d.Id(), err)
416+
} else {
417+
log.Printf("[DEBUG] Finished adding GroupMembership %q: %#v", d.Id(), res)
418+
}
419+
}
328420
}
329421

330422
d.Partial(false)
@@ -443,7 +535,8 @@ func flattenCloudIdentityGroupMembershipRoles(v interface{}, d *schema.ResourceD
443535
continue
444536
}
445537
transformed.Add(map[string]interface{}{
446-
"name": flattenCloudIdentityGroupMembershipRolesName(original["name"], d, config),
538+
"name": flattenCloudIdentityGroupMembershipRolesName(original["name"], d, config),
539+
"expiry_detail": flattenCloudIdentityGroupMembershipRolesExpiryDetail(original["expiryDetail"], d, config),
447540
})
448541
}
449542
return transformed
@@ -452,6 +545,23 @@ func flattenCloudIdentityGroupMembershipRolesName(v interface{}, d *schema.Resou
452545
return v
453546
}
454547

548+
func flattenCloudIdentityGroupMembershipRolesExpiryDetail(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
549+
if v == nil {
550+
return nil
551+
}
552+
original := v.(map[string]interface{})
553+
if len(original) == 0 {
554+
return nil
555+
}
556+
transformed := make(map[string]interface{})
557+
transformed["expire_time"] =
558+
flattenCloudIdentityGroupMembershipRolesExpiryDetailExpireTime(original["expireTime"], d, config)
559+
return []interface{}{transformed}
560+
}
561+
func flattenCloudIdentityGroupMembershipRolesExpiryDetailExpireTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
562+
return v
563+
}
564+
455565
func flattenCloudIdentityGroupMembershipType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
456566
return v
457567
}
@@ -508,6 +618,13 @@ func expandCloudIdentityGroupMembershipRoles(v interface{}, d tpgresource.Terraf
508618
transformed["name"] = transformedName
509619
}
510620

621+
transformedExpiryDetail, err := expandCloudIdentityGroupMembershipRolesExpiryDetail(original["expiry_detail"], d, config)
622+
if err != nil {
623+
return nil, err
624+
} else if val := reflect.ValueOf(transformedExpiryDetail); val.IsValid() && !tpgresource.IsEmptyValue(val) {
625+
transformed["expiryDetail"] = transformedExpiryDetail
626+
}
627+
511628
req = append(req, transformed)
512629
}
513630
return req, nil
@@ -517,17 +634,25 @@ func expandCloudIdentityGroupMembershipRolesName(v interface{}, d tpgresource.Te
517634
return v, nil
518635
}
519636

520-
func resourceCloudIdentityGroupMembershipUpdateEncoder(d *schema.ResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) {
521-
// Return object for modifyMembershipRoles (we build request object from scratch, without using `obj`)
522-
b, a := d.GetChange("roles")
523-
before := b.(*schema.Set)
524-
after := a.(*schema.Set)
525-
// ref: https://cloud.google.com/identity/docs/reference/rest/v1/groups.memberships/modifyMembershipRoles#request-body
526-
addRoles := after.Difference(before).List()
527-
var removeRoles []string
528-
for _, r := range before.Difference(after).List() {
529-
removeRoles = append(removeRoles, r.(map[string]interface{})["name"].(string))
530-
}
531-
req := map[string]interface{}{"addRoles": addRoles, "removeRoles": removeRoles}
532-
return req, nil
637+
func expandCloudIdentityGroupMembershipRolesExpiryDetail(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
638+
l := v.([]interface{})
639+
if len(l) == 0 || l[0] == nil {
640+
return nil, nil
641+
}
642+
raw := l[0]
643+
original := raw.(map[string]interface{})
644+
transformed := make(map[string]interface{})
645+
646+
transformedExpireTime, err := expandCloudIdentityGroupMembershipRolesExpiryDetailExpireTime(original["expire_time"], d, config)
647+
if err != nil {
648+
return nil, err
649+
} else if val := reflect.ValueOf(transformedExpireTime); val.IsValid() && !tpgresource.IsEmptyValue(val) {
650+
transformed["expireTime"] = transformedExpireTime
651+
}
652+
653+
return transformed, nil
654+
}
655+
656+
func expandCloudIdentityGroupMembershipRolesExpiryDetailExpireTime(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
657+
return v, nil
533658
}

google/services/cloudidentity/resource_cloud_identity_group_membership_test.go

+3
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ resource "google_cloud_identity_group_membership" "basic" {
8282
8383
roles {
8484
name = "MEMBER"
85+
expiry_detail {
86+
expire_time = "2215-10-02T15:01:23Z"
87+
}
8588
}
8689
8790
}

website/docs/r/cloud_identity_group_membership.html.markdown

+17-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ resource "google_cloud_identity_group_membership" "cloud_identity_group_membersh
7474
}
7575
7676
roles {
77-
name = "MEMBER"
77+
name = "MEMBER"
7878
}
7979
}
8080
```
@@ -136,6 +136,22 @@ The following arguments are supported:
136136
The name of the MembershipRole. Must be one of OWNER, MANAGER, MEMBER.
137137
Possible values are: `OWNER`, `MANAGER`, `MEMBER`.
138138

139+
* `expiry_detail` -
140+
(Optional)
141+
The MembershipRole expiry details, only supported for MEMBER role.
142+
Other roles cannot be accompanied with MEMBER role having expiry.
143+
Structure is [documented below](#nested_expiry_detail).
144+
145+
146+
<a name="nested_expiry_detail"></a>The `expiry_detail` block supports:
147+
148+
* `expire_time` -
149+
(Required)
150+
The time at which the MembershipRole will expire.
151+
A timestamp in RFC3339 UTC "Zulu" format, with nanosecond
152+
resolution and up to nine fractional digits.
153+
Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".
154+
139155
- - -
140156

141157

0 commit comments

Comments
 (0)